summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock89
-rw-r--r--Cargo.toml1
-rw-r--r--RELEASES.md2
-rw-r--r--compiler/rustc_ast/src/ast.rs13
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs17
-rw-r--r--compiler/rustc_ast/src/visit.rs5
-rw-r--r--compiler/rustc_ast_lowering/src/format.rs25
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs10
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs44
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs3
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs2
-rw-r--r--compiler/rustc_borrowck/src/def_use.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs509
-rw-r--r--compiler/rustc_borrowck/src/lib.rs2
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs2
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl4
-rw-r--r--compiler/rustc_builtin_macros/src/concat_idents.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/bounds.rs23
-rw-r--r--compiler/rustc_builtin_macros/src/env.rs12
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/offset_of.rs99
-rw-r--r--compiler/rustc_builtin_macros/src/trace_macros.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs5
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/callee.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/declare.rs64
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/mono_item.rs2
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs75
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs59
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs19
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs18
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs150
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs26
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs1
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs7
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs13
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs2
-rw-r--r--compiler/rustc_const_eval/src/lib.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs12
-rw-r--r--compiler/rustc_data_structures/Cargo.toml3
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/mod.rs22
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/tests.rs14
-rw-r--r--compiler/rustc_data_structures/src/lib.rs2
-rw-r--r--compiler/rustc_data_structures/src/marker.rs257
-rw-r--r--compiler/rustc_data_structures/src/owned_slice.rs45
-rw-r--r--compiler/rustc_data_structures/src/owned_slice/tests.rs16
-rw-r--r--compiler/rustc_data_structures/src/profiling.rs6
-rw-r--r--compiler/rustc_data_structures/src/sync.rs242
-rw-r--r--compiler/rustc_driver_impl/Cargo.toml10
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0771.md4
-rw-r--r--compiler/rustc_error_messages/src/lib.rs13
-rw-r--r--compiler/rustc_errors/Cargo.toml3
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs8
-rw-r--r--compiler/rustc_errors/src/lib.rs7
-rw-r--r--compiler/rustc_errors/src/lock.rs3
-rw-r--r--compiler/rustc_errors/src/tests.rs10
-rw-r--r--compiler/rustc_expand/src/base.rs12
-rw-r--r--compiler/rustc_feature/src/active.rs6
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs1
-rw-r--r--compiler/rustc_hir/src/errors.rs10
-rw-r--r--compiler/rustc_hir/src/hir.rs5
-rw-r--r--compiler/rustc_hir/src/lang_items.rs8
-rw-r--r--compiler/rustc_hir/src/lib.rs1
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl3
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs76
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs23
-rw-r--r--compiler/rustc_hir_analysis/src/check/dropck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs36
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/constrained_generic_params.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs34
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl11
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs198
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs24
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs172
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs2
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs593
-rw-r--r--compiler/rustc_infer/src/infer/equate.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs17
-rw-r--r--compiler/rustc_infer/src/infer/generalize.rs479
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs5
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs276
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs12
-rw-r--r--compiler/rustc_infer/src/infer/outlives/test_type_match.rs4
-rw-r--r--compiler/rustc_infer/src/infer/sub.rs6
-rw-r--r--compiler/rustc_interface/src/interface.rs25
-rw-r--r--compiler/rustc_interface/src/passes.rs12
-rw-r--r--compiler/rustc_interface/src/proc_macro_decls.rs2
-rw-r--r--compiler/rustc_lexer/src/lib.rs28
-rw-r--r--compiler/rustc_lint/messages.ftl16
-rw-r--r--compiler/rustc_lint/src/builtin.rs27
-rw-r--r--compiler/rustc_lint/src/context.rs16
-rw-r--r--compiler/rustc_lint/src/drop_forget_useless.rs164
-rw-r--r--compiler/rustc_lint/src/expect.rs2
-rw-r--r--compiler/rustc_lint/src/late.rs4
-rw-r--r--compiler/rustc_lint/src/levels.rs2
-rw-r--r--compiler/rustc_lint/src/lib.rs5
-rw-r--r--compiler/rustc_lint/src/lints.rs37
-rw-r--r--compiler/rustc_lint/src/types.rs4
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp109
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp3
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs9
-rw-r--r--compiler/rustc_macros/src/diagnostics/mod.rs2
-rw-r--r--compiler/rustc_macros/src/diagnostics/subdiagnostic.rs33
-rw-r--r--compiler/rustc_macros/src/diagnostics/utils.rs9
-rw-r--r--compiler/rustc_macros/src/query.rs6
-rw-r--r--compiler/rustc_metadata/src/dependency_format.rs31
-rw-r--r--compiler/rustc_metadata/src/locator.rs5
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs98
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs6
-rw-r--r--compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs3
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs29
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs7
-rw-r--r--compiler/rustc_middle/Cargo.toml1
-rw-r--r--compiler/rustc_middle/messages.ftl2
-rw-r--r--compiler/rustc_middle/src/error.rs10
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs11
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs12
-rw-r--r--compiler/rustc_middle/src/lib.rs10
-rw-r--r--compiler/rustc_middle/src/middle/lang_items.rs8
-rw-r--r--compiler/rustc_middle/src/middle/limits.rs4
-rw-r--r--compiler/rustc_middle/src/middle/mod.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs49
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs7
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs66
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs9
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs12
-rw-r--r--compiler/rustc_middle/src/query/erase.rs11
-rw-r--r--compiler/rustc_middle/src/query/mod.rs113
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs (renamed from compiler/rustc_middle/src/ty/query.rs)144
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs16
-rw-r--r--compiler/rustc_middle/src/ty/_match.rs4
-rw-r--r--compiler/rustc_middle/src/ty/abstract_const.rs11
-rw-r--r--compiler/rustc_middle/src/ty/closure.rs5
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs16
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs8
-rw-r--r--compiler/rustc_middle/src/ty/context.rs44
-rw-r--r--compiler/rustc_middle/src/ty/context/tls.rs8
-rw-r--r--compiler/rustc_middle/src/ty/erase_regions.rs5
-rw-r--r--compiler/rustc_middle/src/ty/error.rs4
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs14
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs2
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/mod.rs12
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs11
-rw-r--r--compiler/rustc_middle/src/ty/list.rs6
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs40
-rw-r--r--compiler/rustc_middle/src/ty/normalize_erasing_regions.rs2
-rw-r--r--compiler/rustc_middle/src/ty/opaque_types.rs12
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs69
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs36
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs39
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs63
-rw-r--r--compiler/rustc_middle/src/ty/util.rs43
-rw-r--r--compiler/rustc_middle/src/ty/visit.rs3
-rw-r--r--compiler/rustc_middle/src/util/bug.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs7
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs49
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs6
-rw-r--r--compiler/rustc_mir_build/src/lib.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs25
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs65
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs8
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs16
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/lattice.rs20
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/mod.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs67
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs270
-rw-r--r--compiler/rustc_mir_transform/Cargo.toml2
-rw-r--r--compiler/rustc_mir_transform/messages.ftl66
-rw-r--r--compiler/rustc_mir_transform/src/check_const_item_mutation.rs65
-rw-r--r--compiler/rustc_mir_transform/src/check_packed_ref.rs23
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs70
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs18
-rw-r--r--compiler/rustc_mir_transform/src/const_prop_lint.rs76
-rw-r--r--compiler/rustc_mir_transform/src/copy_prop.rs35
-rw-r--r--compiler/rustc_mir_transform/src/coverage/query.rs2
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs34
-rw-r--r--compiler/rustc_mir_transform/src/deduce_param_attrs.rs34
-rw-r--r--compiler/rustc_mir_transform/src/errors.rs245
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs18
-rw-r--r--compiler/rustc_mir_transform/src/function_item_references.rs33
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs43
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs27
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs13
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs12
-rw-r--r--compiler/rustc_mir_transform/src/lower_intrinsics.rs10
-rw-r--r--compiler/rustc_mir_transform/src/normalize_array_len.rs7
-rw-r--r--compiler/rustc_mir_transform/src/nrvo.rs3
-rw-r--r--compiler/rustc_mir_transform/src/ref_prop.rs408
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs2
-rw-r--r--compiler/rustc_mir_transform/src/ssa.rs247
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs2
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs2
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/mod.rs2
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs2
-rw-r--r--compiler/rustc_parse/messages.ftl10
-rw-r--r--compiler/rustc_parse/src/errors.rs37
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs31
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs65
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs5
-rw-r--r--compiler/rustc_parse/src/parser/item.rs55
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs23
-rw-r--r--compiler/rustc_passes/src/check_attr.rs2
-rw-r--r--compiler/rustc_passes/src/check_const.rs2
-rw-r--r--compiler/rustc_passes/src/dead.rs2
-rw-r--r--compiler/rustc_passes/src/debugger_visualizer.rs2
-rw-r--r--compiler/rustc_passes/src/diagnostic_items.rs2
-rw-r--r--compiler/rustc_passes/src/entry.rs2
-rw-r--r--compiler/rustc_passes/src/lang_items.rs2
-rw-r--r--compiler/rustc_passes/src/lib.rs2
-rw-r--r--compiler/rustc_passes/src/lib_features.rs2
-rw-r--r--compiler/rustc_passes/src/liveness.rs2
-rw-r--r--compiler/rustc_passes/src/loops.rs2
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs2
-rw-r--r--compiler/rustc_passes/src/reachable.rs2
-rw-r--r--compiler/rustc_passes/src/stability.rs3
-rw-r--r--compiler/rustc_passes/src/upvars.rs2
-rw-r--r--compiler/rustc_privacy/src/lib.rs40
-rw-r--r--compiler/rustc_query_impl/Cargo.toml2
-rw-r--r--compiler/rustc_query_impl/src/lib.rs205
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs289
-rw-r--r--compiler/rustc_query_impl/src/profiling_support.rs2
-rw-r--r--compiler/rustc_query_system/src/query/config.rs11
-rw-r--r--compiler/rustc_query_system/src/query/mod.rs2
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs127
-rw-r--r--compiler/rustc_resolve/messages.ftl33
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs24
-rw-r--r--compiler/rustc_resolve/src/errors.rs55
-rw-r--r--compiler/rustc_resolve/src/ident.rs127
-rw-r--r--compiler/rustc_resolve/src/late.rs295
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs70
-rw-r--r--compiler/rustc_resolve/src/lib.rs16
-rw-r--r--compiler/rustc_serialize/src/opaque.rs44
-rw-r--r--compiler/rustc_session/Cargo.toml2
-rw-r--r--compiler/rustc_session/src/config.rs4
-rw-r--r--compiler/rustc_session/src/cstore.rs11
-rw-r--r--compiler/rustc_session/src/filesearch.rs4
-rw-r--r--compiler/rustc_session/src/options.rs4
-rw-r--r--compiler/rustc_smir/src/lib.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs45
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs135
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/body.rs3
-rw-r--r--compiler/rustc_smir/src/stable_mir/mod.rs66
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs15
-rw-r--r--compiler/rustc_span/src/lib.rs1
-rw-r--r--compiler/rustc_span/src/source_map.rs39
-rw-r--r--compiler/rustc_span/src/symbol.rs7
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs2
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid.rs24
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs57
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs8
-rw-r--r--compiler/rustc_target/src/asm/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/messages.ftl2
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs158
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs64
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs49
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs44
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs31
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs163
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs17
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs51
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs23
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs69
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/vtable.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs86
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs1
-rw-r--r--compiler/rustc_traits/src/chalk/mod.rs2
-rw-r--r--compiler/rustc_traits/src/dropck_outlives.rs2
-rw-r--r--compiler/rustc_traits/src/evaluate_obligation.rs2
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs2
-rw-r--r--compiler/rustc_traits/src/lib.rs2
-rw-r--r--compiler/rustc_traits/src/normalize_erasing_regions.rs2
-rw-r--r--compiler/rustc_traits/src/normalize_projection_ty.rs31
-rw-r--r--compiler/rustc_traits/src/type_op.rs2
-rw-r--r--compiler/rustc_ty_utils/messages.ftl8
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs5
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs5
-rw-r--r--compiler/rustc_ty_utils/src/common_traits.rs11
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs13
-rw-r--r--compiler/rustc_ty_utils/src/errors.rs24
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs18
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs30
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs5
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs4
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs5
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs198
-rw-r--r--compiler/rustc_ty_utils/src/representability.rs2
-rw-r--r--compiler/rustc_ty_utils/src/structural_match.rs2
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs5
-rw-r--r--compiler/rustc_type_ir/src/lib.rs29
-rw-r--r--compiler/rustc_type_ir/src/structural_impls.rs1
-rw-r--r--compiler/rustc_type_ir/src/sty.rs1
-rw-r--r--config.example.toml4
-rw-r--r--library/alloc/src/collections/btree/map.rs2
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/vec/mod.rs12
-rw-r--r--library/core/benches/fmt.rs24
-rw-r--r--library/core/benches/num/dec2flt/mod.rs24
-rw-r--r--library/core/benches/num/flt2dec/mod.rs6
-rw-r--r--library/core/benches/num/mod.rs6
-rw-r--r--library/core/src/any.rs2
-rw-r--r--library/core/src/cell.rs23
-rw-r--r--library/core/src/cmp.rs3
-rw-r--r--library/core/src/convert/mod.rs1
-rw-r--r--library/core/src/ffi/c_str.rs5
-rw-r--r--library/core/src/ffi/mod.rs14
-rw-r--r--library/core/src/fmt/mod.rs2
-rw-r--r--library/core/src/fmt/rt.rs15
-rw-r--r--library/core/src/intrinsics.rs5
-rw-r--r--library/core/src/intrinsics/mir.rs4
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/core/src/marker.rs25
-rw-r--r--library/core/src/mem/mod.rs7
-rw-r--r--library/core/src/num/error.rs1
-rw-r--r--library/core/src/num/f32.rs36
-rw-r--r--library/core/src/num/f64.rs36
-rw-r--r--library/core/src/num/int_macros.rs38
-rw-r--r--library/core/src/num/mod.rs59
-rw-r--r--library/core/src/num/nonzero.rs67
-rw-r--r--library/core/src/ops/drop.rs68
-rw-r--r--library/core/src/panic.rs16
-rw-r--r--library/core/src/panic/panic_info.rs2
-rw-r--r--library/core/src/ptr/const_ptr.rs4
-rw-r--r--library/core/src/ptr/mod.rs6
-rw-r--r--library/core/src/ptr/mut_ptr.rs4
-rw-r--r--library/core/src/ptr/non_null.rs13
-rw-r--r--library/core/src/slice/iter.rs20
-rw-r--r--library/core/src/slice/iter/macros.rs73
-rw-r--r--library/core/src/slice/mod.rs46
-rw-r--r--library/core/src/str/pattern.rs8
-rw-r--r--library/core/src/task/poll.rs2
-rw-r--r--library/core/src/task/ready.rs4
-rw-r--r--library/core/src/task/wake.rs2
-rw-r--r--library/core/tests/lib.rs2
-rw-r--r--library/core/tests/num/int_macros.rs26
-rw-r--r--library/core/tests/num/mod.rs56
-rw-r--r--library/core/tests/num/uint_macros.rs26
-rw-r--r--library/portable-simd/.github/workflows/ci.yml4
-rw-r--r--library/portable-simd/README.md34
-rw-r--r--library/portable-simd/crates/core_simd/Cargo.toml9
-rw-r--r--library/portable-simd/crates/core_simd/examples/README.md13
-rw-r--r--library/portable-simd/crates/core_simd/examples/dot_product.rs169
-rw-r--r--library/portable-simd/crates/core_simd/src/alias.rs227
-rw-r--r--library/portable-simd/crates/core_simd/src/cast.rs55
-rw-r--r--library/portable-simd/crates/core_simd/src/elements.rs4
-rw-r--r--library/portable-simd/crates/core_simd/src/elements/const_ptr.rs141
-rw-r--r--library/portable-simd/crates/core_simd/src/elements/mut_ptr.rs136
-rw-r--r--library/portable-simd/crates/core_simd/src/eq.rs38
-rw-r--r--library/portable-simd/crates/core_simd/src/fmt.rs50
-rw-r--r--library/portable-simd/crates/core_simd/src/intrinsics.rs16
-rw-r--r--library/portable-simd/crates/core_simd/src/lane_count.rs36
-rw-r--r--library/portable-simd/crates/core_simd/src/lib.rs8
-rw-r--r--library/portable-simd/crates/core_simd/src/masks.rs69
-rw-r--r--library/portable-simd/crates/core_simd/src/masks/bitmask.rs4
-rw-r--r--library/portable-simd/crates/core_simd/src/masks/full_masks.rs4
-rw-r--r--library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs4
-rw-r--r--library/portable-simd/crates/core_simd/src/mod.rs6
-rw-r--r--library/portable-simd/crates/core_simd/src/ord.rs102
-rw-r--r--library/portable-simd/crates/core_simd/src/swizzle.rs72
-rw-r--r--library/portable-simd/crates/core_simd/src/swizzle_dyn.rs157
-rw-r--r--library/portable-simd/crates/core_simd/src/vector.rs665
-rw-r--r--library/portable-simd/crates/core_simd/src/vector/float.rs24
-rw-r--r--library/portable-simd/crates/core_simd/src/vector/int.rs63
-rw-r--r--library/portable-simd/crates/core_simd/src/vector/ptr.rs51
-rw-r--r--library/portable-simd/crates/core_simd/src/vector/uint.rs63
-rw-r--r--library/portable-simd/crates/core_simd/tests/autoderef.rs2
-rw-r--r--library/portable-simd/crates/core_simd/tests/mask_ops_impl/mask_macros.rs2
-rw-r--r--library/portable-simd/crates/core_simd/tests/masks.rs59
-rw-r--r--library/portable-simd/crates/core_simd/tests/ops_macros.rs14
-rw-r--r--library/portable-simd/crates/core_simd/tests/pointers.rs111
-rw-r--r--library/portable-simd/crates/core_simd/tests/round.rs2
-rw-r--r--library/portable-simd/crates/core_simd/tests/swizzle.rs16
-rw-r--r--library/portable-simd/crates/core_simd/tests/swizzle_dyn.rs74
-rw-r--r--library/portable-simd/crates/core_simd/tests/to_bytes.rs2
-rw-r--r--library/portable-simd/crates/core_simd/tests/try_from_slice.rs25
-rw-r--r--library/portable-simd/crates/test_helpers/Cargo.toml3
-rw-r--r--library/portable-simd/crates/test_helpers/src/array.rs2
-rw-r--r--library/portable-simd/crates/test_helpers/src/biteq.rs20
-rw-r--r--library/portable-simd/crates/test_helpers/src/lib.rs346
-rw-r--r--library/std/src/fs.rs2
-rw-r--r--library/std/src/io/copy.rs2
-rw-r--r--library/std/src/os/windows/io/handle.rs54
-rw-r--r--library/std/src/os/windows/io/raw.rs17
-rw-r--r--library/std/src/os/windows/io/socket.rs75
-rw-r--r--library/std/src/panic.rs4
-rw-r--r--library/std/src/panicking.rs2
-rw-r--r--library/std/src/personality/dwarf/eh.rs5
-rw-r--r--library/std/src/personality/gcc.rs11
-rw-r--r--library/std/src/sync/mpmc/error.rs2
-rw-r--r--library/std/src/sync/mpsc/mod.rs4
-rw-r--r--library/std/src/sys/mod.rs25
-rw-r--r--library/std/src/sys/sgx/waitqueue/mod.rs16
-rw-r--r--library/std/src/sys/unix/fs.rs2
-rw-r--r--library/std/src/sys/windows/c.rs1315
-rw-r--r--library/std/src/sys/windows/c/errors.rs1883
-rw-r--r--library/std/src/sys/windows/c/windows_sys.lst2590
-rw-r--r--library/std/src/sys/windows/c/windows_sys.rs4276
-rw-r--r--library/std/src/sys/windows/compat.rs16
-rw-r--r--library/std/src/sys/windows/fs.rs39
-rw-r--r--library/std/src/sys/windows/handle.rs6
-rw-r--r--library/std/src/sys/windows/io.rs7
-rw-r--r--library/std/src/sys/windows/net.rs4
-rw-r--r--library/std/src/sys/windows/pipe.rs2
-rw-r--r--library/std/src/sys/windows/process.rs10
-rw-r--r--library/std/src/sys/windows/rand.rs6
-rw-r--r--library/std/src/sys/windows/stack_overflow.rs4
-rw-r--r--library/std/src/sys/windows/stdio.rs22
-rw-r--r--library/std/src/sys/windows/thread.rs5
-rw-r--r--library/std/src/thread/local.rs4
-rw-r--r--library/std/src/thread/tests.rs4
-rw-r--r--library/std/tests/run-time-detect.rs1
m---------library/stdarch0
-rw-r--r--src/bootstrap/CHANGELOG.md1
-rw-r--r--src/bootstrap/Cargo.lock17
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/bootstrap/builder.rs4
-rw-r--r--src/bootstrap/config.rs45
-rw-r--r--src/bootstrap/flags.rs49
-rw-r--r--src/bootstrap/lib.rs1
-rw-r--r--src/bootstrap/run.rs56
-rw-r--r--src/bootstrap/test.rs42
-rw-r--r--src/bootstrap/tool.rs1
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version2
m---------src/doc/edition-guide0
m---------src/doc/embedded-book0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/doc/rustc/src/platform-support/esp-idf.md41
-rw-r--r--src/etc/completions/x.py.fish475
-rw-r--r--src/etc/completions/x.py.ps1607
-rw-r--r--src/etc/completions/x.py.sh1644
-rw-r--r--src/librustdoc/clean/auto_trait.rs5
-rw-r--r--src/librustdoc/clean/inline.rs7
-rw-r--r--src/librustdoc/clean/mod.rs140
-rw-r--r--src/librustdoc/clean/types.rs4
-rw-r--r--src/librustdoc/clean/utils.rs3
-rw-r--r--src/librustdoc/formats/cache.rs8
-rw-r--r--src/librustdoc/html/format.rs46
-rw-r--r--src/librustdoc/html/render/mod.rs6
-rw-r--r--src/librustdoc/json/conversions.rs2
-rw-r--r--src/librustdoc/lib.rs3
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs2
-rw-r--r--src/librustdoc/passes/strip_hidden.rs30
-rw-r--r--src/librustdoc/visit_ast.rs84
m---------src/llvm-project0
-rw-r--r--src/rustdoc-json-types/lib.rs8
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/drop_forget_ref.rs117
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/renamed_lints.rs4
-rw-r--r--src/tools/clippy/tests/ui/diverging_sub_expression.stderr10
-rw-r--r--src/tools/clippy/tests/ui/drop_forget_copy.rs86
-rw-r--r--src/tools/clippy/tests/ui/drop_forget_copy.stderr112
-rw-r--r--src/tools/clippy/tests/ui/drop_ref.stderr147
-rw-r--r--src/tools/clippy/tests/ui/forget_ref.rs50
-rw-r--r--src/tools/clippy/tests/ui/forget_ref.stderr111
-rw-r--r--src/tools/clippy/tests/ui/mem_forget.rs2
-rw-r--r--src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs2
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed8
-rw-r--r--src/tools/clippy/tests/ui/rename.rs8
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr112
-rw-r--r--src/tools/clippy/tests/ui/unknown_clippy_lints.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unknown_clippy_lints.stderr2
-rw-r--r--src/tools/compiletest/Cargo.toml2
-rw-r--r--src/tools/compiletest/src/common.rs89
-rw-r--r--src/tools/generate-windows-sys/Cargo.toml7
-rw-r--r--src/tools/generate-windows-sys/src/main.rs37
-rw-r--r--src/tools/jsondoclint/src/validator.rs4
-rw-r--r--src/tools/linkchecker/main.rs35
-rw-r--r--src/tools/miri/Cargo.lock364
-rw-r--r--src/tools/miri/Cargo.toml2
-rw-r--r--src/tools/miri/README.md2
-rw-r--r--src/tools/miri/bench-cargo-miri/zip-equal/Cargo.lock7
-rw-r--r--src/tools/miri/bench-cargo-miri/zip-equal/Cargo.toml8
-rw-r--r--src/tools/miri/bench-cargo-miri/zip-equal/src/main.rs22
-rw-r--r--src/tools/miri/cargo-miri/Cargo.lock303
-rwxr-xr-xsrc/tools/miri/miri10
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/bin/miri.rs8
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs6
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs2
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs110
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs33
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs31
-rw-r--r--src/tools/miri/src/concurrency/data_race.rs181
-rw-r--r--src/tools/miri/src/diagnostics.rs2
-rw-r--r--src/tools/miri/src/lib.rs1
-rw-r--r--src/tools/miri/src/machine.rs18
-rw-r--r--src/tools/miri/src/range_map.rs51
-rw-r--r--src/tools/miri/src/shims/intrinsics/simd.rs26
-rw-r--r--src/tools/miri/test-cargo-miri/subcrate/src/lib.rs13
-rw-r--r--src/tools/miri/tests/compiletest.rs165
-rw-r--r--src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/deallocate-twice.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/global_system_mixup.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/reallocate-dangling.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/stack_free.rs2
-rw-r--r--src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs2
-rw-r--r--src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr4
-rw-r--r--src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr4
-rw-r--r--src/tools/miri/tests/fail/concurrency/windows_join_detached.rs2
-rw-r--r--src/tools/miri/tests/fail/const-ub-checks.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/alloc_read_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/alloc_write_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dangling_thread_race.rs1
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/read_write_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/read_write_race_stack.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/relax_acquire_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/release_seq_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/rmw_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/stack_pop_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/write_write_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/write_write_race_stack.rs2
-rw-r--r--src/tools/miri/tests/fail/deny_lint.rs8
-rw-r--r--src/tools/miri/tests/fail/deny_lint.stderr17
-rw-r--r--src/tools/miri/tests/fail/erroneous_const.stderr2
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-float-to-int.rs3
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr13
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-gather.rs3
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-gather.stderr13
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-scatter.rs2
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr18
-rw-r--r--src/tools/miri/tests/fail/layout_cycle.rs2
-rw-r--r--src/tools/miri/tests/fail/memleak.rs2
-rw-r--r--src/tools/miri/tests/fail/memleak_no_backtrace.rs2
-rw-r--r--src/tools/miri/tests/fail/memleak_rc.rs2
-rw-r--r--src/tools/miri/tests/fail/no_main.rs2
-rw-r--r--src/tools/miri/tests/fail/panic/double_panic.rs2
-rw-r--r--src/tools/miri/tests/fail/panic/double_panic.stderr5
-rw-r--r--src/tools/miri/tests/fail/panic/no_std.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort1.rs2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort1.stderr5
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort2.rs2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort2.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort3.rs2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort3.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort4.rs2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort4.stderr2
-rw-r--r--src/tools/miri/tests/fail/shims/fs/isolated_file.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/zst_slice.rs2
-rw-r--r--src/tools/miri/tests/fail/tokio/sleep.rs2
-rw-r--r--src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs2
-rw-r--r--src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr6
-rw-r--r--src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs2
-rw-r--r--src/tools/miri/tests/fail/uninit_buffer.rs4
-rw-r--r--src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs3
-rw-r--r--src/tools/miri/tests/panic/panic1.stderr8
-rw-r--r--src/tools/miri/tests/pass-dep/shims/libc-misc.rs1
-rw-r--r--src/tools/miri/tests/pass/0weak_memory_consistency.rs2
-rw-r--r--src/tools/miri/tests/pass/concurrency/data_race.rs22
-rw-r--r--src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs2
-rw-r--r--src/tools/miri/tests/pass/concurrency/sync.rs12
-rw-r--r--src/tools/miri/tests/pass/concurrency/thread_locals.rs1
-rw-r--r--src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs8
-rw-r--r--src/tools/miri/tests/pass/concurrency/windows_init_once.rs4
-rw-r--r--src/tools/miri/tests/pass/concurrency/windows_join_multiple.rs6
-rw-r--r--src/tools/miri/tests/pass/panic/catch_panic.rs5
-rw-r--r--src/tools/miri/tests/pass/panic/catch_panic.stderr2
-rw-r--r--src/tools/miri/tests/pass/panic/concurrent-panic.rs2
-rw-r--r--src/tools/miri/tests/pass/portable-simd-ptrs.rs12
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs3
-rw-r--r--src/tools/miri/tests/pass/sysroot.rs9
-rw-r--r--src/tools/rustdoc-gui/tester.js3
-rw-r--r--src/tools/tidy/src/deps.rs80
-rw-r--r--src/tools/tidy/src/style.rs6
-rw-r--r--src/tools/tidy/src/ui_tests.rs38
-rw-r--r--tests/codegen/addr-of-mutate.rs34
-rw-r--r--tests/codegen/binary-search-index-no-bound-check.rs4
-rw-r--r--tests/codegen/fewer-names.rs14
-rw-r--r--tests/codegen/issues/issue-73396-bounds-check-after-position.rs30
-rw-r--r--tests/codegen/mem-replace-big-type.rs15
-rw-r--r--tests/codegen/nrvo.rs2
-rw-r--r--tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs44
-rw-r--r--tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs69
-rw-r--r--tests/codegen/slice-iter-nonnull.rs77
-rw-r--r--tests/codegen/vec-shrink-panik.rs4
-rw-r--r--tests/debuginfo/reference-debuginfo.rs173
-rw-r--r--tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir12
-rw-r--r--tests/mir-opt/building/custom/projections.rs25
-rw-r--r--tests/mir-opt/building/custom/projections.tuples.built.after.mir8
-rw-r--r--tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff166
-rw-r--r--tests/mir-opt/combine_transmutes.rs22
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff3
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff3
-rw-r--r--tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff3
-rw-r--r--tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff3
-rw-r--r--tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff16
-rw-r--r--tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff8
-rw-r--r--tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff3
-rw-r--r--tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff12
-rw-r--r--tests/mir-opt/copy-prop/partial_init.main.CopyProp.diff13
-rw-r--r--tests/mir-opt/copy-prop/partial_init.rs18
-rw-r--r--tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff15
-rw-r--r--tests/mir-opt/issue_99325.main.built.after.mir4
-rw-r--r--tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff8
-rw-r--r--tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir2
-rw-r--r--tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir2
-rw-r--r--tests/mir-opt/nrvo_miscompile_111005.rs22
-rw-r--r--tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff18
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir10
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir178
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir146
-rw-r--r--tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff175
-rw-r--r--tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff38
-rw-r--r--tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff56
-rw-r--r--tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff27
-rw-r--r--tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff75
-rw-r--r--tests/mir-opt/reference_prop.read_through_raw.ReferencePropagation.diff23
-rw-r--r--tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff475
-rw-r--r--tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff536
-rw-r--r--tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff472
-rw-r--r--tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff482
-rw-r--r--tests/mir-opt/reference_prop.rs592
-rw-r--r--tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff67
-rw-r--r--tests/mir-opt/slice_filter.rs2
-rw-r--r--tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff16
-rw-r--r--tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff258
-rw-r--r--tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff267
-rw-r--r--tests/mir-opt/slice_filter.variant_b-{closure#0}.ReferencePropagation.diff103
-rw-r--r--tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir5
-rw-r--r--tests/run-make-fulldeps/obtain-borrowck/driver.rs4
-rw-r--r--tests/run-make/branch-protection-check-IBT/Makefile15
-rw-r--r--tests/run-make/branch-protection-check-IBT/main.rs3
-rw-r--r--tests/run-make/coverage-llvmir/filecheck.testprog.txt2
-rw-r--r--tests/run-make/coverage-reports/Makefile25
-rw-r--r--tests/run-make/coverage-reports/expected_show_coverage.async.txt4
-rw-r--r--tests/run-make/coverage-reports/expected_show_coverage.sort_groups.txt49
-rw-r--r--tests/run-make/coverage-reports/expected_show_coverage.uses_crate.txt16
-rw-r--r--tests/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt14
-rw-r--r--tests/run-make/coverage-reports/sort_subviews.py50
-rw-r--r--tests/run-make/coverage/sort_groups.rs23
-rw-r--r--tests/run-make/forced-unwind-terminate-pof/Makefile9
-rw-r--r--tests/run-make/forced-unwind-terminate-pof/foo.rs17
-rw-r--r--tests/run-make/staticlib-dylib-linkage/Makefile21
-rw-r--r--tests/run-make/staticlib-dylib-linkage/bar.rs5
-rw-r--r--tests/run-make/staticlib-dylib-linkage/foo.c10
-rw-r--r--tests/run-make/staticlib-dylib-linkage/foo.rs13
-rw-r--r--tests/rustdoc-gui/check-stab-in-docblock.goml18
-rw-r--r--tests/rustdoc-gui/codeblock-sub.goml2
-rw-r--r--tests/rustdoc-gui/docblock-details.goml2
-rw-r--r--tests/rustdoc-gui/item-info.goml4
-rw-r--r--tests/rustdoc-gui/notable-trait.goml8
-rw-r--r--tests/rustdoc-gui/scrape-examples-button-focus.goml6
-rw-r--r--tests/rustdoc-gui/scrape-examples-layout.goml7
-rw-r--r--tests/rustdoc-gui/search-result-color.goml172
-rw-r--r--tests/rustdoc-gui/search-result-display.goml4
-rw-r--r--tests/rustdoc-gui/settings.goml2
-rw-r--r--tests/rustdoc-gui/sidebar-source-code-display.goml26
-rw-r--r--tests/rustdoc-gui/sidebar.goml14
-rw-r--r--tests/rustdoc-gui/source-code-page.goml47
-rw-r--r--tests/rustdoc-gui/src-font-size.goml2
-rw-r--r--tests/rustdoc-gui/struct-fields.goml2
-rw-r--r--tests/rustdoc-gui/type-declation-overflow.goml2
-rw-r--r--tests/rustdoc-json/impls/impl_item_visibility.rs26
-rw-r--r--tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs28
-rw-r--r--tests/rustdoc-json/impls/impl_item_visibility_show_private.rs27
-rw-r--r--tests/rustdoc-json/type/inherent_associated_type.rs29
-rw-r--r--tests/rustdoc-json/type/inherent_associated_type_bound.rs21
-rw-r--r--tests/rustdoc-json/type/inherent_associated_type_projections.rs33
-rw-r--r--tests/rustdoc-ui/ice-bug-report-url.rs4
-rw-r--r--tests/rustdoc-ui/ice-bug-report-url.stderr1
-rw-r--r--tests/rustdoc/impl-alias-substituted.rs9
-rw-r--r--tests/rustdoc/inherent-projections.rs44
-rw-r--r--tests/rustdoc/intra-doc/inherent-associated-types.rs45
-rw-r--r--tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs31
-rw-r--r--tests/rustdoc/issue-111064-reexport-trait-from-hidden.rs21
-rw-r--r--tests/rustdoc/nested-items-issue-111415.rs36
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs49
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr30
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs2
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr9
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs4
-rw-r--r--tests/ui/argument-suggestions/issue-97484.stderr2
-rw-r--r--tests/ui/array-slice-vec/slice-mut-2.stderr2
-rw-r--r--tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs10
-rw-r--r--tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr49
-rw-r--r--tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.rs16
-rw-r--r--tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr37
-rw-r--r--tests/ui/associated-inherent-types/bugs/ice-substitution.rs23
-rw-r--r--tests/ui/associated-inherent-types/bugs/ice-substitution.stderr6
-rw-r--r--tests/ui/associated-inherent-types/bugs/inference-fail.rs15
-rw-r--r--tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs19
-rw-r--r--tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs15
-rw-r--r--tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs2
-rw-r--r--tests/ui/associated-inherent-types/former-subst-ice.rs16
-rw-r--r--tests/ui/associated-inherent-types/generic-associated-types-bad.item.stderr15
-rw-r--r--tests/ui/associated-inherent-types/generic-associated-types-bad.local.stderr15
-rw-r--r--tests/ui/associated-inherent-types/generic-associated-types-bad.region.stderr11
-rw-r--r--tests/ui/associated-inherent-types/generic-associated-types-bad.rs26
-rw-r--r--tests/ui/associated-inherent-types/inference-fail.rs11
-rw-r--r--tests/ui/associated-inherent-types/inference-fail.stderr (renamed from tests/ui/associated-inherent-types/bugs/inference-fail.stderr)6
-rw-r--r--tests/ui/associated-inherent-types/inference.rs40
-rw-r--r--tests/ui/associated-inherent-types/issue-109768.rs12
-rw-r--r--tests/ui/associated-inherent-types/issue-109768.stderr35
-rw-r--r--tests/ui/associated-inherent-types/issue-109789.rs22
-rw-r--r--tests/ui/associated-inherent-types/issue-109789.stderr21
-rw-r--r--tests/ui/associated-inherent-types/issue-109790.rs18
-rw-r--r--tests/ui/associated-inherent-types/late-bound-regions.rs25
-rw-r--r--tests/ui/associated-inherent-types/late-bound-regions.stderr12
-rw-r--r--tests/ui/associated-inherent-types/normalization-overflow.rs12
-rw-r--r--tests/ui/associated-inherent-types/normalization-overflow.stderr8
-rw-r--r--tests/ui/associated-inherent-types/private-in-public.rs26
-rw-r--r--tests/ui/associated-inherent-types/private-in-public.stderr34
-rw-r--r--tests/ui/associated-inherent-types/regionck-0.rs14
-rw-r--r--tests/ui/associated-inherent-types/regionck-0.stderr10
-rw-r--r--tests/ui/associated-inherent-types/regionck-1.rs13
-rw-r--r--tests/ui/associated-inherent-types/regionck-1.stderr29
-rw-r--r--tests/ui/associated-inherent-types/regionck-2.rs14
-rw-r--r--tests/ui/associated-inherent-types/regionck-2.stderr18
-rw-r--r--tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs26
-rw-r--r--tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.rs12
-rw-r--r--tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.stderr17
-rw-r--r--tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.rs14
-rw-r--r--tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.stderr18
-rw-r--r--tests/ui/associated-types/associated-types-eq-3.stderr2
-rw-r--r--tests/ui/associated-types/associated-types-overridden-binding-2.stderr2
-rw-r--r--tests/ui/associated-types/issue-65774-1.stderr2
-rw-r--r--tests/ui/associated-types/issue-65774-2.stderr2
-rw-r--r--tests/ui/async-await/async-block-control-flow-static-semantics.stderr4
-rw-r--r--tests/ui/async-await/issue-86507.drop_tracking.stderr2
-rw-r--r--tests/ui/async-await/issue-86507.drop_tracking_mir.stderr2
-rw-r--r--tests/ui/async-await/issue-86507.no_drop_tracking.stderr2
-rw-r--r--tests/ui/async-await/issues/issue-102206.stderr10
-rw-r--r--tests/ui/async-await/multiple-lifetimes/partial-relation.rs2
-rw-r--r--tests/ui/attr-bad-crate-attr.rs (renamed from tests/ui/attr-bad-crate-attr.rc)0
-rw-r--r--tests/ui/attr-bad-crate-attr.stderr8
-rw-r--r--tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr4
-rw-r--r--tests/ui/borrowck/borrowck-access-permissions.stderr6
-rw-r--r--tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr8
-rw-r--r--tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr4
-rw-r--r--tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs1
-rw-r--r--tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs1
-rw-r--r--tests/ui/borrowck/borrowck-issue-14498.stderr2
-rw-r--r--tests/ui/borrowck/borrowck-reborrow-from-mut.stderr2
-rw-r--r--tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs2
-rw-r--r--tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs23
-rw-r--r--tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr24
-rw-r--r--tests/ui/borrowck/issue-85765.stderr2
-rw-r--r--tests/ui/borrowck/mutability-errors.stderr24
-rw-r--r--tests/ui/check-cfg/order-independant.names_after.stderr19
-rw-r--r--tests/ui/check-cfg/order-independant.names_before.stderr19
-rw-r--r--tests/ui/check-cfg/order-independant.rs16
-rw-r--r--tests/ui/closure_context/issue-26046-fn-mut.stderr2
-rw-r--r--tests/ui/closure_context/issue-26046-fn-once.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/bad-pattern.rs23
-rw-r--r--tests/ui/closures/2229_closure_analysis/bad-pattern.stderr113
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs1
-rw-r--r--tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs1
-rw-r--r--tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs2
-rw-r--r--tests/ui/closures/issue-868.rs (renamed from tests/ui/issues/issue-868.rs)0
-rw-r--r--tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr4
-rw-r--r--tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr4
-rw-r--r--tests/ui/coercion/coercion-slice.stderr11
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_good.rs10
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs4
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr13
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs4
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr12
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs33
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr8
-rw-r--r--tests/ui/const-generics/assoc_const_as_type_argument.rs13
-rw-r--r--tests/ui/const-generics/assoc_const_as_type_argument.stderr21
-rw-r--r--tests/ui/const-generics/const-arg-in-const-arg.full.stderr163
-rw-r--r--tests/ui/const-generics/const-arg-in-const-arg.min.stderr206
-rw-r--r--tests/ui/const-generics/const-arg-in-const-arg.rs60
-rw-r--r--tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr9
-rw-r--r--tests/ui/const-generics/const-argument-non-static-lifetime.rs2
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr4
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr4
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr2
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr2
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr2
-rw-r--r--tests/ui/const-generics/defaults/trait_objects_fail.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-74713.rs2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-74713.stderr11
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.rs12
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.stderr11
-rw-r--r--tests/ui/const-generics/issue-46511.rs2
-rw-r--r--tests/ui/const-generics/issue-46511.stderr11
-rw-r--r--tests/ui/const-generics/issues/issue-105821.rs2
-rw-r--r--tests/ui/const-generics/issues/issue-56445-1.full.stderr8
-rw-r--r--tests/ui/const-generics/issues/issue-56445-1.min.stderr8
-rw-r--r--tests/ui/const-generics/issues/issue-56445-1.rs2
-rw-r--r--tests/ui/const-generics/issues/issue-62878.full.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-62878.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-71169.full.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-71169.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-71381.full.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-71381.min.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-71611.full.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-71611.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-77357.rs11
-rw-r--r--tests/ui/const-generics/issues/issue-77357.stderr11
-rw-r--r--tests/ui/const-generics/issues/issue-83993.rs14
-rw-r--r--tests/ui/const-generics/issues/issue-88997.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-90364.stderr2
-rw-r--r--tests/ui/const-generics/late-bound-vars/in_closure.rs20
-rw-r--r--tests/ui/const-generics/late-bound-vars/in_closure.stderr13
-rw-r--r--tests/ui/const-generics/late-bound-vars/simple.rs19
-rw-r--r--tests/ui/const-generics/late-bound-vars/simple.stderr13
-rw-r--r--tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs4
-rw-r--r--tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr17
-rw-r--r--tests/ui/const-generics/outer-lifetime-in-const-generic-default.rs2
-rw-r--r--tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr8
-rw-r--r--tests/ui/const-generics/variant-discrimiant-no-generics.full.stderr34
-rw-r--r--tests/ui/const-generics/variant-discrimiant-no-generics.min.stderr34
-rw-r--r--tests/ui/const-generics/variant-discrimiant-no-generics.rs32
-rw-r--r--tests/ui/const-ptr/out_of_bounds_read.rs2
-rw-r--r--tests/ui/const-ptr/out_of_bounds_read.stderr6
-rw-r--r--tests/ui/consts/const-eval/format.stderr56
-rw-r--r--tests/ui/consts/const-eval/ub-ref-ptr.rs1
-rw-r--r--tests/ui/consts/const-eval/ub-ref-ptr.stderr34
-rw-r--r--tests/ui/consts/const-integer-bool-ops.rs10
-rw-r--r--tests/ui/consts/const-integer-bool-ops.stderr90
-rw-r--r--tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr6
-rw-r--r--tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr6
-rw-r--r--tests/ui/consts/const-mut-refs/issue-76510.rs1
-rw-r--r--tests/ui/consts/const-tup-index-span.rs1
-rw-r--r--tests/ui/consts/const-tup-index-span.stderr6
-rw-r--r--tests/ui/consts/const_forget.rs2
-rw-r--r--tests/ui/consts/extra-const-ub/detect-extra-ub.rs1
-rw-r--r--tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr8
-rw-r--r--tests/ui/consts/issue-104155.rs3
-rw-r--r--tests/ui/consts/issue-54954.rs2
-rw-r--r--tests/ui/consts/issue-54954.stderr12
-rw-r--r--tests/ui/consts/issue-56164.stderr12
-rw-r--r--tests/ui/consts/issue-66693.stderr12
-rw-r--r--tests/ui/consts/issue-miri-1910.rs1
-rw-r--r--tests/ui/consts/issue-miri-1910.stderr2
-rw-r--r--tests/ui/crate-leading-sep.rs2
-rw-r--r--tests/ui/custom_test_frameworks/mismatch.stderr2
-rw-r--r--tests/ui/cycle-trait/issue-12511.rs (renamed from tests/ui/issues/issue-12511.rs)0
-rw-r--r--tests/ui/cycle-trait/issue-12511.stderr (renamed from tests/ui/issues/issue-12511.stderr)0
-rw-r--r--tests/ui/deriving/issue-15689-1.rs (renamed from tests/ui/issues/issue-15689-1.rs)0
-rw-r--r--tests/ui/deriving/issue-15689-2.rs (renamed from tests/ui/issues/issue-15689-2.rs)0
-rw-r--r--tests/ui/diagnostic-width/E0271.stderr4
-rw-r--r--tests/ui/did_you_mean/issue-38147-4.stderr4
-rw-r--r--tests/ui/did_you_mean/issue-39544.stderr12
-rw-r--r--tests/ui/did_you_mean/issue-40823.stderr2
-rw-r--r--tests/ui/drop/dropck-eyepatch-manuallydrop.rs22
-rw-r--r--tests/ui/drop/issue-110682.rs92
-rw-r--r--tests/ui/drop/issue-979.rs (renamed from tests/ui/issues/issue-979.rs)0
-rw-r--r--tests/ui/drop/repeat-drop.rs2
-rw-r--r--tests/ui/dst/dst-bad-coerce1.stderr4
-rw-r--r--tests/ui/dst/dst-object-from-unsized-type.stderr8
-rw-r--r--tests/ui/dupe-first-attr.rs (renamed from tests/ui/dupe-first-attr.rc)16
-rw-r--r--tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.current.stderr (renamed from tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.stderr)2
-rw-r--r--tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.next.stderr15
-rw-r--r--tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs3
-rw-r--r--tests/ui/enum-discriminant/auxiliary/discr-foreign-dep.rs7
-rw-r--r--tests/ui/enum-discriminant/discr-foreign.rs11
-rw-r--r--tests/ui/enum-discriminant/issue-41394.rs1
-rw-r--r--tests/ui/enum-discriminant/issue-41394.stderr6
-rw-r--r--tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs2
-rw-r--r--tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr5
-rw-r--r--tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs2
-rw-r--r--tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr5
-rw-r--r--tests/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr5
-rw-r--r--tests/ui/enum/issue-1821.rs (renamed from tests/ui/issues/issue-1821.rs)0
-rw-r--r--tests/ui/enum/issue-67945-1.stderr5
-rw-r--r--tests/ui/enum/issue-67945-2.stderr5
-rw-r--r--tests/ui/error-codes/E0389.stderr2
-rw-r--r--tests/ui/error-codes/E0771.rs2
-rw-r--r--tests/ui/error-codes/E0771.stderr8
-rw-r--r--tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed3
-rw-r--r--tests/ui/explicit/explicit-call-to-supertrait-dtor.rs3
-rw-r--r--tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr2
-rw-r--r--tests/ui/extenv/extenv-escaped-var.rs3
-rw-r--r--tests/ui/extenv/extenv-escaped-var.stderr11
-rw-r--r--tests/ui/extenv/issue-110547.stderr12
-rw-r--r--tests/ui/extern/auxiliary/invalid-utf8.txt1
-rw-r--r--tests/ui/feature-gates/auxiliary/debugger-visualizer.natvis3
-rw-r--r--tests/ui/feature-gates/feature-gate-builtin_syntax.rs7
-rw-r--r--tests/ui/feature-gates/feature-gate-builtin_syntax.stderr12
-rw-r--r--tests/ui/feature-gates/feature-gate-cfg_overflow_checks.rs6
-rw-r--r--tests/ui/feature-gates/feature-gate-cfg_overflow_checks.stderr12
-rw-r--r--tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr9
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs1
-rw-r--r--tests/ui/fmt/ifmt-unimpl.stderr2
-rw-r--r--tests/ui/fn/issue-3099.rs (renamed from tests/ui/issues/issue-3099.rs)0
-rw-r--r--tests/ui/fn/issue-3099.stderr (renamed from tests/ui/issues/issue-3099.stderr)0
-rw-r--r--tests/ui/generator/drop-env.rs1
-rw-r--r--tests/ui/generator/drop-tracking-error-body.rs18
-rw-r--r--tests/ui/generator/drop-tracking-error-body.stderr17
-rw-r--r--tests/ui/generator/issue-57017.no_drop_tracking.stderr42
-rw-r--r--tests/ui/generator/issue-57017.rs1
-rw-r--r--tests/ui/generator/non-static-is-unpin.rs1
-rw-r--r--tests/ui/generator/resume-arg-size.rs1
-rw-r--r--tests/ui/generic-associated-types/equality-bound.stderr5
-rw-r--r--tests/ui/generic-associated-types/issue-76535.base.stderr3
-rw-r--r--tests/ui/generic-associated-types/issue-79422.base.stderr3
-rw-r--r--tests/ui/generic-associated-types/issue-79422.extended.stderr2
-rw-r--r--tests/ui/generic-associated-types/issue-88595.rs1
-rw-r--r--tests/ui/generic-associated-types/issue-88595.stderr34
-rw-r--r--tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs1
-rw-r--r--tests/ui/illegal-ufcs-drop.fixed3
-rw-r--r--tests/ui/illegal-ufcs-drop.rs3
-rw-r--r--tests/ui/illegal-ufcs-drop.stderr2
-rw-r--r--tests/ui/impl-trait/extra-impl-in-trait-impl.fixed19
-rw-r--r--tests/ui/impl-trait/extra-impl-in-trait-impl.rs19
-rw-r--r--tests/ui/impl-trait/extra-impl-in-trait-impl.stderr26
-rw-r--r--tests/ui/impl-trait/in-assoc-type-unconstrained.rs27
-rw-r--r--tests/ui/impl-trait/in-assoc-type-unconstrained.stderr59
-rw-r--r--tests/ui/impl-trait/in-assoc-type.rs21
-rw-r--r--tests/ui/impl-trait/in-assoc-type.stderr22
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.current.stderr3
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.next.stderr3
-rw-r--r--tests/ui/impl-trait/issue-103181-1.current.stderr (renamed from tests/ui/impl-trait/issue-103181-1.stderr)2
-rw-r--r--tests/ui/impl-trait/issue-103181-1.next.stderr12
-rw-r--r--tests/ui/impl-trait/issue-103181-1.rs2
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr5
-rw-r--r--tests/ui/inference/deref-suggestion.stderr20
-rw-r--r--tests/ui/inference/issue-71584.rs (renamed from tests/ui/issues/issue-71584.rs)0
-rw-r--r--tests/ui/inference/issue-71584.stderr (renamed from tests/ui/issues/issue-71584.stderr)0
-rw-r--r--tests/ui/issues/auxiliary/issue-3136-a.rc4
-rw-r--r--tests/ui/issues/auxiliary/issue-3136-a.rs7
-rw-r--r--tests/ui/issues/issue-11374.stderr10
-rw-r--r--tests/ui/issues/issue-14366.stderr4
-rw-r--r--tests/ui/issues/issue-17033.stderr11
-rw-r--r--tests/ui/issues/issue-18819.stderr2
-rw-r--r--tests/ui/issues/issue-22034.stderr2
-rw-r--r--tests/ui/issues/issue-22872.stderr2
-rw-r--r--tests/ui/issues/issue-2748-a.rs17
-rw-r--r--tests/ui/issues/issue-3136-b.rs2
-rw-r--r--tests/ui/issues/issue-46302.stderr10
-rw-r--r--tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr20
-rw-r--r--tests/ui/issues/issue-51515.rs1
-rw-r--r--tests/ui/issues/issue-51515.stderr6
-rw-r--r--tests/ui/issues/issue-61106.stderr10
-rw-r--r--tests/ui/issues/issue-61623.stderr2
-rw-r--r--tests/ui/kindck/kindck-impl-type-params.stderr12
-rw-r--r--tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr3
-rw-r--r--tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr3
-rw-r--r--tests/ui/kindck/kindck-send-unsafe.rs10
-rw-r--r--tests/ui/kindck/kindck-send-unsafe.rs~rust-lang_master12
-rw-r--r--tests/ui/kindck/kindck-send-unsafe.stderr23
-rw-r--r--tests/ui/lifetimes/issue-64173-unused-lifetimes.rs2
-rw-r--r--tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr11
-rw-r--r--tests/ui/lifetimes/unusual-rib-combinations.rs2
-rw-r--r--tests/ui/lifetimes/unusual-rib-combinations.stderr8
-rw-r--r--tests/ui/lint/drop_copy.rs79
-rw-r--r--tests/ui/lint/drop_copy.stderr108
-rw-r--r--tests/ui/lint/drop_ref.rs (renamed from src/tools/clippy/tests/ui/drop_ref.rs)48
-rw-r--r--tests/ui/lint/drop_ref.stderr127
-rw-r--r--tests/ui/lint/forget_copy.rs56
-rw-r--r--tests/ui/lint/forget_copy.stderr88
-rw-r--r--tests/ui/lint/forget_ref.rs39
-rw-r--r--tests/ui/lint/forget_ref.stderr97
-rw-r--r--tests/ui/lint/issue-111359.rs27
-rw-r--r--tests/ui/lint/issue-111359.stderr26
-rw-r--r--tests/ui/liveness/liveness-unused.rs2
-rw-r--r--tests/ui/macros/builtin-prelude-no-accidents.stderr15
-rw-r--r--tests/ui/macros/issue-2804-2.rs (renamed from tests/ui/issues/issue-2804-2.rs)0
-rw-r--r--tests/ui/macros/panic-temporaries.rs19
-rw-r--r--tests/ui/macros/parse-complex-macro-invoc-op.rs1
-rw-r--r--tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout18
-rw-r--r--tests/ui/methods/method-self-arg-1.stderr10
-rw-r--r--tests/ui/mismatched_types/cast-rfc0401.stderr12
-rw-r--r--tests/ui/mismatched_types/dont-point-return-on-E0308.stderr10
-rw-r--r--tests/ui/mut/mut-cross-borrowing.stderr10
-rw-r--r--tests/ui/never_type/fallback-closure-wrap.fallback.stderr2
-rw-r--r--tests/ui/never_type/never-assign-dead-code.rs1
-rw-r--r--tests/ui/never_type/never-assign-dead-code.stderr8
-rw-r--r--tests/ui/nll/issue-30438-a.rs (renamed from tests/ui/issues/issue-30438-a.rs)0
-rw-r--r--tests/ui/nll/issue-30438-a.stderr (renamed from tests/ui/issues/issue-30438-a.stderr)0
-rw-r--r--tests/ui/nll/issue-30438-b.rs (renamed from tests/ui/issues/issue-30438-b.rs)0
-rw-r--r--tests/ui/nll/issue-30438-b.stderr (renamed from tests/ui/issues/issue-30438-b.stderr)0
-rw-r--r--tests/ui/nll/issue-30438-c.rs (renamed from tests/ui/issues/issue-30438-c.rs)0
-rw-r--r--tests/ui/nll/issue-30438-c.stderr (renamed from tests/ui/issues/issue-30438-c.stderr)0
-rw-r--r--tests/ui/nll/issue-47388.stderr2
-rw-r--r--tests/ui/nll/issue-51244.stderr2
-rw-r--r--tests/ui/nll/issue-54302-cases.rs (renamed from tests/ui/issues/issue-54302-cases.rs)0
-rw-r--r--tests/ui/nll/issue-54302-cases.stderr (renamed from tests/ui/issues/issue-54302-cases.stderr)0
-rw-r--r--tests/ui/nll/issue-54302.rs (renamed from tests/ui/issues/issue-54302.rs)0
-rw-r--r--tests/ui/nll/issue-54302.stderr (renamed from tests/ui/issues/issue-54302.stderr)0
-rw-r--r--tests/ui/nll/issue-57989.stderr2
-rw-r--r--tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs2
-rw-r--r--tests/ui/nll/ty-outlives/projection-body.rs2
-rw-r--r--tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs19
-rw-r--r--tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs19
-rw-r--r--tests/ui/object-safety/issue-19538.stderr3
-rw-r--r--tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr3
-rw-r--r--tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr6
-rw-r--r--tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr6
-rw-r--r--tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr3
-rw-r--r--tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr3
-rw-r--r--tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr3
-rw-r--r--tests/ui/offset-of/offset-of-arg-count.rs19
-rw-r--r--tests/ui/offset-of/offset-of-arg-count.stderr59
-rw-r--r--tests/ui/offset-of/offset-of-builtin.rs44
-rw-r--r--tests/ui/offset-of/offset-of-builtin.stderr65
-rw-r--r--tests/ui/offset-of/offset-of-dst-field.stderr3
-rw-r--r--tests/ui/offset-of/offset-of-unstable.stderr5
-rw-r--r--tests/ui/or-patterns/or-patterns-default-binding-modes.rs2
-rw-r--r--tests/ui/parser/builtin-syntax.rs9
-rw-r--r--tests/ui/parser/builtin-syntax.stderr14
-rw-r--r--tests/ui/parser/dyn-trait-compatibility.stderr12
-rw-r--r--tests/ui/parser/impl-on-unsized-typo.rs6
-rw-r--r--tests/ui/parser/impl-on-unsized-typo.stderr8
-rw-r--r--tests/ui/parser/issues/issue-111416.rs3
-rw-r--r--tests/ui/parser/issues/issue-111416.stderr18
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs3
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs2
-rw-r--r--tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs2
-rw-r--r--tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr4
-rw-r--r--tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs2
-rw-r--r--tests/ui/pattern/pattern-error-continue.stderr15
-rw-r--r--tests/ui/pattern/usefulness/consts-opaque.rs18
-rw-r--r--tests/ui/pattern/usefulness/consts-opaque.stderr75
-rw-r--r--tests/ui/print_type_sizes/async.rs2
-rw-r--r--tests/ui/print_type_sizes/async.stdout8
-rw-r--r--tests/ui/print_type_sizes/generator_discr_placement.rs1
-rw-r--r--tests/ui/print_type_sizes/generator_discr_placement.stdout2
-rw-r--r--tests/ui/range/issue-54505-no-literals.fixed24
-rw-r--r--tests/ui/range/issue-54505-no-literals.rs24
-rw-r--r--tests/ui/range/issue-54505-no-literals.stderr120
-rw-r--r--tests/ui/range/issue-54505-no-std.rs12
-rw-r--r--tests/ui/range/issue-54505-no-std.stderr60
-rw-r--r--tests/ui/range/issue-54505.fixed12
-rw-r--r--tests/ui/range/issue-54505.rs12
-rw-r--r--tests/ui/range/issue-54505.stderr60
-rw-r--r--tests/ui/range/issue-73553-misinterp-range-literal.stderr20
-rw-r--r--tests/ui/reachable/auxiliary/foreign-priv-aux.rs21
-rw-r--r--tests/ui/reachable/foreign-priv.rs12
-rw-r--r--tests/ui/reachable/issue-948.rs (renamed from tests/ui/issues/issue-948.rs)0
-rw-r--r--tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs6
-rw-r--r--tests/ui/regions/type-param-outlives-reempty-issue-74429.rs2
-rw-r--r--tests/ui/resolve/explicit-self-lowercase-param.rs8
-rw-r--r--tests/ui/resolve/explicit-self-lowercase-param.stderr8
-rw-r--r--tests/ui/resolve/issue-109250.rs3
-rw-r--r--tests/ui/resolve/issue-109250.stderr14
-rw-r--r--tests/ui/resolve/issue-111312.rs11
-rw-r--r--tests/ui/resolve/issue-111312.stderr15
-rw-r--r--tests/ui/resolve/issue-3099-a.rs (renamed from tests/ui/issues/issue-3099-a.rs)0
-rw-r--r--tests/ui/resolve/issue-3099-a.stderr (renamed from tests/ui/issues/issue-3099-a.stderr)0
-rw-r--r--tests/ui/resolve/issue-3099-b.rs (renamed from tests/ui/issues/issue-3099-b.rs)0
-rw-r--r--tests/ui/resolve/issue-3099-b.stderr (renamed from tests/ui/issues/issue-3099-b.stderr)0
-rw-r--r--tests/ui/resolve/issue-50599.rs1
-rw-r--r--tests/ui/resolve/issue-50599.stderr6
-rw-r--r--tests/ui/resolve/resolve-variant-assoc-item.stderr14
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs2
-rw-r--r--tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs2
-rw-r--r--tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr30
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs24
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr4
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs24
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs24
-rw-r--r--tests/ui/rust-2018/remove-extern-crate.fixed1
-rw-r--r--tests/ui/rust-2018/remove-extern-crate.rs1
-rw-r--r--tests/ui/rust-2018/remove-extern-crate.stderr6
-rw-r--r--tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr3
-rw-r--r--tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr3
-rw-r--r--tests/ui/self/self-ctor-inner-const.rs17
-rw-r--r--tests/ui/self/self-ctor-inner-const.stderr33
-rw-r--r--tests/ui/self/self-ctor-nongeneric.rs15
-rw-r--r--tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr8
-rw-r--r--tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr4
-rw-r--r--tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr6
-rw-r--r--tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr2
-rw-r--r--tests/ui/span/borrowck-fn-in-const-b.stderr2
-rw-r--r--tests/ui/span/borrowck-object-mutability.stderr2
-rw-r--r--tests/ui/span/coerce-suggestions.stderr11
-rw-r--r--tests/ui/span/issue-39018.stderr10
-rw-r--r--tests/ui/span/mut-arg-hint.stderr6
-rw-r--r--tests/ui/specialization/min_specialization/specialize-associated-type.rs37
-rw-r--r--tests/ui/specialization/min_specialization/specialize_nothing.rs14
-rw-r--r--tests/ui/specialization/min_specialization/specialize_nothing.stderr14
-rw-r--r--tests/ui/specialization/min_specialization/specialize_on_type_error.rs33
-rw-r--r--tests/ui/specialization/min_specialization/specialize_on_type_error.stderr12
-rw-r--r--tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.rs50
-rw-r--r--tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr27
-rw-r--r--tests/ui/statics/issue-91050-1.rs2
-rw-r--r--tests/ui/str/str-array-assignment.stderr21
-rw-r--r--tests/ui/structs-enums/issue-103869.fixed13
-rw-r--r--tests/ui/structs-enums/issue-103869.rs (renamed from tests/ui/parser/issue-103869.rs)11
-rw-r--r--tests/ui/structs-enums/issue-103869.stderr (renamed from tests/ui/parser/issue-103869.stderr)9
-rw-r--r--tests/ui/suggestions/as-ref.stderr88
-rw-r--r--tests/ui/suggestions/derive-macro-missing-bounds.stderr8
-rw-r--r--tests/ui/suggestions/issue-68049-2.stderr8
-rw-r--r--tests/ui/suggestions/issue-99597.rs15
-rw-r--r--tests/ui/suggestions/issue-99597.stderr15
-rw-r--r--tests/ui/suggestions/suggest-borrow-to-dyn-object.rs16
-rw-r--r--tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr18
-rw-r--r--tests/ui/suggestions/suggest-ref-macro.rs4
-rw-r--r--tests/ui/suggestions/suggest-ref-macro.stderr19
-rw-r--r--tests/ui/suggestions/suggest-ref-mut.rs3
-rw-r--r--tests/ui/suggestions/suggest-ref-mut.stderr12
-rw-r--r--tests/ui/suggestions/type-ascription-instead-of-let.fixed11
-rw-r--r--tests/ui/suggestions/type-ascription-instead-of-let.rs4
-rw-r--r--tests/ui/suggestions/type-ascription-instead-of-let.stderr7
-rw-r--r--tests/ui/test-attrs/issue-12997-1.rs (renamed from tests/ui/issues/issue-12997-1.rs)0
-rw-r--r--tests/ui/test-attrs/issue-12997-1.stderr (renamed from tests/ui/issues/issue-12997-1.stderr)0
-rw-r--r--tests/ui/test-attrs/issue-12997-2.rs (renamed from tests/ui/issues/issue-12997-2.rs)0
-rw-r--r--tests/ui/test-attrs/issue-12997-2.stderr (renamed from tests/ui/issues/issue-12997-2.stderr)0
-rw-r--r--tests/ui/test-attrs/issue-34932.rs (renamed from tests/ui/issues/issue-34932.rs)0
-rw-r--r--tests/ui/track-diagnostics/track6.rs3
-rw-r--r--tests/ui/track-diagnostics/track6.stderr4
-rw-r--r--tests/ui/traits/coercion-generic-bad.stderr2
-rw-r--r--tests/ui/traits/copy-guessing.rs3
-rw-r--r--tests/ui/traits/impl-evaluation-order.rs2
-rw-r--r--tests/ui/traits/issue-106072.rs1
-rw-r--r--tests/ui/traits/issue-106072.stderr12
-rw-r--r--tests/ui/traits/issue-20692.stderr3
-rw-r--r--tests/ui/traits/issue-38604.stderr3
-rw-r--r--tests/ui/traits/issue-7013.stderr2
-rw-r--r--tests/ui/traits/map-types.stderr2
-rw-r--r--tests/ui/traits/new-solver/alias-bound-unsound.rs27
-rw-r--r--tests/ui/traits/new-solver/alias-bound-unsound.stderr24
-rw-r--r--tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr4
-rw-r--r--tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs1
-rw-r--r--tests/ui/traits/new-solver/nested-alias-bound.rs20
-rw-r--r--tests/ui/traits/new-solver/temporary-ambiguity.rs2
-rw-r--r--tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr3
-rw-r--r--tests/ui/traits/non_lifetime_binders/universe-error1.rs18
-rw-r--r--tests/ui/traits/non_lifetime_binders/universe-error1.stderr27
-rw-r--r--tests/ui/traits/object/safety.stderr3
-rw-r--r--tests/ui/traits/test-2.stderr3
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-1.stderr2
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-2.stderr4
-rw-r--r--tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr4
-rw-r--r--tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs2
-rw-r--r--tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs9
-rw-r--r--tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr22
-rw-r--r--tests/ui/type-alias-impl-trait/issue-98604.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-98608.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/wf-in-associated-type.fail.stderr25
-rw-r--r--tests/ui/type-alias-impl-trait/wf-in-associated-type.rs45
-rw-r--r--tests/ui/type-alias-impl-trait/wf-nested.fail.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/wf-nested.rs60
-rw-r--r--tests/ui/type/issue-58355.stderr2
-rw-r--r--tests/ui/type/missing-let-in-binding-2.fixed5
-rw-r--r--tests/ui/type/missing-let-in-binding-2.rs5
-rw-r--r--tests/ui/type/missing-let-in-binding-2.stderr13
-rw-r--r--tests/ui/type/missing-let-in-binding-3.rs5
-rw-r--r--tests/ui/type/missing-let-in-binding-3.stderr10
-rw-r--r--tests/ui/type/missing-let-in-binding-4.rs5
-rw-r--r--tests/ui/type/missing-let-in-binding-4.stderr10
-rw-r--r--tests/ui/type/type-dependent-def-issue-49241.rs1
-rw-r--r--tests/ui/type/type-dependent-def-issue-49241.stderr6
-rw-r--r--tests/ui/type/type-mismatch.stderr20
-rw-r--r--tests/ui/type/type-path-err-node-types.stderr12
-rw-r--r--tests/ui/typeck/bad-index-due-to-nested.stderr18
-rw-r--r--tests/ui/typeck/bad-type-in-vec-contains.stderr10
-rw-r--r--tests/ui/typeck/issue-13853.stderr10
-rw-r--r--tests/ui/unsized-locals/align.rs30
-rw-r--r--tests/ui/unsized-locals/suggest-borrow.stderr11
-rw-r--r--tests/ui/unsized/unsized-fn-param.stderr16
-rw-r--r--tests/ui/weird-exprs.rs30
-rw-r--r--tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr9
-rw-r--r--tests/ui/wf/wf-convert-unsafe-trait-obj.stderr9
-rw-r--r--tests/ui/wf/wf-unsafe-trait-obj-match.stderr6
-rw-r--r--triagebot.toml2
1248 files changed, 32162 insertions, 11479 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6d77c2b0b88..be95e63eb76 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -741,7 +741,7 @@ dependencies = [
"tracing-subscriber",
"unified-diff",
"walkdir",
- "windows 0.46.0",
+ "windows",
]
[[package]]
@@ -854,7 +854,7 @@ dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
- "memoffset",
+ "memoffset 0.7.1",
"scopeguard",
]
@@ -1242,6 +1242,16 @@ dependencies = [
]
[[package]]
+name = "field-offset"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3cf3a800ff6e860c863ca6d4b16fd999db8b752819c1606884047b73e468535"
+dependencies = [
+ "memoffset 0.8.0",
+ "rustc_version",
+]
+
+[[package]]
name = "filetime"
version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1444,6 +1454,13 @@ dependencies = [
]
[[package]]
+name = "generate-windows-sys"
+version = "0.1.0"
+dependencies = [
+ "windows-bindgen",
+]
+
+[[package]]
name = "generic-array"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1640,7 +1657,7 @@ dependencies = [
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
- "windows 0.48.0",
+ "windows",
]
[[package]]
@@ -2183,6 +2200,15 @@ dependencies = [
[[package]]
name = "memoffset"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "memoffset"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
@@ -2191,6 +2217,15 @@ dependencies = [
]
[[package]]
+name = "memoffset"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
name = "mime"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3252,7 +3287,7 @@ dependencies = [
"tempfile",
"thorin-dwp",
"tracing",
- "windows 0.46.0",
+ "windows",
]
[[package]]
@@ -3299,6 +3334,7 @@ dependencies = [
"rustc-hash",
"rustc-rayon",
"rustc-rayon-core",
+ "rustc_arena",
"rustc_graphviz",
"rustc_index",
"rustc_macros",
@@ -3308,7 +3344,7 @@ dependencies = [
"tempfile",
"thin-vec",
"tracing",
- "windows 0.46.0",
+ "windows",
]
[[package]]
@@ -3353,6 +3389,7 @@ dependencies = [
"rustc_middle",
"rustc_mir_build",
"rustc_mir_dataflow",
+ "rustc_mir_transform",
"rustc_monomorphize",
"rustc_parse",
"rustc_passes",
@@ -3368,7 +3405,7 @@ dependencies = [
"rustc_ty_utils",
"serde_json",
"tracing",
- "windows 0.46.0",
+ "windows",
]
[[package]]
@@ -3418,7 +3455,7 @@ dependencies = [
"termize",
"tracing",
"unicode-width",
- "windows 0.46.0",
+ "windows",
]
[[package]]
@@ -3773,6 +3810,7 @@ dependencies = [
"chalk-ir",
"derive_more",
"either",
+ "field-offset",
"gsgdt",
"measureme",
"polonius-engine",
@@ -3861,8 +3899,10 @@ dependencies = [
"rustc_const_eval",
"rustc_data_structures",
"rustc_errors",
+ "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
+ "rustc_macros",
"rustc_middle",
"rustc_mir_dataflow",
"rustc_serialize",
@@ -3985,7 +4025,9 @@ dependencies = [
name = "rustc_query_impl"
version = "0.0.0"
dependencies = [
+ "field-offset",
"measureme",
+ "memoffset 0.6.5",
"rustc-rayon-core",
"rustc_ast",
"rustc_data_structures",
@@ -4086,7 +4128,7 @@ dependencies = [
"smallvec",
"termize",
"tracing",
- "windows 0.46.0",
+ "windows",
]
[[package]]
@@ -5112,9 +5154,9 @@ checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
[[package]]
name = "ui_test"
-version = "0.6.2"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e10f5f88ce8c331a388deda1e6e2bd533c73ca89cc5f539a3df02ed35c8efba"
+checksum = "191a442639ea102fa62671026047e51d574bfda44b7fdf32151d7314624c1cd2"
dependencies = [
"bstr 1.3.0",
"cargo-platform",
@@ -5490,23 +5532,30 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
-version = "0.46.0"
+version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25"
+checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [
- "windows-targets 0.42.2",
+ "windows-targets 0.48.0",
]
[[package]]
-name = "windows"
-version = "0.48.0"
+name = "windows-bindgen"
+version = "0.49.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
+checksum = "b6935fb09b84ee57929ae92518b475f5dfdfbeb87c5334756acc28ee8e202b60"
dependencies = [
- "windows-targets 0.48.0",
+ "windows-metadata",
+ "windows-tokens",
]
[[package]]
+name = "windows-metadata"
+version = "0.49.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f5bca94a32bf1e6a376522b6601275a3b611ee885ec0f1b6a05f17e8cfd3385"
+
+[[package]]
name = "windows-sys"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5570,6 +5619,12 @@ dependencies = [
]
[[package]]
+name = "windows-tokens"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b34c9a3b28cb41db7385546f7f9a8179348dffc89923dde66857b1ba5312f6b4"
+
+[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 7aaa34a68e6..53331e2869f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -39,6 +39,7 @@ members = [
"src/tools/collect-license-metadata",
"src/tools/generate-copyright",
"src/tools/suggest-tests",
+ "src/tools/generate-windows-sys",
]
exclude = [
diff --git a/RELEASES.md b/RELEASES.md
index e72905c15bd..85266a17550 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1481,7 +1481,7 @@ and related tools.
[is_power_of_two_usize]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroUsize.html#method.is_power_of_two
[stdarch/1266]: https://github.com/rust-lang/stdarch/pull/1266
-Version 1.58.1 (2022-01-19)
+Version 1.58.1 (2022-01-20)
===========================
* Fix race condition in `std::fs::remove_dir_all` ([CVE-2022-21658])
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index e3ac8a8784a..43b429f6947 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -120,6 +120,12 @@ impl Path {
pub fn is_global(&self) -> bool {
!self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
}
+
+ /// If this path is a single identifier with no arguments, does not ensure
+ /// that the path resolves to a const param, the caller should check this.
+ pub fn is_potential_trivial_const_arg(&self) -> bool {
+ self.segments.len() == 1 && self.segments[0].args.is_none()
+ }
}
/// A segment of a path: an identifier, an optional lifetime, and a set of types.
@@ -1154,7 +1160,9 @@ impl Expr {
///
/// If this is not the case, name resolution does not resolve `N` when using
/// `min_const_generics` as more complex expressions are not supported.
- pub fn is_potential_trivial_const_param(&self) -> bool {
+ ///
+ /// Does not ensure that the path resolves to a const param, the caller should check this.
+ pub fn is_potential_trivial_const_arg(&self) -> bool {
let this = if let ExprKind::Block(block, None) = &self.kind
&& block.stmts.len() == 1
&& let StmtKind::Expr(expr) = &block.stmts[0].kind
@@ -1165,8 +1173,7 @@ impl Expr {
};
if let ExprKind::Path(None, path) = &this.kind
- && path.segments.len() == 1
- && path.segments[0].args.is_none()
+ && path.is_potential_trivial_const_arg()
{
true
} else {
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index f0a6a5e0725..db296aa44db 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -48,14 +48,15 @@ pub enum TokenTree {
Delimited(DelimSpan, Delimiter, TokenStream),
}
-// Ensure all fields of `TokenTree` is `Send` and `Sync`.
+// Ensure all fields of `TokenTree` are `DynSend` and `DynSync`.
#[cfg(parallel_compiler)]
fn _dummy()
where
- Token: Send + Sync,
- DelimSpan: Send + Sync,
- Delimiter: Send + Sync,
- TokenStream: Send + Sync,
+ Token: sync::DynSend + sync::DynSync,
+ Spacing: sync::DynSend + sync::DynSync,
+ DelimSpan: sync::DynSend + sync::DynSync,
+ Delimiter: sync::DynSend + sync::DynSync,
+ TokenStream: sync::DynSend + sync::DynSync,
{
}
@@ -118,7 +119,7 @@ where
}
}
-pub trait ToAttrTokenStream: sync::Send + sync::Sync {
+pub trait ToAttrTokenStream: sync::DynSend + sync::DynSync {
fn to_attr_token_stream(&self) -> AttrTokenStream;
}
@@ -550,6 +551,10 @@ impl TokenStream {
vec_mut.extend(stream_iter);
}
}
+
+ pub fn chunks(&self, chunk_size: usize) -> core::slice::Chunks<'_, TokenTree> {
+ self.0.chunks(chunk_size)
+ }
}
/// By-reference iterator over a [`TokenStream`], that produces `&TokenTree`
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 1526ffa0b03..275692ad5dd 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -188,6 +188,9 @@ pub trait Visitor<'ast>: Sized {
fn visit_variant(&mut self, v: &'ast Variant) {
walk_variant(self, v)
}
+ fn visit_variant_discr(&mut self, discr: &'ast AnonConst) {
+ self.visit_anon_const(discr);
+ }
fn visit_label(&mut self, label: &'ast Label) {
walk_label(self, label)
}
@@ -380,7 +383,7 @@ where
visitor.visit_ident(variant.ident);
visitor.visit_vis(&variant.vis);
visitor.visit_variant_data(&variant.data);
- walk_list!(visitor, visit_anon_const, &variant.disr_expr);
+ walk_list!(visitor, visit_variant_discr, &variant.disr_expr);
walk_list!(visitor, visit_attribute, &variant.attrs);
}
diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs
index 9b295339d94..afcf8b15cd8 100644
--- a/compiler/rustc_ast_lowering/src/format.rs
+++ b/compiler/rustc_ast_lowering/src/format.rs
@@ -446,7 +446,30 @@ fn expand_format_args<'hir>(
&& argmap.iter().enumerate().all(|(i, (&(j, _), _))| i == j)
&& arguments.iter().skip(1).all(|arg| !may_contain_yield_point(&arg.expr));
- let args = if use_simple_array {
+ let args = if arguments.is_empty() {
+ // Generate:
+ // &<core::fmt::Argument>::none()
+ //
+ // Note:
+ // `none()` just returns `[]`. We use `none()` rather than `[]` to limit the lifetime.
+ //
+ // This makes sure that this still fails to compile, even when the argument is inlined:
+ //
+ // ```
+ // let f = format_args!("{}", "a");
+ // println!("{f}"); // error E0716
+ // ```
+ //
+ // Cases where keeping the object around is allowed, such as `format_args!("a")`,
+ // are handled above by the `allow_const` case.
+ let none_fn = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
+ macsp,
+ hir::LangItem::FormatArgument,
+ sym::none,
+ ));
+ let none = ctx.expr_call(macsp, none_fn, &[]);
+ ctx.expr(macsp, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, none))
+ } else if use_simple_array {
// Generate:
// &[
// <core::fmt::Argument>::new_display(&arg0),
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 3d154a93fb2..08ee3761bac 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -305,7 +305,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
);
this.arena.alloc(this.ty(span, hir::TyKind::Err(guar)))
}
- Some(ty) => this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy),
+ Some(ty) => this.lower_ty(
+ ty,
+ &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false },
+ ),
},
);
hir::ItemKind::TyAlias(ty, generics)
@@ -852,7 +855,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ImplItemKind::Type(ty)
}
Some(ty) => {
- let ty = this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy);
+ let ty = this.lower_ty(
+ ty,
+ &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true },
+ );
hir::ImplItemKind::Type(ty)
}
},
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 0d21c8a84d0..cd6614a54a4 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -247,7 +247,7 @@ enum ImplTraitContext {
in_trait: bool,
},
/// Impl trait in type aliases.
- TypeAliasesOpaqueTy,
+ TypeAliasesOpaqueTy { in_assoc_ty: bool },
/// `impl Trait` is unstably accepted in this position.
FeatureGated(ImplTraitPosition, Symbol),
/// `impl Trait` is not accepted in this position.
@@ -1190,13 +1190,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// parsing. We try to resolve that ambiguity by attempting resolution in both the
// type and value namespaces. If we resolved the path in the value namespace, we
// transform it into a generic const argument.
- TyKind::Path(qself, path) => {
+ TyKind::Path(None, path) => {
if let Some(res) = self
.resolver
.get_partial_res(ty.id)
.and_then(|partial_res| partial_res.full_res())
{
- if !res.matches_ns(Namespace::TypeNS) {
+ if !res.matches_ns(Namespace::TypeNS)
+ && path.is_potential_trivial_const_arg()
+ {
debug!(
"lower_generic_arg: Lowering type argument as const argument: {:?}",
ty,
@@ -1218,7 +1220,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let path_expr = Expr {
id: ty.id,
- kind: ExprKind::Path(qself.clone(), path.clone()),
+ kind: ExprKind::Path(None, path.clone()),
span,
attrs: AttrVec::new(),
tokens: None,
@@ -1405,14 +1407,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
*in_trait,
itctx,
),
- ImplTraitContext::TypeAliasesOpaqueTy => self.lower_opaque_impl_trait(
- span,
- hir::OpaqueTyOrigin::TyAlias,
- *def_node_id,
- bounds,
- false,
- itctx,
- ),
+ &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self
+ .lower_opaque_impl_trait(
+ span,
+ hir::OpaqueTyOrigin::TyAlias { in_assoc_ty },
+ *def_node_id,
+ bounds,
+ false,
+ itctx,
+ ),
ImplTraitContext::Universal => {
let span = t.span;
self.create_def(
@@ -1532,13 +1535,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// If this came from a TAIT (as opposed to a function that returns an RPIT), we only want
// to capture the lifetimes that appear in the bounds. So visit the bounds to find out
// exactly which ones those are.
- let lifetimes_to_remap = if origin == hir::OpaqueTyOrigin::TyAlias {
- // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters
- Vec::new()
- } else {
- // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
- // we only keep the lifetimes that appear in the `impl Debug` itself:
- lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds)
+ let lifetimes_to_remap = match origin {
+ hir::OpaqueTyOrigin::TyAlias { .. } => {
+ // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters
+ Vec::new()
+ }
+ hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..) => {
+ // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
+ // we only keep the lifetimes that appear in the `impl Debug` itself:
+ lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds)
+ }
};
debug!(?lifetimes_to_remap);
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index b960671bf6e..3d5056d82c5 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -603,6 +603,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
gate_all!(yeet_expr, "`do yeet` expression is experimental");
gate_all!(dyn_star, "`dyn*` trait objects are experimental");
gate_all!(const_closures, "const closures are experimental");
+ gate_all!(builtin_syntax, "`builtin #` syntax is unstable");
if !visitor.features.negative_bounds {
for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index b74c59bca30..87c32ffce12 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -556,8 +556,7 @@ impl<'a> State<'a> {
self.pclose();
}
ast::ExprKind::OffsetOf(container, fields) => {
- // FIXME: This should have its own syntax, distinct from a macro invocation.
- self.word("offset_of!");
+ self.word("builtin # offset_of");
self.popen();
self.rbox(0, Inconsistent);
self.print_type(container);
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 94939c7e4cd..167f245361a 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -328,7 +328,7 @@ impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> {
fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain {
// bottom = nothing is reserved or activated yet;
- BitSet::new_empty(self.borrow_set.len() * 2)
+ BitSet::new_empty(self.borrow_set.len())
}
fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) {
diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs
index 74e6ce37e97..b775739fed2 100644
--- a/compiler/rustc_borrowck/src/def_use.rs
+++ b/compiler/rustc_borrowck/src/def_use.rs
@@ -55,7 +55,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
// `PlaceMention` and `AscribeUserType` both evaluate the place, which must not
// contain dangling references.
PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) |
- PlaceContext::NonUse(NonUseContext::AscribeUserTy) |
+ PlaceContext::NonUse(NonUseContext::AscribeUserTy(_)) |
PlaceContext::MutatingUse(MutatingUseContext::AddressOf) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) |
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 7558247948f..6286033e067 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -1,4 +1,4 @@
-use rustc_errors::{Applicability, Diagnostic};
+use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::intravisit::Visitor;
use rustc_hir::Node;
@@ -478,179 +478,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
match self.local_names[local] {
Some(name) if !local_decl.from_compiler_desugaring() => {
- let label = match *local_decl.local_info() {
- LocalInfo::User(mir::BindingForm::ImplicitSelf(_)) => {
- let (span, suggestion) =
- suggest_ampmut_self(self.infcx.tcx, local_decl);
- Some((true, span, suggestion))
- }
-
- LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
- binding_mode: ty::BindingMode::BindByValue(_),
- opt_ty_info,
- ..
- })) => {
- // check if the RHS is from desugaring
- let opt_assignment_rhs_span =
- self.body.find_assignments(local).first().map(|&location| {
- if let Some(mir::Statement {
- source_info: _,
- kind:
- mir::StatementKind::Assign(box (
- _,
- mir::Rvalue::Use(mir::Operand::Copy(place)),
- )),
- }) = self.body[location.block]
- .statements
- .get(location.statement_index)
- {
- self.body.local_decls[place.local].source_info.span
- } else {
- self.body.source_info(location).span
- }
- });
- match opt_assignment_rhs_span.and_then(|s| s.desugaring_kind()) {
- // on for loops, RHS points to the iterator part
- Some(DesugaringKind::ForLoop) => {
- self.suggest_similar_mut_method_for_for_loop(&mut err);
- err.span_label(opt_assignment_rhs_span.unwrap(), format!(
- "this iterator yields `{pointer_sigil}` {pointer_desc}s",
- ));
- None
- }
- // don't create labels for compiler-generated spans
- Some(_) => None,
- None => {
- let label = if name != kw::SelfLower {
- suggest_ampmut(
- self.infcx.tcx,
- local_decl,
- opt_assignment_rhs_span,
- opt_ty_info,
- )
- } else {
- match local_decl.local_info() {
- LocalInfo::User(mir::BindingForm::Var(
- mir::VarBindingForm {
- opt_ty_info: None, ..
- },
- )) => {
- let (span, sugg) = suggest_ampmut_self(
- self.infcx.tcx,
- local_decl,
- );
- (true, span, sugg)
- }
- // explicit self (eg `self: &'a Self`)
- _ => suggest_ampmut(
- self.infcx.tcx,
- local_decl,
- opt_assignment_rhs_span,
- opt_ty_info,
- ),
- }
- };
- Some(label)
- }
- }
- }
-
- LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
- binding_mode: ty::BindingMode::BindByReference(_),
- ..
- })) => {
- let pattern_span = local_decl.source_info.span;
- suggest_ref_mut(self.infcx.tcx, pattern_span)
- .map(|replacement| (true, pattern_span, replacement))
- }
-
- _ => unreachable!(),
- };
-
- match label {
- Some((true, err_help_span, suggested_code)) => {
- let (is_trait_sig, local_trait) = self.is_error_in_trait(local);
- if !is_trait_sig {
- err.span_suggestion_verbose(
- err_help_span,
- format!(
- "consider changing this to be a mutable {pointer_desc}"
- ),
- suggested_code,
- Applicability::MachineApplicable,
- );
- } else if let Some(x) = local_trait {
- err.span_suggestion_verbose(
- x,
- format!(
- "consider changing that to be a mutable {pointer_desc}"
- ),
- suggested_code,
- Applicability::MachineApplicable,
- );
- }
- }
- Some((false, err_label_span, message)) => {
- struct BindingFinder {
- span: Span,
- hir_id: Option<hir::HirId>,
- }
-
- impl<'tcx> Visitor<'tcx> for BindingFinder {
- fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
- if let hir::StmtKind::Local(local) = s.kind {
- if local.pat.span == self.span {
- self.hir_id = Some(local.hir_id);
- }
- }
- hir::intravisit::walk_stmt(self, s);
- }
- }
- 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.expect_local());
- let node = hir_map.find(hir_id);
- let hir_id = if let Some(hir::Node::Item(item)) = node
- && let hir::ItemKind::Fn(.., body_id) = item.kind
- {
- let body = hir_map.body(body_id);
- let mut v = BindingFinder {
- span: err_label_span,
- hir_id: None,
- };
- v.visit_body(body);
- v.hir_id
- } else {
- None
- };
- if let Some(hir_id) = hir_id
- && let Some(hir::Node::Local(local)) = hir_map.find(hir_id)
- {
- let (changing, span, sugg) = match local.ty {
- Some(ty) => ("changing", ty.span, message),
- None => (
- "specifying",
- local.pat.span.shrink_to_hi(),
- format!(": {message}"),
- ),
- };
- err.span_suggestion_verbose(
- span,
- format!("consider {changing} this binding's type"),
- sugg,
- Applicability::HasPlaceholders,
- );
- } else {
- err.span_label(
- err_label_span,
- format!(
- "consider changing this binding's type to be: `{message}`"
- ),
- );
- }
- }
- None => {}
- }
err.span_label(
span,
format!(
@@ -658,6 +485,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
so the data it refers to cannot be {acted_on}",
),
);
+
+ self.suggest_make_local_mut(&mut err, local, name);
}
_ => {
err.span_label(
@@ -1131,6 +960,184 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
}
}
+
+ fn suggest_make_local_mut(
+ &self,
+ err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
+ local: Local,
+ name: Symbol,
+ ) {
+ let local_decl = &self.body.local_decls[local];
+
+ let (pointer_sigil, pointer_desc) =
+ if local_decl.ty.is_ref() { ("&", "reference") } else { ("*const", "pointer") };
+
+ let (is_trait_sig, local_trait) = self.is_error_in_trait(local);
+ if is_trait_sig && local_trait.is_none() {
+ return;
+ }
+
+ let decl_span = match local_trait {
+ Some(span) => span,
+ None => local_decl.source_info.span,
+ };
+
+ let label = match *local_decl.local_info() {
+ LocalInfo::User(mir::BindingForm::ImplicitSelf(_)) => {
+ let suggestion = suggest_ampmut_self(self.infcx.tcx, decl_span);
+ Some((true, decl_span, suggestion))
+ }
+
+ LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
+ binding_mode: ty::BindingMode::BindByValue(_),
+ opt_ty_info,
+ ..
+ })) => {
+ // check if the RHS is from desugaring
+ let opt_assignment_rhs_span =
+ self.body.find_assignments(local).first().map(|&location| {
+ if let Some(mir::Statement {
+ source_info: _,
+ kind:
+ mir::StatementKind::Assign(box (
+ _,
+ mir::Rvalue::Use(mir::Operand::Copy(place)),
+ )),
+ }) = self.body[location.block].statements.get(location.statement_index)
+ {
+ self.body.local_decls[place.local].source_info.span
+ } else {
+ self.body.source_info(location).span
+ }
+ });
+ match opt_assignment_rhs_span.and_then(|s| s.desugaring_kind()) {
+ // on for loops, RHS points to the iterator part
+ Some(DesugaringKind::ForLoop) => {
+ self.suggest_similar_mut_method_for_for_loop(err);
+ err.span_label(
+ opt_assignment_rhs_span.unwrap(),
+ format!("this iterator yields `{pointer_sigil}` {pointer_desc}s",),
+ );
+ None
+ }
+ // don't create labels for compiler-generated spans
+ Some(_) => None,
+ None => {
+ let label = if name != kw::SelfLower {
+ suggest_ampmut(
+ self.infcx.tcx,
+ local_decl.ty,
+ decl_span,
+ opt_assignment_rhs_span,
+ opt_ty_info,
+ )
+ } else {
+ match local_decl.local_info() {
+ LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
+ opt_ty_info: None,
+ ..
+ })) => {
+ let sugg = suggest_ampmut_self(self.infcx.tcx, decl_span);
+ (true, decl_span, sugg)
+ }
+ // explicit self (eg `self: &'a Self`)
+ _ => suggest_ampmut(
+ self.infcx.tcx,
+ local_decl.ty,
+ decl_span,
+ opt_assignment_rhs_span,
+ opt_ty_info,
+ ),
+ }
+ };
+ Some(label)
+ }
+ }
+ }
+
+ LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
+ binding_mode: ty::BindingMode::BindByReference(_),
+ ..
+ })) => {
+ let pattern_span: Span = local_decl.source_info.span;
+ suggest_ref_mut(self.infcx.tcx, pattern_span)
+ .map(|span| (true, span, "mut ".to_owned()))
+ }
+
+ _ => unreachable!(),
+ };
+
+ match label {
+ Some((true, err_help_span, suggested_code)) => {
+ err.span_suggestion_verbose(
+ err_help_span,
+ format!("consider changing this to be a mutable {pointer_desc}"),
+ suggested_code,
+ Applicability::MachineApplicable,
+ );
+ }
+ Some((false, err_label_span, message)) => {
+ struct BindingFinder {
+ span: Span,
+ hir_id: Option<hir::HirId>,
+ }
+
+ impl<'tcx> Visitor<'tcx> for BindingFinder {
+ fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
+ if let hir::StmtKind::Local(local) = s.kind {
+ if local.pat.span == self.span {
+ self.hir_id = Some(local.hir_id);
+ }
+ }
+ hir::intravisit::walk_stmt(self, s);
+ }
+ }
+ 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.expect_local());
+ let node = hir_map.find(hir_id);
+ let hir_id = if let Some(hir::Node::Item(item)) = node
+ && let hir::ItemKind::Fn(.., body_id) = item.kind
+ {
+ let body = hir_map.body(body_id);
+ let mut v = BindingFinder {
+ span: err_label_span,
+ hir_id: None,
+ };
+ v.visit_body(body);
+ v.hir_id
+ } else {
+ None
+ };
+ if let Some(hir_id) = hir_id
+ && let Some(hir::Node::Local(local)) = hir_map.find(hir_id)
+ {
+ let (changing, span, sugg) = match local.ty {
+ Some(ty) => ("changing", ty.span, message),
+ None => (
+ "specifying",
+ local.pat.span.shrink_to_hi(),
+ format!(": {message}"),
+ ),
+ };
+ err.span_suggestion_verbose(
+ span,
+ format!("consider {changing} this binding's type"),
+ sugg,
+ Applicability::HasPlaceholders,
+ );
+ } else {
+ err.span_label(
+ err_label_span,
+ format!(
+ "consider changing this binding's type to be: `{message}`"
+ ),
+ );
+ }
+ }
+ None => {}
+ }
+ }
}
pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
@@ -1160,25 +1167,18 @@ pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<
}
}
-fn suggest_ampmut_self<'tcx>(
- tcx: TyCtxt<'tcx>,
- local_decl: &mir::LocalDecl<'tcx>,
-) -> (Span, String) {
- let sp = local_decl.source_info.span;
- (
- sp,
- match tcx.sess.source_map().span_to_snippet(sp) {
- Ok(snippet) => {
- let lt_pos = snippet.find('\'');
- if let Some(lt_pos) = lt_pos {
- format!("&{}mut self", &snippet[lt_pos..snippet.len() - 4])
- } else {
- "&mut self".to_string()
- }
+fn suggest_ampmut_self<'tcx>(tcx: TyCtxt<'tcx>, span: Span) -> String {
+ match tcx.sess.source_map().span_to_snippet(span) {
+ Ok(snippet) => {
+ let lt_pos = snippet.find('\'');
+ if let Some(lt_pos) = lt_pos {
+ format!("&{}mut self", &snippet[lt_pos..snippet.len() - 4])
+ } else {
+ "&mut self".to_string()
}
- _ => "&mut self".to_string(),
- },
- )
+ }
+ _ => "&mut self".to_string(),
+ }
}
// When we want to suggest a user change a local variable to be a `&mut`, there
@@ -1198,72 +1198,89 @@ fn suggest_ampmut_self<'tcx>(
// by trying (3.), then (2.) and finally falling back on (1.).
fn suggest_ampmut<'tcx>(
tcx: TyCtxt<'tcx>,
- local_decl: &mir::LocalDecl<'tcx>,
+ decl_ty: Ty<'tcx>,
+ decl_span: Span,
opt_assignment_rhs_span: Option<Span>,
opt_ty_info: Option<Span>,
) -> (bool, Span, String) {
+ // if there is a RHS and it starts with a `&` from it, then check if it is
+ // mutable, and if not, put suggest putting `mut ` to make it mutable.
+ // we don't have to worry about lifetime annotations here because they are
+ // not valid when taking a reference. For example, the following is not valid Rust:
+ //
+ // let x: &i32 = &'a 5;
+ // ^^ lifetime annotation not allowed
+ //
if let Some(assignment_rhs_span) = opt_assignment_rhs_span
&& let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span)
+ && let Some(stripped) = src.strip_prefix('&')
{
- let is_mutbl = |ty: &str| -> bool {
- if let Some(rest) = ty.strip_prefix("mut") {
- match rest.chars().next() {
- // e.g. `&mut x`
- Some(c) if c.is_whitespace() => true,
- // e.g. `&mut(x)`
- Some('(') => true,
- // e.g. `&mut{x}`
- Some('{') => true,
- // e.g. `&mutablevar`
- _ => false,
- }
- } else {
- false
+ let is_mut = if let Some(rest) = stripped.trim_start().strip_prefix("mut") {
+ match rest.chars().next() {
+ // e.g. `&mut x`
+ Some(c) if c.is_whitespace() => true,
+ // e.g. `&mut(x)`
+ Some('(') => true,
+ // e.g. `&mut{x}`
+ Some('{') => true,
+ // e.g. `&mutablevar`
+ _ => false,
}
+ } else {
+ false
};
- if let (true, Some(ws_pos)) = (src.starts_with("&'"), src.find(char::is_whitespace)) {
- let lt_name = &src[1..ws_pos];
- let ty = src[ws_pos..].trim_start();
- if !is_mutbl(ty) {
- return (true, assignment_rhs_span, format!("&{lt_name} mut {ty}"));
- }
- } else if let Some(stripped) = src.strip_prefix('&') {
- let stripped = stripped.trim_start();
- if !is_mutbl(stripped) {
- return (true, assignment_rhs_span, format!("&mut {stripped}"));
- }
+ // if the reference is already mutable then there is nothing we can do
+ // here.
+ if !is_mut {
+ let span = assignment_rhs_span;
+ // shrink the span to just after the `&` in `&variable`
+ let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo();
+
+ // FIXME(Ezrashaw): returning is bad because we still might want to
+ // update the annotated type, see #106857.
+ return (true, span, "mut ".to_owned());
}
}
- let (suggestibility, highlight_span) = match opt_ty_info {
+ let (binding_exists, span) = match opt_ty_info {
// if this is a variable binding with an explicit type,
- // try to highlight that for the suggestion.
+ // then we will suggest changing it to be mutable.
+ // this is `Applicability::MachineApplicable`.
Some(ty_span) => (true, ty_span),
- // otherwise, just highlight the span associated with
- // the (MIR) LocalDecl.
- None => (false, local_decl.source_info.span),
+ // otherwise, we'll suggest *adding* an annotated type, we'll suggest
+ // the RHS's type for that.
+ // this is `Applicability::HasPlaceholders`.
+ None => (false, decl_span),
};
- if let Ok(src) = tcx.sess.source_map().span_to_snippet(highlight_span)
- && let (true, Some(ws_pos)) = (src.starts_with("&'"), src.find(char::is_whitespace))
+ // if the binding already exists and is a reference with a explicit
+ // lifetime, then we can suggest adding ` mut`. this is special-cased from
+ // the path without a explicit lifetime.
+ if let Ok(src) = tcx.sess.source_map().span_to_snippet(span)
+ && src.starts_with("&'")
+ // note that `& 'a T` is invalid so this is correct.
+ && let Some(ws_pos) = src.find(char::is_whitespace)
{
- let lt_name = &src[1..ws_pos];
- let ty = &src[ws_pos..];
- return (true, highlight_span, format!("&{lt_name} mut{ty}"));
- }
+ let span = span.with_lo(span.lo() + BytePos(ws_pos as u32)).shrink_to_lo();
+ (true, span, " mut".to_owned())
+ // if there is already a binding, we modify it to be `mut`
+ } else if binding_exists {
+ // shrink the span to just after the `&` in `&variable`
+ let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo();
+ (true, span, "mut ".to_owned())
+ } else {
+ // otherwise, suggest that the user annotates the binding; we provide the
+ // type of the local.
+ let ty_mut = decl_ty.builtin_deref(true).unwrap();
+ assert_eq!(ty_mut.mutbl, hir::Mutability::Not);
- let ty_mut = local_decl.ty.builtin_deref(true).unwrap();
- assert_eq!(ty_mut.mutbl, hir::Mutability::Not);
- (
- suggestibility,
- highlight_span,
- if local_decl.ty.is_ref() {
- format!("&mut {}", ty_mut.ty)
- } else {
- format!("*mut {}", ty_mut.ty)
- },
- )
+ (
+ false,
+ span,
+ format!("{}mut {}", if decl_ty.is_ref() {"&"} else {"*"}, ty_mut.ty)
+ )
+ }
}
fn is_closure_or_generator(ty: Ty<'_>) -> bool {
@@ -1300,11 +1317,13 @@ fn get_mut_span_in_struct_field<'tcx>(
}
/// If possible, suggest replacing `ref` with `ref mut`.
-fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<String> {
- let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).ok()?;
- if hi_src.starts_with("ref") && hi_src["ref".len()..].starts_with(rustc_lexer::is_whitespace) {
- let replacement = format!("ref mut{}", &hi_src["ref".len()..]);
- Some(replacement)
+fn suggest_ref_mut(tcx: TyCtxt<'_>, span: Span) -> Option<Span> {
+ let pattern_str = tcx.sess.source_map().span_to_snippet(span).ok()?;
+ if pattern_str.starts_with("ref")
+ && pattern_str["ref".len()..].starts_with(rustc_lexer::is_whitespace)
+ {
+ let span = span.with_lo(span.lo() + BytePos(4)).shrink_to_lo();
+ Some(span)
} else {
None
}
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 315303b25fe..eb25d454339 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -35,7 +35,7 @@ use rustc_middle::mir::{
use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind};
use rustc_middle::mir::{ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, CapturedPlace, ParamEnv, RegionVid, TyCtxt};
use rustc_session::lint::builtin::UNUSED_MUT;
use rustc_span::{Span, Symbol};
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 4970ece5e7d..309f23d9226 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -265,7 +265,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
// Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
// on stable and we'd break that.
- let OpaqueTyOrigin::TyAlias = origin else {
+ let OpaqueTyOrigin::TyAlias { .. } = origin else {
return definition_ty;
};
let def_id = opaque_type_key.def_id;
@@ -360,7 +360,7 @@ fn check_opaque_type_parameter_valid(
// which would error here on all of the `'static` args.
OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return Ok(()),
// Check these
- OpaqueTyOrigin::TyAlias => {}
+ OpaqueTyOrigin::TyAlias { .. } => {}
}
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index dcabeb792be..33b24b68f7c 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -777,7 +777,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
Inspect | Copy | Move | PlaceMention | SharedBorrow | ShallowBorrow | UniqueBorrow
| AddressOf | Projection,
) => ty::Covariant,
- PlaceContext::NonUse(AscribeUserTy) => ty::Covariant,
+ PlaceContext::NonUse(AscribeUserTy(variance)) => variance,
}
}
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index 0d7cf7cdb26..3b458b1d30b 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -150,10 +150,6 @@ builtin_macros_format_pos_mismatch = {$n} positional {$n ->
*[more] arguments
} in format string, but {$desc}
-builtin_macros_offset_of_expected_field = expected field
-
-builtin_macros_offset_of_expected_two_args = expected 2 arguments
-
builtin_macros_test_case_non_item = `#[test_case]` attribute is only allowed on items
builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests
diff --git a/compiler/rustc_builtin_macros/src/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs
index 8c737f04323..ee56d45c9c8 100644
--- a/compiler/rustc_builtin_macros/src/concat_idents.rs
+++ b/compiler/rustc_builtin_macros/src/concat_idents.rs
@@ -19,7 +19,7 @@ pub fn expand_concat_idents<'cx>(
}
let mut res_str = String::new();
- for (i, e) in tts.into_trees().enumerate() {
+ for (i, e) in tts.trees().enumerate() {
if i & 1 == 1 {
match e {
TokenTree::Token(Token { kind: token::Comma, .. }, _) => {}
diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
index 0481a118906..2c8e6f99c67 100644
--- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
@@ -27,3 +27,26 @@ pub fn expand_deriving_copy(
trait_def.expand(cx, mitem, item, push);
}
+
+pub fn expand_deriving_const_param_ty(
+ cx: &mut ExtCtxt<'_>,
+ span: Span,
+ mitem: &MetaItem,
+ item: &Annotatable,
+ push: &mut dyn FnMut(Annotatable),
+ is_const: bool,
+) {
+ let trait_def = TraitDef {
+ span,
+ path: path_std!(marker::ConstParamTy),
+ skip_path_as_bound: false,
+ needs_copy_as_bound_if_packed: false,
+ additional_bounds: Vec::new(),
+ supports_unions: false,
+ methods: Vec::new(),
+ associated_types: Vec::new(),
+ is_const,
+ };
+
+ trait_def.expand(cx, mitem, item, push);
+}
diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index 58c972738c4..8f64e332861 100644
--- a/compiler/rustc_builtin_macros/src/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
@@ -63,7 +63,8 @@ pub fn expand_env<'cx>(
Some(exprs) => exprs.into_iter(),
};
- let Some((var, _style)) = expr_to_string(cx, exprs.next().unwrap(), "expected string literal") else {
+ let var_expr = exprs.next().unwrap();
+ let Some((var, _)) = expr_to_string(cx, var_expr.clone(), "expected string literal") else {
return DummyResult::any(sp);
};
@@ -71,7 +72,7 @@ pub fn expand_env<'cx>(
None => None,
Some(second) => match expr_to_string(cx, second, "expected string literal") {
None => return DummyResult::any(sp),
- Some((s, _style)) => Some(s),
+ Some((s, _)) => Some(s),
},
};
@@ -80,10 +81,15 @@ pub fn expand_env<'cx>(
cx.sess.parse_sess.env_depinfo.borrow_mut().insert((var, value));
let e = match value {
None => {
+ // Use the string literal in the code in the diagnostic to avoid confusing diagnostics,
+ // e.g. when the literal contains escape sequences.
+ let ast::ExprKind::Lit(ast::token::Lit { kind: ast::token::LitKind::Str, symbol: original_var, ..}) = &var_expr.kind else {
+ unreachable!("`expr_to_string` ensures this is a string lit")
+ };
cx.emit_err(errors::EnvNotDefined {
span: sp,
msg: custom_msg,
- var,
+ var: *original_var,
help: custom_msg.is_none().then(|| help_for_missing_env_var(var.as_str())),
});
return DummyResult::any(sp);
diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs
index bd9e903b6ba..bd5356575ca 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign.rs
@@ -562,15 +562,13 @@ pub(crate) mod printf {
}
if let Type = state {
- drop(c);
type_ = at.slice_between(next).unwrap();
// Don't use `move_to!` here, as we *can* be at the end of the input.
at = next;
}
- drop(c);
- drop(next);
+ let _ = c; // to avoid never used value
end = at;
let position = InnerSpan::new(start.at, end.at);
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index c7da61d72b3..ebf1448f55c 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -44,7 +44,6 @@ mod format;
mod format_foreign;
mod global_allocator;
mod log_syntax;
-mod offset_of;
mod source_util;
mod test;
mod trace_macros;
@@ -92,7 +91,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
line: source_util::expand_line,
log_syntax: log_syntax::expand_log_syntax,
module_path: source_util::expand_mod,
- offset_of: offset_of::expand_offset_of,
option_env: env::expand_option_env,
core_panic: edition_panic::expand_panic,
std_panic: edition_panic::expand_panic,
@@ -117,6 +115,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
register_derive! {
Clone: clone::expand_deriving_clone,
Copy: bounds::expand_deriving_copy,
+ ConstParamTy: bounds::expand_deriving_const_param_ty,
Debug: debug::expand_deriving_debug,
Default: default::expand_deriving_default,
Eq: eq::expand_deriving_eq,
diff --git a/compiler/rustc_builtin_macros/src/offset_of.rs b/compiler/rustc_builtin_macros/src/offset_of.rs
deleted file mode 100644
index 0ef3e000e41..00000000000
--- a/compiler/rustc_builtin_macros/src/offset_of.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use rustc_ast as ast;
-use rustc_ast::ptr::P;
-use rustc_ast::token;
-use rustc_ast::tokenstream::TokenStream;
-use rustc_errors::PResult;
-use rustc_expand::base::{self, *};
-use rustc_macros::Diagnostic;
-use rustc_parse::parser::Parser;
-use rustc_span::{symbol::Ident, Span};
-
-#[derive(Diagnostic)]
-#[diag(builtin_macros_offset_of_expected_field)]
-struct ExpectedField {
- #[primary_span]
- span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(builtin_macros_offset_of_expected_two_args)]
-struct ExpectedTwoArgs {
- #[primary_span]
- span: Span,
-}
-
-fn parse_field<'a>(cx: &ExtCtxt<'a>, p: &mut Parser<'a>) -> PResult<'a, Ident> {
- let token = p.token.uninterpolate();
- let field = match token.kind {
- token::Ident(name, _) => Ident::new(name, token.span),
- token::Literal(token::Lit { kind: token::Integer, symbol, suffix: None }) => {
- Ident::new(symbol, token.span)
- }
- _ => return Err(cx.create_err(ExpectedField { span: p.token.span })),
- };
-
- p.bump();
-
- Ok(field)
-}
-
-fn parse_args<'a>(
- cx: &mut ExtCtxt<'a>,
- sp: Span,
- tts: TokenStream,
-) -> PResult<'a, (P<ast::Ty>, P<[Ident]>)> {
- let mut p = cx.new_parser_from_tts(tts);
-
- let container = p.parse_ty()?;
-
- p.expect(&token::Comma)?;
-
- if p.eat(&token::Eof) {
- return Err(cx.create_err(ExpectedTwoArgs { span: sp }));
- }
-
- let mut fields = Vec::new();
-
- loop {
- let field = parse_field(cx, &mut p)?;
- fields.push(field);
-
- if p.eat(&token::Dot) {
- continue;
- }
-
- p.eat(&token::Comma);
-
- if !p.eat(&token::Eof) {
- return Err(cx.create_err(ExpectedTwoArgs { span: sp }));
- }
-
- break;
- }
-
- Ok((container, fields.into()))
-}
-
-pub fn expand_offset_of<'cx>(
- cx: &'cx mut ExtCtxt<'_>,
- sp: Span,
- tts: TokenStream,
-) -> Box<dyn base::MacResult + 'cx> {
- match parse_args(cx, sp, tts) {
- Ok((container, fields)) => {
- let expr = P(ast::Expr {
- id: ast::DUMMY_NODE_ID,
- kind: ast::ExprKind::OffsetOf(container, fields),
- span: sp,
- attrs: ast::AttrVec::new(),
- tokens: None,
- });
-
- MacEager::expr(expr)
- }
- Err(mut err) => {
- err.emit();
- DummyResult::any(sp)
- }
- }
-}
diff --git a/compiler/rustc_builtin_macros/src/trace_macros.rs b/compiler/rustc_builtin_macros/src/trace_macros.rs
index cc5ae6894e6..9c98723e1f4 100644
--- a/compiler/rustc_builtin_macros/src/trace_macros.rs
+++ b/compiler/rustc_builtin_macros/src/trace_macros.rs
@@ -8,7 +8,7 @@ pub fn expand_trace_macros(
sp: Span,
tt: TokenStream,
) -> Box<dyn base::MacResult + 'static> {
- let mut cursor = tt.into_trees();
+ let mut cursor = tt.trees();
let mut err = false;
let value = match &cursor.next() {
Some(TokenTree::Token(token, _)) if token.is_keyword(kw::True) => true,
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index e9dbea1be67..25fd5ca3ae8 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -966,11 +966,7 @@ fn codegen_panic_inner<'tcx>(
args: &[Value],
span: Span,
) {
- let def_id = fx
- .tcx
- .lang_items()
- .require(lang_item)
- .unwrap_or_else(|e| fx.tcx.sess.span_fatal(span, e.to_string()));
+ let def_id = fx.tcx.require_lang_item(lang_item, Some(span));
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_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index a66ddb6a09f..869344ce92d 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -1227,6 +1227,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
(value1, value2)
}
+ fn filter_landing_pad(&mut self, pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) {
+ // TODO(antoyo): generate the correct landing pad
+ self.cleanup_landing_pad(pers_fn)
+ }
+
#[cfg(feature="master")]
fn resume(&mut self, exn0: RValue<'gcc>, _exn1: RValue<'gcc>) {
let exn_type = exn0.get_type();
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 1cabb05de97..442ce0ea542 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -80,8 +80,8 @@ use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, Handler, SubdiagnosticMes
use rustc_fluent_macro::fluent_messages;
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
-use rustc_middle::ty::query::Providers;
use rustc_session::config::{Lto, OptLevel, OutputFilenames};
use rustc_session::Session;
use rustc_span::Symbol;
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 2fd6db8cbfe..4d0bcd53d15 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -985,13 +985,20 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
fn cleanup_landing_pad(&mut self, pers_fn: &'ll Value) -> (&'ll Value, &'ll Value) {
let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
- let landing_pad = self.landing_pad(ty, pers_fn, 1 /* FIXME should this be 0? */);
+ let landing_pad = self.landing_pad(ty, pers_fn, 0);
unsafe {
llvm::LLVMSetCleanup(landing_pad, llvm::True);
}
(self.extract_value(landing_pad, 0), self.extract_value(landing_pad, 1))
}
+ fn filter_landing_pad(&mut self, pers_fn: &'ll Value) -> (&'ll Value, &'ll Value) {
+ let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
+ let landing_pad = self.landing_pad(ty, pers_fn, 1);
+ self.add_clause(landing_pad, self.const_array(self.type_i8p(), &[]));
+ (self.extract_value(landing_pad, 0), self.extract_value(landing_pad, 1))
+ }
+
fn resume(&mut self, exn0: &'ll Value, exn1: &'ll Value) {
let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
let mut exn = self.const_poison(ty);
diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs
index 30a0cf1d019..4b9ca2e7d19 100644
--- a/compiler/rustc_codegen_llvm/src/callee.rs
+++ b/compiler/rustc_codegen_llvm/src/callee.rs
@@ -94,11 +94,11 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
// LLVM will prefix the name with `__imp_`. Ideally, we'd like the
// existing logic below to set the Storage Class, but it has an
// exemption for MinGW for backwards compatability.
- let llfn = cx.declare_fn(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&tcx.sess.target), true), fn_abi);
+ let llfn = cx.declare_fn(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&tcx.sess.target), true), fn_abi, Some(instance));
unsafe { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); }
llfn
} else {
- cx.declare_fn(sym, fn_abi)
+ cx.declare_fn(sym, fn_abi, Some(instance))
};
debug!("get_fn: not casting pointer!");
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index 3dc0ac03312..cd261293e9b 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -207,6 +207,7 @@ fn declare_unused_fn<'tcx>(cx: &CodegenCx<'_, 'tcx>, def_id: DefId) -> Instance<
)),
ty::List::empty(),
),
+ None,
);
llvm::set_linkage(llfn, llvm::Linkage::PrivateLinkage);
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
index cc2a5d158be..164b12cf8d4 100644
--- a/compiler/rustc_codegen_llvm/src/declare.rs
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
@@ -19,8 +19,11 @@ use crate::llvm::AttributePlace::Function;
use crate::type_::Type;
use crate::value::Value;
use rustc_codegen_ssa::traits::TypeMembershipMethods;
-use rustc_middle::ty::Ty;
-use rustc_symbol_mangling::typeid::{kcfi_typeid_for_fnabi, typeid_for_fnabi, TypeIdOptions};
+use rustc_middle::ty::{Instance, Ty};
+use rustc_symbol_mangling::typeid::{
+ kcfi_typeid_for_fnabi, kcfi_typeid_for_instance, typeid_for_fnabi, typeid_for_instance,
+ TypeIdOptions,
+};
use smallvec::SmallVec;
/// Declare a function.
@@ -116,7 +119,12 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
- pub fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> &'ll Value {
+ pub fn declare_fn(
+ &self,
+ name: &str,
+ fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
+ instance: Option<Instance<'tcx>>,
+ ) -> &'ll Value {
debug!("declare_rust_fn(name={:?}, fn_abi={:?})", name, fn_abi);
// Function addresses in Rust are never significant, allowing functions to
@@ -132,18 +140,35 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
fn_abi.apply_attrs_llfn(self, llfn);
if self.tcx.sess.is_sanitizer_cfi_enabled() {
- let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::empty());
- self.set_type_metadata(llfn, typeid);
- let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::GENERALIZE_POINTERS);
- self.add_type_metadata(llfn, typeid);
- let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::NORMALIZE_INTEGERS);
- self.add_type_metadata(llfn, typeid);
- let typeid = typeid_for_fnabi(
- self.tcx,
- fn_abi,
- TypeIdOptions::GENERALIZE_POINTERS | TypeIdOptions::NORMALIZE_INTEGERS,
- );
- self.add_type_metadata(llfn, typeid);
+ if let Some(instance) = instance {
+ let typeid = typeid_for_instance(self.tcx, &instance, TypeIdOptions::empty());
+ self.set_type_metadata(llfn, typeid);
+ let typeid =
+ typeid_for_instance(self.tcx, &instance, TypeIdOptions::GENERALIZE_POINTERS);
+ self.add_type_metadata(llfn, typeid);
+ let typeid =
+ typeid_for_instance(self.tcx, &instance, TypeIdOptions::NORMALIZE_INTEGERS);
+ self.add_type_metadata(llfn, typeid);
+ let typeid = typeid_for_instance(
+ self.tcx,
+ &instance,
+ TypeIdOptions::GENERALIZE_POINTERS | TypeIdOptions::NORMALIZE_INTEGERS,
+ );
+ self.add_type_metadata(llfn, typeid);
+ } else {
+ let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::empty());
+ self.set_type_metadata(llfn, typeid);
+ let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::GENERALIZE_POINTERS);
+ self.add_type_metadata(llfn, typeid);
+ let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::NORMALIZE_INTEGERS);
+ self.add_type_metadata(llfn, typeid);
+ let typeid = typeid_for_fnabi(
+ self.tcx,
+ fn_abi,
+ TypeIdOptions::GENERALIZE_POINTERS | TypeIdOptions::NORMALIZE_INTEGERS,
+ );
+ self.add_type_metadata(llfn, typeid);
+ }
}
if self.tcx.sess.is_sanitizer_kcfi_enabled() {
@@ -156,8 +181,13 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
}
- let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options);
- self.set_kcfi_type_metadata(llfn, kcfi_typeid);
+ if let Some(instance) = instance {
+ let kcfi_typeid = kcfi_typeid_for_instance(self.tcx, &instance, options);
+ self.set_kcfi_type_metadata(llfn, kcfi_typeid);
+ } else {
+ let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options);
+ self.set_kcfi_type_metadata(llfn, kcfi_typeid);
+ }
}
llfn
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 00d1796f210..4e28034a850 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -772,7 +772,7 @@ fn gen_fn<'ll, 'tcx>(
) -> (&'ll Type, &'ll Value) {
let fn_abi = cx.fn_abi_of_fn_ptr(rust_fn_sig, ty::List::empty());
let llty = fn_abi.llvm_type(cx);
- let llfn = cx.declare_fn(name, fn_abi);
+ let llfn = cx.declare_fn(name, fn_abi, None);
cx.set_frame_pointer_type(llfn);
cx.apply_target_cpu_attr(llfn);
// FIXME(eddyb) find a nicer way to do this.
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 8305a0a4c28..6a86237d79e 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -37,7 +37,7 @@ use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, FatalError, Handler, Subd
use rustc_fluent_macro::fluent_messages;
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{OptLevel, OutputFilenames, PrintRequest};
use rustc_session::Session;
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index d5be678c1bb..de93a64c0d6 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -680,7 +680,9 @@ pub type InlineAsmDiagHandlerTy = unsafe extern "C" fn(&SMDiagnostic, *const c_v
pub mod coverageinfo {
use super::coverage_map;
- /// Aligns with [llvm::coverage::CounterMappingRegion::RegionKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L209-L230)
+ /// Corresponds to enum `llvm::coverage::CounterMappingRegion::RegionKind`.
+ ///
+ /// Must match the layout of `LLVMRustCounterMappingRegionKind`.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum RegionKind {
@@ -714,7 +716,9 @@ pub mod coverageinfo {
/// array", encoded separately), and source location (start and end positions of the represented
/// code region).
///
- /// Matches LLVMRustCounterMappingRegion.
+ /// Corresponds to struct `llvm::coverage::CounterMappingRegion`.
+ ///
+ /// Must match the layout of `LLVMRustCounterMappingRegion`.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct CounterMappingRegion {
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 2fbdab9f8ce..994addf12eb 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -155,12 +155,6 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]
("x86", "rdrand") => smallvec!["rdrnd"],
("x86", "bmi1") => smallvec!["bmi"],
("x86", "cmpxchg16b") => smallvec!["cx16"],
- // FIXME: These aliases are misleading, and should be removed before avx512_target_feature is
- // stabilized. They must remain until std::arch switches off them.
- // rust#100752
- ("x86", "avx512vaes") => smallvec!["vaes"],
- ("x86", "avx512gfni") => smallvec!["gfni"],
- ("x86", "avx512vpclmulqdq") => smallvec!["vpclmulqdq"],
("aarch64", "rcpc2") => smallvec!["rcpc-immo"],
("aarch64", "dpb") => smallvec!["ccpp"],
("aarch64", "dpb2") => smallvec!["ccdp"],
diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs
index 59bdc60830f..e8f8c321510 100644
--- a/compiler/rustc_codegen_llvm/src/mono_item.rs
+++ b/compiler/rustc_codegen_llvm/src/mono_item.rs
@@ -51,7 +51,7 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
assert!(!instance.substs.has_infer());
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
- let lldecl = self.declare_fn(symbol_name, fn_abi);
+ let lldecl = self.declare_fn(symbol_name, fn_abi, Some(instance));
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
base::set_link_section(lldecl, attrs);
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 4f73b731f5a..02be88df103 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -51,5 +51,5 @@ default-features = false
features = ["read_core", "elf", "macho", "pe", "unaligned", "archive", "write"]
[target.'cfg(windows)'.dependencies.windows]
-version = "0.46.0"
+version = "0.48.0"
features = ["Win32_Globalization"]
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 8a7809a1468..ea06cb02d8b 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -546,12 +546,38 @@ fn link_staticlib<'a>(
ab.build(out_filename);
- if !all_native_libs.is_empty() {
- if sess.opts.prints.contains(&PrintRequest::NativeStaticLibs) {
- print_native_static_libs(sess, &all_native_libs);
+ let crates = codegen_results.crate_info.used_crates.iter();
+
+ let fmts = codegen_results
+ .crate_info
+ .dependency_formats
+ .iter()
+ .find_map(|&(ty, ref list)| if ty == CrateType::Staticlib { Some(list) } else { None })
+ .expect("no dependency formats for staticlib");
+
+ let mut all_rust_dylibs = vec![];
+ for &cnum in crates {
+ match fmts.get(cnum.as_usize() - 1) {
+ Some(&Linkage::Dynamic) => {}
+ _ => continue,
+ }
+ let crate_name = codegen_results.crate_info.crate_name[&cnum];
+ let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum];
+ if let Some((path, _)) = &used_crate_source.dylib {
+ all_rust_dylibs.push(&**path);
+ } else {
+ if used_crate_source.rmeta.is_some() {
+ sess.emit_fatal(errors::LinkRlibError::OnlyRmetaFound { crate_name });
+ } else {
+ sess.emit_fatal(errors::LinkRlibError::NotFound { crate_name });
+ }
}
}
+ if sess.opts.prints.contains(&PrintRequest::NativeStaticLibs) {
+ print_native_static_libs(sess, &all_native_libs, &all_rust_dylibs);
+ }
+
Ok(())
}
@@ -1370,8 +1396,12 @@ enum RlibFlavor {
StaticlibBase,
}
-fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
- let lib_args: Vec<_> = all_native_libs
+fn print_native_static_libs(
+ sess: &Session,
+ all_native_libs: &[NativeLib],
+ all_rust_dylibs: &[&Path],
+) {
+ let mut lib_args: Vec<_> = all_native_libs
.iter()
.filter(|l| relevant_lib(sess, l))
.filter_map(|lib| {
@@ -1401,6 +1431,41 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
}
})
.collect();
+ for path in all_rust_dylibs {
+ // FIXME deduplicate with add_dynamic_crate
+
+ // Just need to tell the linker about where the library lives and
+ // what its name is
+ let parent = path.parent();
+ if let Some(dir) = parent {
+ let dir = fix_windows_verbatim_for_gcc(dir);
+ if sess.target.is_like_msvc {
+ let mut arg = String::from("/LIBPATH:");
+ arg.push_str(&dir.display().to_string());
+ lib_args.push(arg);
+ } else {
+ lib_args.push("-L".to_owned());
+ lib_args.push(dir.display().to_string());
+ }
+ }
+ let stem = path.file_stem().unwrap().to_str().unwrap();
+ // Convert library file-stem into a cc -l argument.
+ let prefix = if stem.starts_with("lib") && !sess.target.is_like_windows { 3 } else { 0 };
+ let lib = &stem[prefix..];
+ let path = parent.unwrap_or_else(|| Path::new(""));
+ if sess.target.is_like_msvc {
+ // When producing a dll, the MSVC linker may not actually emit a
+ // `foo.lib` file if the dll doesn't actually export any symbols, so we
+ // check to see if the file is there and just omit linking to it if it's
+ // not present.
+ let name = format!("{}.dll.lib", lib);
+ if path.join(&name).exists() {
+ lib_args.push(name);
+ }
+ } else {
+ lib_args.push(format!("-l{}", lib));
+ }
+ }
if !lib_args.is_empty() {
sess.emit_note(errors::StaticLibraryNativeArtifacts);
// Prefix for greppability
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index d5d843702c0..8bf84772f08 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -12,9 +12,9 @@ use object::{
use snap::write::FrameEncoder;
+use object::elf::NT_GNU_PROPERTY_TYPE_0;
use rustc_data_structures::memmap::Mmap;
-use rustc_data_structures::owned_slice::try_slice_owned;
-use rustc_data_structures::sync::MetadataRef;
+use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice};
use rustc_metadata::fs::METADATA_FILENAME;
use rustc_metadata::EncodedMetadata;
use rustc_session::cstore::MetadataLoader;
@@ -38,7 +38,7 @@ pub struct DefaultMetadataLoader;
fn load_metadata_with(
path: &Path,
f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>,
-) -> Result<MetadataRef, String> {
+) -> Result<OwnedSlice, String> {
let file =
File::open(path).map_err(|e| format!("failed to open file '{}': {}", path.display(), e))?;
@@ -48,7 +48,7 @@ fn load_metadata_with(
}
impl MetadataLoader for DefaultMetadataLoader {
- fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> {
+ fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result<OwnedSlice, String> {
load_metadata_with(path, |data| {
let archive = object::read::archive::ArchiveFile::parse(&*data)
.map_err(|e| format!("failed to parse rlib '{}': {}", path.display(), e))?;
@@ -68,7 +68,7 @@ impl MetadataLoader for DefaultMetadataLoader {
})
}
- fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> {
+ fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<OwnedSlice, String> {
load_metadata_with(path, |data| search_for_section(path, data, ".rustc"))
}
}
@@ -93,6 +93,54 @@ pub(super) fn search_for_section<'a>(
.map_err(|e| format!("failed to read {} section in '{}': {}", section, path.display(), e))
}
+fn add_gnu_property_note(
+ file: &mut write::Object<'static>,
+ architecture: Architecture,
+ binary_format: BinaryFormat,
+ endianness: Endianness,
+) {
+ // check bti protection
+ if binary_format != BinaryFormat::Elf
+ || !matches!(architecture, Architecture::X86_64 | Architecture::Aarch64)
+ {
+ return;
+ }
+
+ let section = file.add_section(
+ file.segment_name(StandardSegment::Data).to_vec(),
+ b".note.gnu.property".to_vec(),
+ SectionKind::Note,
+ );
+ let mut data: Vec<u8> = Vec::new();
+ let n_namsz: u32 = 4; // Size of the n_name field
+ let n_descsz: u32 = 16; // Size of the n_desc field
+ let n_type: u32 = NT_GNU_PROPERTY_TYPE_0; // Type of note descriptor
+ let header_values = [n_namsz, n_descsz, n_type];
+ header_values.iter().for_each(|v| {
+ data.extend_from_slice(&match endianness {
+ Endianness::Little => v.to_le_bytes(),
+ Endianness::Big => v.to_be_bytes(),
+ })
+ });
+ data.extend_from_slice(b"GNU\0"); // Owner of the program property note
+ let pr_type: u32 = match architecture {
+ Architecture::X86_64 => 0xc0000002,
+ Architecture::Aarch64 => 0xc0000000,
+ _ => unreachable!(),
+ };
+ let pr_datasz: u32 = 4; //size of the pr_data field
+ let pr_data: u32 = 3; //program property descriptor
+ let pr_padding: u32 = 0;
+ let property_values = [pr_type, pr_datasz, pr_data, pr_padding];
+ property_values.iter().for_each(|v| {
+ data.extend_from_slice(&match endianness {
+ Endianness::Little => v.to_le_bytes(),
+ Endianness::Big => v.to_be_bytes(),
+ })
+ });
+ file.append_section_data(section, &data, 8);
+}
+
pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static>> {
let endianness = match sess.target.options.endian {
Endian::Little => Endianness::Little,
@@ -205,6 +253,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
_ => elf::ELFOSABI_NONE,
};
let abi_version = 0;
+ add_gnu_property_note(&mut file, architecture, binary_format, endianness);
file.flags = FileFlags::Elf { os_abi, abi_version, e_flags };
Some(file)
}
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 8f2f829c17c..14460efc1b0 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -11,7 +11,7 @@ use rustc_middle::middle::exported_symbols::{
metadata_symbol_name, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
};
use rustc_middle::query::LocalCrate;
-use rustc_middle::ty::query::{ExternProviders, Providers};
+use rustc_middle::query::{ExternProviders, Providers};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::Instance;
use rustc_middle::ty::{self, SymbolName, TyCtxt};
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index ae45ae9d802..d9b0a152594 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -17,10 +17,7 @@ use rustc_ast::expand::allocator::AllocatorKind;
use rustc_attr as attr;
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;
-#[cfg(parallel_compiler)]
-use rustc_data_structures::sync::ParallelIterator;
+use rustc_data_structures::sync::par_map;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::lang_items::LangItem;
@@ -30,8 +27,8 @@ 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::query::Providers;
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_session::cgu_reuse_tracker::CguReuse;
use rustc_session::config::{self, CrateType, EntryFnType, OutputType};
@@ -689,7 +686,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
// This likely is a temporary measure. Once we don't have to support the
// non-parallel compiler anymore, we can compile CGUs end-to-end in
// parallel and get rid of the complicated scheduling logic.
- let mut pre_compiled_cgus = if cfg!(parallel_compiler) {
+ let mut pre_compiled_cgus = if tcx.sess.threads() > 1 {
tcx.sess.time("compile_first_CGU_batch", || {
// Try to find one CGU to compile per thread.
let cgus: Vec<_> = cgu_reuse
@@ -702,12 +699,10 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
// Compile the found CGUs in parallel.
let start_time = Instant::now();
- let pre_compiled_cgus = par_iter(cgus)
- .map(|(i, _)| {
- let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
- (i, module)
- })
- .collect();
+ let pre_compiled_cgus = par_map(cgus, |(i, _)| {
+ let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
+ (i, module)
+ });
total_codegen_time += start_time.elapsed();
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 8dae5dab429..d6c23012762 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -7,7 +7,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
use rustc_hir::{lang_items, weak_lang_items::WEAK_LANG_ITEMS, LangItem};
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::mono::Linkage;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self as ty, TyCtxt};
use rustc_session::{lint, parse::feature_err};
use rustc_span::symbol::Ident;
diff --git a/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs
index e288760a02b..1791ce4b315 100644
--- a/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs
+++ b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs
@@ -1,6 +1,6 @@
use rustc_middle::mir::coverage::{CounterValueReference, MappedExpressionIndex};
-/// Aligns with [llvm::coverage::Counter::CounterKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L95)
+/// Must match the layout of `LLVMRustCounterKind`.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum CounterKind {
@@ -17,8 +17,10 @@ pub enum CounterKind {
/// `instrprof.increment()`)
/// * For `CounterKind::Expression`, `id` is the index into the coverage map's array of
/// counter expressions.
-/// Aligns with [llvm::coverage::Counter](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L102-L103)
-/// Important: The Rust struct layout (order and types of fields) must match its C++ counterpart.
+///
+/// Corresponds to struct `llvm::coverage::Counter`.
+///
+/// Must match the layout of `LLVMRustCounter`.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct Counter {
@@ -59,7 +61,9 @@ impl Counter {
}
}
-/// Aligns with [llvm::coverage::CounterExpression::ExprKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L150)
+/// Corresponds to enum `llvm::coverage::CounterExpression::ExprKind`.
+///
+/// Must match the layout of `LLVMRustCounterExprKind`.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum ExprKind {
@@ -67,9 +71,9 @@ pub enum ExprKind {
Add = 1,
}
-/// Aligns with [llvm::coverage::CounterExpression](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L151-L152)
-/// Important: The Rust struct layout (order and types of fields) must match its C++
-/// counterpart.
+/// Corresponds to struct `llvm::coverage::CounterExpression`.
+///
+/// Must match the layout of `LLVMRustCounterExpression`.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct CounterExpression {
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index c3cc17c255b..f4b9d1dea58 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -30,7 +30,7 @@ use rustc_hir::def_id::CrateNum;
use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::middle::dependency_format::Dependencies;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
-use rustc_middle::ty::query::{ExternProviders, Providers};
+use rustc_middle::query::{ExternProviders, Providers};
use rustc_serialize::opaque::{FileEncoder, MemDecoder};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT};
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index c1613a9640a..a832999225a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -1600,7 +1600,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx = Bx::build(self.cx, llbb);
let llpersonality = self.cx.eh_personality();
- bx.cleanup_landing_pad(llpersonality);
+ bx.filter_landing_pad(llpersonality);
funclet = None;
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 4e5e2dd5d50..bba2800fb05 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -8,7 +8,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
use rustc_session::config::DebugInfo;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{BytePos, Span};
-use rustc_target::abi::{Abi, FieldIdx, Size, VariantIdx};
+use rustc_target::abi::{Abi, FieldIdx, FieldsShape, Size, VariantIdx};
use super::operand::{OperandRef, OperandValue};
use super::place::PlaceRef;
@@ -41,6 +41,9 @@ pub struct PerLocalVarDebugInfo<'tcx, D> {
/// `.place.projection` from `mir::VarDebugInfo`.
pub projection: &'tcx ty::List<mir::PlaceElem<'tcx>>,
+
+ /// `references` from `mir::VarDebugInfo`.
+ pub references: u8,
}
#[derive(Clone, Copy, Debug)]
@@ -80,6 +83,7 @@ trait DebugInfoOffsetLocation<'tcx, Bx> {
fn deref(&self, bx: &mut Bx) -> Self;
fn layout(&self) -> TyAndLayout<'tcx>;
fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self;
+ fn project_constant_index(&self, bx: &mut Bx, offset: u64) -> Self;
fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self;
}
@@ -98,6 +102,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx>
PlaceRef::project_field(*self, bx, field.index())
}
+ fn project_constant_index(&self, bx: &mut Bx, offset: u64) -> Self {
+ let lloffset = bx.cx().const_usize(offset);
+ self.project_index(bx, lloffset)
+ }
+
fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self {
self.project_downcast(bx, variant)
}
@@ -120,6 +129,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx>
self.field(bx.cx(), field.index())
}
+ fn project_constant_index(&self, bx: &mut Bx, index: u64) -> Self {
+ self.field(bx.cx(), index as usize)
+ }
+
fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self {
self.for_variant(bx.cx(), variant)
}
@@ -165,6 +178,18 @@ fn calculate_debuginfo_offset<
mir::ProjectionElem::Downcast(_, variant) => {
place = place.downcast(bx, variant);
}
+ mir::ProjectionElem::ConstantIndex {
+ offset: index,
+ min_length: _,
+ from_end: false,
+ } => {
+ let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
+ let FieldsShape::Array { stride, count: _ } = place.layout().fields else {
+ span_bug!(var.source_info.span, "ConstantIndex on non-array type {:?}", place.layout())
+ };
+ *offset += stride * index;
+ place = place.project_constant_index(bx, index);
+ }
_ => {
// Sanity check for `can_use_in_debuginfo`.
debug_assert!(!elem.can_use_in_debuginfo());
@@ -293,6 +318,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
dbg_var,
fragment: None,
projection: ty::List::empty(),
+ references: 0,
})
}
} else {
@@ -358,55 +384,74 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let vars = vars.iter().cloned().chain(fallback_var);
for var in vars {
- let Some(dbg_var) = var.dbg_var else { continue };
- let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue };
-
- let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
- calculate_debuginfo_offset(bx, local, &var, base.layout);
-
- // When targeting MSVC, create extra allocas for arguments instead of pointing multiple
- // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
- // not DWARF and LLVM doesn't support translating the resulting
- // [DW_OP_deref, DW_OP_plus_uconst, offset, DW_OP_deref] debug info to CodeView.
- // Creating extra allocas on the stack makes the resulting debug info simple enough
- // that LLVM can generate correct CodeView records and thus the values appear in the
- // debugger. (#83709)
- let should_create_individual_allocas = bx.cx().sess().target.is_like_msvc
- && self.mir.local_kind(local) == mir::LocalKind::Arg
- // LLVM can handle simple things but anything more complex than just a direct
- // offset or one indirect offset of 0 is too complex for it to generate CV records
- // correctly.
- && (direct_offset != Size::ZERO
- || !matches!(&indirect_offsets[..], [Size::ZERO] | []));
-
- if should_create_individual_allocas {
- let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } =
- calculate_debuginfo_offset(bx, local, &var, base);
-
- // Create a variable which will be a pointer to the actual value
- let ptr_ty = bx
- .tcx()
- .mk_ptr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, ty: place.layout.ty });
- let ptr_layout = bx.layout_of(ptr_ty);
- let alloca = PlaceRef::alloca(bx, ptr_layout);
- bx.set_var_name(alloca.llval, &(var.name.to_string() + ".dbg.spill"));
-
- // Write the pointer to the variable
- bx.store(place.llval, alloca.llval, alloca.align);
-
- // Point the debug info to `*alloca` for the current variable
- bx.dbg_var_addr(dbg_var, dbg_loc, alloca.llval, Size::ZERO, &[Size::ZERO], None);
- } else {
- bx.dbg_var_addr(
- dbg_var,
- dbg_loc,
- base.llval,
- direct_offset,
- &indirect_offsets,
- None,
- );
+ self.debug_introduce_local_as_var(bx, local, base, var);
+ }
+ }
+
+ fn debug_introduce_local_as_var(
+ &self,
+ bx: &mut Bx,
+ local: mir::Local,
+ mut base: PlaceRef<'tcx, Bx::Value>,
+ var: PerLocalVarDebugInfo<'tcx, Bx::DIVariable>,
+ ) {
+ let Some(dbg_var) = var.dbg_var else { return };
+ let Some(dbg_loc) = self.dbg_loc(var.source_info) else { return };
+
+ let DebugInfoOffset { mut direct_offset, indirect_offsets, result: _ } =
+ calculate_debuginfo_offset(bx, local, &var, base.layout);
+ let mut indirect_offsets = &indirect_offsets[..];
+
+ // When targeting MSVC, create extra allocas for arguments instead of pointing multiple
+ // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
+ // not DWARF and LLVM doesn't support translating the resulting
+ // [DW_OP_deref, DW_OP_plus_uconst, offset, DW_OP_deref] debug info to CodeView.
+ // Creating extra allocas on the stack makes the resulting debug info simple enough
+ // that LLVM can generate correct CodeView records and thus the values appear in the
+ // debugger. (#83709)
+ let should_create_individual_allocas = bx.cx().sess().target.is_like_msvc
+ && self.mir.local_kind(local) == mir::LocalKind::Arg
+ // LLVM can handle simple things but anything more complex than just a direct
+ // offset or one indirect offset of 0 is too complex for it to generate CV records
+ // correctly.
+ && (direct_offset != Size::ZERO || !matches!(indirect_offsets, [Size::ZERO] | []));
+
+ let create_alloca = |bx: &mut Bx, place: PlaceRef<'tcx, Bx::Value>, refcount| {
+ // Create a variable which will be a pointer to the actual value
+ let ptr_ty = bx
+ .tcx()
+ .mk_ptr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, ty: place.layout.ty });
+ let ptr_layout = bx.layout_of(ptr_ty);
+ let alloca = PlaceRef::alloca(bx, ptr_layout);
+ bx.set_var_name(alloca.llval, &format!("{}.ref{}.dbg.spill", var.name, refcount));
+
+ // Write the pointer to the variable
+ bx.store(place.llval, alloca.llval, alloca.align);
+
+ // Point the debug info to `*alloca` for the current variable
+ alloca
+ };
+
+ if var.references > 0 {
+ base = calculate_debuginfo_offset(bx, local, &var, base).result;
+
+ // Point the debug info to `&...&base == alloca` for the current variable
+ for refcount in 0..var.references {
+ base = create_alloca(bx, base, refcount);
}
+
+ direct_offset = Size::ZERO;
+ indirect_offsets = &[];
+ } else if should_create_individual_allocas {
+ let place = calculate_debuginfo_offset(bx, local, &var, base).result;
+
+ // Point the debug info to `*alloca` for the current variable
+ base = create_alloca(bx, place, 0);
+ direct_offset = Size::ZERO;
+ indirect_offsets = &[Size::ZERO];
}
+
+ bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, direct_offset, indirect_offsets, None);
}
pub fn debug_introduce_locals(&self, bx: &mut Bx) {
@@ -439,7 +484,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
};
let dbg_var = dbg_scope_and_span.map(|(dbg_scope, _, span)| {
- let (var_ty, var_kind) = match var.value {
+ let (mut var_ty, var_kind) = match var.value {
mir::VarDebugInfoContents::Place(place) => {
let var_ty = self.monomorphized_place_ty(place.as_ref());
let var_kind = if let Some(arg_index) = var.argument_index
@@ -476,6 +521,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
};
+ for _ in 0..var.references {
+ var_ty =
+ bx.tcx().mk_ptr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, ty: var_ty });
+ }
+
self.cx.create_dbg_var(var.name, var_ty, dbg_scope, var_kind, span)
});
@@ -487,6 +537,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
dbg_var,
fragment: None,
projection: place.projection,
+ references: var.references,
});
}
mir::VarDebugInfoContents::Const(c) => {
@@ -540,6 +591,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
Some(fragment_start..fragment_start + fragment_layout.size)
},
projection: place.projection,
+ references: var.references,
});
}
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 9efbb34b515..2301c3ef13e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -402,8 +402,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
indirect_dest: PlaceRef<'tcx, V>,
) {
debug!("OperandRef::store_unsized: operand={:?}, indirect_dest={:?}", self, indirect_dest);
- let flags = MemFlags::empty();
-
// `indirect_dest` must have `*mut T` type. We extract `T` out of it.
let unsized_ty = indirect_dest
.layout
@@ -416,17 +414,23 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
bug!("store_unsized called with a sized value")
};
- // FIXME: choose an appropriate alignment, or use dynamic align somehow
- let max_align = Align::from_bits(128).unwrap();
- let min_align = Align::from_bits(8).unwrap();
-
- // Allocate an appropriate region on the stack, and copy the value into it
- let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
- let lldst = bx.byte_array_alloca(llsize, max_align);
- bx.memcpy(lldst, max_align, llptr, min_align, llsize, flags);
+ // Allocate an appropriate region on the stack, and copy the value into it. Since alloca
+ // doesn't support dynamic alignment, we allocate an extra align - 1 bytes, and align the
+ // pointer manually.
+ let (size, align) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
+ let one = bx.const_usize(1);
+ let align_minus_1 = bx.sub(align, one);
+ let size_extra = bx.add(size, align_minus_1);
+ let min_align = Align::ONE;
+ let alloca = bx.byte_array_alloca(size_extra, min_align);
+ let address = bx.ptrtoint(alloca, bx.type_isize());
+ let neg_address = bx.neg(address);
+ let offset = bx.and(neg_address, align_minus_1);
+ let dst = bx.inbounds_gep(bx.type_i8(), alloca, &[offset]);
+ bx.memcpy(dst, min_align, llptr, min_align, size, MemFlags::empty());
// Store the allocated region and the extra to the indirect place.
- let indirect_operand = OperandValue::Pair(lldst, llextra);
+ let indirect_operand = OperandValue::Pair(dst, llextra);
indirect_operand.store(bx, indirect_dest);
}
}
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 1cfc4b933a8..3719283cccc 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -8,7 +8,7 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::def_id::LOCAL_CRATE;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::parse::feature_err;
use rustc_session::Session;
@@ -173,16 +173,13 @@ const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("avx512dq", Some(sym::avx512_target_feature)),
("avx512er", Some(sym::avx512_target_feature)),
("avx512f", Some(sym::avx512_target_feature)),
- ("avx512gfni", Some(sym::avx512_target_feature)),
("avx512ifma", Some(sym::avx512_target_feature)),
("avx512pf", Some(sym::avx512_target_feature)),
- ("avx512vaes", Some(sym::avx512_target_feature)),
("avx512vbmi", Some(sym::avx512_target_feature)),
("avx512vbmi2", Some(sym::avx512_target_feature)),
("avx512vl", Some(sym::avx512_target_feature)),
("avx512vnni", Some(sym::avx512_target_feature)),
("avx512vp2intersect", Some(sym::avx512_target_feature)),
- ("avx512vpclmulqdq", Some(sym::avx512_target_feature)),
("avx512vpopcntdq", Some(sym::avx512_target_feature)),
("bmi1", None),
("bmi2", None),
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 64bebe50ddb..d83bfc74082 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -1,3 +1,5 @@
+use std::any::Any;
+
use super::write::WriteBackendMethods;
use super::CodegenObject;
use crate::back::write::TargetMachineFactoryFn;
@@ -5,11 +7,12 @@ use crate::{CodegenResults, ModuleCodegen};
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_errors::ErrorGuaranteed;
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
+use rustc_middle::query::{ExternProviders, Providers};
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout};
-use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_session::{
config::{self, OutputFilenames, PrintRequest},
@@ -20,10 +23,6 @@ use rustc_span::symbol::Symbol;
use rustc_target::abi::call::FnAbi;
use rustc_target::spec::Target;
-pub use rustc_data_structures::sync::MetadataRef;
-
-use std::any::Any;
-
pub trait BackendTypes {
type Value: CodegenObject;
type Function: CodegenObject;
@@ -117,7 +116,9 @@ pub trait CodegenBackend {
) -> Result<(), ErrorGuaranteed>;
}
-pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send + Sync {
+pub trait ExtraBackendMethods:
+ CodegenBackend + WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync
+{
fn codegen_allocator<'tcx>(
&self,
tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index 57de7e9620e..853c6934c2c 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -274,6 +274,7 @@ pub trait BuilderMethods<'a, 'tcx>:
// These are used by everyone except msvc
fn cleanup_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value);
+ fn filter_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value);
fn resume(&mut self, exn0: Self::Value, exn1: Self::Value);
// These are used only by msvc
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index cdef3fb2339..c591ff75ab8 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -3,7 +3,8 @@ use std::fmt;
use rustc_errors::Diagnostic;
use rustc_middle::mir::AssertKind;
-use rustc_middle::ty::{layout::LayoutError, query::TyCtxtAt, ConstInt};
+use rustc_middle::query::TyCtxtAt;
+use rustc_middle::ty::{layout::LayoutError, ConstInt};
use rustc_span::{Span, Symbol};
use super::InterpCx;
@@ -169,14 +170,14 @@ impl<'tcx> ConstEvalErr<'tcx> {
// See <https://github.com/rust-lang/rust/pull/63152>.
let mut err = struct_error(tcx, &self.error.to_string());
self.decorate(&mut err, decorate);
- ErrorHandled::Reported(err.emit())
+ ErrorHandled::Reported(err.emit().into())
}
_ => {
// Report as hard error.
let mut err = struct_error(tcx, message);
err.span_label(self.span, self.error.to_string());
self.decorate(&mut err, decorate);
- ErrorHandled::Reported(err.emit())
+ ErrorHandled::Reported(err.emit().into())
}
}
}
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index 088a824fd8f..fa8253d5e49 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -2,7 +2,7 @@ use rustc_attr as attr;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::Symbol;
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 814b67b46ec..58b5755af07 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -382,7 +382,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
rustc_span::DUMMY_SP,
"This is likely a const item that is missing from its impl",
);
- throw_inval!(AlreadyReported(guar));
+ throw_inval!(AlreadyReported(guar.into()));
} else {
// `find_mir_or_eval_fn` checks that this is a const fn before even calling us,
// so this should be unreachable.
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index b2197a0aabb..040eba10eb4 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -7,14 +7,13 @@ use either::{Either, Left, Right};
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
use rustc_index::IndexVec;
use rustc_middle::mir;
-use rustc_middle::mir::interpret::{ErrorHandled, InterpError};
+use rustc_middle::mir::interpret::{ErrorHandled, InterpError, ReportedErrorInfo};
+use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
TyAndLayout,
};
-use rustc_middle::ty::{
- self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable,
-};
+use rustc_middle::ty::{self, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable};
use rustc_mir_dataflow::storage::always_storage_live_locals;
use rustc_session::Limit;
use rustc_span::Span;
@@ -470,7 +469,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
};
// do not continue if typeck errors occurred (can only occur in local crate)
if let Some(err) = body.tainted_by_errors {
- throw_inval!(AlreadyReported(err));
+ throw_inval!(AlreadyReported(ReportedErrorInfo::tainted_by_errors(err)));
}
Ok(body)
}
@@ -517,7 +516,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(None) => throw_inval!(TooGeneric),
// FIXME(eddyb) this could be a bit more specific than `AlreadyReported`.
- Err(error_reported) => throw_inval!(AlreadyReported(error_reported)),
+ Err(error_reported) => throw_inval!(AlreadyReported(error_reported.into())),
}
}
@@ -905,7 +904,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
query(self.tcx.at(span.unwrap_or_else(|| self.cur_span()))).map_err(|err| {
match err {
ErrorHandled::Reported(err) => {
- if let Some(span) = span {
+ if !err.is_tainted_by_errors() && let Some(span) = span {
// To make it easier to figure out where this error comes from, also add a note at the current location.
self.tcx.sess.span_note_without_error(span, "erroneous constant used");
}
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index a7f66071fe2..e30af165501 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -595,7 +595,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// FIXME(generic_const_exprs): `ConstKind::Expr` should be able to be evaluated
ty::ConstKind::Expr(_) => throw_inval!(TooGeneric),
ty::ConstKind::Error(reported) => {
- throw_inval!(AlreadyReported(reported))
+ throw_inval!(AlreadyReported(reported.into()))
}
ty::ConstKind::Unevaluated(uv) => {
let instance = self.resolve(uv.def, uv.substs)?;
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 1b66eca97a5..c36282d5ed4 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -35,8 +35,8 @@ pub mod util;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
+use rustc_middle::query::Providers;
use rustc_middle::ty;
-use rustc_middle::ty::query::Providers;
fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index f46c2d00fe4..3c350e25ba6 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -164,7 +164,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if let Some(root) = post_contract_node.get(&bb) {
break *root;
}
- let parent = doms.immediate_dominator(bb);
+ let parent = doms.immediate_dominator(bb).unwrap();
dom_path.push(bb);
if !self.body.basic_blocks[parent].is_cleanup {
break bb;
@@ -448,7 +448,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
};
match debuginfo.value {
VarDebugInfoContents::Const(_) => {}
- VarDebugInfoContents::Place(place) => check_place(place),
+ VarDebugInfoContents::Place(place) => {
+ check_place(place);
+ if debuginfo.references != 0 && place.projection.last() == Some(&PlaceElem::Deref) {
+ self.fail(
+ START_BLOCK.start_location(),
+ format!("debuginfo {:?}, has both ref and deref", debuginfo),
+ );
+ }
+ }
VarDebugInfoContents::Composite { ty, ref fragments } => {
for f in fragments {
check_place(f.contents);
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index 5e05fe463ed..78f73d193e3 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -16,6 +16,7 @@ libc = "0.2"
measureme = "10.0.0"
rustc-rayon-core = { version = "0.5.0", optional = true }
rustc-rayon = { version = "0.5.0", optional = true }
+rustc_arena = { path = "../rustc_arena" }
rustc_graphviz = { path = "../rustc_graphviz" }
rustc-hash = "1.1.0"
rustc_index = { path = "../rustc_index", package = "rustc_index" }
@@ -37,7 +38,7 @@ itertools = "0.10.1"
version = "0.11"
[target.'cfg(windows)'.dependencies.windows]
-version = "0.46.0"
+version = "0.48.0"
features = [
"Win32_Foundation",
"Win32_Storage_FileSystem",
diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
index e76bdac2864..a7de709ba72 100644
--- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
@@ -242,7 +242,9 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
immediate_dominators[*node] = Some(pre_order_to_real[idom[idx]]);
}
- Dominators { post_order_rank, immediate_dominators }
+ let start_node = graph.start_node();
+ immediate_dominators[start_node] = None;
+ Dominators { start_node, post_order_rank, immediate_dominators }
}
/// Evaluate the link-eval virtual forest, providing the currently minimum semi
@@ -308,6 +310,7 @@ fn compress(
/// Tracks the list of dominators for each node.
#[derive(Clone, Debug)]
pub struct Dominators<N: Idx> {
+ start_node: N,
post_order_rank: IndexVec<N, usize>,
// Even though we track only the immediate dominator of each node, it's
// possible to get its full list of dominators by looking up the dominator
@@ -316,14 +319,14 @@ pub struct Dominators<N: Idx> {
}
impl<Node: Idx> Dominators<Node> {
- /// Whether the given Node has an immediate dominator.
+ /// Returns true if node is reachable from the start node.
pub fn is_reachable(&self, node: Node) -> bool {
- self.immediate_dominators[node].is_some()
+ node == self.start_node || self.immediate_dominators[node].is_some()
}
- pub fn immediate_dominator(&self, node: Node) -> Node {
- assert!(self.is_reachable(node), "node {node:?} is not reachable");
- self.immediate_dominators[node].unwrap()
+ /// Returns the immediate dominator of node, if any.
+ pub fn immediate_dominator(&self, node: Node) -> Option<Node> {
+ self.immediate_dominators[node]
}
/// Provides an iterator over each dominator up the CFG, for the given Node.
@@ -357,12 +360,7 @@ impl<'dom, Node: Idx> Iterator for Iter<'dom, Node> {
fn next(&mut self) -> Option<Self::Item> {
if let Some(node) = self.node {
- let dom = self.dominators.immediate_dominator(node);
- if dom == node {
- self.node = None; // reached the root
- } else {
- self.node = Some(dom);
- }
+ self.node = self.dominators.immediate_dominator(node);
Some(node)
} else {
None
diff --git a/compiler/rustc_data_structures/src/graph/dominators/tests.rs b/compiler/rustc_data_structures/src/graph/dominators/tests.rs
index ff31d8f7fdc..8b124516623 100644
--- a/compiler/rustc_data_structures/src/graph/dominators/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/tests.rs
@@ -8,7 +8,7 @@ fn diamond() {
let dominators = dominators(&graph);
let immediate_dominators = &dominators.immediate_dominators;
- assert_eq!(immediate_dominators[0], Some(0));
+ assert_eq!(immediate_dominators[0], None);
assert_eq!(immediate_dominators[1], Some(0));
assert_eq!(immediate_dominators[2], Some(0));
assert_eq!(immediate_dominators[3], Some(0));
@@ -30,7 +30,7 @@ fn paper() {
assert_eq!(immediate_dominators[3], Some(6));
assert_eq!(immediate_dominators[4], Some(6));
assert_eq!(immediate_dominators[5], Some(6));
- assert_eq!(immediate_dominators[6], Some(6));
+ assert_eq!(immediate_dominators[6], None);
}
#[test]
@@ -43,3 +43,13 @@ fn paper_slt() {
dominators(&graph);
}
+
+#[test]
+fn immediate_dominator() {
+ let graph = TestGraph::new(1, &[(1, 2), (2, 3)]);
+ let dominators = dominators(&graph);
+ assert_eq!(dominators.immediate_dominator(0), None);
+ assert_eq!(dominators.immediate_dominator(1), None);
+ assert_eq!(dominators.immediate_dominator(2), Some(1));
+ assert_eq!(dominators.immediate_dominator(3), Some(2));
+}
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 004017ec5f3..5b9b0e106d2 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -26,6 +26,7 @@
#![feature(test)]
#![feature(thread_id_value)]
#![feature(vec_into_raw_parts)]
+#![feature(allocator_api)]
#![feature(get_mut_unchecked)]
#![feature(lint_reasons)]
#![feature(unwrap_infallible)]
@@ -77,6 +78,7 @@ pub mod sorted_map;
pub mod stable_hasher;
mod atomic_ref;
pub mod fingerprint;
+pub mod marker;
pub mod profiling;
pub mod sharded;
pub mod stack;
diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs
new file mode 100644
index 00000000000..f8c06f9a814
--- /dev/null
+++ b/compiler/rustc_data_structures/src/marker.rs
@@ -0,0 +1,257 @@
+cfg_if!(
+ if #[cfg(not(parallel_compiler))] {
+ pub auto trait DynSend {}
+ pub auto trait DynSync {}
+
+ impl<T> DynSend for T {}
+ impl<T> DynSync for T {}
+ } else {
+ #[rustc_on_unimplemented(
+ message = "`{Self}` doesn't implement `DynSend`. \
+ Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`"
+ )]
+ // This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()`
+ // is true. These types can be wrapped in a `FromDyn` to get a `Send` type. Wrapping a
+ // `Send` type in `IntoDynSyncSend` will create a `DynSend` type.
+ pub unsafe auto trait DynSend {}
+
+ #[rustc_on_unimplemented(
+ message = "`{Self}` doesn't implement `DynSync`. \
+ Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Sync`"
+ )]
+ // This is an auto trait for types which can be shared across threads if `sync::is_dyn_thread_safe()`
+ // is true. These types can be wrapped in a `FromDyn` to get a `Sync` type. Wrapping a
+ // `Sync` type in `IntoDynSyncSend` will create a `DynSync` type.
+ pub unsafe auto trait DynSync {}
+
+ // Same with `Sync` and `Send`.
+ unsafe impl<T: DynSync + ?Sized> DynSend for &T {}
+
+ macro_rules! impls_dyn_send_neg {
+ ($([$t1: ty $(where $($generics1: tt)*)?])*) => {
+ $(impl$(<$($generics1)*>)? !DynSend for $t1 {})*
+ };
+ }
+
+ // Consistent with `std`
+ impls_dyn_send_neg!(
+ [std::env::Args]
+ [std::env::ArgsOs]
+ [*const T where T: ?Sized]
+ [*mut T where T: ?Sized]
+ [std::ptr::NonNull<T> where T: ?Sized]
+ [std::rc::Rc<T> where T: ?Sized]
+ [std::rc::Weak<T> where T: ?Sized]
+ [std::sync::MutexGuard<'_, T> where T: ?Sized]
+ [std::sync::RwLockReadGuard<'_, T> where T: ?Sized]
+ [std::sync::RwLockWriteGuard<'_, T> where T: ?Sized]
+ [std::io::StdoutLock<'_>]
+ [std::io::StderrLock<'_>]
+ );
+ cfg_if!(
+ // Consistent with `std`
+ // `os_imp::Env` is `!Send` in these platforms
+ if #[cfg(any(unix, target_os = "hermit", target_os = "wasi", target_os = "solid_asp3"))] {
+ impl !DynSend for std::env::VarsOs {}
+ }
+ );
+
+ macro_rules! already_send {
+ ($([$ty: ty])*) => {
+ $(unsafe impl DynSend for $ty where $ty: Send {})*
+ };
+ }
+
+ // These structures are already `Send`.
+ already_send!(
+ [std::backtrace::Backtrace]
+ [std::io::Stdout]
+ [std::io::Stderr]
+ [std::io::Error]
+ [std::fs::File]
+ [rustc_arena::DroplessArena]
+ [crate::memmap::Mmap]
+ [crate::profiling::SelfProfiler]
+ [crate::owned_slice::OwnedSlice]
+ );
+
+ macro_rules! impl_dyn_send {
+ ($($($attr: meta)* [$ty: ty where $($generics2: tt)*])*) => {
+ $(unsafe impl<$($generics2)*> DynSend for $ty {})*
+ };
+ }
+
+ impl_dyn_send!(
+ [std::sync::atomic::AtomicPtr<T> where T]
+ [std::sync::Mutex<T> where T: ?Sized+ DynSend]
+ [std::sync::mpsc::Sender<T> where T: DynSend]
+ [std::sync::Arc<T> where T: ?Sized + DynSync + DynSend]
+ [std::sync::LazyLock<T, F> where T: DynSend, F: DynSend]
+ [std::collections::HashSet<K, S> where K: DynSend, S: DynSend]
+ [std::collections::HashMap<K, V, S> where K: DynSend, V: DynSend, S: DynSend]
+ [std::collections::BTreeMap<K, V, A> where K: DynSend, V: DynSend, A: std::alloc::Allocator + Clone + DynSend]
+ [Vec<T, A> where T: DynSend, A: std::alloc::Allocator + DynSend]
+ [Box<T, A> where T: ?Sized + DynSend, A: std::alloc::Allocator + DynSend]
+ [crate::sync::Lock<T> where T: DynSend]
+ [crate::sync::RwLock<T> where T: DynSend]
+ [crate::tagged_ptr::CopyTaggedPtr<P, T, CP> where P: Send + crate::tagged_ptr::Pointer, T: Send + crate::tagged_ptr::Tag, const CP: bool]
+ [rustc_arena::TypedArena<T> where T: DynSend]
+ [indexmap::IndexSet<V, S> where V: DynSend, S: DynSend]
+ [indexmap::IndexMap<K, V, S> where K: DynSend, V: DynSend, S: DynSend]
+ [thin_vec::ThinVec<T> where T: DynSend]
+ [smallvec::SmallVec<A> where A: smallvec::Array + DynSend]
+ );
+
+ macro_rules! impls_dyn_sync_neg {
+ ($([$t1: ty $(where $($generics1: tt)*)?])*) => {
+ $(impl$(<$($generics1)*>)? !DynSync for $t1 {})*
+ };
+ }
+
+ // Consistent with `std`
+ impls_dyn_sync_neg!(
+ [std::env::Args]
+ [std::env::ArgsOs]
+ [*const T where T: ?Sized]
+ [*mut T where T: ?Sized]
+ [std::cell::Cell<T> where T: ?Sized]
+ [std::cell::RefCell<T> where T: ?Sized]
+ [std::cell::UnsafeCell<T> where T: ?Sized]
+ [std::ptr::NonNull<T> where T: ?Sized]
+ [std::rc::Rc<T> where T: ?Sized]
+ [std::rc::Weak<T> where T: ?Sized]
+ [std::cell::OnceCell<T> where T]
+ [std::sync::mpsc::Receiver<T> where T]
+ [std::sync::mpsc::Sender<T> where T]
+ );
+ cfg_if!(
+ // Consistent with `std`
+ // `os_imp::Env` is `!Sync` in these platforms
+ if #[cfg(any(unix, target_os = "hermit", target_os = "wasi", target_os = "solid_asp3"))] {
+ impl !DynSync for std::env::VarsOs {}
+ }
+ );
+
+ macro_rules! already_sync {
+ ($([$ty: ty])*) => {
+ $(unsafe impl DynSync for $ty where $ty: Sync {})*
+ };
+ }
+
+ // These structures are already `Sync`.
+ already_sync!(
+ [std::sync::atomic::AtomicBool]
+ [std::sync::atomic::AtomicUsize]
+ [std::sync::atomic::AtomicU8]
+ [std::sync::atomic::AtomicU32]
+ [std::sync::atomic::AtomicU64]
+ [std::backtrace::Backtrace]
+ [std::io::Error]
+ [std::fs::File]
+ [jobserver_crate::Client]
+ [crate::memmap::Mmap]
+ [crate::profiling::SelfProfiler]
+ [crate::owned_slice::OwnedSlice]
+ );
+
+ macro_rules! impl_dyn_sync {
+ ($($($attr: meta)* [$ty: ty where $($generics2: tt)*])*) => {
+ $(unsafe impl<$($generics2)*> DynSync for $ty {})*
+ };
+ }
+
+ impl_dyn_sync!(
+ [std::sync::atomic::AtomicPtr<T> where T]
+ [std::sync::OnceLock<T> where T: DynSend + DynSync]
+ [std::sync::Mutex<T> where T: ?Sized + DynSend]
+ [std::sync::Arc<T> where T: ?Sized + DynSync + DynSend]
+ [std::sync::LazyLock<T, F> where T: DynSend + DynSync, F: DynSend]
+ [std::collections::HashSet<K, S> where K: DynSync, S: DynSync]
+ [std::collections::HashMap<K, V, S> where K: DynSync, V: DynSync, S: DynSync]
+ [std::collections::BTreeMap<K, V, A> where K: DynSync, V: DynSync, A: std::alloc::Allocator + Clone + DynSync]
+ [Vec<T, A> where T: DynSync, A: std::alloc::Allocator + DynSync]
+ [Box<T, A> where T: ?Sized + DynSync, A: std::alloc::Allocator + DynSync]
+ [crate::sync::Lock<T> where T: DynSend]
+ [crate::sync::RwLock<T> where T: DynSend + DynSync]
+ [crate::sync::OneThread<T> where T]
+ [crate::sync::WorkerLocal<T> where T: DynSend]
+ [crate::intern::Interned<'a, T> where 'a, T: DynSync]
+ [crate::tagged_ptr::CopyTaggedPtr<P, T, CP> where P: Sync + crate::tagged_ptr::Pointer, T: Sync + crate::tagged_ptr::Tag, const CP: bool]
+ [parking_lot::lock_api::Mutex<R, T> where R: DynSync, T: ?Sized + DynSend]
+ [parking_lot::lock_api::RwLock<R, T> where R: DynSync, T: ?Sized + DynSend + DynSync]
+ [indexmap::IndexSet<V, S> where V: DynSync, S: DynSync]
+ [indexmap::IndexMap<K, V, S> where K: DynSync, V: DynSync, S: DynSync]
+ [smallvec::SmallVec<A> where A: smallvec::Array + DynSync]
+ [thin_vec::ThinVec<T> where T: DynSync]
+ );
+ }
+);
+
+pub fn assert_dyn_sync<T: ?Sized + DynSync>() {}
+pub fn assert_dyn_send<T: ?Sized + DynSend>() {}
+pub fn assert_dyn_send_val<T: ?Sized + DynSend>(_t: &T) {}
+pub fn assert_dyn_send_sync_val<T: ?Sized + DynSync + DynSend>(_t: &T) {}
+
+#[derive(Copy, Clone)]
+pub struct FromDyn<T>(T);
+
+impl<T> FromDyn<T> {
+ #[inline(always)]
+ pub fn from(val: T) -> Self {
+ // Check that `sync::is_dyn_thread_safe()` is true on creation so we can
+ // implement `Send` and `Sync` for this structure when `T`
+ // implements `DynSend` and `DynSync` respectively.
+ #[cfg(parallel_compiler)]
+ assert!(crate::sync::is_dyn_thread_safe());
+ FromDyn(val)
+ }
+
+ #[inline(always)]
+ pub fn into_inner(self) -> T {
+ self.0
+ }
+}
+
+// `FromDyn` is `Send` if `T` is `DynSend`, since it ensures that sync::is_dyn_thread_safe() is true.
+#[cfg(parallel_compiler)]
+unsafe impl<T: DynSend> Send for FromDyn<T> {}
+
+// `FromDyn` is `Sync` if `T` is `DynSync`, since it ensures that sync::is_dyn_thread_safe() is true.
+#[cfg(parallel_compiler)]
+unsafe impl<T: DynSync> Sync for FromDyn<T> {}
+
+impl<T> std::ops::Deref for FromDyn<T> {
+ type Target = T;
+
+ #[inline(always)]
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+// A wrapper to convert a struct that is already a `Send` or `Sync` into
+// an instance of `DynSend` and `DynSync`, since the compiler cannot infer
+// it automatically in some cases. (e.g. Box<dyn Send / Sync>)
+#[derive(Copy, Clone)]
+pub struct IntoDynSyncSend<T: ?Sized>(pub T);
+
+#[cfg(parallel_compiler)]
+unsafe impl<T: ?Sized + Send> DynSend for IntoDynSyncSend<T> {}
+#[cfg(parallel_compiler)]
+unsafe impl<T: ?Sized + Sync> DynSync for IntoDynSyncSend<T> {}
+
+impl<T> std::ops::Deref for IntoDynSyncSend<T> {
+ type Target = T;
+
+ #[inline(always)]
+ fn deref(&self) -> &T {
+ &self.0
+ }
+}
+
+impl<T> std::ops::DerefMut for IntoDynSyncSend<T> {
+ #[inline(always)]
+ fn deref_mut(&mut self) -> &mut T {
+ &mut self.0
+ }
+}
diff --git a/compiler/rustc_data_structures/src/owned_slice.rs b/compiler/rustc_data_structures/src/owned_slice.rs
index 048401f66c2..cbb3047d884 100644
--- a/compiler/rustc_data_structures/src/owned_slice.rs
+++ b/compiler/rustc_data_structures/src/owned_slice.rs
@@ -1,5 +1,6 @@
use std::{borrow::Borrow, ops::Deref};
+use crate::sync::Lrc;
// Use our fake Send/Sync traits when on not parallel compiler,
// so that `OwnedSlice` only implements/requires Send/Sync
// for parallel compiler builds.
@@ -7,7 +8,7 @@ use crate::sync::{Send, Sync};
/// An owned slice.
///
-/// This is similar to `Box<[u8]>` but allows slicing and using anything as the
+/// This is similar to `Lrc<[u8]>` but allows slicing and using anything as the
/// backing buffer.
///
/// See [`slice_owned`] for `OwnedSlice` construction and examples.
@@ -16,6 +17,7 @@ use crate::sync::{Send, Sync};
///
/// This is essentially a replacement for `owning_ref` which is a lot simpler
/// and even sound! 🌸
+#[derive(Clone)]
pub struct OwnedSlice {
/// This is conceptually a `&'self.owner [u8]`.
bytes: *const [u8],
@@ -31,7 +33,7 @@ pub struct OwnedSlice {
// \/
// ⊂(´・◡・⊂ )∘˚˳° (I am the phantom remnant of #97770)
#[expect(dead_code)]
- owner: Box<dyn Send + Sync>,
+ owner: Lrc<dyn Send + Sync>,
}
/// Makes an [`OwnedSlice`] out of an `owner` and a `slicer` function.
@@ -72,10 +74,10 @@ where
O: Send + Sync + 'static,
F: FnOnce(&O) -> Result<&[u8], E>,
{
- // We box the owner of the bytes, so it doesn't move.
+ // We wrap the owner of the bytes in, so it doesn't move.
//
// Since the owner does not move and we don't access it in any way
- // before drop, there is nothing that can invalidate the bytes pointer.
+ // before dropping, there is nothing that can invalidate the bytes pointer.
//
// Thus, "extending" the lifetime of the reference returned from `F` is fine.
// We pretend that we pass it a reference that lives as long as the returned slice.
@@ -83,12 +85,39 @@ where
// N.B. the HRTB on the `slicer` is important — without it the caller could provide
// a short lived slice, unrelated to the owner.
- let owner = Box::new(owner);
+ let owner = Lrc::new(owner);
let bytes = slicer(&*owner)?;
Ok(OwnedSlice { bytes, owner })
}
+impl OwnedSlice {
+ /// Slice this slice by `slicer`.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned};
+ /// let vec = vec![1, 2, 3, 4];
+ ///
+ /// // Identical to slicing via `&v[1..3]` but produces an owned slice
+ /// let slice: OwnedSlice = slice_owned(vec, |v| &v[..]);
+ /// assert_eq!(&*slice, [1, 2, 3, 4]);
+ ///
+ /// let slice = slice.slice(|slice| &slice[1..][..2]);
+ /// assert_eq!(&*slice, [2, 3]);
+ /// ```
+ ///
+ pub fn slice(self, slicer: impl FnOnce(&[u8]) -> &[u8]) -> OwnedSlice {
+ // This is basically identical to `try_slice_owned`,
+ // `slicer` can only return slices of its argument or some static data,
+ // both of which are valid while `owner` is alive.
+
+ let bytes = slicer(&self);
+ OwnedSlice { bytes, ..self }
+ }
+}
+
impl Deref for OwnedSlice {
type Target = [u8];
@@ -108,10 +137,12 @@ impl Borrow<[u8]> for OwnedSlice {
}
}
-// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Box<dyn Send + Sync>)`, which is `Send`
+// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Arc<dyn Send + Sync>)`, which is `Send`
+#[cfg(parallel_compiler)]
unsafe impl Send for OwnedSlice {}
-// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Box<dyn Send + Sync>)`, which is `Sync`
+// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Arc<dyn Send + Sync>)`, which is `Sync`
+#[cfg(parallel_compiler)]
unsafe impl Sync for OwnedSlice {}
#[cfg(test)]
diff --git a/compiler/rustc_data_structures/src/owned_slice/tests.rs b/compiler/rustc_data_structures/src/owned_slice/tests.rs
index e715fb55362..1eb5378cd1a 100644
--- a/compiler/rustc_data_structures/src/owned_slice/tests.rs
+++ b/compiler/rustc_data_structures/src/owned_slice/tests.rs
@@ -26,7 +26,7 @@ fn static_storage() {
}
#[test]
-fn slice_the_slice() {
+fn slice_owned_the_slice() {
let slice = slice_owned(vec![1, 2, 3, 4, 5, 6], Vec::as_slice);
let slice = slice_owned(slice, |s| &s[1..][..4]);
let slice = slice_owned(slice, |s| s);
@@ -36,6 +36,16 @@ fn slice_the_slice() {
}
#[test]
+fn slice_the_slice() {
+ let slice = slice_owned(vec![1, 2, 3, 4, 5, 6], Vec::as_slice)
+ .slice(|s| &s[1..][..4])
+ .slice(|s| s)
+ .slice(|s| &s[1..]);
+
+ assert_eq!(&*slice, &[1, 2, 3, 4, 5, 6][1..][..4][1..]);
+}
+
+#[test]
fn try_and_fail() {
let res = try_slice_owned(vec![0], |v| v.get(12..).ok_or(()));
@@ -69,6 +79,6 @@ fn drop_drops() {
#[test]
fn send_sync() {
- crate::sync::assert_send::<OwnedSlice>();
- crate::sync::assert_sync::<OwnedSlice>();
+ crate::sync::assert_dyn_send::<OwnedSlice>();
+ crate::sync::assert_dyn_sync::<OwnedSlice>();
}
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index 5e13e7c8aaf..3c76c2b7991 100644
--- a/compiler/rustc_data_structures/src/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
@@ -865,14 +865,16 @@ cfg_if! {
use std::mem;
use windows::{
- Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS},
+ // FIXME: change back to K32GetProcessMemoryInfo when windows crate
+ // updated to 0.49.0+ to drop dependency on psapi.dll
+ Win32::System::ProcessStatus::{GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS},
Win32::System::Threading::GetCurrentProcess,
};
let mut pmc = PROCESS_MEMORY_COUNTERS::default();
let pmc_size = mem::size_of_val(&pmc);
unsafe {
- K32GetProcessMemoryInfo(
+ GetProcessMemoryInfo(
GetCurrentProcess(),
&mut pmc,
pmc_size as u32,
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index e73ca56efa0..6c3197d8ec2 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -39,7 +39,7 @@
//!
//! [^2] `MTLockRef` is a typedef.
-use crate::owned_slice::OwnedSlice;
+pub use crate::marker::*;
use std::collections::HashMap;
use std::hash::{BuildHasher, Hash};
use std::ops::{Deref, DerefMut};
@@ -55,6 +55,43 @@ pub use vec::{AppendOnlyIndexVec, AppendOnlyVec};
mod vec;
+mod mode {
+ use super::Ordering;
+ use std::sync::atomic::AtomicU8;
+
+ const UNINITIALIZED: u8 = 0;
+ const DYN_NOT_THREAD_SAFE: u8 = 1;
+ const DYN_THREAD_SAFE: u8 = 2;
+
+ static DYN_THREAD_SAFE_MODE: AtomicU8 = AtomicU8::new(UNINITIALIZED);
+
+ // Whether thread safety is enabled (due to running under multiple threads).
+ #[inline]
+ pub fn is_dyn_thread_safe() -> bool {
+ match DYN_THREAD_SAFE_MODE.load(Ordering::Relaxed) {
+ DYN_NOT_THREAD_SAFE => false,
+ DYN_THREAD_SAFE => true,
+ _ => panic!("uninitialized dyn_thread_safe mode!"),
+ }
+ }
+
+ // Only set by the `-Z threads` compile option
+ pub fn set_dyn_thread_safe_mode(mode: bool) {
+ let set: u8 = if mode { DYN_THREAD_SAFE } else { DYN_NOT_THREAD_SAFE };
+ let previous = DYN_THREAD_SAFE_MODE.compare_exchange(
+ UNINITIALIZED,
+ set,
+ Ordering::Relaxed,
+ Ordering::Relaxed,
+ );
+
+ // Check that the mode was either uninitialized or was already set to the requested mode.
+ assert!(previous.is_ok() || previous == Err(set));
+ }
+}
+
+pub use mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode};
+
cfg_if! {
if #[cfg(not(parallel_compiler))] {
pub unsafe auto trait Send {}
@@ -149,7 +186,7 @@ cfg_if! {
#[macro_export]
macro_rules! parallel {
- ($($blocks:tt),*) => {
+ ($($blocks:block),*) => {
// We catch panics here ensuring that all the blocks execute.
// This makes behavior consistent with the parallel compiler.
let mut panic = None;
@@ -168,12 +205,6 @@ cfg_if! {
}
}
- pub use Iterator as ParallelIterator;
-
- pub fn par_iter<T: IntoIterator>(t: T) -> T::IntoIter {
- t.into_iter()
- }
-
pub fn par_for_each_in<T: IntoIterator>(t: T, mut for_each: impl FnMut(T::Item) + Sync + Send) {
// We catch panics here ensuring that all the loop iterations execute.
// This makes behavior consistent with the parallel compiler.
@@ -190,7 +221,28 @@ cfg_if! {
}
}
- pub type MetadataRef = OwnedSlice;
+ pub fn par_map<T: IntoIterator, R, C: FromIterator<R>>(
+ t: T,
+ mut map: impl FnMut(<<T as IntoIterator>::IntoIter as Iterator>::Item) -> R,
+ ) -> C {
+ // We catch panics here ensuring that all the loop iterations execute.
+ let mut panic = None;
+ let r = t.into_iter().filter_map(|i| {
+ match catch_unwind(AssertUnwindSafe(|| map(i))) {
+ Ok(r) => Some(r),
+ Err(p) => {
+ if panic.is_none() {
+ panic = Some(p);
+ }
+ None
+ }
+ }
+ }).collect();
+ if let Some(panic) = panic {
+ resume_unwind(panic);
+ }
+ r
+ }
pub use std::rc::Rc as Lrc;
pub use std::rc::Weak as Weak;
@@ -302,49 +354,166 @@ cfg_if! {
use parking_lot::RwLock as InnerRwLock;
use std::thread;
- pub use rayon::{join, scope};
+
+ #[inline]
+ pub fn join<A, B, RA: DynSend, RB: DynSend>(oper_a: A, oper_b: B) -> (RA, RB)
+ where
+ A: FnOnce() -> RA + DynSend,
+ B: FnOnce() -> RB + DynSend,
+ {
+ if mode::is_dyn_thread_safe() {
+ let oper_a = FromDyn::from(oper_a);
+ let oper_b = FromDyn::from(oper_b);
+ let (a, b) = rayon::join(move || FromDyn::from(oper_a.into_inner()()), move || FromDyn::from(oper_b.into_inner()()));
+ (a.into_inner(), b.into_inner())
+ } else {
+ (oper_a(), oper_b())
+ }
+ }
+
+ // This function only works when `mode::is_dyn_thread_safe()`.
+ pub fn scope<'scope, OP, R>(op: OP) -> R
+ where
+ OP: FnOnce(&rayon::Scope<'scope>) -> R + DynSend,
+ R: DynSend,
+ {
+ let op = FromDyn::from(op);
+ rayon::scope(|s| FromDyn::from(op.into_inner()(s))).into_inner()
+ }
/// Runs a list of blocks in parallel. The first block is executed immediately on
/// the current thread. Use that for the longest running block.
#[macro_export]
macro_rules! parallel {
- (impl $fblock:tt [$($c:tt,)*] [$block:tt $(, $rest:tt)*]) => {
+ (impl $fblock:block [$($c:expr,)*] [$block:expr $(, $rest:expr)*]) => {
parallel!(impl $fblock [$block, $($c,)*] [$($rest),*])
};
- (impl $fblock:tt [$($blocks:tt,)*] []) => {
+ (impl $fblock:block [$($blocks:expr,)*] []) => {
::rustc_data_structures::sync::scope(|s| {
+ $(let block = rustc_data_structures::sync::FromDyn::from(|| $blocks);
+ s.spawn(move |_| block.into_inner()());)*
+ (|| $fblock)();
+ });
+ };
+ ($fblock:block, $($blocks:block),*) => {
+ if rustc_data_structures::sync::is_dyn_thread_safe() {
+ // Reverse the order of the later blocks since Rayon executes them in reverse order
+ // when using a single thread. This ensures the execution order matches that
+ // of a single threaded rustc.
+ parallel!(impl $fblock [] [$($blocks),*]);
+ } else {
+ // We catch panics here ensuring that all the blocks execute.
+ // This makes behavior consistent with the parallel compiler.
+ let mut panic = None;
+ if let Err(p) = ::std::panic::catch_unwind(
+ ::std::panic::AssertUnwindSafe(|| $fblock)
+ ) {
+ if panic.is_none() {
+ panic = Some(p);
+ }
+ }
$(
- s.spawn(|_| $blocks);
+ if let Err(p) = ::std::panic::catch_unwind(
+ ::std::panic::AssertUnwindSafe(|| $blocks)
+ ) {
+ if panic.is_none() {
+ panic = Some(p);
+ }
+ }
)*
- $fblock;
- })
- };
- ($fblock:tt, $($blocks:tt),*) => {
- // Reverse the order of the later blocks since Rayon executes them in reverse order
- // when using a single thread. This ensures the execution order matches that
- // of a single threaded rustc
- parallel!(impl $fblock [] [$($blocks),*]);
+ if let Some(panic) = panic {
+ ::std::panic::resume_unwind(panic);
+ }
+ }
};
}
- pub use rayon::iter::ParallelIterator;
- use rayon::iter::IntoParallelIterator;
+ use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelIterator};
- pub fn par_iter<T: IntoParallelIterator>(t: T) -> T::Iter {
- t.into_par_iter()
- }
-
- pub fn par_for_each_in<T: IntoParallelIterator>(
+ pub fn par_for_each_in<I, T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>>(
t: T,
- for_each: impl Fn(T::Item) + Sync + Send,
+ for_each: impl Fn(I) + DynSync + DynSend
) {
- let ps: Vec<_> = t.into_par_iter().map(|i| catch_unwind(AssertUnwindSafe(|| for_each(i)))).collect();
- ps.into_iter().for_each(|p| if let Err(panic) = p {
- resume_unwind(panic)
- });
+ if mode::is_dyn_thread_safe() {
+ let for_each = FromDyn::from(for_each);
+ let panic: Lock<Option<_>> = Lock::new(None);
+ t.into_par_iter().for_each(|i| if let Err(p) = catch_unwind(AssertUnwindSafe(|| for_each(i))) {
+ let mut l = panic.lock();
+ if l.is_none() {
+ *l = Some(p)
+ }
+ });
+
+ if let Some(panic) = panic.into_inner() {
+ resume_unwind(panic);
+ }
+ } else {
+ // We catch panics here ensuring that all the loop iterations execute.
+ // This makes behavior consistent with the parallel compiler.
+ let mut panic = None;
+ t.into_iter().for_each(|i| {
+ if let Err(p) = catch_unwind(AssertUnwindSafe(|| for_each(i))) {
+ if panic.is_none() {
+ panic = Some(p);
+ }
+ }
+ });
+ if let Some(panic) = panic {
+ resume_unwind(panic);
+ }
+ }
}
- pub type MetadataRef = OwnedSlice;
+ pub fn par_map<
+ I,
+ T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>,
+ R: std::marker::Send,
+ C: FromIterator<R> + FromParallelIterator<R>
+ >(
+ t: T,
+ map: impl Fn(I) -> R + DynSync + DynSend
+ ) -> C {
+ if mode::is_dyn_thread_safe() {
+ let panic: Lock<Option<_>> = Lock::new(None);
+ let map = FromDyn::from(map);
+ // We catch panics here ensuring that all the loop iterations execute.
+ let r = t.into_par_iter().filter_map(|i| {
+ match catch_unwind(AssertUnwindSafe(|| map(i))) {
+ Ok(r) => Some(r),
+ Err(p) => {
+ let mut l = panic.lock();
+ if l.is_none() {
+ *l = Some(p);
+ }
+ None
+ },
+ }
+ }).collect();
+
+ if let Some(panic) = panic.into_inner() {
+ resume_unwind(panic);
+ }
+ r
+ } else {
+ // We catch panics here ensuring that all the loop iterations execute.
+ let mut panic = None;
+ let r = t.into_iter().filter_map(|i| {
+ match catch_unwind(AssertUnwindSafe(|| map(i))) {
+ Ok(r) => Some(r),
+ Err(p) => {
+ if panic.is_none() {
+ panic = Some(p);
+ }
+ None
+ }
+ }
+ }).collect();
+ if let Some(panic) = panic {
+ resume_unwind(panic);
+ }
+ r
+ }
+ }
/// This makes locks panic if they are already held.
/// It is only useful when you are running in a single thread
@@ -352,11 +521,6 @@ cfg_if! {
}
}
-pub fn assert_sync<T: ?Sized + Sync>() {}
-pub fn assert_send<T: ?Sized + Send>() {}
-pub fn assert_send_val<T: ?Sized + Send>(_t: &T) {}
-pub fn assert_send_sync_val<T: ?Sized + Sync + Send>(_t: &T) {}
-
#[derive(Default)]
#[cfg_attr(parallel_compiler, repr(align(64)))]
pub struct CacheAligned<T>(pub T);
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index cc4c5a0cacd..67352c55c90 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -51,12 +51,13 @@ rustc_interface = { path = "../rustc_interface" }
rustc_ast = { path = "../rustc_ast" }
rustc_span = { path = "../rustc_span" }
rustc_hir_analysis = { path = "../rustc_hir_analysis" }
+rustc_mir_transform = { path = "../rustc_mir_transform" }
[target.'cfg(unix)'.dependencies]
libc = "0.2"
[target.'cfg(windows)'.dependencies.windows]
-version = "0.46.0"
+version = "0.48.0"
features = [
"Win32_System_Diagnostics_Debug",
]
@@ -64,5 +65,8 @@ features = [
[features]
llvm = ['rustc_interface/llvm']
max_level_info = ['rustc_log/max_level_info']
-rustc_use_parallel_compiler = ['rustc_data_structures/rustc_use_parallel_compiler', 'rustc_interface/rustc_use_parallel_compiler',
- 'rustc_middle/rustc_use_parallel_compiler']
+rustc_use_parallel_compiler = [
+ 'rustc_data_structures/rustc_use_parallel_compiler',
+ 'rustc_interface/rustc_use_parallel_compiler',
+ 'rustc_middle/rustc_use_parallel_compiler'
+]
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 446e29199c6..80a9dfd251a 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -99,6 +99,7 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
rustc_middle::DEFAULT_LOCALE_RESOURCE,
rustc_mir_build::DEFAULT_LOCALE_RESOURCE,
rustc_mir_dataflow::DEFAULT_LOCALE_RESOURCE,
+ rustc_mir_transform::DEFAULT_LOCALE_RESOURCE,
rustc_monomorphize::DEFAULT_LOCALE_RESOURCE,
rustc_parse::DEFAULT_LOCALE_RESOURCE,
rustc_passes::DEFAULT_LOCALE_RESOURCE,
@@ -255,6 +256,9 @@ fn run_compiler(
let sopts = config::build_session_options(&matches);
+ // Set parallel mode before thread pool creation, which will create `Lock`s.
+ interface::set_thread_safe_mode(&sopts.unstable_opts);
+
if let Some(ref code) = matches.opt_str("explain") {
handle_explain(diagnostics_registry(), code, sopts.error_format);
return Ok(());
diff --git a/compiler/rustc_error_codes/src/error_codes/E0771.md b/compiler/rustc_error_codes/src/error_codes/E0771.md
index a2a1a20f230..4f36590025b 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0771.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0771.md
@@ -1,9 +1,11 @@
+#### Note: this error code is no longer emitted by the compiler
+
A non-`'static` lifetime was used in a const generic. This is currently not
allowed.
Erroneous code example:
-```compile_fail,E0771
+```compile_fail,E0770
#![feature(adt_const_params)]
fn function_with_str<'a, const STRING: &'a str>() {} // error!
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 6c3f677ab8e..0accb4ab96f 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -11,7 +11,7 @@ extern crate tracing;
use fluent_bundle::FluentResource;
use fluent_syntax::parser::ParserError;
use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker};
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
use rustc_fluent_macro::fluent_messages;
use rustc_macros::{Decodable, Encodable};
use rustc_span::Span;
@@ -37,16 +37,17 @@ pub use unic_langid::{langid, LanguageIdentifier};
fluent_messages! { "../messages.ftl" }
-pub type FluentBundle = fluent_bundle::bundle::FluentBundle<FluentResource, IntlLangMemoizer>;
+pub type FluentBundle =
+ IntoDynSyncSend<fluent_bundle::bundle::FluentBundle<FluentResource, IntlLangMemoizer>>;
-#[cfg(parallel_compiler)]
+#[cfg(not(parallel_compiler))]
fn new_bundle(locales: Vec<LanguageIdentifier>) -> FluentBundle {
- FluentBundle::new_concurrent(locales)
+ IntoDynSyncSend(fluent_bundle::bundle::FluentBundle::new(locales))
}
-#[cfg(not(parallel_compiler))]
+#[cfg(parallel_compiler)]
fn new_bundle(locales: Vec<LanguageIdentifier>) -> FluentBundle {
- FluentBundle::new(locales)
+ IntoDynSyncSend(fluent_bundle::bundle::FluentBundle::new_concurrent(locales))
}
#[derive(Debug)]
diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml
index 46ace8eb2dd..bd3033fcb3e 100644
--- a/compiler/rustc_errors/Cargo.toml
+++ b/compiler/rustc_errors/Cargo.toml
@@ -27,12 +27,11 @@ serde = { version = "1.0.125", features = [ "derive" ] }
serde_json = "1.0.59"
[target.'cfg(windows)'.dependencies.windows]
-version = "0.46.0"
+version = "0.48.0"
features = [
"Win32_Foundation",
"Win32_Security",
"Win32_System_Threading",
- "Win32_System_WindowsProgramming",
]
[features]
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index ef528d87cb2..db97d96fccd 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -571,6 +571,14 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
Some((diagnostic, handler))
}
+ /// Retrieves the [`Handler`] if available
+ pub fn handler(&self) -> Option<&Handler> {
+ match self.inner.state {
+ DiagnosticBuilderState::Emittable(handler) => Some(handler),
+ DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => None,
+ }
+ }
+
/// Buffers the diagnostic for later emission,
/// unless handler has disabled such buffering.
pub fn buffer(self, buffered_diagnostics: &mut Vec<Diagnostic>) {
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index fcbd9a53b48..0f360473619 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -32,7 +32,7 @@ use emitter::{is_case_difference, Emitter, EmitterWriter};
use registry::Registry;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
-use rustc_data_structures::sync::{self, Lock, Lrc};
+use rustc_data_structures::sync::{self, IntoDynSyncSend, Lock, Lrc};
use rustc_data_structures::AtomicRef;
pub use rustc_error_messages::{
fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle,
@@ -409,7 +409,7 @@ struct HandlerInner {
err_count: usize,
warn_count: usize,
deduplicated_err_count: usize,
- emitter: Box<dyn Emitter + sync::Send>,
+ emitter: IntoDynSyncSend<Box<dyn Emitter + sync::Send>>,
delayed_span_bugs: Vec<DelayedDiagnostic>,
delayed_good_path_bugs: Vec<DelayedDiagnostic>,
/// This flag indicates that an expected diagnostic was emitted and suppressed.
@@ -478,6 +478,7 @@ pub enum StashKey {
/// FRU syntax
MaybeFruTypo,
CallAssocMethod,
+ TraitMissingMethod,
}
fn default_track_diagnostic(d: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) {
@@ -605,7 +606,7 @@ impl Handler {
warn_count: 0,
deduplicated_err_count: 0,
deduplicated_warn_count: 0,
- emitter,
+ emitter: IntoDynSyncSend(emitter),
delayed_span_bugs: Vec::new(),
delayed_good_path_bugs: Vec::new(),
suppressed_expected_diag: false,
diff --git a/compiler/rustc_errors/src/lock.rs b/compiler/rustc_errors/src/lock.rs
index 7db262abfde..bd5cf49b56b 100644
--- a/compiler/rustc_errors/src/lock.rs
+++ b/compiler/rustc_errors/src/lock.rs
@@ -19,8 +19,7 @@ pub fn acquire_global_lock(name: &str) -> Box<dyn Any> {
use windows::{
core::PCSTR,
Win32::Foundation::{CloseHandle, HANDLE, WAIT_ABANDONED, WAIT_OBJECT_0},
- Win32::System::Threading::{CreateMutexA, ReleaseMutex, WaitForSingleObject},
- Win32::System::WindowsProgramming::INFINITE,
+ Win32::System::Threading::{CreateMutexA, ReleaseMutex, WaitForSingleObject, INFINITE},
};
struct Handle(HANDLE);
diff --git a/compiler/rustc_errors/src/tests.rs b/compiler/rustc_errors/src/tests.rs
index 52103e46097..0e729b71680 100644
--- a/compiler/rustc_errors/src/tests.rs
+++ b/compiler/rustc_errors/src/tests.rs
@@ -2,7 +2,7 @@ use crate::error::{TranslateError, TranslateErrorKind};
use crate::fluent_bundle::*;
use crate::translation::Translate;
use crate::FluentBundle;
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
use rustc_error_messages::fluent_bundle::resolver::errors::{ReferenceKind, ResolverError};
use rustc_error_messages::langid;
use rustc_error_messages::DiagnosticMessage;
@@ -27,10 +27,14 @@ fn make_dummy(ftl: &'static str) -> Dummy {
let langid_en = langid!("en-US");
#[cfg(parallel_compiler)]
- let mut bundle = FluentBundle::new_concurrent(vec![langid_en]);
+ let mut bundle: FluentBundle =
+ IntoDynSyncSend(crate::fluent_bundle::bundle::FluentBundle::new_concurrent(vec![
+ langid_en,
+ ]));
#[cfg(not(parallel_compiler))]
- let mut bundle = FluentBundle::new(vec![langid_en]);
+ let mut bundle: FluentBundle =
+ IntoDynSyncSend(crate::fluent_bundle::bundle::FluentBundle::new(vec![langid_en]));
bundle.add_resource(resource).expect("Failed to add FTL resources to the bundle.");
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index c1cca89df8c..e03576c55f4 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -653,13 +653,13 @@ pub enum SyntaxExtensionKind {
/// A token-based function-like macro.
Bang(
/// An expander with signature TokenStream -> TokenStream.
- Box<dyn BangProcMacro + sync::Sync + sync::Send>,
+ Box<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
),
/// An AST-based function-like macro.
LegacyBang(
/// An expander with signature TokenStream -> AST.
- Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
+ Box<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
),
/// A token-based attribute macro.
@@ -667,7 +667,7 @@ pub enum SyntaxExtensionKind {
/// An expander with signature (TokenStream, TokenStream) -> TokenStream.
/// The first TokenSteam is the attribute itself, the second is the annotated item.
/// The produced TokenSteam replaces the input TokenSteam.
- Box<dyn AttrProcMacro + sync::Sync + sync::Send>,
+ Box<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
),
/// An AST-based attribute macro.
@@ -675,7 +675,7 @@ pub enum SyntaxExtensionKind {
/// An expander with signature (AST, AST) -> AST.
/// The first AST fragment is the attribute itself, the second is the annotated item.
/// The produced AST fragment replaces the input AST fragment.
- Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
+ Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
),
/// A trivial attribute "macro" that does nothing,
@@ -692,14 +692,14 @@ pub enum SyntaxExtensionKind {
/// is handled identically to `LegacyDerive`. It should be migrated to
/// a token-based representation like `Bang` and `Attr`, instead of
/// using `MultiItemModifier`.
- Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
+ Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
),
/// An AST-based derive macro.
LegacyDerive(
/// An expander with signature AST -> AST.
/// The produced AST fragment is appended to the input AST fragment.
- Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
+ Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
),
}
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 27d30c315af..57e55752027 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -313,12 +313,16 @@ declare_features! (
(active, async_closure, "1.37.0", Some(62290), None),
/// Allows async functions to be declared, implemented, and used in traits.
(active, async_fn_in_trait, "1.66.0", Some(91611), None),
+ /// Allows builtin # foo() syntax
+ (active, builtin_syntax, "CURRENT_RUSTC_VERSION", Some(110680), None),
/// Allows `c"foo"` literals.
(active, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723), None),
/// Treat `extern "C"` function as nounwind.
(active, c_unwind, "1.52.0", Some(74990), None),
/// Allows using C-variadics.
(active, c_variadic, "1.34.0", Some(44930), None),
+ /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour.
+ (active, cfg_overflow_checks, "CURRENT_RUSTC_VERSION", Some(111466), None),
/// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used.
(active, cfg_sanitize, "1.41.0", Some(39699), None),
/// Allows `cfg(target_abi = "...")`.
@@ -334,7 +338,7 @@ declare_features! (
/// Allow conditional compilation depending on rust version
(active, cfg_version, "1.45.0", Some(64796), None),
/// Allows to use the `#[cfi_encoding = ""]` attribute.
- (active, cfi_encoding, "1.69.0", Some(89653), None),
+ (active, cfi_encoding, "CURRENT_RUSTC_VERSION", Some(89653), None),
/// Allows `for<...>` on closures and generators.
(active, closure_lifetime_binder, "1.64.0", Some(97362), None),
/// Allows `#[track_caller]` on closures and generators.
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index fe05d4590e7..61cfbf5c5e5 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -24,6 +24,7 @@ pub type GatedCfg = (Symbol, Symbol, GateFn);
/// `cfg(...)`'s that are feature gated.
const GATED_CFGS: &[GatedCfg] = &[
// (name in cfg, feature, function to check if the feature is enabled)
+ (sym::overflow_checks, sym::cfg_overflow_checks, cfg_fn!(cfg_overflow_checks)),
(sym::target_abi, sym::cfg_target_abi, cfg_fn!(cfg_target_abi)),
(sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
(
diff --git a/compiler/rustc_hir/src/errors.rs b/compiler/rustc_hir/src/errors.rs
deleted file mode 100644
index e593ed1044a..00000000000
--- a/compiler/rustc_hir/src/errors.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-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 38cd5865cc3..932f0396282 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2662,7 +2662,10 @@ pub enum OpaqueTyOrigin {
/// `async fn`
AsyncFn(LocalDefId),
/// type aliases: `type Foo = impl Trait;`
- TyAlias,
+ TyAlias {
+ /// associated types in impl blocks for traits.
+ in_assoc_ty: bool,
+ },
}
/// The various kinds of types recognized by the compiler.
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 1f08befb180..4b3bc816b95 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -8,7 +8,6 @@
//! * Functions called by the compiler itself.
use crate::def_id::DefId;
-use crate::errors::LangItemError;
use crate::{MethodKind, Target};
use rustc_ast as ast;
@@ -42,13 +41,6 @@ impl LanguageItems {
self.items[item as usize] = Some(def_id);
}
- /// 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 encapsulating the `LangItem`.
- pub fn require(&self, it: LangItem) -> Result<DefId, LangItemError> {
- self.get(it).ok_or_else(|| LangItemError(it))
- }
-
pub fn iter(&self) -> impl Iterator<Item = (LangItem, DefId)> + '_ {
self.items
.iter()
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 98d967cc0b8..616de57dc63 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -30,7 +30,6 @@ 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_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 3b42b0fe246..5e5c984a7ea 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -279,6 +279,9 @@ hir_analysis_specialization_trait = implementing `rustc_specialization_trait` tr
hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are forbidden when `for<...>` is present
.label = `for<...>` is here
+hir_analysis_empty_specialization = specialization impl does not specialize any associated items
+ .note = impl is a specialization of this impl
+
hir_analysis_const_specialize = cannot specialize on const impl with non-const impl
hir_analysis_static_specialize = cannot specialize on `'static` lifetime
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 5ee0cf94360..cf082f1ffaa 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -19,7 +19,7 @@ use rustc_ast::TraitObjectSyntax;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, FatalError,
- MultiSpan,
+ MultiSpan, StashKey,
};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
@@ -38,7 +38,6 @@ use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}
use rustc_middle::ty::{DynKind, ToPredicate};
use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS};
use rustc_span::edit_distance::find_best_match_for_name;
-use rustc_span::edition::Edition;
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::{sym, Span, DUMMY_SP};
use rustc_target::spec::abi;
@@ -464,7 +463,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.astconv.ct_infer(ty, Some(param), inf.span).into()
} else {
self.inferred_params.push(inf.span);
- tcx.const_error(ty).into()
+ tcx.const_error_misc(ty).into()
}
}
_ => unreachable!(),
@@ -518,7 +517,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.no_bound_vars()
.expect("const parameter types cannot be generic");
if let Err(guar) = ty.error_reported() {
- return tcx.const_error_with_guaranteed(ty, guar).into();
+ return tcx.const_error(ty, guar).into();
}
if !infer_args && has_default {
tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into()
@@ -527,7 +526,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.astconv.ct_infer(ty, Some(param), self.span).into()
} else {
// We've already errored above about the mismatch.
- tcx.const_error(ty).into()
+ tcx.const_error_misc(ty).into()
}
}
}
@@ -1387,7 +1386,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
term = match def_kind {
hir::def::DefKind::AssocTy => tcx.ty_error(reported).into(),
hir::def::DefKind::AssocConst => tcx
- .const_error_with_guaranteed(
+ .const_error(
tcx.type_of(assoc_item_def_id)
.subst(tcx, projection_ty.skip_binder().substs),
reported,
@@ -2419,6 +2418,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
return Ok(None);
}
+ //
+ // Select applicable inherent associated type candidates modulo regions.
+ //
+
// In contexts that have no inference context, just make a new one.
// We do need a local variable to store it, though.
let infcx_;
@@ -2431,7 +2434,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
};
- let param_env = tcx.param_env(block.owner.to_def_id());
+ // FIXME(inherent_associated_types): Acquiring the ParamEnv this early leads to cycle errors
+ // when inside of an ADT (#108491) or where clause.
+ let param_env = tcx.param_env(block.owner);
let cause = ObligationCause::misc(span, block.owner.def_id);
let mut fulfillment_errors = Vec::new();
@@ -2439,6 +2444,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let universe = infcx.create_next_universe();
// Regions are not considered during selection.
+ // FIXME(non_lifetime_binders): Here we are "truncating" or "flattening" the universes
+ // of type and const binders. Is that correct in the selection phase? See also #109505.
let self_ty = tcx.replace_escaping_bound_vars_uncached(
self_ty,
FnMutDelegate {
@@ -2454,41 +2461,40 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
candidates
.iter()
- .filter_map(|&(impl_, (assoc_item, def_scope))| {
+ .copied()
+ .filter(|&(impl_, _)| {
infcx.probe(|_| {
let ocx = ObligationCtxt::new_in_snapshot(&infcx);
- let impl_ty = tcx.type_of(impl_);
let impl_substs = infcx.fresh_item_substs(impl_);
- let impl_ty = impl_ty.subst(tcx, impl_substs);
+ let impl_ty = tcx.type_of(impl_).subst(tcx, impl_substs);
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
- // Check that the Self-types can be related.
- // FIXME(fmease): Should we use `eq` here?
- ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).ok()?;
+ // Check that the self types can be related.
+ // FIXME(inherent_associated_types): Should we use `eq` here? Method probing uses
+ // `sup` for this situtation, too. What for? To constrain inference variables?
+ if ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err()
+ {
+ return false;
+ }
// Check whether the impl imposes obligations we have to worry about.
- let impl_bounds = tcx.predicates_of(impl_);
- let impl_bounds = impl_bounds.instantiate(tcx, impl_substs);
-
+ let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_substs);
let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
-
let impl_obligations = traits::predicates_for_generics(
|_, _| cause.clone(),
param_env,
impl_bounds,
);
-
ocx.register_obligations(impl_obligations);
let mut errors = ocx.select_where_possible();
if !errors.is_empty() {
fulfillment_errors.append(&mut errors);
- return None;
+ return false;
}
- // FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot.
- Some((assoc_item, def_scope, infcx.resolve_vars_if_possible(impl_substs)))
+ true
})
})
.collect()
@@ -2497,24 +2503,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if applicable_candidates.len() > 1 {
return Err(self.complain_about_ambiguous_inherent_assoc_type(
name,
- applicable_candidates.into_iter().map(|(candidate, ..)| candidate).collect(),
+ applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(),
span,
));
}
- if let Some((assoc_item, def_scope, impl_substs)) = applicable_candidates.pop() {
+ if let Some((impl_, (assoc_item, def_scope))) = applicable_candidates.pop() {
self.check_assoc_ty(assoc_item, name, def_scope, block, span);
- // FIXME(inherent_associated_types): To fully *confirm* the *probed* candidate, we still
- // need to relate the Self-type with fresh item substs & register region obligations for
- // regionck to prove/disprove.
-
- let item_substs =
- self.create_substs_for_associated_item(span, assoc_item, segment, impl_substs);
+ // FIXME(fmease): Currently creating throwaway `parent_substs` to please
+ // `create_substs_for_associated_item`. Modify the latter instead (or sth. similar) to
+ // not require the parent substs logic.
+ let parent_substs = InternalSubsts::identity_for_item(tcx, impl_);
+ let substs =
+ self.create_substs_for_associated_item(span, assoc_item, segment, parent_substs);
+ let substs = tcx.mk_substs_from_iter(
+ std::iter::once(ty::GenericArg::from(self_ty))
+ .chain(substs.into_iter().skip(parent_substs.len())),
+ );
- // FIXME(fmease, #106722): Check if the bounds on the parameters of the
- // associated type hold, if any.
- let ty = tcx.type_of(assoc_item).subst(tcx, item_substs);
+ let ty = tcx.mk_alias(ty::Inherent, tcx.mk_alias_ty(assoc_item, substs));
return Ok(Some((ty, assoc_item)));
}
@@ -3709,7 +3717,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
));
}
- if self_ty.span.edition() >= Edition::Edition2021 {
+ if self_ty.span.edition().rust_2021() {
let msg = "trait objects must include the `dyn` keyword";
let label = "add `dyn` keyword before this trait";
let mut diag =
@@ -3723,7 +3731,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
// check if the impl trait that we are considering is a impl of a local trait
self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag);
- diag.emit();
+ diag.stash(self_ty.span, StashKey::TraitMissingMethod);
} else {
let msg = "trait objects without an explicit `dyn` are deprecated";
tcx.struct_span_lint_hir(
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index c4d4e0d6d78..d3495d3dbd7 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -31,6 +31,7 @@ use rustc_target::abi::FieldIdx;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
+use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCtxt, TraitEngine, TraitEngineExt as _};
use std::ops::ControlFlow;
@@ -222,7 +223,7 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
if check_opaque_for_cycles(tcx, item.owner_id.def_id, substs, span, &origin).is_err() {
return;
}
- check_opaque_meets_bounds(tcx, item.owner_id.def_id, substs, span, &origin);
+ check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, &origin);
}
/// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
@@ -391,13 +392,12 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
fn check_opaque_meets_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
- substs: SubstsRef<'tcx>,
span: Span,
origin: &hir::OpaqueTyOrigin,
) {
let defining_use_anchor = match *origin {
hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did,
- hir::OpaqueTyOrigin::TyAlias => def_id,
+ hir::OpaqueTyOrigin::TyAlias { .. } => tcx.impl_trait_parent(def_id),
};
let param_env = tcx.param_env(defining_use_anchor);
@@ -406,6 +406,8 @@ fn check_opaque_meets_bounds<'tcx>(
.with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor))
.build();
let ocx = ObligationCtxt::new(&infcx);
+
+ let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
// `ReErased` regions appear in the "parent_substs" of closures/generators.
@@ -448,9 +450,18 @@ fn check_opaque_meets_bounds<'tcx>(
match origin {
// Checked when type checking the function containing them.
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {}
+ // Nested opaque types occur only in associated types:
+ // ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
+ // They can only be referenced as `<Opaque<T> as Trait<&'static T>>::AssocTy`.
+ // We don't have to check them here because their well-formedness follows from the WF of
+ // the projection input types in the defining- and use-sites.
+ hir::OpaqueTyOrigin::TyAlias { .. }
+ if tcx.def_kind(tcx.parent(def_id.to_def_id())) == DefKind::OpaqueTy => {}
// Can have different predicates to their defining use
- hir::OpaqueTyOrigin::TyAlias => {
- let outlives_env = OutlivesEnvironment::new(param_env);
+ hir::OpaqueTyOrigin::TyAlias { .. } => {
+ let wf_tys = ocx.assumed_wf_types(param_env, span, def_id);
+ let implied_bounds = infcx.implied_bounds_tys(param_env, def_id, wf_tys);
+ let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
let _ = ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env);
}
}
@@ -1503,8 +1514,8 @@ fn opaque_type_cycle_error(
}
if tcx.sess.opts.unstable_opts.drop_tracking_mir
&& let DefKind::Generator = tcx.def_kind(closure_def_id)
+ && let Some(generator_layout) = tcx.mir_generator_witnesses(closure_def_id)
{
- let generator_layout = tcx.mir_generator_witnesses(closure_def_id);
for interior_ty in &generator_layout.field_tys {
label_match(interior_ty.ty, interior_ty.source_info.span);
}
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs
index 5ba1ca1c807..e0ba255cc06 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/dropck.rs
@@ -6,7 +6,7 @@ use rustc_errors::{struct_span_err, ErrorGuaranteed};
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::util::IgnoreRegions;
+use rustc_middle::ty::util::CheckRegions;
use rustc_middle::ty::{self, TyCtxt};
use rustc_trait_selection::traits::{self, ObligationCtxt};
@@ -81,7 +81,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
self_type_did: DefId,
adt_to_impl_substs: SubstsRef<'tcx>,
) -> Result<(), ErrorGuaranteed> {
- let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_substs, IgnoreRegions::No) else {
+ let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_substs, CheckRegions::OnlyEarlyBound) else {
return Ok(())
};
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 08154cdae47..3971a4c01d6 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -78,7 +78,7 @@ use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
use rustc_index::bit_set::BitSet;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{InternalSubsts, SubstsRef};
use rustc_session::parse::feature_err;
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 862f0a9b0e2..8918553e5f9 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -12,7 +12,7 @@ use rustc_infer::infer::outlives::env::{OutlivesEnvironment, RegionBoundPairs};
use rustc_infer::infer::outlives::obligations::TypeOutlives;
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
use rustc_middle::mir::ConstraintCategory;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{
self, AdtKind, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index d05d8508408..a98d8e17153 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -298,9 +298,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
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.to_string()));
- });
+ let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span));
let source = tcx.type_of(impl_did).subst_identity();
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity();
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index cd2ec2bef20..4524b87a418 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -8,7 +8,7 @@
use crate::errors;
use rustc_errors::{error_code, struct_span_err};
use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_span::sym;
use rustc_trait_selection::traits;
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 5ce8a83aad7..23beacd2a8c 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -6,7 +6,7 @@ use rustc_errors::{struct_span_err, DelayDm};
use rustc_errors::{Diagnostic, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::util::IgnoreRegions;
+use rustc_middle::ty::util::CheckRegions;
use rustc_middle::ty::{
self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
TypeVisitor,
@@ -210,6 +210,19 @@ fn do_orphan_check_impl<'tcx>(
NonlocalImpl::DisallowOther,
),
+ // ```
+ // struct S<T>(T);
+ // impl<T: ?Sized> S<T> {
+ // type This = T;
+ // }
+ // impl<T: ?Sized> AutoTrait for S<T>::This {}
+ // ```
+ // FIXME(inherent_associated_types): The example code above currently leads to a cycle
+ ty::Alias(AliasKind::Inherent, _) => (
+ LocalImpl::Disallow { problematic_kind: "associated type" },
+ NonlocalImpl::DisallowOther,
+ ),
+
// type Opaque = impl Trait;
// impl AutoTrait for Opaque {}
ty::Alias(AliasKind::Opaque, _) => (
@@ -494,7 +507,7 @@ fn lint_auto_trait_impl<'tcx>(
// Impls which completely cover a given root type are fine as they
// disable auto impls entirely. So only lint if the substs
// are not a permutation of the identity substs.
- let Err(arg) = tcx.uses_unique_generic_params(substs, IgnoreRegions::Yes) else {
+ let Err(arg) = tcx.uses_unique_generic_params(substs, CheckRegions::No) else {
// ok
return;
};
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index b65817ee95e..9f00dc418ee 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -28,7 +28,7 @@ use rustc_hir::{GenericParamKind, Node};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::util::{Discr, IntTypeExt};
use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, ToPredicate, Ty, TyCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -1483,7 +1483,7 @@ fn generator_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::GeneratorK
fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
match tcx.hir().get_by_def_id(def_id) {
Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(opaque), .. }) => {
- matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias)
+ matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. })
}
_ => bug!("tried getting opaque_ty_origin for non-opaque: {:?}", def_id),
}
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 119933697a1..ed60998ec8d 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -51,7 +51,15 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
// of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed.
None
} else if tcx.lazy_normalization() {
- if let Some(param_id) = tcx.hir().opt_const_param_default_param_def_id(hir_id) {
+ let parent_node = tcx.hir().get_parent(hir_id);
+ if let Node::Variant(Variant { disr_expr: Some(constant), .. }) = parent_node
+ && constant.hir_id == hir_id
+ {
+ // enum variant discriminants are not allowed to use any kind of generics
+ None
+ } else if let Some(param_id) =
+ tcx.hir().opt_const_param_default_param_def_id(hir_id)
+ {
// If the def_id we are calling generics_of on is an anon ct default i.e:
//
// struct Foo<const N: usize = { .. }>;
@@ -94,15 +102,15 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
has_self: generics.has_self,
has_late_bound_regions: generics.has_late_bound_regions,
};
+ } else {
+ // HACK(eddyb) this provides the correct generics when
+ // `feature(generic_const_expressions)` is enabled, so that const expressions
+ // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
+ //
+ // Note that we do not supply the parent generics when using
+ // `min_const_generics`.
+ Some(parent_def_id.to_def_id())
}
-
- // HACK(eddyb) this provides the correct generics when
- // `feature(generic_const_expressions)` is enabled, so that const expressions
- // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
- //
- // Note that we do not supply the parent generics when using
- // `min_const_generics`.
- Some(parent_def_id.to_def_id())
} else {
let parent_node = tcx.hir().get_parent(hir_id);
match parent_node {
@@ -115,11 +123,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
{
Some(parent_def_id.to_def_id())
}
- Node::Variant(Variant { disr_expr: Some(constant), .. })
- if constant.hir_id == hir_id =>
- {
- Some(parent_def_id.to_def_id())
- }
Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) => {
Some(tcx.typeck_root_def_id(def_id.to_def_id()))
}
@@ -156,7 +159,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
}
Some(fn_def_id.to_def_id())
}
- ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
+ ItemKind::OpaqueTy(hir::OpaqueTy {
+ origin: hir::OpaqueTyOrigin::TyAlias { .. },
+ ..
+ }) => {
let parent_id = tcx.hir().get_parent_item(hir_id);
assert_ne!(parent_id, hir::CRATE_OWNER_ID);
debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id);
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index e04658c8e77..a33990813b8 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -721,7 +721,7 @@ pub(super) fn type_param_predicates(
| ItemKind::TyAlias(_, generics)
| ItemKind::OpaqueTy(OpaqueTy {
generics,
- origin: hir::OpaqueTyOrigin::TyAlias,
+ origin: hir::OpaqueTyOrigin::TyAlias { .. },
..
})
| ItemKind::Enum(_, generics)
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 821567c1d88..794812a5ce7 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -17,6 +17,7 @@ use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeNa
use rustc_middle::bug;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::*;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
use rustc_session::lint;
use rustc_span::def_id::DefId;
@@ -232,8 +233,8 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
type ScopeRef<'a> = &'a Scope<'a>;
-pub(crate) fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers {
+pub(crate) fn provide(providers: &mut Providers) {
+ *providers = Providers {
resolve_bound_vars,
named_variable_map: |tcx, id| tcx.resolve_bound_vars(id).defs.get(&id),
@@ -526,7 +527,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
});
}
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
- origin: hir::OpaqueTyOrigin::TyAlias, ..
+ origin: hir::OpaqueTyOrigin::TyAlias { .. },
+ ..
}) => {
// Opaque types are visited when we visit the
// `TyKind::OpaqueDef`, so that they have the lifetimes from
@@ -707,7 +709,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
let opaque_ty = self.tcx.hir().item(item_id);
match &opaque_ty.kind {
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
- origin: hir::OpaqueTyOrigin::TyAlias,
+ origin: hir::OpaqueTyOrigin::TyAlias { .. },
..
}) => {
intravisit::walk_ty(self, ty);
@@ -1948,7 +1950,7 @@ fn is_late_bound_map(
ty::Param(param_ty) => {
self.arg_is_constrained[param_ty.index as usize] = true;
}
- ty::Alias(ty::Projection, _) => return ControlFlow::Continue(()),
+ ty::Alias(ty::Projection | ty::Inherent, _) => return ControlFlow::Continue(()),
_ => (),
}
t.super_visit_with(self)
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index c20fbfd1e40..6c7c2b9eea2 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -127,7 +127,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
// 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::Alias(ty::Projection, projection) = ty.kind() {
+ if let ty::Alias(ty::Projection | ty::Inherent, projection) = ty.kind() {
let generics = tcx.generics_of(projection.def_id);
let arg_index = segment
@@ -426,9 +426,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_adt(def, substs)
}
- ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
- find_opaque_ty_constraints_for_tait(tcx, def_id)
- }
+ ItemKind::OpaqueTy(OpaqueTy {
+ origin: hir::OpaqueTyOrigin::TyAlias { .. },
+ ..
+ }) => find_opaque_ty_constraints_for_tait(tcx, def_id),
// Opaque types desugared from `impl Trait`.
ItemKind::OpaqueTy(OpaqueTy {
origin:
diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
index e18b0f08279..9200c2aecf5 100644
--- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
+++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
@@ -59,7 +59,7 @@ struct ParameterCollector {
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match *t.kind() {
- ty::Alias(ty::Projection, ..) if !self.include_nonconstraining => {
+ ty::Alias(ty::Projection | ty::Inherent, ..) if !self.include_nonconstraining => {
// projections are not injective
return ControlFlow::Continue(());
}
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 379a88538a9..6e7eb4f6cdc 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -815,6 +815,15 @@ pub(crate) struct ClosureImplicitHrtb {
}
#[derive(Diagnostic)]
+#[diag(hir_analysis_empty_specialization)]
+pub(crate) struct EmptySpecialization {
+ #[primary_span]
+ pub span: Span,
+ #[note]
+ pub base_impl_span: Span,
+}
+
+#[derive(Diagnostic)]
#[diag(hir_analysis_const_specialize)]
pub(crate) struct ConstSpecialize {
#[primary_span]
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index 8269a6ddea5..e4c6e6e391a 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -4,7 +4,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{ForeignItem, ForeignItemKind};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ObligationCause, WellFormedLoc};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Region, TyCtxt, TypeFoldable, TypeFolder};
use rustc_span::def_id::LocalDefId;
use rustc_trait_selection::traits::{self, ObligationCtxt};
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index f070b4f9bae..612d4ff3df8 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -15,7 +15,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_errors::struct_span_err;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_span::{Span, Symbol};
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index 5cca2dacb5c..e84da2519ae 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -80,7 +80,7 @@ use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
-use rustc_trait_selection::traits::{self, translate_substs, wf, ObligationCtxt};
+use rustc_trait_selection::traits::{self, translate_substs_with_cause, 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) {
@@ -100,12 +100,19 @@ fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId) -> Opti
// Implementing a normal trait isn't a specialization.
return None;
}
+ if trait_def.is_marker {
+ // Overlapping marker implementations are not really specializations.
+ return None;
+ }
Some(impl2_node)
}
/// Check that `impl1` is a sound specialization
#[instrument(level = "debug", skip(tcx))]
fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node) {
+ let span = tcx.def_span(impl1_def_id);
+ check_has_items(tcx, impl1_def_id, impl2_node, span);
+
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!(?impl2_def_id, ?impl2_substs);
@@ -116,7 +123,6 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node
unconstrained_parent_impl_substs(tcx, impl2_def_id, impl2_substs)
};
- let span = tcx.def_span(impl1_def_id);
check_constness(tcx, impl1_def_id, impl2_node, span);
check_static_lifetimes(tcx, &parent_substs, span);
check_duplicate_params(tcx, impl1_substs, &parent_substs, span);
@@ -124,6 +130,13 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node
}
}
+fn check_has_items(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node, span: Span) {
+ if let Node::Impl(impl2_id) = impl2_node && tcx.associated_item_def_ids(impl1_def_id).is_empty() {
+ let base_impl_span = tcx.def_span(impl2_id);
+ tcx.sess.emit_err(errors::EmptySpecialization { span, base_impl_span });
+ }
+}
+
/// Check that the specializing impl `impl1` is at least as const as the base
/// impl `impl2`
fn check_constness(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node, span: Span) {
@@ -167,8 +180,21 @@ fn get_impl_substs(
ocx.assumed_wf_types(param_env, tcx.def_span(impl1_def_id), impl1_def_id);
let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id);
- let impl2_substs =
- translate_substs(infcx, param_env, impl1_def_id.to_def_id(), impl1_substs, impl2_node);
+ let impl1_span = tcx.def_span(impl1_def_id);
+ let impl2_substs = translate_substs_with_cause(
+ infcx,
+ param_env,
+ impl1_def_id.to_def_id(),
+ impl1_substs,
+ impl2_node,
+ |_, span| {
+ traits::ObligationCause::new(
+ impl1_span,
+ impl1_def_id,
+ traits::ObligationCauseCode::BindingObligation(impl2_node.def_id(), span),
+ )
+ },
+ );
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 3fe34f23aef..5cd2cd50c11 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -104,7 +104,7 @@ use rustc_hir as hir;
use rustc_hir::Node;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::middle;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::util;
use rustc_session::{config::EntryFnType, parse::feature_err};
diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
index d53c429ca15..0cd2fc1aa29 100644
--- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
@@ -210,6 +210,9 @@ fn insert_required_predicates_to_be_wf<'tcx>(
);
}
+ // FIXME(inherent_associated_types): Handle this case properly.
+ ty::Alias(ty::Inherent, _) => {}
+
_ => {}
}
}
diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs
index 42612eed750..a8596c707f3 100644
--- a/compiler/rustc_hir_analysis/src/outlives/mod.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs
@@ -1,7 +1,7 @@
use hir::Node;
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt};
use rustc_span::symbol::sym;
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index e735b048d73..3ebd9e134bf 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -6,7 +6,7 @@
use rustc_arena::DroplessArena;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt};
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
use std::ops::ControlFlow;
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index aa664031a87..4a669e3f8b8 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -79,3 +79,14 @@ hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but
hir_typeck_suggest_boxing_note = for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
hir_typeck_suggest_boxing_when_appropriate = store this in the heap by calling `Box::new`
+
+hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method ->
+ [true] {""}
+ *[other] {" "}in the current scope
+}
+
+hir_typeck_candidate_trait_note = `{$trait_name}` defines an item `{$item_name}`{$action_or_ty ->
+ [NONE] {""}
+ [implement] , perhaps you need to implement it
+ *[other] , perhaps you need to restrict type parameter `{$action_or_ty}` with it
+}
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 9d59cdcbc60..2defca54aff 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -86,9 +86,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error);
self.note_type_is_not_clone(err, expected, expr_ty, expr);
self.note_internal_mutation_in_method(err, expr, Some(expected), expr_ty);
- self.check_for_range_as_method_call(err, expr, expr_ty, expected);
- self.check_for_binding_assigned_block_without_tail_expression(err, expr, expr_ty, expected);
- self.check_wrong_return_type_due_to_generic_arg(err, expr, expr_ty);
+ self.suggest_method_call_on_range_literal(err, expr, expr_ty, expected);
+ self.suggest_return_binding_for_missing_tail_expr(err, expr, expr_ty, expected);
+ self.note_wrong_return_ty_due_to_generic_arg(err, expr, expr_ty);
}
/// Requires that the two types unify, and prints an error message if
@@ -1087,7 +1087,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// ```ignore (illustrative)
/// opt.map(|param| { takes_ref(param) });
/// ```
- fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, String)> {
+ fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Vec<(Span, String)>, &'static str)> {
let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.kind else {
return None;
};
@@ -1133,12 +1133,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
_ => 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);
- Some((method_path.ident.span, "consider using `as_ref` instead", suggestion))
- }
- _ => None,
+ if is_as_ref_able {
+ Some((
+ vec![(method_path.ident.span.shrink_to_lo(), "as_ref().".to_string())],
+ "consider using `as_ref` instead",
+ ))
+ } else {
+ None
}
}
@@ -1217,14 +1218,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// In addition of this check, it also checks between references mutability state. If the
/// expected is mutable but the provided isn't, maybe we could just say "Hey, try with
/// `&mut`!".
- pub fn check_ref(
+ pub fn suggest_deref_or_ref(
&self,
expr: &hir::Expr<'tcx>,
checked_ty: Ty<'tcx>,
expected: Ty<'tcx>,
) -> Option<(
- Span,
- String,
+ Vec<(Span, String)>,
String,
Applicability,
bool, /* verbose */
@@ -1254,30 +1254,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let Ok(src) = sm.span_to_snippet(sp)
&& replace_prefix(&src, "b\"", "\"").is_some()
{
- let pos = sp.lo() + BytePos(1);
- return Some((
- sp.with_hi(pos),
- "consider removing the leading `b`".to_string(),
- String::new(),
- Applicability::MachineApplicable,
- true,
- false,
- ));
- }
- }
+ let pos = sp.lo() + BytePos(1);
+ return Some((
+ vec![(sp.with_hi(pos), String::new())],
+ "consider removing the leading `b`".to_string(),
+ Applicability::MachineApplicable,
+ true,
+ false,
+ ));
+ }
+ }
(&ty::Array(arr, _) | &ty::Slice(arr), &ty::Str) if arr == self.tcx.types.u8 => {
if let hir::ExprKind::Lit(_) = expr.kind
&& let Ok(src) = sm.span_to_snippet(sp)
&& replace_prefix(&src, "\"", "b\"").is_some()
{
- return Some((
- sp.shrink_to_lo(),
- "consider adding a leading `b`".to_string(),
- "b".to_string(),
- Applicability::MachineApplicable,
- true,
- false,
- ));
+ return Some((
+ vec![(sp.shrink_to_lo(), "b".to_string())],
+ "consider adding a leading `b`".to_string(),
+ Applicability::MachineApplicable,
+ true,
+ false,
+ ));
}
}
_ => {}
@@ -1320,66 +1318,73 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner) = expr.kind
- && let Some(1) = self.deref_steps(expected, checked_ty) {
+ && let Some(1) = self.deref_steps(expected, checked_ty)
+ {
// We have `*&T`, check if what was expected was `&T`.
// If so, we may want to suggest removing a `*`.
sugg_sp = sugg_sp.with_hi(inner.span.lo());
return Some((
- sugg_sp,
+ vec![(sugg_sp, String::new())],
"consider removing deref here".to_string(),
- "".to_string(),
Applicability::MachineApplicable,
true,
false,
));
}
- if let Ok(src) = sm.span_to_snippet(sugg_sp) {
- let needs_parens = match expr.kind {
- // parenthesize if needed (Issue #46756)
- hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
- // parenthesize borrows of range literals (Issue #54505)
- _ if is_range_literal(expr) => true,
- _ => false,
- };
-
- if let Some(sugg) = self.can_use_as_ref(expr) {
- return Some((
- sugg.0,
- sugg.1.to_string(),
- sugg.2,
- Applicability::MachineApplicable,
- false,
- false,
- ));
- }
-
- let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
- Some(ident) => format!("{ident}: "),
- None => String::new(),
- };
-
- if let Some(hir::Node::Expr(hir::Expr {
- kind: hir::ExprKind::Assign(..),
- ..
- })) = self.tcx.hir().find_parent(expr.hir_id)
- {
- if mutability.is_mut() {
- // Suppressing this diagnostic, we'll properly print it in `check_expr_assign`
- return None;
- }
- }
+ let needs_parens = match expr.kind {
+ // parenthesize if needed (Issue #46756)
+ hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
+ // parenthesize borrows of range literals (Issue #54505)
+ _ if is_range_literal(expr) => true,
+ _ => false,
+ };
- let sugg_expr = if needs_parens { format!("({src})") } else { src };
+ if let Some((sugg, msg)) = self.can_use_as_ref(expr) {
return Some((
- sp,
- format!("consider {}borrowing here", mutability.mutably_str()),
- format!("{prefix}{}{sugg_expr}", mutability.ref_prefix_str()),
+ sugg,
+ msg.to_string(),
Applicability::MachineApplicable,
- false,
+ true,
false,
));
}
+
+ let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
+ Some(ident) => format!("{ident}: "),
+ None => String::new(),
+ };
+
+ if let Some(hir::Node::Expr(hir::Expr {
+ kind: hir::ExprKind::Assign(..),
+ ..
+ })) = self.tcx.hir().find_parent(expr.hir_id)
+ {
+ if mutability.is_mut() {
+ // Suppressing this diagnostic, we'll properly print it in `check_expr_assign`
+ return None;
+ }
+ }
+
+ let sugg = mutability.ref_prefix_str();
+ let (sugg, verbose) = if needs_parens {
+ (
+ vec![
+ (sp.shrink_to_lo(), format!("{prefix}{sugg}(")),
+ (sp.shrink_to_hi(), ")".to_string()),
+ ],
+ false,
+ )
+ } else {
+ (vec![(sp.shrink_to_lo(), format!("{prefix}{sugg}"))], true)
+ };
+ return Some((
+ sugg,
+ format!("consider {}borrowing here", mutability.mutably_str()),
+ Applicability::MachineApplicable,
+ verbose,
+ false,
+ ));
}
}
(
@@ -1401,23 +1406,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& sm.is_span_accessible(call_span)
{
return Some((
- sp.with_hi(call_span.lo()),
+ vec![(sp.with_hi(call_span.lo()), String::new())],
"consider removing the borrow".to_string(),
- String::new(),
Applicability::MachineApplicable,
true,
- true
+ true,
));
}
return None;
}
- if sp.contains(expr.span)
- && sm.is_span_accessible(expr.span)
- {
+ if sp.contains(expr.span) && sm.is_span_accessible(expr.span) {
return Some((
- sp.with_hi(expr.span.lo()),
+ vec![(sp.with_hi(expr.span.lo()), String::new())],
"consider removing the borrow".to_string(),
- String::new(),
Applicability::MachineApplicable,
true,
true,
@@ -1441,23 +1442,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let suggestion = replace_prefix(&src, old_prefix, &new_prefix).map(|_| {
// skip `&` or `&mut ` if both mutabilities are mutable
- let lo = sp.lo() + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _);
+ let lo = sp.lo()
+ + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _);
// skip `&` or `&mut `
let hi = sp.lo() + BytePos(old_prefix.len() as _);
let sp = sp.with_lo(lo).with_hi(hi);
(
sp,
- format!("{}{derefs}", if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" }),
- if mutbl_b <= mutbl_a { Applicability::MachineApplicable } else { Applicability::MaybeIncorrect }
+ format!(
+ "{}{derefs}",
+ if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" }
+ ),
+ if mutbl_b <= mutbl_a {
+ Applicability::MachineApplicable
+ } else {
+ Applicability::MaybeIncorrect
+ },
)
});
if let Some((span, src, applicability)) = suggestion {
return Some((
- span,
+ vec![(span, src)],
"consider dereferencing".to_string(),
- src,
applicability,
true,
false,
@@ -1486,9 +1494,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// If we've reached our target type with just removing `&`, then just print now.
if steps == 0 && !remove.trim().is_empty() {
return Some((
- prefix_span,
+ vec![(prefix_span, String::new())],
format!("consider removing the `{}`", remove.trim()),
- String::new(),
// Do not remove `&&` to get to bool, because it might be something like
// { a } && b, which we have a separate fixup suggestion that is more
// likely correct...
@@ -1554,9 +1561,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
return Some((
- span,
+ vec![(span, suggestion)],
message,
- suggestion,
Applicability::MachineApplicable,
true,
false,
@@ -1569,7 +1575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None
}
- pub fn check_for_cast(
+ pub fn suggest_cast(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
@@ -1936,7 +1942,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
/// Identify when the user has written `foo..bar()` instead of `foo.bar()`.
- pub fn check_for_range_as_method_call(
+ pub fn suggest_method_call_on_range_literal(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'tcx>,
@@ -2005,7 +2011,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Identify when the type error is because `()` is found in a binding that was assigned a
/// block without a tail expression.
- fn check_for_binding_assigned_block_without_tail_expression(
+ fn suggest_return_binding_for_missing_tail_expr(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
@@ -2047,7 +2053,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
- fn check_wrong_return_type_due_to_generic_arg(
+ fn note_wrong_return_ty_due_to_generic_arg(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index ce30bbeca0b..102a313067f 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -1,4 +1,6 @@
//! Errors emitted by `rustc_hir_typeck`.
+use std::borrow::Cow;
+
use crate::fluent_generated as fluent;
use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage};
use rustc_macros::{Diagnostic, Subdiagnostic};
@@ -295,3 +297,25 @@ pub enum SuggestBoxing {
end: Span,
},
}
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_no_associated_item, code = "E0599")]
+pub struct NoAssociatedItem {
+ #[primary_span]
+ pub span: Span,
+ pub item_kind: &'static str,
+ pub item_name: Ident,
+ pub ty_prefix: Cow<'static, str>,
+ pub ty_str: String,
+ pub trait_missing_method: bool,
+}
+
+#[derive(Subdiagnostic)]
+#[note(hir_typeck_candidate_trait_note)]
+pub struct CandidateTraitNote {
+ #[primary_span]
+ pub span: Span,
+ pub trait_name: String,
+ pub item_name: Ident,
+ pub action_or_ty: String,
+}
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index bba049c3819..8ea159bba74 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1245,6 +1245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
error,
Some((rcvr, args)),
expected,
+ false,
) {
err.emit();
}
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 9e78e6acba5..039316c74dd 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -4,7 +4,7 @@ use crate::rvalue_scopes;
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, RawTy};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan};
+use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
@@ -853,6 +853,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let item_name = item_segment.ident;
let result = self
.resolve_fully_qualified_call(span, item_name, ty.normalized, qself.span, hir_id)
+ .and_then(|r| {
+ // lint bare trait if the method is found in the trait
+ if span.edition().rust_2021() && let Some(mut diag) = self.tcx.sess.diagnostic().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) {
+ diag.emit();
+ }
+ Ok(r)
+ })
.or_else(|error| {
let guar = self
.tcx
@@ -863,17 +870,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => Err(guar),
};
+ let trait_missing_method =
+ matches!(error, method::MethodError::NoMatch(_)) && ty.normalized.is_trait();
// If we have a path like `MyTrait::missing_method`, then don't register
// a WF obligation for `dyn MyTrait` when method lookup fails. Otherwise,
// register a WF obligation so that we can detect any additional
// errors in the self type.
- if !(matches!(error, method::MethodError::NoMatch(_)) && ty.normalized.is_trait()) {
+ if !trait_missing_method {
self.register_wf_obligation(
ty.raw.into(),
qself.span,
traits::WellFormed(None),
);
}
+
+ // emit or cancel the diagnostic for bare traits
+ if span.edition().rust_2021() && let Some(mut diag) = self.tcx.sess.diagnostic().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) {
+ if trait_missing_method {
+ // cancel the diag for bare traits when meeting `MyTrait::missing_method`
+ diag.cancel();
+ } else {
+ diag.emit();
+ }
+ }
+
if item_name.name != kw::Empty {
if let Some(mut e) = self.report_method_error(
span,
@@ -883,10 +903,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
error,
None,
Expectation::NoExpectation,
+ trait_missing_method && span.edition().rust_2021(), // emits missing method for trait only after edition 2021
) {
e.emit();
}
}
+
result
});
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index 70ce45e21ea..3efdab53438 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -278,9 +278,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: Span,
) -> bool {
if let traits::FulfillmentErrorCode::CodeSelectionError(
- traits::SelectionError::OutputTypeParameterMismatch(_, expected, _),
+ traits::SelectionError::OutputTypeParameterMismatch(box traits::SelectionOutputTypeParameterMismatch{
+ expected_trait_ref, ..
+ }),
) = error.code
- && let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = expected.skip_binder().self_ty().kind()
+ && let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = expected_trait_ref.skip_binder().self_ty().kind()
&& span.overlaps(self.tcx.def_span(*def_id))
{
true
@@ -843,7 +845,7 @@ fn find_param_in_ty<'tcx>(
return true;
}
if let ty::GenericArgKind::Type(ty) = arg.unpack()
- && let ty::Alias(ty::Projection, ..) = ty.kind()
+ && let ty::Alias(ty::Projection | ty::Inherent, ..) = ty.kind()
{
// This logic may seem a bit strange, but typically when
// we have a projection type in a function signature, the
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 73a7bbebb65..67f45f9aa3f 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -300,7 +300,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
match ty.kind() {
ty::Adt(adt_def, _) => Some(*adt_def),
// FIXME(#104767): Should we handle bound regions here?
- ty::Alias(ty::Projection, _) if !ty.has_escaping_bound_vars() => {
+ ty::Alias(ty::Projection | ty::Inherent, _) if !ty.has_escaping_bound_vars() => {
self.normalize(span, ty).ty_adt_def()
}
_ => None,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 2867fcc8ecd..c4add4dbdfb 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -275,13 +275,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
) -> bool {
let expr = expr.peel_blocks();
- if let Some((sp, msg, suggestion, applicability, verbose, annotation)) =
- self.check_ref(expr, found, expected)
+ if let Some((suggestion, msg, applicability, verbose, annotation)) =
+ self.suggest_deref_or_ref(expr, found, expected)
{
if verbose {
- err.span_suggestion_verbose(sp, msg, suggestion, applicability);
+ err.multipart_suggestion_verbose(msg, suggestion, applicability);
} else {
- err.span_suggestion(sp, msg, suggestion, applicability);
+ err.multipart_suggestion(msg, suggestion, applicability);
}
if annotation {
let suggest_annotation = match expr.peel_drop_temps().kind {
@@ -343,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.span_label(sp, format!("{descr} `{name}` defined here"));
}
return true;
- } else if self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
+ } else if self.suggest_cast(err, expr, found, expected, expected_ty_expr) {
return true;
} else {
let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index a2a4362e2f5..54b222ade03 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -2,6 +2,7 @@
#![feature(let_chains)]
#![feature(try_blocks)]
#![feature(never_type)]
+#![feature(box_patterns)]
#![feature(min_specialization)]
#![feature(control_flow_enum)]
#![feature(drain_filter)]
@@ -67,8 +68,8 @@ use rustc_hir::{HirIdMap, Node};
use rustc_hir_analysis::astconv::AstConv;
use rustc_hir_analysis::check::check_abi;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_middle::query::Providers;
use rustc_middle::traits;
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_session::config;
use rustc_session::Session;
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index 5963a1632c5..cf9290c1a48 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -18,6 +18,7 @@ use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace};
use rustc_hir::def_id::DefId;
use rustc_infer::infer::{self, InferOk};
+use rustc_middle::query::Providers;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitableExt};
@@ -28,7 +29,7 @@ use rustc_trait_selection::traits::{self, NormalizeExt};
use self::probe::{IsSuggestion, ProbeScope};
-pub fn provide(providers: &mut ty::query::Providers) {
+pub fn provide(providers: &mut Providers) {
probe::provide(providers);
}
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 483e17460b3..f91f4f887c6 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -16,6 +16,7 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse};
use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
use rustc_middle::middle::stability;
+use rustc_middle::query::Providers;
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
use rustc_middle::ty::AssocItem;
use rustc_middle::ty::GenericParamDefKind;
@@ -495,7 +496,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
-pub fn provide(providers: &mut ty::query::Providers) {
+pub fn provide(providers: &mut Providers) {
providers.method_autoderef_steps = method_autoderef_steps;
}
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 30f0978d190..12bc17ca97c 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -2,6 +2,8 @@
//! found or is otherwise invalid.
use crate::errors;
+use crate::errors::CandidateTraitNote;
+use crate::errors::NoAssociatedItem;
use crate::Expectation;
use crate::FnCtxt;
use rustc_ast::ast::Mutability;
@@ -38,6 +40,7 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _
use rustc_trait_selection::traits::{
FulfillmentError, Obligation, ObligationCause, ObligationCauseCode,
};
+use std::borrow::Cow;
use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope};
use super::{CandidateSource, MethodError, NoMatchData};
@@ -112,6 +115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
error: MethodError<'tcx>,
args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
expected: Expectation<'tcx>,
+ trait_missing_method: bool,
) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
// Avoid suggestions when we don't know what's going on.
if rcvr_ty.references_error() {
@@ -136,6 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sugg_span,
&mut no_match_data,
expected,
+ trait_missing_method,
);
}
@@ -278,6 +283,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sugg_span: Span,
no_match_data: &mut NoMatchData<'tcx>,
expected: Expectation<'tcx>,
+ trait_missing_method: bool,
) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
let mode = no_match_data.mode;
let tcx = self.tcx;
@@ -323,7 +329,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span = item_name.span;
// Don't show generic arguments when the method can't be found in any implementation (#81576).
- let mut ty_str_reported = ty_str.clone();
+ let mut ty_str_reported = if trait_missing_method {
+ ty_str.strip_prefix("dyn ").expect("Failed to remove the prefix dyn").to_owned()
+ } else {
+ ty_str.clone()
+ };
+
if let ty::Adt(_, generics) = rcvr_ty.kind() {
if generics.len() > 0 {
let mut autoderef = self.autoderef(span, rcvr_ty);
@@ -355,25 +366,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{
self.suggest_missing_writer(rcvr_ty, args)
} else {
- struct_span_err!(
- tcx.sess,
+ tcx.sess.create_err(NoAssociatedItem {
span,
- E0599,
- "no {} named `{}` found for {} `{}` in the current scope",
item_kind,
item_name,
- rcvr_ty.prefix_string(self.tcx),
- ty_str_reported,
- )
+ ty_prefix: if trait_missing_method {
+ // FIXME(mu001999) E0599 maybe not suitable here because it is for types
+ Cow::from("trait")
+ } else {
+ rcvr_ty.prefix_string(self.tcx)
+ },
+ ty_str: ty_str_reported,
+ trait_missing_method,
+ })
};
if tcx.sess.source_map().is_multiline(sugg_span) {
err.span_label(sugg_span.with_hi(span.lo()), "");
}
- let ty_str = if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 {
+ let mut ty_str = if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 {
short_ty_str
} else {
ty_str
};
+ if trait_missing_method {
+ ty_str =
+ ty_str.strip_prefix("dyn ").expect("Failed to remove the prefix dyn").to_owned();
+ }
+
if let Some(file) = ty_file {
err.note(format!("the full type name has been written to '{}'", file.display(),));
}
@@ -1045,7 +1064,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
}
- self.check_for_inner_self(&mut err, source, rcvr_ty, item_name);
+ self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_name);
bound_spans.sort();
bound_spans.dedup();
@@ -1067,6 +1086,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&static_candidates,
unsatisfied_bounds,
expected.only_has_type(self),
+ trait_missing_method,
);
}
@@ -1132,7 +1152,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
- self.check_for_deref_method(&mut err, source, rcvr_ty, item_name, expected);
+ self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
return Some(err);
}
@@ -1805,7 +1825,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
- fn check_for_inner_self(
+ fn suggest_unwrapping_inner_self(
&self,
err: &mut Diagnostic,
source: SelfSource<'tcx>,
@@ -2175,7 +2195,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
- fn check_for_deref_method(
+ fn note_derefed_ty_has_method(
&self,
err: &mut Diagnostic,
self_source: SelfSource<'tcx>,
@@ -2211,7 +2231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| ty::Float(_)
| ty::Adt(_, _)
| ty::Str
- | ty::Alias(ty::Projection, _)
+ | ty::Alias(ty::Projection | ty::Inherent, _)
| ty::Param(_) => format!("{deref_ty}"),
// we need to test something like <&[_]>::len or <(&[u32])>::len
// and Vec::function();
@@ -2375,6 +2395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
static_candidates: &[CandidateSource],
unsatisfied_bounds: bool,
return_type: Option<Ty<'tcx>>,
+ trait_missing_method: bool,
) {
let mut alt_rcvr_sugg = false;
if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) {
@@ -2598,11 +2619,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
},
_ => None,
};
- err.help(if param_type.is_some() {
- "items from traits can only be used if the type parameter is bounded by the trait"
- } else {
- "items from traits can only be used if the trait is implemented and in scope"
- });
+ if !trait_missing_method {
+ err.help(if param_type.is_some() {
+ "items from traits can only be used if the type parameter is bounded by the trait"
+ } else {
+ "items from traits can only be used if the trait is implemented and in scope"
+ });
+ }
+
let candidates_len = candidates.len();
let message = |action| {
format!(
@@ -2633,47 +2657,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Nothing,
}
let ast_generics = hir.get_generics(id.owner.def_id).unwrap();
- let (sp, mut introducer) = if let Some(span) =
- ast_generics.bounds_span_for_suggestions(def_id)
- {
- (span, Introducer::Plus)
- } else if let Some(colon_span) = param.colon_span {
- (colon_span.shrink_to_hi(), Introducer::Nothing)
- } else {
- (param.span.shrink_to_hi(), Introducer::Colon)
- };
- if matches!(
- param.kind,
- hir::GenericParamKind::Type { synthetic: true, .. },
- ) {
- introducer = Introducer::Plus
- }
let trait_def_ids: FxHashSet<DefId> = ast_generics
.bounds_for_param(def_id)
.flat_map(|bp| bp.bounds.iter())
.filter_map(|bound| bound.trait_ref()?.trait_def_id())
.collect();
- if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
- err.span_suggestions(
- sp,
- message(format!(
- "restrict type parameter `{}` with",
- param.name.ident(),
- )),
+ if candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
+ return;
+ }
+ let msg = message(format!(
+ "restrict type parameter `{}` with",
+ param.name.ident(),
+ ));
+ let bounds_span = ast_generics.bounds_span_for_suggestions(def_id);
+ if rcvr_ty.is_ref() && param.is_impl_trait() && bounds_span.is_some() {
+ err.multipart_suggestions(
+ msg,
candidates.iter().map(|t| {
- format!(
- "{} {}",
- match introducer {
- Introducer::Plus => " +",
- Introducer::Colon => ":",
- Introducer::Nothing => "",
- },
- self.tcx.def_path_str(t.def_id),
- )
+ vec![
+ (param.span.shrink_to_lo(), "(".to_string()),
+ (
+ bounds_span.unwrap(),
+ format!(" + {})", self.tcx.def_path_str(t.def_id)),
+ ),
+ ]
}),
Applicability::MaybeIncorrect,
);
+ return;
}
+
+ let (sp, introducer) = if let Some(span) = bounds_span {
+ (span, Introducer::Plus)
+ } else if let Some(colon_span) = param.colon_span {
+ (colon_span.shrink_to_hi(), Introducer::Nothing)
+ } else if param.is_impl_trait() {
+ (param.span.shrink_to_hi(), Introducer::Plus)
+ } else {
+ (param.span.shrink_to_hi(), Introducer::Colon)
+ };
+
+ err.span_suggestions(
+ sp,
+ msg,
+ candidates.iter().map(|t| {
+ format!(
+ "{} {}",
+ match introducer {
+ Introducer::Plus => " +",
+ Introducer::Colon => ":",
+ Introducer::Nothing => "",
+ },
+ self.tcx.def_path_str(t.def_id)
+ )
+ }),
+ Applicability::MaybeIncorrect,
+ );
return;
}
Node::Item(hir::Item {
@@ -2736,27 +2775,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(candidates, Vec::new())
};
- let action = if let Some(param) = param_type {
- format!("restrict type parameter `{}` with", param)
- } else {
- // FIXME: it might only need to be imported into scope, not implemented.
- "implement".to_string()
- };
match &potential_candidates[..] {
[] => {}
[trait_info] if trait_info.def_id.is_local() => {
- err.span_note(
- self.tcx.def_span(trait_info.def_id),
- format!(
- "`{}` defines an item `{}`, perhaps you need to {} it",
- self.tcx.def_path_str(trait_info.def_id),
- item_name,
- action
- ),
- );
+ err.subdiagnostic(CandidateTraitNote {
+ span: self.tcx.def_span(trait_info.def_id),
+ trait_name: self.tcx.def_path_str(trait_info.def_id),
+ item_name,
+ action_or_ty: if trait_missing_method {
+ "NONE".to_string()
+ } else {
+ param_type.map_or_else(
+ || "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented.
+ ToString::to_string,
+ )
+ },
+ });
}
trait_infos => {
- let mut msg = message(action);
+ let mut msg = message(param_type.map_or_else(
+ || "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented.
+ |param| format!("restrict type parameter `{}` with", param),
+ ));
for (i, trait_info) in trait_infos.iter().enumerate() {
msg.push_str(&format!(
"\ncandidate #{}: `{}`",
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index cf95d4f04bb..59bee69cfff 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -836,7 +836,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
let e = self.report_error(ct);
self.replaced_with_error = Some(e);
- self.interner().const_error_with_guaranteed(ct.ty(), e)
+ self.interner().const_error(ct.ty(), e)
}
}
}
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index 2a51439b0a9..79fc02c6c79 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -26,24 +26,17 @@ use super::equate::Equate;
use super::glb::Glb;
use super::lub::Lub;
use super::sub::Sub;
-use super::type_variable::TypeVariableValue;
-use super::{DefineOpaqueTypes, InferCtxt, MiscVariable, TypeTrace};
+use super::{DefineOpaqueTypes, InferCtxt, TypeTrace};
+use crate::infer::generalize::{self, CombineDelegate, Generalization};
use crate::traits::{Obligation, PredicateObligations};
-use rustc_data_structures::sso::SsoHashMap;
-use rustc_hir::def_id::DefId;
use rustc_middle::infer::canonical::OriginalQueryValues;
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
-use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
-use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{
- self, AliasKind, FallibleTypeFolder, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable,
- TypeSuperFoldable, TypeVisitableExt,
-};
+use rustc_middle::ty::relate::{RelateResult, TypeRelation};
+use rustc_middle::ty::{self, AliasKind, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{IntType, UintType};
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::DUMMY_SP;
#[derive(Clone)]
pub struct CombineFields<'infcx, 'tcx> {
@@ -55,13 +48,6 @@ pub struct CombineFields<'infcx, 'tcx> {
pub define_opaque_types: DefineOpaqueTypes,
}
-#[derive(Copy, Clone, Debug)]
-pub enum RelationDir {
- SubtypeOf,
- SupertypeOf,
- EqTo,
-}
-
impl<'tcx> InferCtxt<'tcx> {
pub fn super_combine_tys<R>(
&self,
@@ -127,7 +113,8 @@ impl<'tcx> InferCtxt<'tcx> {
bug!()
}
- (_, ty::Alias(AliasKind::Projection, _)) | (ty::Alias(AliasKind::Projection, _), _)
+ (_, ty::Alias(AliasKind::Projection | AliasKind::Inherent, _))
+ | (ty::Alias(AliasKind::Projection | AliasKind::Inherent, _), _)
if self.tcx.trait_solver_next() =>
{
relation.register_type_relate_obligation(a, b);
@@ -151,7 +138,7 @@ impl<'tcx> InferCtxt<'tcx> {
Ok(a)
}
- _ => ty::relate::super_relate_tys(relation, a, b),
+ _ => ty::relate::structurally_relate_tys(relation, a, b),
}
}
@@ -208,13 +195,13 @@ impl<'tcx> InferCtxt<'tcx> {
// HACK: equating both sides with `[const error]` eagerly prevents us
// from leaving unconstrained inference vars during things like impl
// matching in the solver.
- let a_error = self.tcx.const_error_with_guaranteed(a.ty(), guar);
+ let a_error = self.tcx.const_error(a.ty(), guar);
if let ty::ConstKind::Infer(InferConst::Var(vid)) = a.kind() {
- return self.unify_const_variable(vid, a_error);
+ return self.unify_const_variable(vid, a_error, relation.param_env());
}
- let b_error = self.tcx.const_error_with_guaranteed(b.ty(), guar);
+ let b_error = self.tcx.const_error(b.ty(), guar);
if let ty::ConstKind::Infer(InferConst::Var(vid)) = b.kind() {
- return self.unify_const_variable(vid, b_error);
+ return self.unify_const_variable(vid, b_error, relation.param_env());
}
return Ok(if relation.a_is_expected() { a_error } else { b_error });
@@ -236,11 +223,11 @@ impl<'tcx> InferCtxt<'tcx> {
}
(ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
- return self.unify_const_variable(vid, b);
+ return self.unify_const_variable(vid, b, relation.param_env());
}
(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
- return self.unify_const_variable(vid, a);
+ return self.unify_const_variable(vid, a, relation.param_env());
}
(ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
if self.tcx.lazy_normalization() =>
@@ -251,7 +238,7 @@ impl<'tcx> InferCtxt<'tcx> {
_ => {}
}
- ty::relate::super_relate_consts(relation, a, b)
+ ty::relate::structurally_relate_consts(relation, a, b)
}
/// Unifies the const variable `target_vid` with the given constant.
@@ -293,24 +280,17 @@ impl<'tcx> InferCtxt<'tcx> {
&self,
target_vid: ty::ConstVid<'tcx>,
ct: ty::Const<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
- let (for_universe, span) = {
- let mut inner = self.inner.borrow_mut();
- let variable_table = &mut inner.const_unification_table();
- let var_value = variable_table.probe_value(target_vid);
- match var_value.val {
- ConstVariableValue::Known { value } => {
- bug!("instantiating {:?} which has a known value {:?}", target_vid, value)
- }
- ConstVariableValue::Unknown { universe } => (universe, var_value.origin.span),
- }
- };
- let value = ct.try_fold_with(&mut ConstInferUnifier {
- infcx: self,
- span,
- for_universe,
+ let span =
+ self.inner.borrow_mut().const_unification_table().probe_value(target_vid).origin.span;
+ let Generalization { value, needs_wf: _ } = generalize::generalize(
+ self,
+ &mut CombineDelegate { infcx: self, span, param_env },
+ ct,
target_vid,
- })?;
+ ty::Variance::Invariant,
+ )?;
self.inner.borrow_mut().const_unification_table().union_value(
target_vid,
@@ -391,12 +371,10 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
pub fn instantiate(
&mut self,
a_ty: Ty<'tcx>,
- dir: RelationDir,
+ ambient_variance: ty::Variance,
b_vid: ty::TyVid,
a_is_expected: bool,
) -> RelateResult<'tcx, ()> {
- use self::RelationDir::*;
-
// Get the actual variable that b_vid has been inferred to
debug_assert!(self.infcx.inner.borrow_mut().type_variables().probe(b_vid).is_unknown());
@@ -411,7 +389,18 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
// `'?2` and `?3` are fresh region/type inference
// variables. (Down below, we will relate `a_ty <: b_ty`,
// adding constraints like `'x: '?2` and `?1 <: ?3`.)
- let Generalization { ty: b_ty, needs_wf } = self.generalize(a_ty, b_vid, dir)?;
+ let Generalization { value: b_ty, needs_wf } = generalize::generalize(
+ self.infcx,
+ &mut CombineDelegate {
+ infcx: self.infcx,
+ param_env: self.param_env,
+ span: self.trace.span(),
+ },
+ a_ty,
+ b_vid,
+ ambient_variance,
+ )?;
+
debug!(?b_ty);
self.infcx.inner.borrow_mut().type_variables().instantiate(b_vid, b_ty);
@@ -430,78 +419,23 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
// relations wind up attributed to the same spans. We need
// to associate causes/spans with each of the relations in
// the stack to get this right.
- match dir {
- EqTo => self.equate(a_is_expected).relate(a_ty, b_ty),
- SubtypeOf => self.sub(a_is_expected).relate(a_ty, b_ty),
- SupertypeOf => self.sub(a_is_expected).relate_with_variance(
+ match ambient_variance {
+ ty::Variance::Invariant => self.equate(a_is_expected).relate(a_ty, b_ty),
+ ty::Variance::Covariant => self.sub(a_is_expected).relate(a_ty, b_ty),
+ ty::Variance::Contravariant => self.sub(a_is_expected).relate_with_variance(
ty::Contravariant,
ty::VarianceDiagInfo::default(),
a_ty,
b_ty,
),
+ ty::Variance::Bivariant => {
+ unreachable!("no code should be generalizing bivariantly (currently)")
+ }
}?;
Ok(())
}
- /// Attempts to generalize `ty` for the type variable `for_vid`.
- /// This checks for cycle -- that is, whether the type `ty`
- /// references `for_vid`. The `dir` is the "direction" for which we
- /// a performing the generalization (i.e., are we producing a type
- /// that can be used as a supertype etc).
- ///
- /// Preconditions:
- ///
- /// - `for_vid` is a "root vid"
- #[instrument(skip(self), level = "trace", ret)]
- fn generalize(
- &self,
- ty: Ty<'tcx>,
- for_vid: ty::TyVid,
- dir: RelationDir,
- ) -> RelateResult<'tcx, Generalization<'tcx>> {
- // Determine the ambient variance within which `ty` appears.
- // The surrounding equation is:
- //
- // ty [op] ty2
- //
- // where `op` is either `==`, `<:`, or `:>`. This maps quite
- // naturally.
- let ambient_variance = match dir {
- RelationDir::EqTo => ty::Invariant,
- RelationDir::SubtypeOf => ty::Covariant,
- RelationDir::SupertypeOf => ty::Contravariant,
- };
-
- trace!(?ambient_variance);
-
- let for_universe = match self.infcx.inner.borrow_mut().type_variables().probe(for_vid) {
- v @ TypeVariableValue::Known { .. } => {
- bug!("instantiating {:?} which has a known value {:?}", for_vid, v,)
- }
- TypeVariableValue::Unknown { universe } => universe,
- };
-
- trace!(?for_universe);
- trace!(?self.trace);
-
- let mut generalize = Generalizer {
- infcx: self.infcx,
- cause: &self.trace.cause,
- for_vid_sub_root: self.infcx.inner.borrow_mut().type_variables().sub_root_var(for_vid),
- for_universe,
- ambient_variance,
- needs_wf: false,
- root_ty: ty,
- param_env: self.param_env,
- cache: SsoHashMap::new(),
- };
-
- let ty = generalize.relate(ty, ty)?;
- let needs_wf = generalize.needs_wf;
- Ok(Generalization { ty, needs_wf })
- }
-
pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
self.obligations.extend(obligations.into_iter());
}
@@ -513,313 +447,6 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
}
}
-struct Generalizer<'cx, 'tcx> {
- infcx: &'cx InferCtxt<'tcx>,
-
- /// The span, used when creating new type variables and things.
- cause: &'cx ObligationCause<'tcx>,
-
- /// The vid of the type variable that is in the process of being
- /// instantiated; if we find this within the type we are folding,
- /// that means we would have created a cyclic type.
- for_vid_sub_root: ty::TyVid,
-
- /// The universe of the type variable that is in the process of
- /// being instantiated. Any fresh variables that we create in this
- /// process should be in that same universe.
- for_universe: ty::UniverseIndex,
-
- /// Track the variance as we descend into the type.
- ambient_variance: ty::Variance,
-
- /// See the field `needs_wf` in `Generalization`.
- needs_wf: bool,
-
- /// The root type that we are generalizing. Used when reporting cycles.
- root_ty: Ty<'tcx>,
-
- param_env: ty::ParamEnv<'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>,
-
- /// If true, then the generalized type may not be well-formed,
- /// even if the source type is well-formed, so we should add an
- /// additional check to enforce that it is. This arises in
- /// particular around 'bivariant' type parameters that are only
- /// constrained by a where-clause. As an example, imagine a type:
- ///
- /// struct Foo<A, B> where A: Iterator<Item = B> {
- /// data: A
- /// }
- ///
- /// here, `A` will be covariant, but `B` is
- /// unconstrained. However, whatever it is, for `Foo` to be WF, it
- /// must be equal to `A::Item`. If we have an input `Foo<?A, ?B>`,
- /// then after generalization we will wind up with a type like
- /// `Foo<?C, ?D>`. When we enforce that `Foo<?A, ?B> <: Foo<?C,
- /// ?D>` (or `>:`), we will wind up with the requirement that `?A
- /// <: ?C`, but no particular relationship between `?B` and `?D`
- /// (after all, we do not know the variance of the normalized form
- /// of `A::Item` with respect to `A`). If we do nothing else, this
- /// may mean that `?D` goes unconstrained (as in #41677). So, in
- /// this scenario where we create a new type variable in a
- /// bivariant context, we set the `needs_wf` flag to true. This
- /// will force the calling code to check that `WF(Foo<?C, ?D>)`
- /// holds, which in turn implies that `?C::Item == ?D`. So once
- /// `?C` is constrained, that should suffice to restrict `?D`.
- needs_wf: bool,
-}
-
-impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
- fn tcx(&self) -> TyCtxt<'tcx> {
- self.infcx.tcx
- }
-
- fn param_env(&self) -> ty::ParamEnv<'tcx> {
- self.param_env
- }
-
- fn tag(&self) -> &'static str {
- "Generalizer"
- }
-
- fn a_is_expected(&self) -> bool {
- true
- }
-
- fn binders<T>(
- &mut self,
- a: ty::Binder<'tcx, T>,
- b: ty::Binder<'tcx, T>,
- ) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
- where
- T: Relate<'tcx>,
- {
- Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
- }
-
- fn relate_item_substs(
- &mut self,
- item_def_id: DefId,
- a_subst: SubstsRef<'tcx>,
- b_subst: SubstsRef<'tcx>,
- ) -> RelateResult<'tcx, SubstsRef<'tcx>> {
- if self.ambient_variance == ty::Variance::Invariant {
- // Avoid fetching the variance if we are in an invariant
- // context; no need, and it can induce dependency cycles
- // (e.g., #41849).
- relate::relate_substs(self, a_subst, b_subst)
- } else {
- let tcx = self.tcx();
- let opt_variances = tcx.variances_of(item_def_id);
- relate::relate_substs_with_variances(
- self,
- item_def_id,
- &opt_variances,
- a_subst,
- b_subst,
- true,
- )
- }
- }
-
- fn relate_with_variance<T: Relate<'tcx>>(
- &mut self,
- variance: ty::Variance,
- _info: ty::VarianceDiagInfo<'tcx>,
- a: T,
- b: T,
- ) -> RelateResult<'tcx, T> {
- let old_ambient_variance = self.ambient_variance;
- self.ambient_variance = self.ambient_variance.xform(variance);
-
- let result = self.relate(a, b);
- self.ambient_variance = old_ambient_variance;
- result
- }
-
- 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 Ok(result);
- }
- debug!("generalize: t={:?}", t);
-
- // Check to see whether the type we are generalizing references
- // any other type variable related to `vid` via
- // subtyping. This is basically our "occurs check", preventing
- // us from creating infinitely sized types.
- let result = match *t.kind() {
- ty::Infer(ty::TyVar(vid)) => {
- let vid = self.infcx.inner.borrow_mut().type_variables().root_var(vid);
- let sub_vid = self.infcx.inner.borrow_mut().type_variables().sub_root_var(vid);
- if sub_vid == self.for_vid_sub_root {
- // If sub-roots are equal, then `for_vid` and
- // `vid` are related via subtyping.
- Err(TypeError::CyclicTy(self.root_ty))
- } else {
- let probe = self.infcx.inner.borrow_mut().type_variables().probe(vid);
- match probe {
- TypeVariableValue::Known { value: u } => {
- debug!("generalize: known value {:?}", u);
- self.relate(u, u)
- }
- TypeVariableValue::Unknown { universe } => {
- match self.ambient_variance {
- // Invariant: no need to make a fresh type variable.
- ty::Invariant => {
- if self.for_universe.can_name(universe) {
- return Ok(t);
- }
- }
-
- // Bivariant: make a fresh var, but we
- // may need a WF predicate. See
- // comment on `needs_wf` field for
- // more info.
- ty::Bivariant => self.needs_wf = true,
-
- // Co/contravariant: this will be
- // sufficiently constrained later on.
- ty::Covariant | ty::Contravariant => (),
- }
-
- let origin =
- *self.infcx.inner.borrow_mut().type_variables().var_origin(vid);
- let new_var_id = self
- .infcx
- .inner
- .borrow_mut()
- .type_variables()
- .new_var(self.for_universe, origin);
- let u = self.tcx().mk_ty_var(new_var_id);
-
- // Record that we replaced `vid` with `new_var_id` as part of a generalization
- // operation. This is needed to detect cyclic types. To see why, see the
- // docs in the `type_variables` module.
- self.infcx.inner.borrow_mut().type_variables().sub(vid, new_var_id);
- debug!("generalize: replacing original vid={:?} with new={:?}", vid, u);
- Ok(u)
- }
- }
- }
- }
- ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => {
- // No matter what mode we are in,
- // integer/floating-point types must be equal to be
- // relatable.
- Ok(t)
- }
- ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
- let s = self.relate(substs, substs)?;
- Ok(if s == substs { t } else { self.infcx.tcx.mk_opaque(def_id, s) })
- }
- _ => relate::super_relate_tys(self, t, t),
- }?;
-
- self.cache.insert(t, result);
- Ok(result)
- }
-
- fn regions(
- &mut self,
- r: ty::Region<'tcx>,
- r2: ty::Region<'tcx>,
- ) -> RelateResult<'tcx, ty::Region<'tcx>> {
- assert_eq!(r, r2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
-
- debug!("generalize: regions r={:?}", r);
-
- match *r {
- // Never make variables for regions bound within the type itself,
- // nor for erased regions.
- ty::ReLateBound(..) | ty::ReErased => {
- return Ok(r);
- }
-
- ty::ReError(_) => {
- return Ok(r);
- }
-
- ty::RePlaceholder(..)
- | ty::ReVar(..)
- | ty::ReStatic
- | ty::ReEarlyBound(..)
- | ty::ReFree(..) => {
- // see common code below
- }
- }
-
- // If we are in an invariant context, we can re-use the region
- // as is, unless it happens to be in some universe that we
- // can't name. (In the case of a region *variable*, we could
- // use it if we promoted it into our universe, but we don't
- // bother.)
- if let ty::Invariant = self.ambient_variance {
- let r_universe = self.infcx.universe_of_region(r);
- if self.for_universe.can_name(r_universe) {
- return Ok(r);
- }
- }
-
- // FIXME: This is non-ideal because we don't give a
- // very descriptive origin for this region variable.
- Ok(self.infcx.next_region_var_in_universe(MiscVariable(self.cause.span), self.for_universe))
- }
-
- fn consts(
- &mut self,
- c: ty::Const<'tcx>,
- c2: ty::Const<'tcx>,
- ) -> RelateResult<'tcx, ty::Const<'tcx>> {
- assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
-
- match c.kind() {
- ty::ConstKind::Infer(InferConst::Var(vid)) => {
- let mut inner = self.infcx.inner.borrow_mut();
- let variable_table = &mut inner.const_unification_table();
- let var_value = variable_table.probe_value(vid);
- match var_value.val {
- ConstVariableValue::Known { value: u } => {
- drop(inner);
- self.relate(u, u)
- }
- ConstVariableValue::Unknown { universe } => {
- if self.for_universe.can_name(universe) {
- Ok(c)
- } else {
- let new_var_id = variable_table.new_key(ConstVarValue {
- origin: var_value.origin,
- val: ConstVariableValue::Unknown { universe: self.for_universe },
- });
- Ok(self.tcx().mk_const(new_var_id, c.ty()))
- }
- }
- }
- }
- ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => {
- let substs = self.relate_with_variance(
- ty::Variance::Invariant,
- ty::VarianceDiagInfo::default(),
- substs,
- substs,
- )?;
- Ok(self.tcx().mk_const(ty::UnevaluatedConst { def, substs }, c.ty()))
- }
- _ => relate::super_relate_consts(self, c, c),
- }
- }
-}
-
pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
/// Register obligations that must hold in order for this relation to hold
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>);
@@ -872,135 +499,3 @@ fn float_unification_error<'tcx>(
let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v;
TypeError::FloatMismatch(ExpectedFound::new(a_is_expected, a, b))
}
-
-struct ConstInferUnifier<'cx, 'tcx> {
- infcx: &'cx InferCtxt<'tcx>,
-
- span: Span,
-
- for_universe: ty::UniverseIndex,
-
- /// The vid of the const variable that is in the process of being
- /// instantiated; if we find this within the const we are folding,
- /// that means we would have created a cyclic const.
- target_vid: ty::ConstVid<'tcx>,
-}
-
-impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for ConstInferUnifier<'_, 'tcx> {
- type Error = TypeError<'tcx>;
-
- fn interner(&self) -> TyCtxt<'tcx> {
- self.infcx.tcx
- }
-
- #[instrument(level = "debug", skip(self), ret)]
- fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, TypeError<'tcx>> {
- match t.kind() {
- &ty::Infer(ty::TyVar(vid)) => {
- let vid = self.infcx.inner.borrow_mut().type_variables().root_var(vid);
- let probe = self.infcx.inner.borrow_mut().type_variables().probe(vid);
- match probe {
- TypeVariableValue::Known { value: u } => {
- debug!("ConstOccursChecker: known value {:?}", u);
- u.try_fold_with(self)
- }
- TypeVariableValue::Unknown { universe } => {
- if self.for_universe.can_name(universe) {
- return Ok(t);
- }
-
- let origin =
- *self.infcx.inner.borrow_mut().type_variables().var_origin(vid);
- let new_var_id = self
- .infcx
- .inner
- .borrow_mut()
- .type_variables()
- .new_var(self.for_universe, origin);
- Ok(self.interner().mk_ty_var(new_var_id))
- }
- }
- }
- ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => Ok(t),
- _ => t.try_super_fold_with(self),
- }
- }
-
- #[instrument(level = "debug", skip(self), ret)]
- fn try_fold_region(
- &mut self,
- r: ty::Region<'tcx>,
- ) -> Result<ty::Region<'tcx>, TypeError<'tcx>> {
- debug!("ConstInferUnifier: r={:?}", r);
-
- match *r {
- // Never make variables for regions bound within the type itself,
- // nor for erased regions.
- ty::ReLateBound(..) | ty::ReErased | ty::ReError(_) => {
- return Ok(r);
- }
-
- ty::RePlaceholder(..)
- | ty::ReVar(..)
- | ty::ReStatic
- | ty::ReEarlyBound(..)
- | ty::ReFree(..) => {
- // see common code below
- }
- }
-
- let r_universe = self.infcx.universe_of_region(r);
- if self.for_universe.can_name(r_universe) {
- return Ok(r);
- } else {
- // FIXME: This is non-ideal because we don't give a
- // very descriptive origin for this region variable.
- Ok(self.infcx.next_region_var_in_universe(MiscVariable(self.span), self.for_universe))
- }
- }
-
- #[instrument(level = "debug", skip(self), ret)]
- fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, TypeError<'tcx>> {
- match c.kind() {
- ty::ConstKind::Infer(InferConst::Var(vid)) => {
- // Check if the current unification would end up
- // unifying `target_vid` with a const which contains
- // an inference variable which is unioned with `target_vid`.
- //
- // Not doing so can easily result in stack overflows.
- if self
- .infcx
- .inner
- .borrow_mut()
- .const_unification_table()
- .unioned(self.target_vid, vid)
- {
- return Err(TypeError::CyclicConst(c));
- }
-
- let var_value =
- self.infcx.inner.borrow_mut().const_unification_table().probe_value(vid);
- match var_value.val {
- ConstVariableValue::Known { value: u } => u.try_fold_with(self),
- ConstVariableValue::Unknown { universe } => {
- if self.for_universe.can_name(universe) {
- Ok(c)
- } else {
- let new_var_id =
- self.infcx.inner.borrow_mut().const_unification_table().new_key(
- ConstVarValue {
- origin: var_value.origin,
- val: ConstVariableValue::Unknown {
- universe: self.for_universe,
- },
- },
- );
- Ok(self.interner().mk_const(new_var_id, c.ty()))
- }
- }
- }
- }
- _ => c.try_super_fold_with(self),
- }
- }
-}
diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs
index f90f7674b55..793505e4ab2 100644
--- a/compiler/rustc_infer/src/infer/equate.rs
+++ b/compiler/rustc_infer/src/infer/equate.rs
@@ -1,7 +1,7 @@
use crate::infer::DefineOpaqueTypes;
use crate::traits::PredicateObligations;
-use super::combine::{CombineFields, ObligationEmittingRelation, RelationDir};
+use super::combine::{CombineFields, ObligationEmittingRelation};
use super::Subtype;
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
@@ -88,11 +88,11 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
}
(&ty::Infer(TyVar(a_id)), _) => {
- self.fields.instantiate(b, RelationDir::EqTo, a_id, self.a_is_expected)?;
+ self.fields.instantiate(b, ty::Invariant, a_id, self.a_is_expected)?;
}
(_, &ty::Infer(TyVar(b_id))) => {
- self.fields.instantiate(a, RelationDir::EqTo, b_id, self.a_is_expected)?;
+ self.fields.instantiate(a, ty::Invariant, b_id, self.a_is_expected)?;
}
(
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 98da5ba65b7..ad4f5058b5e 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2354,7 +2354,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let labeled_user_string = match bound_kind {
GenericKind::Param(ref p) => format!("the parameter type `{}`", p),
GenericKind::Alias(ref p) => match p.kind(self.tcx) {
- ty::AliasKind::Projection => format!("the associated type `{}`", p),
+ ty::AliasKind::Projection | ty::AliasKind::Inherent => {
+ format!("the associated type `{}`", p)
+ }
ty::AliasKind::Opaque => format!("the opaque type `{}`", p),
},
};
@@ -2721,7 +2723,7 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
| (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),
+ _ => relate::structurally_relate_tys(self, a, b),
}
}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index a3116351940..421eb807a14 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -2,6 +2,7 @@ use super::TypeErrCtxt;
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
use rustc_errors::{pluralize, Diagnostic, MultiSpan};
use rustc_hir as hir;
+use rustc_hir::def::DefKind;
use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::print::Printer;
@@ -71,9 +72,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
#traits-as-parameters",
);
}
- (ty::Alias(ty::Projection, _), ty::Alias(ty::Projection, _)) => {
+ (ty::Alias(ty::Projection | ty::Inherent, _), ty::Alias(ty::Projection | ty::Inherent, _)) => {
diag.note("an associated type was expected, but a different one was found");
}
+ // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too.
(ty::Param(p), ty::Alias(ty::Projection, proj)) | (ty::Alias(ty::Projection, proj), ty::Param(p))
if !tcx.is_impl_trait_in_trait(proj.def_id) =>
{
@@ -222,7 +224,7 @@ impl<T> Trait<T> for X {
diag.span_label(p_span, "this type parameter");
}
}
- (ty::Alias(ty::Projection, proj_ty), _) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => {
+ (ty::Alias(ty::Projection | ty::Inherent, proj_ty), _) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => {
self.expected_projection(
diag,
proj_ty,
@@ -231,7 +233,7 @@ impl<T> Trait<T> for X {
cause.code(),
);
}
- (_, ty::Alias(ty::Projection, proj_ty)) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => {
+ (_, ty::Alias(ty::Projection | ty::Inherent, proj_ty)) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => {
let msg = format!(
"consider constraining the associated type `{}` to `{}`",
values.found, values.expected,
@@ -255,6 +257,15 @@ impl<T> Trait<T> for X {
);
}
}
+ (ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) if alias.def_id.is_local() && matches!(tcx.def_kind(body_owner_def_id), DefKind::AssocFn | DefKind::AssocConst) => {
+ if tcx.is_type_alias_impl_trait(alias.def_id) {
+ if !tcx.opaque_types_defined_by(body_owner_def_id.expect_local()).contains(&alias.def_id.expect_local()) {
+ diag.span_note(tcx.def_span(body_owner_def_id), "\
+ this item must have the opaque type in its signature \
+ in order to be able to register hidden types");
+ }
+ }
+ }
(ty::FnPtr(_), ty::FnDef(def, _))
if let hir::def::DefKind::Fn = tcx.def_kind(def) => {
diag.note(
diff --git a/compiler/rustc_infer/src/infer/generalize.rs b/compiler/rustc_infer/src/infer/generalize.rs
new file mode 100644
index 00000000000..d4a1dacde10
--- /dev/null
+++ b/compiler/rustc_infer/src/infer/generalize.rs
@@ -0,0 +1,479 @@
+use rustc_data_structures::sso::SsoHashMap;
+use rustc_hir::def_id::DefId;
+use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
+use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::{self, InferConst, Term, Ty, TyCtxt, TypeVisitableExt};
+use rustc_span::Span;
+
+use crate::infer::nll_relate::TypeRelatingDelegate;
+use crate::infer::type_variable::TypeVariableValue;
+use crate::infer::{InferCtxt, RegionVariableOrigin};
+
+/// Attempts to generalize `term` for the type variable `for_vid`.
+/// This checks for cycles -- that is, whether the type `term`
+/// references `for_vid`.
+pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>(
+ infcx: &InferCtxt<'tcx>,
+ delegate: &mut D,
+ term: T,
+ for_vid: impl Into<ty::TermVid<'tcx>>,
+ ambient_variance: ty::Variance,
+) -> RelateResult<'tcx, Generalization<T>> {
+ let (for_universe, root_vid) = match for_vid.into() {
+ ty::TermVid::Ty(ty_vid) => (
+ infcx.probe_ty_var(ty_vid).unwrap_err(),
+ ty::TermVid::Ty(infcx.inner.borrow_mut().type_variables().sub_root_var(ty_vid)),
+ ),
+ ty::TermVid::Const(ct_vid) => (
+ infcx.probe_const_var(ct_vid).unwrap_err(),
+ ty::TermVid::Const(infcx.inner.borrow_mut().const_unification_table().find(ct_vid)),
+ ),
+ };
+
+ let mut generalizer = Generalizer {
+ infcx,
+ delegate,
+ ambient_variance,
+ root_vid,
+ for_universe,
+ root_term: term.into(),
+ needs_wf: false,
+ cache: Default::default(),
+ };
+
+ assert!(!term.has_escaping_bound_vars());
+ let value = generalizer.relate(term, term)?;
+ let needs_wf = generalizer.needs_wf;
+ Ok(Generalization { value, needs_wf })
+}
+
+/// Abstracts the handling of region vars between HIR and MIR/NLL typechecking
+/// in the generalizer code.
+pub trait GeneralizerDelegate<'tcx> {
+ fn param_env(&self) -> ty::ParamEnv<'tcx>;
+
+ fn forbid_inference_vars() -> bool;
+
+ fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx>;
+}
+
+pub struct CombineDelegate<'cx, 'tcx> {
+ pub infcx: &'cx InferCtxt<'tcx>,
+ pub param_env: ty::ParamEnv<'tcx>,
+ pub span: Span,
+}
+
+impl<'tcx> GeneralizerDelegate<'tcx> for CombineDelegate<'_, 'tcx> {
+ fn param_env(&self) -> ty::ParamEnv<'tcx> {
+ self.param_env
+ }
+
+ fn forbid_inference_vars() -> bool {
+ false
+ }
+
+ fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
+ // FIXME: This is non-ideal because we don't give a
+ // very descriptive origin for this region variable.
+ self.infcx
+ .next_region_var_in_universe(RegionVariableOrigin::MiscVariable(self.span), universe)
+ }
+}
+
+impl<'tcx, T> GeneralizerDelegate<'tcx> for T
+where
+ T: TypeRelatingDelegate<'tcx>,
+{
+ fn param_env(&self) -> ty::ParamEnv<'tcx> {
+ <Self as TypeRelatingDelegate<'tcx>>::param_env(self)
+ }
+
+ fn forbid_inference_vars() -> bool {
+ <Self as TypeRelatingDelegate<'tcx>>::forbid_inference_vars()
+ }
+
+ fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
+ <Self as TypeRelatingDelegate<'tcx>>::generalize_existential(self, universe)
+ }
+}
+
+/// The "generalizer" is used when handling inference variables.
+///
+/// The basic strategy for handling a constraint like `?A <: B` is to
+/// apply a "generalization strategy" to the term `B` -- this replaces
+/// all the lifetimes in the term `B` with fresh inference variables.
+/// (You can read more about the strategy in this [blog post].)
+///
+/// As an example, if we had `?A <: &'x u32`, we would generalize `&'x
+/// u32` to `&'0 u32` where `'0` is a fresh variable. This becomes the
+/// value of `A`. Finally, we relate `&'0 u32 <: &'x u32`, which
+/// establishes `'0: 'x` as a constraint.
+///
+/// [blog post]: https://is.gd/0hKvIr
+struct Generalizer<'me, 'tcx, D> {
+ infcx: &'me InferCtxt<'tcx>,
+
+ /// This is used to abstract the behaviors of the three previous
+ /// generalizer-like implementations (`Generalizer`, `TypeGeneralizer`,
+ /// and `ConstInferUnifier`). See [`GeneralizerDelegate`] for more
+ /// information.
+ delegate: &'me mut D,
+
+ /// After we generalize this type, we are going to relate it to
+ /// some other type. What will be the variance at this point?
+ ambient_variance: ty::Variance,
+
+ /// The vid of the type variable that is in the process of being
+ /// instantiated. If we find this within the value we are folding,
+ /// that means we would have created a cyclic value.
+ root_vid: ty::TermVid<'tcx>,
+
+ /// The universe of the type variable that is in the process of being
+ /// instantiated. If we find anything that this universe cannot name,
+ /// we reject the relation.
+ for_universe: ty::UniverseIndex,
+
+ /// The root term (const or type) we're generalizing. Used for cycle errors.
+ root_term: Term<'tcx>,
+
+ cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>,
+
+ /// See the field `needs_wf` in `Generalization`.
+ needs_wf: bool,
+}
+
+impl<'tcx, D> Generalizer<'_, 'tcx, D> {
+ /// Create an error that corresponds to the term kind in `root_term`
+ fn cyclic_term_error(&self) -> TypeError<'tcx> {
+ match self.root_term.unpack() {
+ ty::TermKind::Ty(ty) => TypeError::CyclicTy(ty),
+ ty::TermKind::Const(ct) => TypeError::CyclicConst(ct),
+ }
+ }
+}
+
+impl<'tcx, D> TypeRelation<'tcx> for Generalizer<'_, 'tcx, D>
+where
+ D: GeneralizerDelegate<'tcx>,
+{
+ fn tcx(&self) -> TyCtxt<'tcx> {
+ self.infcx.tcx
+ }
+
+ fn param_env(&self) -> ty::ParamEnv<'tcx> {
+ self.delegate.param_env()
+ }
+
+ fn tag(&self) -> &'static str {
+ "Generalizer"
+ }
+
+ fn a_is_expected(&self) -> bool {
+ true
+ }
+
+ fn relate_item_substs(
+ &mut self,
+ item_def_id: DefId,
+ a_subst: ty::SubstsRef<'tcx>,
+ b_subst: ty::SubstsRef<'tcx>,
+ ) -> RelateResult<'tcx, ty::SubstsRef<'tcx>> {
+ if self.ambient_variance == ty::Variance::Invariant {
+ // Avoid fetching the variance if we are in an invariant
+ // context; no need, and it can induce dependency cycles
+ // (e.g., #41849).
+ relate::relate_substs(self, a_subst, b_subst)
+ } else {
+ let tcx = self.tcx();
+ let opt_variances = tcx.variances_of(item_def_id);
+ relate::relate_substs_with_variances(
+ self,
+ item_def_id,
+ opt_variances,
+ a_subst,
+ b_subst,
+ true,
+ )
+ }
+ }
+
+ #[instrument(level = "debug", skip(self, variance, b), ret)]
+ fn relate_with_variance<T: Relate<'tcx>>(
+ &mut self,
+ variance: ty::Variance,
+ _info: ty::VarianceDiagInfo<'tcx>,
+ a: T,
+ b: T,
+ ) -> RelateResult<'tcx, T> {
+ let old_ambient_variance = self.ambient_variance;
+ self.ambient_variance = self.ambient_variance.xform(variance);
+ debug!(?self.ambient_variance, "new ambient variance");
+ let r = self.relate(a, b)?;
+ self.ambient_variance = old_ambient_variance;
+ Ok(r)
+ }
+
+ #[instrument(level = "debug", skip(self, t2), ret)]
+ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+ assert_eq!(t, t2); // we are misusing TypeRelation here; both LHS and RHS ought to be ==
+
+ if let Some(&result) = self.cache.get(&t) {
+ return Ok(result);
+ }
+
+ // Check to see whether the type we are generalizing references
+ // any other type variable related to `vid` via
+ // subtyping. This is basically our "occurs check", preventing
+ // us from creating infinitely sized types.
+ let g = match *t.kind() {
+ ty::Infer(ty::TyVar(_)) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_))
+ if D::forbid_inference_vars() =>
+ {
+ bug!("unexpected inference variable encountered in NLL generalization: {t}");
+ }
+
+ ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
+ bug!("unexpected infer type: {t}")
+ }
+
+ ty::Infer(ty::TyVar(vid)) => {
+ let mut inner = self.infcx.inner.borrow_mut();
+ let vid = inner.type_variables().root_var(vid);
+ let sub_vid = inner.type_variables().sub_root_var(vid);
+
+ if ty::TermVid::Ty(sub_vid) == self.root_vid {
+ // If sub-roots are equal, then `root_vid` and
+ // `vid` are related via subtyping.
+ Err(self.cyclic_term_error())
+ } else {
+ let probe = inner.type_variables().probe(vid);
+ match probe {
+ TypeVariableValue::Known { value: u } => {
+ drop(inner);
+ self.relate(u, u)
+ }
+ TypeVariableValue::Unknown { universe } => {
+ match self.ambient_variance {
+ // Invariant: no need to make a fresh type variable
+ // if we can name the universe.
+ ty::Invariant => {
+ if self.for_universe.can_name(universe) {
+ return Ok(t);
+ }
+ }
+
+ // Bivariant: make a fresh var, but we
+ // may need a WF predicate. See
+ // comment on `needs_wf` field for
+ // more info.
+ ty::Bivariant => self.needs_wf = true,
+
+ // Co/contravariant: this will be
+ // sufficiently constrained later on.
+ ty::Covariant | ty::Contravariant => (),
+ }
+
+ let origin = *inner.type_variables().var_origin(vid);
+ let new_var_id =
+ inner.type_variables().new_var(self.for_universe, origin);
+ let u = self.tcx().mk_ty_var(new_var_id);
+
+ // Record that we replaced `vid` with `new_var_id` as part of a generalization
+ // operation. This is needed to detect cyclic types. To see why, see the
+ // docs in the `type_variables` module.
+ inner.type_variables().sub(vid, new_var_id);
+ debug!("replacing original vid={:?} with new={:?}", vid, u);
+ Ok(u)
+ }
+ }
+ }
+ }
+
+ ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => {
+ // No matter what mode we are in,
+ // integer/floating-point types must be equal to be
+ // relatable.
+ Ok(t)
+ }
+
+ ty::Placeholder(placeholder) => {
+ if self.for_universe.can_name(placeholder.universe) {
+ Ok(t)
+ } else {
+ debug!(
+ "root universe {:?} cannot name placeholder in universe {:?}",
+ self.for_universe, placeholder.universe
+ );
+ Err(TypeError::Mismatch)
+ }
+ }
+
+ _ => relate::structurally_relate_tys(self, t, t),
+ }?;
+
+ self.cache.insert(t, g);
+ Ok(g)
+ }
+
+ #[instrument(level = "debug", skip(self, r2), ret)]
+ fn regions(
+ &mut self,
+ r: ty::Region<'tcx>,
+ r2: ty::Region<'tcx>,
+ ) -> RelateResult<'tcx, ty::Region<'tcx>> {
+ assert_eq!(r, r2); // we are misusing TypeRelation here; both LHS and RHS ought to be ==
+
+ match *r {
+ // Never make variables for regions bound within the type itself,
+ // nor for erased regions.
+ ty::ReLateBound(..) | ty::ReErased => {
+ return Ok(r);
+ }
+
+ // It doesn't really matter for correctness if we generalize ReError,
+ // since we're already on a doomed compilation path.
+ ty::ReError(_) => {
+ return Ok(r);
+ }
+
+ ty::RePlaceholder(..)
+ | ty::ReVar(..)
+ | ty::ReStatic
+ | ty::ReEarlyBound(..)
+ | ty::ReFree(..) => {
+ // see common code below
+ }
+ }
+
+ // If we are in an invariant context, we can re-use the region
+ // as is, unless it happens to be in some universe that we
+ // can't name.
+ if let ty::Invariant = self.ambient_variance {
+ let r_universe = self.infcx.universe_of_region(r);
+ if self.for_universe.can_name(r_universe) {
+ return Ok(r);
+ }
+ }
+
+ Ok(self.delegate.generalize_region(self.for_universe))
+ }
+
+ #[instrument(level = "debug", skip(self, c2), ret)]
+ fn consts(
+ &mut self,
+ c: ty::Const<'tcx>,
+ c2: ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, ty::Const<'tcx>> {
+ assert_eq!(c, c2); // we are misusing TypeRelation here; both LHS and RHS ought to be ==
+
+ match c.kind() {
+ ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
+ bug!("unexpected inference variable encountered in NLL generalization: {:?}", c);
+ }
+ ty::ConstKind::Infer(InferConst::Var(vid)) => {
+ // If root const vids are equal, then `root_vid` and
+ // `vid` are related and we'd be inferring an infinitely
+ // deep const.
+ if ty::TermVid::Const(
+ self.infcx.inner.borrow_mut().const_unification_table().find(vid),
+ ) == self.root_vid
+ {
+ return Err(self.cyclic_term_error());
+ }
+
+ let mut inner = self.infcx.inner.borrow_mut();
+ let variable_table = &mut inner.const_unification_table();
+ let var_value = variable_table.probe_value(vid);
+ match var_value.val {
+ ConstVariableValue::Known { value: u } => {
+ drop(inner);
+ self.relate(u, u)
+ }
+ ConstVariableValue::Unknown { universe } => {
+ if self.for_universe.can_name(universe) {
+ Ok(c)
+ } else {
+ let new_var_id = variable_table.new_key(ConstVarValue {
+ origin: var_value.origin,
+ val: ConstVariableValue::Unknown { universe: self.for_universe },
+ });
+ Ok(self.tcx().mk_const(new_var_id, c.ty()))
+ }
+ }
+ }
+ }
+ // FIXME: remove this branch once `structurally_relate_consts` is fully
+ // structural.
+ ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => {
+ let substs = self.relate_with_variance(
+ ty::Variance::Invariant,
+ ty::VarianceDiagInfo::default(),
+ substs,
+ substs,
+ )?;
+ Ok(self.tcx().mk_const(ty::UnevaluatedConst { def, substs }, c.ty()))
+ }
+ ty::ConstKind::Placeholder(placeholder) => {
+ if self.for_universe.can_name(placeholder.universe) {
+ Ok(c)
+ } else {
+ debug!(
+ "root universe {:?} cannot name placeholder in universe {:?}",
+ self.for_universe, placeholder.universe
+ );
+ Err(TypeError::Mismatch)
+ }
+ }
+ _ => relate::structurally_relate_consts(self, c, c),
+ }
+ }
+
+ #[instrument(level = "debug", skip(self), ret)]
+ fn binders<T>(
+ &mut self,
+ a: ty::Binder<'tcx, T>,
+ _: ty::Binder<'tcx, T>,
+ ) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
+ where
+ T: Relate<'tcx>,
+ {
+ let result = self.relate(a.skip_binder(), a.skip_binder())?;
+ Ok(a.rebind(result))
+ }
+}
+
+/// 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)]
+pub struct Generalization<T> {
+ pub value: T,
+
+ /// If true, then the generalized type may not be well-formed,
+ /// even if the source type is well-formed, so we should add an
+ /// additional check to enforce that it is. This arises in
+ /// particular around 'bivariant' type parameters that are only
+ /// constrained by a where-clause. As an example, imagine a type:
+ ///
+ /// struct Foo<A, B> where A: Iterator<Item = B> {
+ /// data: A
+ /// }
+ ///
+ /// here, `A` will be covariant, but `B` is
+ /// unconstrained. However, whatever it is, for `Foo` to be WF, it
+ /// must be equal to `A::Item`. If we have an input `Foo<?A, ?B>`,
+ /// then after generalization we will wind up with a type like
+ /// `Foo<?C, ?D>`. When we enforce that `Foo<?A, ?B> <: Foo<?C,
+ /// ?D>` (or `>:`), we will wind up with the requirement that `?A
+ /// <: ?C`, but no particular relationship between `?B` and `?D`
+ /// (after all, we do not know the variance of the normalized form
+ /// of `A::Item` with respect to `A`). If we do nothing else, this
+ /// may mean that `?D` goes unconstrained (as in #41677). So, in
+ /// this scenario where we create a new type variable in a
+ /// bivariant context, we set the `needs_wf` flag to true. This
+ /// will force the calling code to check that `WF(Foo<?C, ?D>)`
+ /// holds, which in turn implies that `?C::Item == ?D`. So once
+ /// `?C` is constrained, that should suffice to restrict `?D`.
+ pub needs_wf: bool,
+}
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index a89b9931599..f8329965c43 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -58,6 +58,7 @@ pub mod error_reporting;
pub mod free_regions;
mod freshen;
mod fudge;
+mod generalize;
mod glb;
mod higher_ranked;
pub mod lattice;
@@ -1530,10 +1531,10 @@ impl<'tcx> InferCtxt<'tcx> {
// variables
let tcx = self.tcx;
if substs.has_non_region_infer() {
- if let Some(ct) = tcx.bound_abstract_const(unevaluated.def)? {
+ if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? {
let ct = tcx.expand_abstract_consts(ct.subst(tcx, substs));
if let Err(e) = ct.error_reported() {
- return Err(ErrorHandled::Reported(e));
+ return Err(ErrorHandled::Reported(e.into()));
} else if ct.has_non_region_infer() || ct.has_non_region_param() {
return Err(ErrorHandled::TooGeneric);
} else {
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index 88a0a81e276..4ae6af5f5be 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -21,21 +21,20 @@
//! thing we relate in chalk are basically domain goals and their
//! constituents)
-use crate::infer::InferCtxt;
-use crate::infer::{ConstVarValue, ConstVariableValue};
-use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
-use crate::traits::{Obligation, PredicateObligations};
use rustc_data_structures::fx::FxHashMap;
use rustc_middle::traits::ObligationCause;
-use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::fold::FnMutDelegate;
-use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
use rustc_span::{Span, Symbol};
use std::fmt::Debug;
-use super::combine::ObligationEmittingRelation;
+use crate::infer::combine::ObligationEmittingRelation;
+use crate::infer::generalize::{self, Generalization};
+use crate::infer::InferCtxt;
+use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
+use crate::traits::{Obligation, PredicateObligations};
pub struct TypeRelating<'me, 'tcx, D>
where
@@ -198,7 +197,7 @@ where
_ => (),
}
- let generalized_ty = self.generalize_value(value_ty, vid)?;
+ let generalized_ty = self.generalize(value_ty, vid)?;
debug!("relate_ty_var: generalized_ty = {:?}", generalized_ty);
if D::forbid_inference_vars() {
@@ -217,26 +216,15 @@ where
result
}
- fn generalize_value<T: Relate<'tcx>>(
- &mut self,
- value: T,
- for_vid: ty::TyVid,
- ) -> RelateResult<'tcx, T> {
- let universe = self.infcx.probe_ty_var(for_vid).unwrap_err();
-
- if value.has_escaping_bound_vars() {
- bug!("trying to instantiate {for_vid:?} with escaping bound vars: {value:?}");
- }
-
- let mut generalizer = TypeGeneralizer {
- infcx: self.infcx,
- delegate: &mut self.delegate,
- ambient_variance: self.ambient_variance,
- for_vid_sub_root: self.infcx.inner.borrow_mut().type_variables().sub_root_var(for_vid),
- universe,
- };
-
- generalizer.relate(value, value)
+ fn generalize(&mut self, ty: Ty<'tcx>, for_vid: ty::TyVid) -> RelateResult<'tcx, Ty<'tcx>> {
+ let Generalization { value: ty, needs_wf: _ } = generalize::generalize(
+ self.infcx,
+ &mut self.delegate,
+ ty,
+ for_vid,
+ self.ambient_variance,
+ )?;
+ Ok(ty)
}
fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
@@ -716,235 +704,3 @@ where
})]);
}
}
-
-/// The "type generalizer" is used when handling inference variables.
-///
-/// The basic strategy for handling a constraint like `?A <: B` is to
-/// apply a "generalization strategy" to the type `B` -- this replaces
-/// all the lifetimes in the type `B` with fresh inference
-/// variables. (You can read more about the strategy in this [blog
-/// post].)
-///
-/// As an example, if we had `?A <: &'x u32`, we would generalize `&'x
-/// u32` to `&'0 u32` where `'0` is a fresh variable. This becomes the
-/// value of `A`. Finally, we relate `&'0 u32 <: &'x u32`, which
-/// establishes `'0: 'x` as a constraint.
-///
-/// [blog post]: https://is.gd/0hKvIr
-struct TypeGeneralizer<'me, 'tcx, D>
-where
- D: TypeRelatingDelegate<'tcx>,
-{
- infcx: &'me InferCtxt<'tcx>,
-
- delegate: &'me mut D,
-
- /// After we generalize this type, we are going to relate it to
- /// some other type. What will be the variance at this point?
- ambient_variance: ty::Variance,
-
- /// The vid of the type variable that is in the process of being
- /// instantiated. If we find this within the value we are folding,
- /// that means we would have created a cyclic value.
- for_vid_sub_root: ty::TyVid,
-
- /// The universe of the type variable that is in the process of being
- /// instantiated. If we find anything that this universe cannot name,
- /// we reject the relation.
- universe: ty::UniverseIndex,
-}
-
-impl<'tcx, D> TypeRelation<'tcx> for TypeGeneralizer<'_, 'tcx, D>
-where
- D: TypeRelatingDelegate<'tcx>,
-{
- fn tcx(&self) -> TyCtxt<'tcx> {
- self.infcx.tcx
- }
-
- fn param_env(&self) -> ty::ParamEnv<'tcx> {
- self.delegate.param_env()
- }
-
- fn tag(&self) -> &'static str {
- "nll::generalizer"
- }
-
- fn a_is_expected(&self) -> bool {
- true
- }
-
- fn relate_with_variance<T: Relate<'tcx>>(
- &mut self,
- variance: ty::Variance,
- _info: ty::VarianceDiagInfo<'tcx>,
- a: T,
- b: T,
- ) -> RelateResult<'tcx, T> {
- debug!(
- "TypeGeneralizer::relate_with_variance(variance={:?}, a={:?}, b={:?})",
- variance, a, b
- );
-
- let old_ambient_variance = self.ambient_variance;
- self.ambient_variance = self.ambient_variance.xform(variance);
-
- debug!(
- "TypeGeneralizer::relate_with_variance: ambient_variance = {:?}",
- self.ambient_variance
- );
-
- let r = self.relate(a, b)?;
-
- self.ambient_variance = old_ambient_variance;
-
- debug!("TypeGeneralizer::relate_with_variance: r={:?}", r);
-
- Ok(r)
- }
-
- fn tys(&mut self, a: Ty<'tcx>, _: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
- use crate::infer::type_variable::TypeVariableValue;
-
- debug!("TypeGeneralizer::tys(a={:?})", a);
-
- match *a.kind() {
- ty::Infer(ty::TyVar(_)) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_))
- if D::forbid_inference_vars() =>
- {
- bug!("unexpected inference variable encountered in NLL generalization: {:?}", a);
- }
-
- ty::Infer(ty::TyVar(vid)) => {
- let mut inner = self.infcx.inner.borrow_mut();
- let variables = &mut inner.type_variables();
- let vid = variables.root_var(vid);
- let sub_vid = variables.sub_root_var(vid);
- if sub_vid == self.for_vid_sub_root {
- // If sub-roots are equal, then `for_vid` and
- // `vid` are related via subtyping.
- debug!("TypeGeneralizer::tys: occurs check failed");
- Err(TypeError::Mismatch)
- } else {
- match variables.probe(vid) {
- TypeVariableValue::Known { value: u } => {
- drop(variables);
- self.relate(u, u)
- }
- TypeVariableValue::Unknown { universe: _universe } => {
- if self.ambient_variance == ty::Bivariant {
- // FIXME: we may need a WF predicate (related to #54105).
- }
-
- let origin = *variables.var_origin(vid);
-
- // Replacing with a new variable in the universe `self.universe`,
- // it will be unified later with the original type variable in
- // the universe `_universe`.
- let new_var_id = variables.new_var(self.universe, origin);
-
- let u = self.tcx().mk_ty_var(new_var_id);
- debug!("generalize: replacing original vid={:?} with new={:?}", vid, u);
- Ok(u)
- }
- }
- }
- }
-
- ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => {
- // No matter what mode we are in,
- // integer/floating-point types must be equal to be
- // relatable.
- Ok(a)
- }
-
- ty::Placeholder(placeholder) => {
- if self.universe.cannot_name(placeholder.universe) {
- debug!(
- "TypeGeneralizer::tys: root universe {:?} cannot name\
- placeholder in universe {:?}",
- self.universe, placeholder.universe
- );
- Err(TypeError::Mismatch)
- } else {
- Ok(a)
- }
- }
-
- _ => relate::super_relate_tys(self, a, a),
- }
- }
-
- fn regions(
- &mut self,
- a: ty::Region<'tcx>,
- _: ty::Region<'tcx>,
- ) -> RelateResult<'tcx, ty::Region<'tcx>> {
- debug!("TypeGeneralizer::regions(a={:?})", a);
-
- if let ty::ReLateBound(..) = *a {
- return Ok(a);
- }
-
- // For now, we just always create a fresh region variable to
- // replace all the regions in the source type. In the main
- // type checker, we special case the case where the ambient
- // variance is `Invariant` and try to avoid creating a fresh
- // region variable, but since this comes up so much less in
- // NLL (only when users use `_` etc) it is much less
- // important.
- //
- // As an aside, since these new variables are created in
- // `self.universe` universe, this also serves to enforce the
- // universe scoping rules.
- //
- // FIXME(#54105) -- if the ambient variance is bivariant,
- // though, we may however need to check well-formedness or
- // risk a problem like #41677 again.
- let replacement_region_vid = self.delegate.generalize_existential(self.universe);
-
- Ok(replacement_region_vid)
- }
-
- fn consts(
- &mut self,
- a: ty::Const<'tcx>,
- _: ty::Const<'tcx>,
- ) -> RelateResult<'tcx, ty::Const<'tcx>> {
- match a.kind() {
- ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
- bug!("unexpected inference variable encountered in NLL generalization: {:?}", a);
- }
- ty::ConstKind::Infer(InferConst::Var(vid)) => {
- let mut inner = self.infcx.inner.borrow_mut();
- let variable_table = &mut inner.const_unification_table();
- let var_value = variable_table.probe_value(vid);
- match var_value.val.known() {
- Some(u) => self.relate(u, u),
- None => {
- let new_var_id = variable_table.new_key(ConstVarValue {
- origin: var_value.origin,
- val: ConstVariableValue::Unknown { universe: self.universe },
- });
- Ok(self.tcx().mk_const(new_var_id, a.ty()))
- }
- }
- }
- ty::ConstKind::Unevaluated(..) if self.tcx().lazy_normalization() => Ok(a),
- _ => relate::super_relate_consts(self, a, a),
- }
- }
-
- fn binders<T>(
- &mut self,
- a: ty::Binder<'tcx, T>,
- _: ty::Binder<'tcx, T>,
- ) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
- where
- T: Relate<'tcx>,
- {
- debug!("TypeGeneralizer::binders(a={:?})", a);
- let result = self.relate(a.skip_binder(), a.skip_binder())?;
- Ok(a.rebind(result))
- }
-}
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 334395945ea..545310ad351 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -149,7 +149,7 @@ impl<'tcx> InferCtxt<'tcx> {
// no one encounters it in practice.
// It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
// where it is of no concern, so we only check for TAITs.
- if let Some(OpaqueTyOrigin::TyAlias) =
+ if let Some(OpaqueTyOrigin::TyAlias { .. }) =
b_def_id.as_local().and_then(|b_def_id| self.opaque_type_origin(b_def_id))
{
self.tcx.sess.emit_err(OpaqueHiddenTypeDiag {
@@ -381,8 +381,12 @@ impl<'tcx> InferCtxt<'tcx> {
// Anonymous `impl Trait`
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
// Named `type Foo = impl Bar;`
- hir::OpaqueTyOrigin::TyAlias => {
- may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id)
+ hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
+ if in_assoc_ty {
+ self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id)
+ } else {
+ may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id)
+ }
}
};
in_definition_scope.then_some(origin)
@@ -549,6 +553,7 @@ impl<'tcx> InferCtxt<'tcx> {
// We can't normalize associated types from `rustc_infer`,
// but we can eagerly register inference variables for them.
// FIXME(RPITIT): Don't replace RPITITs with inference vars.
+ // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too.
ty::Alias(ty::Projection, projection_ty)
if !projection_ty.has_escaping_bound_vars()
&& !tcx.is_impl_trait_in_trait(projection_ty.def_id) =>
@@ -569,6 +574,7 @@ impl<'tcx> InferCtxt<'tcx> {
hidden_ty
}
// FIXME(RPITIT): This can go away when we move to associated types
+ // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too.
ty::Alias(
ty::Projection,
ty::AliasTy { def_id: def_id2, substs: substs2, .. },
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 75ce0f83fd6..cd2462d3c31 100644
--- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
+++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
@@ -187,7 +187,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
} else if pattern == value {
Ok(pattern)
} else {
- relate::super_relate_tys(self, pattern, value)
+ relate::structurally_relate_tys(self, pattern, value)
}
}
@@ -201,7 +201,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
if pattern == value {
Ok(pattern)
} else {
- relate::super_relate_consts(self, pattern, value)
+ relate::structurally_relate_consts(self, pattern, value)
}
}
diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs
index 3766c250a9c..e0f29a8de8f 100644
--- a/compiler/rustc_infer/src/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/sub.rs
@@ -1,4 +1,4 @@
-use super::combine::{CombineFields, RelationDir};
+use super::combine::CombineFields;
use super::{DefineOpaqueTypes, ObligationEmittingRelation, SubregionOrigin};
use crate::traits::{Obligation, PredicateObligations};
@@ -108,11 +108,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
Ok(a)
}
(&ty::Infer(TyVar(a_id)), _) => {
- self.fields.instantiate(b, RelationDir::SupertypeOf, a_id, !self.a_is_expected)?;
+ self.fields.instantiate(b, ty::Contravariant, a_id, !self.a_is_expected)?;
Ok(a)
}
(_, &ty::Infer(TyVar(b_id))) => {
- self.fields.instantiate(a, RelationDir::SubtypeOf, b_id, self.a_is_expected)?;
+ self.fields.instantiate(a, ty::Covariant, b_id, self.a_is_expected)?;
Ok(a)
}
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 9d9f4ee13f4..c9e857141c9 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -9,6 +9,7 @@ use rustc_data_structures::OnDrop;
use rustc_errors::registry::Registry;
use rustc_errors::{ErrorGuaranteed, Handler};
use rustc_lint::LintStore;
+use rustc_middle::query::{ExternProviders, Providers};
use rustc_middle::{bug, ty};
use rustc_parse::maybe_new_parser_from_source_str;
use rustc_query_impl::QueryCtxt;
@@ -37,8 +38,7 @@ pub struct Compiler {
pub(crate) sess: Lrc<Session>,
codegen_backend: Lrc<Box<dyn CodegenBackend>>,
pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>,
- pub(crate) override_queries:
- Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::ExternProviders)>,
+ pub(crate) override_queries: Option<fn(&Session, &mut Providers, &mut ExternProviders)>,
}
impl Compiler {
@@ -60,6 +60,11 @@ impl Compiler {
}
}
+#[allow(rustc::bad_opt_access)]
+pub fn set_thread_safe_mode(sopts: &config::UnstableOptions) {
+ rustc_data_structures::sync::set_dyn_thread_safe_mode(sopts.threads > 1);
+}
+
/// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String>)> {
rustc_span::create_default_session_if_not_set_then(move |_| {
@@ -173,12 +178,21 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
let expected_values = check_cfg
.expecteds
.entry(ident.name.to_string())
+ .and_modify(|expected_values| match expected_values {
+ ExpectedValues::Some(_) => {}
+ ExpectedValues::Any => {
+ // handle the case where names(...) was done
+ // before values by changing to a list
+ *expected_values =
+ ExpectedValues::Some(FxHashSet::default());
+ }
+ })
.or_insert_with(|| {
ExpectedValues::Some(FxHashSet::default())
});
let ExpectedValues::Some(expected_values) = expected_values else {
- bug!("shoudn't be possible")
+ bug!("`expected_values` should be a list a values")
};
for val in values {
@@ -261,8 +275,7 @@ pub struct Config {
/// the list of queries.
///
/// The second parameter is local providers and the third parameter is external providers.
- pub override_queries:
- Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::ExternProviders)>,
+ pub override_queries: Option<fn(&Session, &mut Providers, &mut ExternProviders)>,
/// This is a callback from the driver that is called to create a codegen backend.
pub make_codegen_backend:
@@ -338,7 +351,7 @@ pub fn try_print_query_stack(handler: &Handler, num_frames: Option<usize>) {
// state if it was responsible for triggering the panic.
let i = ty::tls::with_context_opt(|icx| {
if let Some(icx) = icx {
- print_query_stack(QueryCtxt { tcx: icx.tcx }, icx.query, handler, num_frames)
+ print_query_stack(QueryCtxt::new(icx.tcx), icx.query, handler, num_frames)
} else {
0
}
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 48401eabd1e..bbf9d9d515d 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -17,7 +17,7 @@ use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintSto
use rustc_metadata::creader::CStore;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph;
-use rustc_middle::ty::query::{ExternProviders, Providers};
+use rustc_middle::query::{ExternProviders, Providers};
use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt};
use rustc_mir_build as mir_build;
use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr};
@@ -691,6 +691,8 @@ pub fn create_global_ctxt<'tcx>(
callback(sess, &mut local_providers, &mut extern_providers);
}
+ let incremental = dep_graph.is_fully_enabled();
+
sess.time("setup_global_ctxt", || {
gcx_cell.get_or_init(move || {
TyCtxt::create_global_ctxt(
@@ -700,9 +702,13 @@ pub fn create_global_ctxt<'tcx>(
hir_arena,
untracked,
dep_graph,
- query_result_on_disk_cache,
rustc_query_impl::query_callbacks(arena),
- rustc_query_impl::query_system_fns(local_providers, extern_providers),
+ rustc_query_impl::query_system(
+ local_providers,
+ extern_providers,
+ query_result_on_disk_cache,
+ incremental,
+ ),
)
})
})
diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs
index 1c58caa0353..2c8014d8b3a 100644
--- a/compiler/rustc_interface/src/proc_macro_decls.rs
+++ b/compiler/rustc_interface/src/proc_macro_decls.rs
@@ -1,6 +1,6 @@
use rustc_ast::attr;
use rustc_hir::def_id::LocalDefId;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::sym;
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index c07dc19a0ac..d511d2b1280 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -582,34 +582,38 @@ impl Cursor<'_> {
let mut base = Base::Decimal;
if first_digit == '0' {
// Attempt to parse encoding base.
- let has_digits = match self.first() {
+ match self.first() {
'b' => {
base = Base::Binary;
self.bump();
- self.eat_decimal_digits()
+ if !self.eat_decimal_digits() {
+ return Int { base, empty_int: true };
+ }
}
'o' => {
base = Base::Octal;
self.bump();
- self.eat_decimal_digits()
+ if !self.eat_decimal_digits() {
+ return Int { base, empty_int: true };
+ }
}
'x' => {
base = Base::Hexadecimal;
self.bump();
- self.eat_hexadecimal_digits()
+ if !self.eat_hexadecimal_digits() {
+ return Int { base, empty_int: true };
+ }
}
- // Not a base prefix.
- '0'..='9' | '_' | '.' | 'e' | 'E' => {
+ // Not a base prefix; consume additional digits.
+ '0'..='9' | '_' => {
self.eat_decimal_digits();
- true
}
+
+ // Also not a base prefix; nothing more to do here.
+ '.' | 'e' | 'E' => {}
+
// Just a 0.
_ => return Int { base, empty_int: false },
- };
- // Base prefix was provided, but there were no digits
- // after it, e.g. "0x".
- if !has_digits {
- return Int { base, empty_int: true };
}
} else {
// No base prefix, parse number in the usual way.
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 71cf644eb50..a5639404faf 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -520,3 +520,19 @@ lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its ass
.specifically = this associated type bound is unsatisfied for `{$proj_ty}`
lint_opaque_hidden_inferred_bound_sugg = add this bound
+
+lint_drop_ref = calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ .label = argument has type `{$arg_ty}`
+ .note = use `let _ = ...` to ignore the expression or result
+
+lint_drop_copy = calls to `std::mem::drop` with a value that implements `Copy` does nothing
+ .label = argument has type `{$arg_ty}`
+ .note = use `let _ = ...` to ignore the expression or result
+
+lint_forget_ref = calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ .label = argument has type `{$arg_ty}`
+ .note = use `let _ = ...` to ignore the expression or result
+
+lint_forget_copy = calls to `std::mem::forget` with a value that implements `Copy` does nothing
+ .label = argument has type `{$arg_ty}`
+ .note = use `let _ = ...` to ignore the expression or result
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 0b7a704eb57..6601a80920b 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -62,6 +62,7 @@ use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::layout::{LayoutError, LayoutOf};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::subst::GenericArgKind;
+use rustc_middle::ty::TypeVisitableExt;
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, VariantDef};
use rustc_session::config::ExpectedValues;
use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason};
@@ -610,7 +611,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
declare_lint! {
/// The `missing_copy_implementations` lint detects potentially-forgotten
- /// implementations of [`Copy`].
+ /// implementations of [`Copy`] for public types.
///
/// [`Copy`]: https://doc.rust-lang.org/std/marker/trait.Copy.html
///
@@ -646,7 +647,9 @@ declare_lint_pass!(MissingCopyImplementations => [MISSING_COPY_IMPLEMENTATIONS])
impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
- if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) {
+ if !(cx.effective_visibilities.is_reachable(item.owner_id.def_id)
+ && cx.tcx.local_visibility(item.owner_id.def_id).is_public())
+ {
return;
}
let (def, ty) = match item.kind {
@@ -726,7 +729,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
declare_lint! {
/// The `missing_debug_implementations` lint detects missing
- /// implementations of [`fmt::Debug`].
+ /// implementations of [`fmt::Debug`] for public types.
///
/// [`fmt::Debug`]: https://doc.rust-lang.org/std/fmt/trait.Debug.html
///
@@ -765,7 +768,9 @@ impl_lint_pass!(MissingDebugImplementations => [MISSING_DEBUG_IMPLEMENTATIONS]);
impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
- if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) {
+ if !(cx.effective_visibilities.is_reachable(item.owner_id.def_id)
+ && cx.tcx.local_visibility(item.owner_id.def_id).is_public())
+ {
return;
}
@@ -1442,6 +1447,10 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
// Bounds are respected for `type X = impl Trait`
return;
}
+ if cx.tcx.type_of(item.owner_id).skip_binder().has_inherent_projections() {
+ // Bounds are respected for `type X = … Type::Inherent …`
+ return;
+ }
// There must not be a where clause
if type_alias_generics.predicates.is_empty() {
return;
@@ -1561,7 +1570,6 @@ declare_lint_pass!(
impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
- use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::Clause;
use rustc_middle::ty::PredicateKind::*;
@@ -1878,8 +1886,8 @@ declare_lint_pass!(
struct UnderMacro(bool);
impl KeywordIdents {
- fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: TokenStream) {
- for tt in tokens.into_trees() {
+ fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: &TokenStream) {
+ for tt in tokens.trees() {
match tt {
// Only report non-raw idents.
TokenTree::Token(token, _) => {
@@ -1940,10 +1948,10 @@ impl KeywordIdents {
impl EarlyLintPass for KeywordIdents {
fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef) {
- self.check_tokens(cx, mac_def.body.tokens.clone());
+ self.check_tokens(cx, &mac_def.body.tokens);
}
fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::MacCall) {
- self.check_tokens(cx, mac.args.tokens.clone());
+ self.check_tokens(cx, &mac.args.tokens);
}
fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
self.check_ident_token(cx, UnderMacro(false), ident);
@@ -2898,6 +2906,7 @@ impl ClashingExternDeclarations {
| (Generator(..), Generator(..))
| (GeneratorWitness(..), GeneratorWitness(..))
| (Alias(ty::Projection, ..), Alias(ty::Projection, ..))
+ | (Alias(ty::Inherent, ..), Alias(ty::Inherent, ..))
| (Alias(ty::Opaque, ..), Alias(ty::Opaque, ..)) => false,
// These definitely should have been caught above.
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 53d7cf74cde..1d0c43e95e0 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -49,9 +49,9 @@ use std::cell::Cell;
use std::iter;
use std::slice;
-type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync;
+type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::DynSend + sync::DynSync;
type LateLintPassFactory =
- dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::Send + sync::Sync;
+ dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::DynSend + sync::DynSync;
/// Information about the registered lints.
///
@@ -169,7 +169,7 @@ impl LintStore {
pub fn register_early_pass(
&mut self,
- pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync,
+ pass: impl Fn() -> EarlyLintPassObject + 'static + sync::DynSend + sync::DynSync,
) {
self.early_passes.push(Box::new(pass));
}
@@ -182,7 +182,7 @@ impl LintStore {
/// * See [rust-clippy#5518](https://github.com/rust-lang/rust-clippy/pull/5518)
pub fn register_pre_expansion_pass(
&mut self,
- pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync,
+ pass: impl Fn() -> EarlyLintPassObject + 'static + sync::DynSend + sync::DynSync,
) {
self.pre_expansion_passes.push(Box::new(pass));
}
@@ -191,8 +191,8 @@ impl LintStore {
&mut self,
pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx>
+ 'static
- + sync::Send
- + sync::Sync,
+ + sync::DynSend
+ + sync::DynSync,
) {
self.late_passes.push(Box::new(pass));
}
@@ -201,8 +201,8 @@ impl LintStore {
&mut self,
pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx>
+ 'static
- + sync::Send
- + sync::Sync,
+ + sync::DynSend
+ + sync::DynSync,
) {
self.late_module_passes.push(Box::new(pass));
}
diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs
new file mode 100644
index 00000000000..259abc2af11
--- /dev/null
+++ b/compiler/rustc_lint/src/drop_forget_useless.rs
@@ -0,0 +1,164 @@
+use rustc_hir::{Arm, Expr, ExprKind, Node};
+use rustc_span::sym;
+
+use crate::{
+ lints::{DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag},
+ LateContext, LateLintPass, LintContext,
+};
+
+declare_lint! {
+ /// The `drop_ref` lint checks for calls to `std::mem::drop` with a reference
+ /// instead of an owned value.
+ ///
+ /// ### Example
+ ///
+ /// ```rust
+ /// # fn operation_that_requires_mutex_to_be_unlocked() {} // just to make it compile
+ /// # let mutex = std::sync::Mutex::new(1); // just to make it compile
+ /// 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();
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// 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.
+ pub DROP_REF,
+ Warn,
+ "calls to `std::mem::drop` with a reference instead of an owned value"
+}
+
+declare_lint! {
+ /// The `forget_ref` lint checks for calls to `std::mem::forget` with a reference
+ /// instead of an owned value.
+ ///
+ /// ### Example
+ ///
+ /// ```rust
+ /// let x = Box::new(1);
+ /// std::mem::forget(&x); // Should have been forget(x), x will still be dropped
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// 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.
+ pub FORGET_REF,
+ Warn,
+ "calls to `std::mem::forget` with a reference instead of an owned value"
+}
+
+declare_lint! {
+ /// The `drop_copy` lint checks for calls to `std::mem::drop` with a value
+ /// that derives the Copy trait.
+ ///
+ /// ### Example
+ ///
+ /// ```rust
+ /// let x: i32 = 42; // i32 implements Copy
+ /// std::mem::drop(x); // A copy of x is passed to the function, leaving the
+ /// // original unaffected
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// 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.
+ pub DROP_COPY,
+ Warn,
+ "calls to `std::mem::drop` with a value that implements Copy"
+}
+
+declare_lint! {
+ /// The `forget_copy` lint checks for calls to `std::mem::forget` with a value
+ /// that derives the Copy trait.
+ ///
+ /// ### Example
+ ///
+ /// ```rust
+ /// let x: i32 = 42; // i32 implements Copy
+ /// std::mem::forget(x); // A copy of x is passed to the function, leaving the
+ /// // original unaffected
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// 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.
+ pub FORGET_COPY,
+ Warn,
+ "calls to `std::mem::forget` with a value that implements Copy"
+}
+
+declare_lint_pass!(DropForgetUseless => [DROP_REF, FORGET_REF, DROP_COPY, FORGET_COPY]);
+
+impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+ if let ExprKind::Call(path, [arg]) = expr.kind
+ && let ExprKind::Path(ref qpath) = path.kind
+ && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+ && let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id)
+ {
+ let arg_ty = cx.typeck_results().expr_ty(arg);
+ let is_copy = arg_ty.is_copy_modulo_regions(cx.tcx, cx.param_env);
+ let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
+ match fn_name {
+ sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => {
+ cx.emit_spanned_lint(DROP_REF, expr.span, DropRefDiag { arg_ty, label: arg.span });
+ },
+ sym::mem_forget if arg_ty.is_ref() => {
+ cx.emit_spanned_lint(FORGET_REF, expr.span, ForgetRefDiag { arg_ty, label: arg.span });
+ },
+ sym::mem_drop if is_copy && !drop_is_single_call_in_arm => {
+ cx.emit_spanned_lint(DROP_COPY, expr.span, DropCopyDiag { arg_ty, label: arg.span });
+ }
+ sym::mem_forget if is_copy => {
+ cx.emit_spanned_lint(FORGET_COPY, expr.span, ForgetCopyDiag { arg_ty, label: arg.span });
+ }
+ _ => return,
+ };
+ }
+ }
+}
+
+// Dropping returned value of a function, as in the following snippet is considered idiomatic, see
+// rust-lang/rust-clippy#9482 for examples.
+//
+// ```
+// match <var> {
+// <pat> => drop(fn_with_side_effect_and_returning_some_value()),
+// ..
+// }
+// ```
+fn is_single_call_in_arm<'tcx>(
+ cx: &LateContext<'tcx>,
+ arg: &'tcx Expr<'_>,
+ drop_expr: &'tcx Expr<'_>,
+) -> bool {
+ if matches!(arg.kind, ExprKind::Call(..) | ExprKind::MethodCall(..)) {
+ let parent_node = cx.tcx.hir().find_parent(drop_expr.hir_id);
+ if let Some(Node::Arm(Arm { body, .. })) = &parent_node {
+ return body.hir_id == drop_expr.hir_id;
+ }
+ }
+ false
+}
diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs
index e9eb14ea188..b1266b58a61 100644
--- a/compiler/rustc_lint/src/expect.rs
+++ b/compiler/rustc_lint/src/expect.rs
@@ -1,5 +1,5 @@
use crate::lints::{Expectation, ExpectationNote};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::UNFULFILLED_LINT_EXPECTATIONS;
use rustc_session::lint::LintExpectationId;
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index b42878a02ee..c9781a72704 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -16,7 +16,7 @@
use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore};
use rustc_ast as ast;
-use rustc_data_structures::sync::join;
+use rustc_data_structures::sync::{join, DynSend};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit as hir_visit;
@@ -429,7 +429,7 @@ fn late_lint_crate_inner<'tcx, T: LateLintPass<'tcx>>(
/// Performs lint checking on a crate.
pub fn check_crate<'tcx, T: LateLintPass<'tcx> + 'tcx>(
tcx: TyCtxt<'tcx>,
- builtin_lints: impl FnOnce() -> T + Send,
+ builtin_lints: impl FnOnce() -> T + Send + DynSend,
) {
join(
|| {
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index a43c09a7939..b92ed11f38a 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -20,7 +20,7 @@ use rustc_middle::lint::{
reveal_actual_level, struct_lint_level, LevelAndSource, LintExpectation, LintLevelSource,
ShallowLintLevelMap,
};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{RegisteredTools, TyCtxt};
use rustc_session::lint::builtin::{RENAMED_AND_REMOVED_LINTS, UNKNOWN_LINTS, UNUSED_ATTRIBUTES};
use rustc_session::lint::{
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 319eb2ea445..dfddfe09ab3 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -52,6 +52,7 @@ mod array_into_iter;
pub mod builtin;
mod context;
mod deref_into_dyn_supertrait;
+mod drop_forget_useless;
mod early;
mod enum_intrinsics_non_enums;
mod errors;
@@ -85,7 +86,7 @@ use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::{
BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS,
@@ -96,6 +97,7 @@ use rustc_span::Span;
use array_into_iter::ArrayIntoIter;
use builtin::*;
use deref_into_dyn_supertrait::*;
+use drop_forget_useless::*;
use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
use for_loops_over_fallibles::*;
use hidden_unicode_codepoints::*;
@@ -201,6 +203,7 @@ late_lint_methods!(
[
ForLoopsOverFallibles: ForLoopsOverFallibles,
DerefIntoDynSupertrait: DerefIntoDynSupertrait,
+ DropForgetUseless: DropForgetUseless,
HardwiredLints: HardwiredLints,
ImproperCTypesDeclarations: ImproperCTypesDeclarations,
ImproperCTypesDefinitions: ImproperCTypesDefinitions,
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index d7bacc6485f..8e48806b504 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -662,6 +662,43 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> {
pub end_span: Span,
}
+// drop_ref.rs
+#[derive(LintDiagnostic)]
+#[diag(lint_drop_ref)]
+#[note]
+pub struct DropRefDiag<'a> {
+ pub arg_ty: Ty<'a>,
+ #[label]
+ pub label: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(lint_drop_copy)]
+#[note]
+pub struct DropCopyDiag<'a> {
+ pub arg_ty: Ty<'a>,
+ #[label]
+ pub label: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(lint_forget_ref)]
+#[note]
+pub struct ForgetRefDiag<'a> {
+ pub arg_ty: Ty<'a>,
+ #[label]
+ pub label: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(lint_forget_copy)]
+#[note]
+pub struct ForgetCopyDiag<'a> {
+ pub arg_ty: Ty<'a>,
+ #[label]
+ pub label: Span,
+}
+
// hidden_unicode_codepoints.rs
#[derive(LintDiagnostic)]
#[diag(lint_hidden_unicode_codepoints)]
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index a6ba742201a..125b4dc5503 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1119,14 +1119,14 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
// `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe,
// so they are currently ignored for the purposes of this lint.
- ty::Param(..) | ty::Alias(ty::Projection, ..)
+ ty::Param(..) | ty::Alias(ty::Projection | ty::Inherent, ..)
if matches!(self.mode, CItemKind::Definition) =>
{
FfiSafe
}
ty::Param(..)
- | ty::Alias(ty::Projection, ..)
+ | ty::Alias(ty::Projection | ty::Inherent, ..)
| ty::Infer(..)
| ty::Bound(..)
| ty::Error(_)
diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
index 03e6d2149e9..87906dee4d3 100644
--- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
@@ -8,18 +8,100 @@
using namespace llvm;
+// FFI equivalent of enum `llvm::coverage::Counter::CounterKind`
+// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L97-L99
+enum class LLVMRustCounterKind {
+ Zero = 0,
+ CounterValueReference = 1,
+ Expression = 2,
+};
+
+// FFI equivalent of struct `llvm::coverage::Counter`
+// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L94-L149
+struct LLVMRustCounter {
+ LLVMRustCounterKind CounterKind;
+ uint32_t ID;
+};
+
+static coverage::Counter fromRust(LLVMRustCounter Counter) {
+ switch (Counter.CounterKind) {
+ case LLVMRustCounterKind::Zero:
+ return coverage::Counter::getZero();
+ case LLVMRustCounterKind::CounterValueReference:
+ return coverage::Counter::getCounter(Counter.ID);
+ case LLVMRustCounterKind::Expression:
+ return coverage::Counter::getExpression(Counter.ID);
+ }
+ report_fatal_error("Bad LLVMRustCounterKind!");
+}
+
+// FFI equivalent of enum `llvm::coverage::CounterMappingRegion::RegionKind`
+// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L213-L234
+enum class LLVMRustCounterMappingRegionKind {
+ CodeRegion = 0,
+ ExpansionRegion = 1,
+ SkippedRegion = 2,
+ GapRegion = 3,
+ BranchRegion = 4,
+};
+
+static coverage::CounterMappingRegion::RegionKind
+fromRust(LLVMRustCounterMappingRegionKind Kind) {
+ switch (Kind) {
+ case LLVMRustCounterMappingRegionKind::CodeRegion:
+ return coverage::CounterMappingRegion::CodeRegion;
+ case LLVMRustCounterMappingRegionKind::ExpansionRegion:
+ return coverage::CounterMappingRegion::ExpansionRegion;
+ case LLVMRustCounterMappingRegionKind::SkippedRegion:
+ return coverage::CounterMappingRegion::SkippedRegion;
+ case LLVMRustCounterMappingRegionKind::GapRegion:
+ return coverage::CounterMappingRegion::GapRegion;
+ case LLVMRustCounterMappingRegionKind::BranchRegion:
+ return coverage::CounterMappingRegion::BranchRegion;
+ }
+ report_fatal_error("Bad LLVMRustCounterMappingRegionKind!");
+}
+
+// FFI equivalent of struct `llvm::coverage::CounterMappingRegion`
+// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L211-L304
struct LLVMRustCounterMappingRegion {
- coverage::Counter Count;
- coverage::Counter FalseCount;
+ LLVMRustCounter Count;
+ LLVMRustCounter FalseCount;
uint32_t FileID;
uint32_t ExpandedFileID;
uint32_t LineStart;
uint32_t ColumnStart;
uint32_t LineEnd;
uint32_t ColumnEnd;
- coverage::CounterMappingRegion::RegionKind Kind;
+ LLVMRustCounterMappingRegionKind Kind;
+};
+
+// FFI equivalent of enum `llvm::coverage::CounterExpression::ExprKind`
+// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L154
+enum class LLVMRustCounterExprKind {
+ Subtract = 0,
+ Add = 1,
};
+// FFI equivalent of struct `llvm::coverage::CounterExpression`
+// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L151-L160
+struct LLVMRustCounterExpression {
+ LLVMRustCounterExprKind Kind;
+ LLVMRustCounter LHS;
+ LLVMRustCounter RHS;
+};
+
+static coverage::CounterExpression::ExprKind
+fromRust(LLVMRustCounterExprKind Kind) {
+ switch (Kind) {
+ case LLVMRustCounterExprKind::Subtract:
+ return coverage::CounterExpression::Subtract;
+ case LLVMRustCounterExprKind::Add:
+ return coverage::CounterExpression::Add;
+ }
+ report_fatal_error("Bad LLVMRustCounterExprKind!");
+}
+
extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
const char* const Filenames[],
size_t FilenamesLen,
@@ -37,9 +119,9 @@ extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
extern "C" void LLVMRustCoverageWriteMappingToBuffer(
const unsigned *VirtualFileMappingIDs,
unsigned NumVirtualFileMappingIDs,
- const coverage::CounterExpression *Expressions,
+ const LLVMRustCounterExpression *RustExpressions,
unsigned NumExpressions,
- LLVMRustCounterMappingRegion *RustMappingRegions,
+ const LLVMRustCounterMappingRegion *RustMappingRegions,
unsigned NumMappingRegions,
RustStringRef BufferOut) {
// Convert from FFI representation to LLVM representation.
@@ -48,13 +130,24 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
for (const auto &Region : ArrayRef<LLVMRustCounterMappingRegion>(
RustMappingRegions, NumMappingRegions)) {
MappingRegions.emplace_back(
- Region.Count, Region.FalseCount, Region.FileID, Region.ExpandedFileID,
+ fromRust(Region.Count), fromRust(Region.FalseCount),
+ Region.FileID, Region.ExpandedFileID,
Region.LineStart, Region.ColumnStart, Region.LineEnd, Region.ColumnEnd,
- Region.Kind);
+ fromRust(Region.Kind));
}
+
+ std::vector<coverage::CounterExpression> Expressions;
+ Expressions.reserve(NumExpressions);
+ for (const auto &Expression :
+ ArrayRef<LLVMRustCounterExpression>(RustExpressions, NumExpressions)) {
+ Expressions.emplace_back(fromRust(Expression.Kind),
+ fromRust(Expression.LHS),
+ fromRust(Expression.RHS));
+ }
+
auto CoverageMappingWriter = coverage::CoverageMappingWriter(
ArrayRef<unsigned>(VirtualFileMappingIDs, NumVirtualFileMappingIDs),
- ArrayRef<coverage::CounterExpression>(Expressions, NumExpressions),
+ Expressions,
MappingRegions);
RawRustStringOstream OS(BufferOut);
CoverageMappingWriter.write(OS);
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index fc28f6efa44..c43a0272477 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -745,6 +745,9 @@ LLVMRustOptimize(
if (InstrProfileOutput) {
Options.InstrProfileOutput = InstrProfileOutput;
}
+ // cargo run tests in multhreading mode by default
+ // so use atomics for coverage counters
+ Options.Atomic = true;
MPM.addPass(InstrProfiling(Options, false));
}
);
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
index 427c82c410b..cd6e3687460 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
@@ -9,7 +9,7 @@ use crate::diagnostics::utils::{
FieldInnerTy, FieldMap, HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind,
};
use proc_macro2::{Ident, Span, TokenStream};
-use quote::{format_ident, quote};
+use quote::{format_ident, quote, quote_spanned};
use syn::Token;
use syn::{parse_quote, spanned::Spanned, Attribute, Meta, Path, Type};
use synstructure::{BindingInfo, Structure, VariantInfo};
@@ -251,7 +251,8 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
let diag = &self.parent.diag;
let field = binding_info.ast();
- let field_binding = &binding_info.binding;
+ let mut field_binding = binding_info.binding.clone();
+ field_binding.set_span(field.ty.span());
let ident = field.ident.as_ref().unwrap();
let ident = format_ident!("{}", ident); // strip `r#` prefix, if present
@@ -284,9 +285,9 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
name == "primary_span" && matches!(inner_ty, FieldInnerTy::Vec(_));
let (binding, needs_destructure) = if needs_clone {
// `primary_span` can accept a `Vec<Span>` so don't destructure that.
- (quote! { #field_binding.clone() }, false)
+ (quote_spanned! {inner_ty.span()=> #field_binding.clone() }, false)
} else {
- (quote! { #field_binding }, true)
+ (quote_spanned! {inner_ty.span()=> #field_binding }, true)
};
let generated_code = self
diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs
index bd84681cbb4..a536eb3b04e 100644
--- a/compiler/rustc_macros/src/diagnostics/mod.rs
+++ b/compiler/rustc_macros/src/diagnostics/mod.rs
@@ -140,7 +140,7 @@ pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
/// ```fluent
/// 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
/// ```
diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
index 62d49c1c64e..374ba1a45c0 100644
--- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
@@ -4,17 +4,16 @@ use crate::diagnostics::error::{
invalid_attr, span_err, throw_invalid_attr, throw_span_err, DiagnosticDeriveError,
};
use crate::diagnostics::utils::{
- build_field_mapping, is_doc_comment, new_code_ident,
- report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span, FieldInfo,
- FieldInnerTy, FieldMap, HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind,
+ build_field_mapping, build_suggestion_code, is_doc_comment, new_code_ident,
+ report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span,
+ should_generate_set_arg, AllowMultipleAlternatives, FieldInfo, FieldInnerTy, FieldMap,
+ HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind,
};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use syn::{spanned::Spanned, Attribute, Meta, MetaList, Path};
use synstructure::{BindingInfo, Structure, VariantInfo};
-use super::utils::{build_suggestion_code, AllowMultipleAlternatives};
-
/// The central struct for constructing the `add_to_diagnostic` method from an annotated struct.
pub(crate) struct SubdiagnosticDeriveBuilder {
diag: syn::Ident,
@@ -210,19 +209,20 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
}
/// 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");
-
+ fn generate_field_set_arg(&mut self, binding_info: &BindingInfo<'_>) -> TokenStream {
let diag = &self.parent.diag;
- let ident = ast.ident.as_ref().unwrap();
- // strip `r#` prefix, if present
- let ident = format_ident!("{}", ident);
+
+ let field = binding_info.ast();
+ let mut field_binding = binding_info.binding.clone();
+ field_binding.set_span(field.ty.span());
+
+ let ident = field.ident.as_ref().unwrap();
+ let ident = format_ident!("{}", ident); // strip `r#` prefix, if present
quote! {
#diag.set_arg(
stringify!(#ident),
- #binding
+ #field_binding
);
}
}
@@ -399,7 +399,8 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
clone_suggestion_code: bool,
) -> Result<TokenStream, DiagnosticDeriveError> {
let span = attr.span().unwrap();
- let ident = &list.path.segments.last().unwrap().ident;
+ let mut ident = list.path.segments.last().unwrap().ident.clone();
+ ident.set_span(info.ty.span());
let name = ident.to_string();
let name = name.as_str();
@@ -498,7 +499,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
.variant
.bindings()
.iter()
- .filter(|binding| !binding.ast().attrs.is_empty())
+ .filter(|binding| !should_generate_set_arg(binding.ast()))
.map(|binding| self.generate_field_attr_code(binding, kind_stats))
.collect();
@@ -580,7 +581,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
.variant
.bindings()
.iter()
- .filter(|binding| binding.ast().attrs.is_empty())
+ .filter(|binding| should_generate_set_arg(binding.ast()))
.map(|binding| self.generate_field_set_arg(binding))
.collect();
diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs
index b9b09c66230..e2434981f8d 100644
--- a/compiler/rustc_macros/src/diagnostics/utils.rs
+++ b/compiler/rustc_macros/src/diagnostics/utils.rs
@@ -207,6 +207,12 @@ impl<'ty> FieldInnerTy<'ty> {
FieldInnerTy::Plain(..) => quote! { #inner },
}
}
+
+ pub fn span(&self) -> proc_macro2::Span {
+ match self {
+ FieldInnerTy::Option(ty) | FieldInnerTy::Vec(ty) | FieldInnerTy::Plain(ty) => ty.span(),
+ }
+ }
}
/// Field information passed to the builder. Deliberately omits attrs to discourage the
@@ -851,7 +857,8 @@ impl quote::IdentFragment for SubdiagnosticKind {
/// Returns `true` if `field` should generate a `set_arg` call rather than any other diagnostic
/// call (like `span_label`).
pub(super) fn should_generate_set_arg(field: &Field) -> bool {
- field.attrs.is_empty()
+ // Perhaps this should be an exhaustive list...
+ field.attrs.iter().all(|attr| is_doc_comment(attr))
}
pub(super) fn is_doc_comment(attr: &Attribute) -> bool {
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index a8b25ff66d7..001d53b1099 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -253,7 +253,7 @@ fn add_query_desc_cached_impl(
quote! {
#[allow(unused_variables, unused_braces, rustc::pass_by_value)]
#[inline]
- pub fn #name<'tcx>(#tcx: TyCtxt<'tcx>, #key: &crate::ty::query::query_keys::#name<'tcx>) -> bool {
+ pub fn #name<'tcx>(#tcx: TyCtxt<'tcx>, #key: &crate::query::query_keys::#name<'tcx>) -> bool {
#expr
}
}
@@ -262,7 +262,7 @@ fn add_query_desc_cached_impl(
// we're taking `key` by reference, but some rustc types usually prefer being passed by value
#[allow(rustc::pass_by_value)]
#[inline]
- pub fn #name<'tcx>(_: TyCtxt<'tcx>, _: &crate::ty::query::query_keys::#name<'tcx>) -> bool {
+ pub fn #name<'tcx>(_: TyCtxt<'tcx>, _: &crate::query::query_keys::#name<'tcx>) -> bool {
false
}
}
@@ -273,7 +273,7 @@ fn add_query_desc_cached_impl(
let desc = quote! {
#[allow(unused_variables)]
- pub fn #name<'tcx>(tcx: TyCtxt<'tcx>, key: crate::ty::query::query_keys::#name<'tcx>) -> String {
+ pub fn #name<'tcx>(tcx: TyCtxt<'tcx>, key: crate::query::query_keys::#name<'tcx>) -> String {
let (#tcx, #key) = (tcx, key);
::rustc_middle::ty::print::with_no_trimmed_paths!(
format!(#desc)
diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs
index 39ef4276faf..72b208a7132 100644
--- a/compiler/rustc_metadata/src/dependency_format.rs
+++ b/compiler/rustc_metadata/src/dependency_format.rs
@@ -89,11 +89,25 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
// to try to eagerly statically link all dependencies. This is normally
// done for end-product dylibs, not intermediate products.
//
- // Treat cdylibs similarly. If `-C prefer-dynamic` is set, the caller may
- // be code-size conscious, but without it, it makes sense to statically
- // link a cdylib.
- CrateType::Dylib | CrateType::Cdylib if !sess.opts.cg.prefer_dynamic => Linkage::Static,
- CrateType::Dylib | CrateType::Cdylib => Linkage::Dynamic,
+ // Treat cdylibs and staticlibs similarly. If `-C prefer-dynamic` is set,
+ // the caller may be code-size conscious, but without it, it makes sense
+ // to statically link a cdylib or staticlib. For staticlibs we use
+ // `-Z staticlib-prefer-dynamic` for now. This may be merged into
+ // `-C prefer-dynamic` in the future.
+ CrateType::Dylib | CrateType::Cdylib => {
+ if sess.opts.cg.prefer_dynamic {
+ Linkage::Dynamic
+ } else {
+ Linkage::Static
+ }
+ }
+ CrateType::Staticlib => {
+ if sess.opts.unstable_opts.staticlib_prefer_dynamic {
+ Linkage::Dynamic
+ } else {
+ Linkage::Static
+ }
+ }
// If the global prefer_dynamic switch is turned off, or the final
// executable will be statically linked, prefer static crate linkage.
@@ -108,9 +122,6 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
// No linkage happens with rlibs, we just needed the metadata (which we
// got long ago), so don't bother with anything.
CrateType::Rlib => Linkage::NotLinked,
-
- // staticlibs must have all static dependencies.
- CrateType::Staticlib => Linkage::Static,
};
match preferred_linkage {
@@ -123,9 +134,9 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
return v;
}
- // Staticlibs and static executables must have all static dependencies.
+ // Static executables must have all static dependencies.
// If any are not found, generate some nice pretty errors.
- if ty == CrateType::Staticlib
+ if (ty == CrateType::Staticlib && !sess.opts.unstable_opts.staticlib_allow_rdylib_deps)
|| (ty == CrateType::Executable
&& sess.crt_static(Some(ty))
&& !sess.target.crt_static_allows_dylibs)
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index c6af8d63289..6c4d121fd01 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -220,7 +220,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::owned_slice::slice_owned;
use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::MetadataRef;
use rustc_errors::{DiagnosticArgValue, FatalError, IntoDiagnosticArg};
use rustc_fs_util::try_canonicalize;
use rustc_session::config::{self, CrateType};
@@ -782,7 +781,7 @@ fn get_metadata_section<'p>(
if !filename.exists() {
return Err(MetadataError::NotPresent(filename));
}
- let raw_bytes: MetadataRef = match flavor {
+ let raw_bytes = match flavor {
CrateFlavor::Rlib => {
loader.get_rlib_metadata(target, filename).map_err(MetadataError::LoadFailure)?
}
@@ -843,7 +842,7 @@ fn get_metadata_section<'p>(
slice_owned(mmap, Deref::deref)
}
};
- let blob = MetadataBlob::new(raw_bytes);
+ let blob = MetadataBlob(raw_bytes);
if blob.is_compatible() {
Ok(blob)
} else {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index a310cbb8029..699e1f49ed6 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -7,6 +7,7 @@ use crate::rmeta::*;
use rustc_ast as ast;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::owned_slice::OwnedSlice;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc, OnceCell};
use rustc_data_structures::unhash::UnhashMap;
@@ -50,7 +51,7 @@ mod cstore_impl;
/// A `MetadataBlob` internally is just a reference counted pointer to
/// the actual data, so cloning it is cheap.
#[derive(Clone)]
-pub(crate) struct MetadataBlob(Lrc<MetadataRef>);
+pub(crate) struct MetadataBlob(pub(crate) OwnedSlice);
impl std::ops::Deref for MetadataBlob {
type Target = [u8];
@@ -660,10 +661,6 @@ impl<'a, 'tcx, I: Idx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyTable<I, T>
implement_ty_decoder!(DecodeContext<'a, 'tcx>);
impl MetadataBlob {
- pub(crate) fn new(metadata_ref: MetadataRef) -> MetadataBlob {
- MetadataBlob(Lrc::new(metadata_ref))
- }
-
pub(crate) fn is_compatible(&self) -> bool {
self.blob().starts_with(METADATA_HEADER)
}
@@ -856,7 +853,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
ty::EarlyBinder(&*output)
}
- fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef {
+ fn get_variant(
+ self,
+ kind: DefKind,
+ index: DefIndex,
+ parent_did: DefId,
+ ) -> (VariantIdx, ty::VariantDef) {
let adt_kind = match kind {
DefKind::Variant => ty::AdtKind::Enum,
DefKind::Struct => ty::AdtKind::Struct,
@@ -870,22 +872,25 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None };
let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index)));
- ty::VariantDef::new(
- self.item_name(index),
- variant_did,
- ctor,
- data.discr,
- self.get_associated_item_or_field_def_ids(index)
- .map(|did| ty::FieldDef {
- did,
- name: self.item_name(did.index),
- vis: self.get_visibility(did.index),
- })
- .collect(),
- adt_kind,
- parent_did,
- false,
- data.is_non_exhaustive,
+ (
+ data.idx,
+ ty::VariantDef::new(
+ self.item_name(index),
+ variant_did,
+ ctor,
+ data.discr,
+ self.get_associated_item_or_field_def_ids(index)
+ .map(|did| ty::FieldDef {
+ did,
+ name: self.item_name(did.index),
+ vis: self.get_visibility(did.index),
+ })
+ .collect(),
+ adt_kind,
+ parent_did,
+ false,
+ data.is_non_exhaustive,
+ ),
)
}
@@ -901,7 +906,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
};
let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self);
- let variants = if let ty::AdtKind::Enum = adt_kind {
+ let mut variants: Vec<_> = if let ty::AdtKind::Enum = adt_kind {
self.root
.tables
.module_children_non_reexports
@@ -912,15 +917,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
let kind = self.def_kind(index);
match kind {
DefKind::Ctor(..) => None,
- _ => Some(self.get_variant(&kind, index, did)),
+ _ => Some(self.get_variant(kind, index, did)),
}
})
.collect()
} else {
- std::iter::once(self.get_variant(&kind, item_id, did)).collect()
+ std::iter::once(self.get_variant(kind, item_id, did)).collect()
};
- tcx.mk_adt_def(did, adt_kind, variants, repr)
+ variants.sort_by_key(|(idx, _)| *idx);
+
+ tcx.mk_adt_def(
+ did,
+ adt_kind,
+ variants.into_iter().map(|(_, variant)| variant).collect(),
+ repr,
+ )
}
fn get_visibility(self, id: DefIndex) -> Visibility<DefId> {
@@ -1457,28 +1469,30 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
..
} = 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,
+ // If this file is under $sysroot/lib/rustlib/src/
+ // and the user wish to simulate remapping with -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 {
- for subdir in ["library", "compiler"] {
- 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.join(subdir)) {
- *old_name = rustc_span::RealFileName::Remapped {
- local_path: None,
- virtual_name: virtual_dir.join(subdir).join(rest),
- };
- }
- }
- }
+ && let Some(real_dir) = &sess.opts.real_rust_source_base_dir
+ && let rustc_span::FileName::Real(ref mut old_name) = name {
+ let relative_path = match old_name {
+ rustc_span::RealFileName::LocalPath(local) => local.strip_prefix(real_dir).ok(),
+ rustc_span::RealFileName::Remapped { virtual_name, .. } => {
+ option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").and_then(|virtual_dir| virtual_name.strip_prefix(virtual_dir).ok())
+ }
+ };
+ debug!(?relative_path, ?virtual_dir, "simulate_remapped_rust_src_base");
+ for subdir in ["library", "compiler"] {
+ if let Some(rest) = relative_path.and_then(|p| p.strip_prefix(subdir).ok()) {
+ *old_name = rustc_span::RealFileName::Remapped {
+ local_path: None, // FIXME: maybe we should preserve this?
+ virtual_name: virtual_dir.join(subdir).join(rest),
+ };
+ break;
}
}
}
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 4a3b783c636..fe880b939ef 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -14,8 +14,8 @@ use rustc_middle::metadata::ModChild;
use rustc_middle::middle::exported_symbols::ExportedSymbol;
use rustc_middle::middle::stability::DeprecationEntry;
use rustc_middle::query::LocalCrate;
+use rustc_middle::query::{ExternProviders, Providers};
use rustc_middle::ty::fast_reject::SimplifiedType;
-use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::cstore::CrateStore;
use rustc_session::{Session, StableCrateId};
@@ -114,8 +114,8 @@ macro_rules! provide_one {
($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_provided::$name<'tcx> {
+ def_id_arg: rustc_middle::query::query_keys::$name<'tcx>,
+ ) -> rustc_middle::query::query_provided::$name<'tcx> {
let _prof_timer =
$tcx.prof.generic_activity(concat!("metadata_decode_entry_", stringify!($name)));
diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
index 05402a58701..4f280bb9d80 100644
--- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
+++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
@@ -1,6 +1,5 @@
use crate::rmeta::DecodeContext;
use crate::rmeta::EncodeContext;
-use rustc_data_structures::owned_slice::slice_owned;
use rustc_data_structures::owned_slice::OwnedSlice;
use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap};
use rustc_middle::parameterized_over_tcx;
@@ -47,7 +46,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefPathHashMapRef<'static>
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefPathHashMapRef<'static> {
let len = d.read_usize();
let pos = d.position();
- let o = slice_owned(d.blob().clone(), |blob| &blob[pos..pos + len]);
+ let o = d.blob().clone().0.slice(|blob| &blob[pos..pos + len]);
// Although we already have the data we need via the `OwnedSlice`, we still need
// to advance the `DecodeContext`'s position so it's in a valid state after
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 82c66b9dfb9..79eb48a1a31 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -8,7 +8,7 @@ use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::memmap::{Mmap, MmapMut};
use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
-use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator};
+use rustc_data_structures::sync::{join, par_for_each_in, Lrc};
use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
@@ -25,10 +25,10 @@ use rustc_middle::middle::exported_symbols::{
};
use rustc_middle::mir::interpret;
use rustc_middle::query::LocalCrate;
+use rustc_middle::query::Providers;
use rustc_middle::traits::specialization_graph;
use rustc_middle::ty::codec::TyEncoder;
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
use rustc_middle::util::common::to_readable_str;
use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
@@ -862,6 +862,11 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
| DefKind::Macro(_)
| DefKind::Field
| DefKind::Impl { .. } => true,
+ // Tools may want to be able to detect their tool lints on
+ // closures from upstream crates, too. This is used by
+ // https://github.com/model-checking/kani and is not a performance
+ // or maintenance issue for us.
+ DefKind::Closure => true,
DefKind::TyParam
| DefKind::ConstParam
| DefKind::Ctor(..)
@@ -874,7 +879,6 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
| DefKind::ImplTraitPlaceholder
| DefKind::LifetimeParam
| DefKind::GlobalAsm
- | DefKind::Closure
| DefKind::Generator => false,
}
}
@@ -1371,9 +1375,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Therefore, the loop over variants will encode its fields as the adt's children.
}
- for variant in adt_def.variants().iter() {
+ for (idx, variant) in adt_def.variants().iter_enumerated() {
let data = VariantData {
discr: variant.discr,
+ idx,
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
};
@@ -1511,8 +1516,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
if encode_opt {
record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id));
- if tcx.sess.opts.unstable_opts.drop_tracking_mir && let DefKind::Generator = self.tcx.def_kind(def_id) {
- record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- tcx.mir_generator_witnesses(def_id));
+ if tcx.sess.opts.unstable_opts.drop_tracking_mir
+ && let DefKind::Generator = self.tcx.def_kind(def_id)
+ && let Some(witnesses) = tcx.mir_generator_witnesses(def_id)
+ {
+ record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- witnesses);
}
}
if encode_const {
@@ -1637,9 +1645,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
hir::ItemKind::OpaqueTy(ref opaque) => {
self.encode_explicit_item_bounds(def_id);
- self.tables
- .is_type_alias_impl_trait
- .set(def_id.index, matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias));
+ self.tables.is_type_alias_impl_trait.set(
+ def_id.index,
+ matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. }),
+ );
}
hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
self.tables.impl_defaultness.set_some(def_id.index, *defaultness);
@@ -2125,7 +2134,7 @@ fn prefetch_mir(tcx: TyCtxt<'_>) {
return;
}
- par_iter(tcx.mir_keys(())).for_each(|&def_id| {
+ par_for_each_in(tcx.mir_keys(()), |&def_id| {
let (encode_const, encode_opt) = should_encode_mir(tcx, def_id);
if encode_const {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 84f6b7f934d..987a484049f 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -7,7 +7,6 @@ use table::TableBuilder;
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::MetadataRef;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, DocLinkResMap};
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId};
@@ -20,8 +19,8 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
use rustc_middle::mir;
+use rustc_middle::query::Providers;
use rustc_middle::ty::fast_reject::SimplifiedType;
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, ReprOptions, Ty, UnusedGenericParams};
use rustc_middle::ty::{DeducedParamAttrs, GeneratorDiagnosticData, ParameterizedOverTcx, TyCtxt};
use rustc_serialize::opaque::FileEncoder;
@@ -31,6 +30,7 @@ use rustc_span::edition::Edition;
use rustc_span::hygiene::{ExpnIndex, MacroKind};
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span};
+use rustc_target::abi::VariantIdx;
use rustc_target::spec::{PanicStrategy, TargetTriple};
use std::marker::PhantomData;
@@ -394,7 +394,7 @@ define_tables! {
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
mir_generator_witnesses: Table<DefIndex, LazyValue<mir::GeneratorLayout<'static>>>,
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
- thir_abstract_const: Table<DefIndex, LazyValue<ty::Const<'static>>>,
+ thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::Const<'static>>>>,
impl_parent: Table<DefIndex, RawDefId>,
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
constness: Table<DefIndex, hir::Constness>,
@@ -430,6 +430,7 @@ define_tables! {
#[derive(TyEncodable, TyDecodable)]
struct VariantData {
+ idx: VariantIdx,
discr: ty::VariantDiscr,
/// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
ctor: Option<(CtorKind, DefIndex)>,
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index a7d97bd3cf5..7c56af1da41 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -11,6 +11,7 @@ chalk-ir = "0.87.0"
derive_more = "0.99.17"
either = "1.5.0"
gsgdt = "0.1.2"
+field-offset = "0.3.5"
measureme = "10.0.0"
polonius-engine = "0.13.0"
rustc_apfloat = { path = "../rustc_apfloat" }
diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl
index c6bbf2ef0cd..64d511c261a 100644
--- a/compiler/rustc_middle/messages.ftl
+++ b/compiler/rustc_middle/messages.ftl
@@ -39,5 +39,7 @@ middle_strict_coherence_needs_negative_coherence =
to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
.label = due to this attribute
+middle_requires_lang_item = requires `{$name}` lang_item
+
middle_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
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index dc4aa18640f..046186d274c 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -1,5 +1,5 @@
use rustc_macros::Diagnostic;
-use rustc_span::Span;
+use rustc_span::{Span, Symbol};
use crate::ty::Ty;
@@ -74,6 +74,14 @@ pub(crate) struct StrictCoherenceNeedsNegativeCoherence {
}
#[derive(Diagnostic)]
+#[diag(middle_requires_lang_item)]
+pub(crate) struct RequiresLangItem {
+ #[primary_span]
+ pub span: Option<Span>,
+ pub name: Symbol,
+}
+
+#[derive(Diagnostic)]
#[diag(middle_const_not_used_in_type_alias)]
pub(super) struct ConstNotUsedTraitAlias {
pub ct: String,
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 15d672c1408..5bf0938d518 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -5,7 +5,7 @@ use rustc_ast as ast;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
+use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
@@ -150,11 +150,6 @@ impl<'hir> Map<'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));
- }
-
pub fn def_key(self, def_id: LocalDefId) -> DefKey {
// Accessing the DefKey is ok, since it is part of DefPathHash.
self.tcx.definitions_untracked().def_key(def_id)
@@ -502,7 +497,7 @@ impl<'hir> Map<'hir> {
}
#[inline]
- pub fn par_body_owners(self, f: impl Fn(LocalDefId) + Sync + Send) {
+ pub fn par_body_owners(self, f: impl Fn(LocalDefId) + DynSend + DynSync) {
par_for_each_in(&self.tcx.hir_crate_items(()).body_owners[..], |&def_id| f(def_id));
}
@@ -640,7 +635,7 @@ impl<'hir> Map<'hir> {
}
#[inline]
- pub fn par_for_each_module(self, f: impl Fn(LocalDefId) + Sync + Send) {
+ pub fn par_for_each_module(self, f: impl Fn(LocalDefId) + DynSend + DynSync) {
let crate_items = self.tcx.hir_crate_items(());
par_for_each_in(&crate_items.submodules[..], |module| f(module.def_id))
}
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 7770a5e4764..61c9e72db2c 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -6,10 +6,10 @@ pub mod map;
pub mod nested_filter;
pub mod place;
-use crate::ty::query::Providers;
+use crate::query::Providers;
use crate::ty::{EarlyBinder, ImplSubject, TyCtxt};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
+use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::*;
use rustc_query_system::ich::StableHashingContext;
@@ -77,19 +77,19 @@ impl ModuleItems {
self.owners().map(|id| id.def_id)
}
- pub fn par_items(&self, f: impl Fn(ItemId) + Send + Sync) {
+ pub fn par_items(&self, f: impl Fn(ItemId) + DynSend + DynSync) {
par_for_each_in(&self.items[..], |&id| f(id))
}
- pub fn par_trait_items(&self, f: impl Fn(TraitItemId) + Send + Sync) {
+ pub fn par_trait_items(&self, f: impl Fn(TraitItemId) + DynSend + DynSync) {
par_for_each_in(&self.trait_items[..], |&id| f(id))
}
- pub fn par_impl_items(&self, f: impl Fn(ImplItemId) + Send + Sync) {
+ pub fn par_impl_items(&self, f: impl Fn(ImplItemId) + DynSend + DynSync) {
par_for_each_in(&self.impl_items[..], |&id| f(id))
}
- pub fn par_foreign_items(&self, f: impl Fn(ForeignItemId) + Send + Sync) {
+ pub fn par_foreign_items(&self, f: impl Fn(ForeignItemId) + DynSend + DynSync) {
par_for_each_in(&self.foreign_items[..], |&id| f(id))
}
}
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index e9172e767e0..22ee2a8c5e5 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -85,12 +85,7 @@ mod tests;
mod macros;
#[macro_use]
-pub mod query;
-
-#[macro_use]
pub mod arena;
-#[macro_use]
-pub mod dep_graph;
pub(crate) mod error;
pub mod hir;
pub mod infer;
@@ -104,6 +99,11 @@ pub mod ty;
pub mod util;
mod values;
+#[macro_use]
+pub mod query;
+#[macro_use]
+pub mod dep_graph;
+
// Allows macros to refer to this crate as `::rustc_middle`
extern crate self as rustc_middle;
diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs
index 343ea1f00f5..9a633e04ce7 100644
--- a/compiler/rustc_middle/src/middle/lang_items.rs
+++ b/compiler/rustc_middle/src/middle/lang_items.rs
@@ -18,12 +18,8 @@ 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(|err| {
- if let Some(span) = span {
- self.sess.span_fatal(span, err.to_string())
- } else {
- self.sess.fatal(err.to_string())
- }
+ self.lang_items().get(lang_item).unwrap_or_else(|| {
+ self.sess.emit_fatal(crate::error::RequiresLangItem { span, name: lang_item.name() });
})
}
diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs
index 12aef66bcf9..bd859d4d61b 100644
--- a/compiler/rustc_middle/src/middle/limits.rs
+++ b/compiler/rustc_middle/src/middle/limits.rs
@@ -11,7 +11,7 @@
use crate::bug;
use crate::error::LimitInvalid;
-use crate::ty;
+use crate::query::Providers;
use rustc_ast::Attribute;
use rustc_session::Session;
use rustc_session::{Limit, Limits};
@@ -19,7 +19,7 @@ use rustc_span::symbol::{sym, Symbol};
use std::num::IntErrorKind;
-pub fn provide(providers: &mut ty::query::Providers) {
+pub fn provide(providers: &mut Providers) {
providers.limits = |tcx, ()| Limits {
recursion_limit: get_recursion_limit(tcx.hir().krate_attrs(), tcx.sess),
move_size_limit: get_limit(
diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs
index 9c25f3009ba..9bb4570ef14 100644
--- a/compiler/rustc_middle/src/middle/mod.rs
+++ b/compiler/rustc_middle/src/middle/mod.rs
@@ -32,6 +32,6 @@ pub mod region;
pub mod resolve_bound_vars;
pub mod stability;
-pub fn provide(providers: &mut crate::ty::query::Providers) {
+pub fn provide(providers: &mut crate::query::Providers) {
limits::provide(providers);
}
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index e45284ca506..055d8e9a352 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -1,7 +1,8 @@
use super::{AllocId, AllocRange, ConstAlloc, Pointer, Scalar};
use crate::mir::interpret::ConstValue;
-use crate::ty::{layout, query::TyCtxtAt, tls, Ty, ValTree};
+use crate::query::TyCtxtAt;
+use crate::ty::{layout, tls, Ty, ValTree};
use rustc_data_structures::sync::Lock;
use rustc_errors::{pluralize, struct_span_err, DiagnosticBuilder, ErrorGuaranteed};
@@ -15,15 +16,49 @@ use std::{any::Any, backtrace::Backtrace, fmt};
pub enum ErrorHandled {
/// Already reported an error for this evaluation, and the compilation is
/// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`.
- Reported(ErrorGuaranteed),
+ Reported(ReportedErrorInfo),
/// Don't emit an error, the evaluation failed because the MIR was generic
/// and the substs didn't fully monomorphize it.
TooGeneric,
}
impl From<ErrorGuaranteed> for ErrorHandled {
- fn from(err: ErrorGuaranteed) -> ErrorHandled {
- ErrorHandled::Reported(err)
+ #[inline]
+ fn from(error: ErrorGuaranteed) -> ErrorHandled {
+ ErrorHandled::Reported(error.into())
+ }
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
+pub struct ReportedErrorInfo {
+ error: ErrorGuaranteed,
+ is_tainted_by_errors: bool,
+}
+
+impl ReportedErrorInfo {
+ #[inline]
+ pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo {
+ ReportedErrorInfo { is_tainted_by_errors: true, error }
+ }
+
+ /// Returns true if evaluation failed because MIR was tainted by errors.
+ #[inline]
+ pub fn is_tainted_by_errors(self) -> bool {
+ self.is_tainted_by_errors
+ }
+}
+
+impl From<ErrorGuaranteed> for ReportedErrorInfo {
+ #[inline]
+ fn from(error: ErrorGuaranteed) -> ReportedErrorInfo {
+ ReportedErrorInfo { is_tainted_by_errors: false, error }
+ }
+}
+
+impl Into<ErrorGuaranteed> for ReportedErrorInfo {
+ #[inline]
+ fn into(self) -> ErrorGuaranteed {
+ self.error
}
}
@@ -89,7 +124,7 @@ fn print_backtrace(backtrace: &Backtrace) {
impl From<ErrorGuaranteed> for InterpErrorInfo<'_> {
fn from(err: ErrorGuaranteed) -> Self {
- InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err)).into()
+ InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err.into())).into()
}
}
@@ -125,7 +160,7 @@ pub enum InvalidProgramInfo<'tcx> {
/// Resolution can fail if we are in a too generic context.
TooGeneric,
/// Abort in case errors are already reported.
- AlreadyReported(ErrorGuaranteed),
+ AlreadyReported(ReportedErrorInfo),
/// An error occurred during layout computation.
Layout(layout::LayoutError<'tcx>),
/// An error occurred during FnAbi computation: the passed --target lacks FFI support
@@ -144,7 +179,7 @@ impl fmt::Display for InvalidProgramInfo<'_> {
use InvalidProgramInfo::*;
match self {
TooGeneric => write!(f, "encountered overly generic constant"),
- AlreadyReported(ErrorGuaranteed { .. }) => {
+ AlreadyReported(_) => {
write!(
f,
"an error has already been reported elsewhere (this should not usually be printed)"
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index e5a9766c84d..3620385fab1 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -120,8 +120,8 @@ use crate::ty::{self, Instance, Ty, TyCtxt};
pub use self::error::{
struct_error, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult, EvalToConstValueResult,
EvalToValTreeResult, InterpError, InterpErrorInfo, InterpResult, InvalidProgramInfo,
- MachineStopType, ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo,
- UninitBytesAccess, UnsupportedOpInfo,
+ MachineStopType, ReportedErrorInfo, ResourceExhaustionInfo, ScalarSizeMismatch,
+ UndefinedBehaviorInfo, UninitBytesAccess, UnsupportedOpInfo,
};
pub use self::value::{get_slice_bytes, ConstAlloc, ConstValue, Scalar};
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index ed4ee93e97d..f53dc8cb0ec 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -1,9 +1,10 @@
use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId};
use crate::mir;
+use crate::query::{TyCtxtAt, TyCtxtEnsure};
use crate::ty::subst::InternalSubsts;
use crate::ty::visit::TypeVisitableExt;
-use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt};
+use crate::ty::{self, TyCtxt};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_session::lint;
@@ -61,7 +62,7 @@ impl<'tcx> TyCtxt<'tcx> {
self.const_eval_global_id(param_env, cid, span)
}
Ok(None) => Err(ErrorHandled::TooGeneric),
- Err(error_reported) => Err(ErrorHandled::Reported(error_reported)),
+ Err(err) => Err(ErrorHandled::Reported(err.into())),
}
}
@@ -110,7 +111,7 @@ impl<'tcx> TyCtxt<'tcx> {
})
}
Ok(None) => Err(ErrorHandled::TooGeneric),
- Err(error_reported) => Err(ErrorHandled::Reported(error_reported)),
+ Err(err) => Err(ErrorHandled::Reported(err.into())),
}
}
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 858a3d266ea..1da94dd7917 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1111,6 +1111,10 @@ pub struct VarDebugInfo<'tcx> {
/// originated from (starting from 1). Note, if MIR inlining is enabled, then this is the
/// argument number in the original function before it was inlined.
pub argument_index: Option<u16>,
+
+ /// The data represents `name` dereferenced `references` times,
+ /// and not the direct value.
+ pub references: u8,
}
///////////////////////////////////////////////////////////////////////////
@@ -1524,6 +1528,19 @@ impl<V, T> ProjectionElem<V, T> {
}
}
+ /// Returns `true` if the target of this projection always refers to the same memory region
+ /// whatever the state of the program.
+ pub fn is_stable_offset(&self) -> bool {
+ match self {
+ Self::Deref | Self::Index(_) => false,
+ Self::Field(_, _)
+ | Self::OpaqueCast(_)
+ | Self::ConstantIndex { .. }
+ | Self::Subslice { .. }
+ | Self::Downcast(_, _) => true,
+ }
+ }
+
/// Returns `true` if this is a `Downcast` projection with the given `VariantIdx`.
pub fn is_downcast_to(&self, v: VariantIdx) -> bool {
matches!(*self, Self::Downcast(_, x) if x == v)
@@ -1537,8 +1554,11 @@ impl<V, T> ProjectionElem<V, T> {
/// Returns `true` if this is accepted inside `VarDebugInfoContents::Place`.
pub fn can_use_in_debuginfo(&self) -> bool {
match self {
- Self::Deref | Self::Downcast(_, _) | Self::Field(_, _) => true,
- Self::ConstantIndex { .. }
+ Self::ConstantIndex { from_end: false, .. }
+ | Self::Deref
+ | Self::Downcast(_, _)
+ | Self::Field(_, _) => true,
+ Self::ConstantIndex { from_end: true, .. }
| Self::Index(_)
| Self::OpaqueCast(_)
| Self::Subslice { .. } => false,
@@ -1626,18 +1646,7 @@ impl<'tcx> Place<'tcx> {
return self;
}
- let mut v: Vec<PlaceElem<'tcx>>;
-
- let new_projections = if self.projection.is_empty() {
- more_projections
- } else {
- v = Vec::with_capacity(self.projection.len() + more_projections.len());
- v.extend(self.projection);
- v.extend(more_projections);
- &v
- };
-
- Place { local: self.local, projection: tcx.mk_place_elems(new_projections) }
+ self.as_ref().project_deeper(more_projections, tcx)
}
}
@@ -1708,6 +1717,27 @@ impl<'tcx> PlaceRef<'tcx> {
(base, *proj)
})
}
+
+ /// Generates a new place by appending `more_projections` to the existing ones
+ /// and interning the result.
+ pub fn project_deeper(
+ self,
+ more_projections: &[PlaceElem<'tcx>],
+ tcx: TyCtxt<'tcx>,
+ ) -> Place<'tcx> {
+ let mut v: Vec<PlaceElem<'tcx>>;
+
+ let new_projections = if self.projection.is_empty() {
+ more_projections
+ } else {
+ v = Vec::with_capacity(self.projection.len() + more_projections.len());
+ v.extend(self.projection);
+ v.extend(more_projections);
+ &v
+ };
+
+ Place { local: self.local, projection: tcx.mk_place_elems(new_projections) }
+ }
}
impl Debug for Place<'_> {
@@ -2300,7 +2330,7 @@ impl<'tcx> ConstantKind<'tcx> {
if let Some(val) = c.kind().try_eval_for_mir(tcx, param_env) {
match val {
Ok(val) => Self::Val(val, c.ty()),
- Err(_) => Self::Ty(tcx.const_error(self.ty())),
+ Err(guar) => Self::Ty(tcx.const_error(self.ty(), guar)),
}
} else {
self
@@ -2312,9 +2342,7 @@ impl<'tcx> ConstantKind<'tcx> {
match tcx.const_eval_resolve(param_env, uneval, None) {
Ok(val) => Self::Val(val, ty),
Err(ErrorHandled::TooGeneric) => self,
- Err(ErrorHandled::Reported(guar)) => {
- Self::Ty(tcx.const_error_with_guaranteed(ty, guar))
- }
+ Err(ErrorHandled::Reported(guar)) => Self::Ty(tcx.const_error(ty, guar.into())),
}
}
}
@@ -2728,8 +2756,6 @@ pub struct UserTypeProjection {
pub projs: Vec<ProjectionKind>,
}
-impl Copy for ProjectionKind {}
-
impl UserTypeProjection {
pub(crate) fn index(mut self) -> Self {
self.projs.push(ProjectionElem::Index(()));
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index fa8a339631e..62c3d8cf239 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -551,8 +551,13 @@ fn write_scope_tree(
}
let indented_debug_info = format!(
- "{0:1$}debug {2} => {3:?};",
- INDENT, indent, var_debug_info.name, var_debug_info.value,
+ "{0:1$}debug {2} => {3:&<4$}{5:?};",
+ INDENT,
+ indent,
+ var_debug_info.name,
+ "",
+ var_debug_info.references as usize,
+ var_debug_info.value,
);
writeln!(
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 6718605ed0b..596dd80bf48 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -64,7 +64,7 @@
use crate::mir::*;
use crate::ty::subst::SubstsRef;
-use crate::ty::{CanonicalUserTypeAnnotation, Ty};
+use crate::ty::{self, CanonicalUserTypeAnnotation, Ty};
use rustc_span::Span;
macro_rules! make_mir_visitor {
@@ -782,12 +782,12 @@ macro_rules! make_mir_visitor {
fn super_ascribe_user_ty(&mut self,
place: & $($mutability)? Place<'tcx>,
- _variance: $(& $mutability)? ty::Variance,
+ variance: $(& $mutability)? ty::Variance,
user_ty: & $($mutability)? UserTypeProjection,
location: Location) {
self.visit_place(
place,
- PlaceContext::NonUse(NonUseContext::AscribeUserTy),
+ PlaceContext::NonUse(NonUseContext::AscribeUserTy($(* &$mutability *)? variance)),
location
);
self.visit_user_type_projection(user_ty);
@@ -842,6 +842,7 @@ macro_rules! make_mir_visitor {
source_info,
value,
argument_index: _,
+ references: _,
} = var_debug_info;
self.visit_source_info(source_info);
@@ -880,12 +881,11 @@ macro_rules! make_mir_visitor {
) {
let Constant {
span,
- user_ty,
+ user_ty: _, // no visit method for this
literal,
} = constant;
self.visit_span($(& $mutability)? *span);
- drop(user_ty); // no visit method for this
match literal {
ConstantKind::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location),
ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
@@ -1320,7 +1320,7 @@ pub enum NonUseContext {
/// Ending a storage live range.
StorageDead,
/// User type annotation assertions for NLL.
- AscribeUserTy,
+ AscribeUserTy(ty::Variance),
/// The data of a user variable, for debug info.
VarDebugInfo,
}
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index 7d9aea02289..b45f7caaabe 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -82,9 +82,10 @@ impl EraseType for Result<Option<ty::Instance<'_>>, rustc_errors::ErrorGuarantee
[u8; size_of::<Result<Option<ty::Instance<'static>>, rustc_errors::ErrorGuaranteed>>()];
}
-impl EraseType for Result<Option<ty::Const<'_>>, rustc_errors::ErrorGuaranteed> {
- type Result =
- [u8; size_of::<Result<Option<ty::Const<'static>>, rustc_errors::ErrorGuaranteed>>()];
+impl EraseType for Result<Option<ty::EarlyBinder<ty::Const<'_>>>, rustc_errors::ErrorGuaranteed> {
+ type Result = [u8; size_of::<
+ Result<Option<ty::EarlyBinder<ty::Const<'static>>>, rustc_errors::ErrorGuaranteed>,
+ >()];
}
impl EraseType for Result<ty::GenericArg<'_>, traits::query::NoSolution> {
@@ -171,6 +172,10 @@ impl EraseType for ty::Binder<'_, ty::FnSig<'_>> {
type Result = [u8; size_of::<ty::Binder<'static, ty::FnSig<'static>>>()];
}
+impl EraseType for ty::Binder<'_, &'_ ty::List<Ty<'_>>> {
+ type Result = [u8; size_of::<ty::Binder<'static, &'static ty::List<Ty<'static>>>>()];
+}
+
impl<T0, T1> EraseType for (&'_ T0, &'_ T1) {
type Result = [u8; size_of::<(&'static (), &'static ())>()];
}
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index b425c7600ac..21c69662b9e 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -4,13 +4,94 @@
//! ["Queries: demand-driven compilation"](https://rustc-dev-guide.rust-lang.org/query.html).
//! This chapter includes instructions for adding new queries.
-use crate::ty::{self, print::describe_as_module, TyCtxt};
+#![allow(unused_parens)]
+
+use crate::dep_graph;
+use crate::dep_graph::DepKind;
+use crate::infer::canonical::{self, Canonical};
+use crate::lint::LintExpectation;
+use crate::metadata::ModChild;
+use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
+use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
+use crate::middle::lib_features::LibFeatures;
+use crate::middle::privacy::EffectiveVisibilities;
+use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, ResolvedArg};
+use crate::middle::stability::{self, DeprecationEntry};
+use crate::mir;
+use crate::mir::interpret::GlobalId;
+use crate::mir::interpret::{
+ ConstValue, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult,
+};
+use crate::mir::interpret::{LitToConstError, LitToConstInput};
+use crate::mir::mono::CodegenUnit;
+use crate::query::erase::{erase, restore, Erase};
+use crate::query::plumbing::{query_ensure, query_get_at, DynamicQuery};
+use crate::thir;
+use crate::traits::query::{
+ CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
+ CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
+ CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution,
+};
+use crate::traits::query::{
+ DropckConstraint, DropckOutlivesResult, MethodAutoderefStepsResult, NormalizationResult,
+ OutlivesBound,
+};
+use crate::traits::specialization_graph;
+use crate::traits::{self, ImplSource};
+use crate::ty::fast_reject::SimplifiedType;
+use crate::ty::layout::ValidityRequirement;
+use crate::ty::subst::{GenericArg, SubstsRef};
+use crate::ty::util::AlwaysRequiresDrop;
+use crate::ty::GeneratorDiagnosticData;
+use crate::ty::TyCtxtFeed;
+use crate::ty::{
+ self, print::describe_as_module, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt,
+ UnusedGenericParams,
+};
+use rustc_arena::TypedArena;
+use rustc_ast as ast;
+use rustc_ast::expand::allocator::AllocatorKind;
+use rustc_attr as attr;
+use rustc_data_structures::fingerprint::Fingerprint;
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
+use rustc_data_structures::steal::Steal;
+use rustc_data_structures::svh::Svh;
+use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::WorkerLocal;
+use rustc_data_structures::unord::UnordSet;
+use rustc_errors::ErrorGuaranteed;
+use rustc_hir as hir;
+use rustc_hir::def::{DefKind, DocLinkResMap};
+use rustc_hir::def_id::{
+ CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LocalDefIdMap, LocalDefIdSet,
+};
+use rustc_hir::lang_items::{LangItem, LanguageItems};
+use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
+use rustc_index::IndexVec;
+use rustc_query_system::ich::StableHashingContext;
+use rustc_query_system::query::{try_get_cached, CacheSelector, QueryCache, QueryMode, QueryState};
+use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
+use rustc_session::cstore::{CrateDepKind, CrateSource};
+use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
+use rustc_session::lint::LintExpectationId;
+use rustc_session::Limits;
use rustc_span::def_id::LOCAL_CRATE;
+use rustc_span::symbol::Symbol;
+use rustc_span::{Span, DUMMY_SP};
+use rustc_target::abi;
+use rustc_target::spec::PanicStrategy;
+use std::mem;
+use std::ops::Deref;
+use std::path::PathBuf;
+use std::sync::Arc;
pub mod erase;
mod keys;
-pub mod on_disk_cache;
pub use keys::{AsLocalKey, Key, LocalCrate};
+pub mod on_disk_cache;
+#[macro_use]
+pub mod plumbing;
+pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue};
// Each of these queries corresponds to a function pointer field in the
// `Providers` struct for requesting a value of that type, and a method
@@ -236,6 +317,15 @@ rustc_queries! {
cache_on_disk_if { key.is_local() }
}
+ query opaque_types_defined_by(
+ key: LocalDefId
+ ) -> &'tcx [LocalDefId] {
+ desc {
+ |tcx| "computing the opaque types defined by `{}`",
+ tcx.def_path_str(key.to_def_id())
+ }
+ }
+
/// Returns the list of bounds that can be used for
/// `SelectionCandidate::ProjectionCandidate(_)` and
/// `ProjectionTyCandidate::TraitDef`.
@@ -402,7 +492,7 @@ rustc_queries! {
/// Try to build an abstract representation of the given constant.
query thir_abstract_const(
key: DefId
- ) -> Result<Option<ty::Const<'tcx>>, ErrorGuaranteed> {
+ ) -> Result<Option<ty::EarlyBinder<ty::Const<'tcx>>>, ErrorGuaranteed> {
desc {
|tcx| "building an abstract representation for `{}`", tcx.def_path_str(key),
}
@@ -437,7 +527,7 @@ rustc_queries! {
}
}
- query mir_generator_witnesses(key: DefId) -> &'tcx mir::GeneratorLayout<'tcx> {
+ query mir_generator_witnesses(key: DefId) -> &'tcx Option<mir::GeneratorLayout<'tcx>> {
arena_cache
desc { |tcx| "generator witness types for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
@@ -1016,7 +1106,7 @@ rustc_queries! {
desc { "converting literal to mir constant" }
}
- query check_match(key: LocalDefId) {
+ query check_match(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> {
desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) }
cache_on_disk_if { true }
}
@@ -1821,6 +1911,16 @@ rustc_queries! {
desc { "normalizing `{}`", goal.value.value }
}
+ /// Do not call this query directly: invoke `normalize` instead.
+ query normalize_inherent_projection_ty(
+ goal: CanonicalProjectionGoal<'tcx>
+ ) -> Result<
+ &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>,
+ NoSolution,
+ > {
+ desc { "normalizing `{}`", goal.value.value }
+ }
+
/// Do not call this query directly: invoke `try_normalize_erasing_regions` instead.
query try_normalize_generic_arg_after_erasing_regions(
goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>
@@ -2083,3 +2183,6 @@ rustc_queries! {
desc { "check whether two const param are definitely not equal to eachother"}
}
}
+
+rustc_query_append! { define_callbacks! }
+rustc_feedable_queries! { define_feedable! }
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 07d47cae5ee..647f4826876 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -1,89 +1,26 @@
-#![allow(unused_parens)]
-
use crate::dep_graph;
use crate::dep_graph::DepKind;
-use crate::infer::canonical::{self, Canonical};
-use crate::lint::LintExpectation;
-use crate::metadata::ModChild;
-use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
-use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
-use crate::middle::lib_features::LibFeatures;
-use crate::middle::privacy::EffectiveVisibilities;
-use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, ResolvedArg};
-use crate::middle::stability::{self, DeprecationEntry};
-use crate::mir;
-use crate::mir::interpret::GlobalId;
-use crate::mir::interpret::{
- ConstValue, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult,
-};
-use crate::mir::interpret::{LitToConstError, LitToConstInput};
-use crate::mir::mono::CodegenUnit;
-
-use crate::query::erase::{erase, restore, Erase};
use crate::query::on_disk_cache::CacheEncoder;
use crate::query::on_disk_cache::EncodedDepNodeIndex;
use crate::query::on_disk_cache::OnDiskCache;
-use crate::query::{AsLocalKey, Key};
-use crate::thir;
-use crate::traits::query::{
- CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
- CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
- CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution,
+use crate::query::{
+ DynamicQueries, ExternProviders, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates,
};
-use crate::traits::query::{
- DropckConstraint, DropckOutlivesResult, MethodAutoderefStepsResult, NormalizationResult,
- OutlivesBound,
-};
-use crate::traits::specialization_graph;
-use crate::traits::{self, ImplSource};
-use crate::ty::context::TyCtxtFeed;
-use crate::ty::fast_reject::SimplifiedType;
-use crate::ty::layout::ValidityRequirement;
-use crate::ty::subst::{GenericArg, SubstsRef};
-use crate::ty::util::AlwaysRequiresDrop;
-use crate::ty::GeneratorDiagnosticData;
-use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt, UnusedGenericParams};
+use crate::ty::TyCtxt;
+use field_offset::FieldOffset;
use measureme::StringId;
-use rustc_arena::TypedArena;
-use rustc_ast as ast;
-use rustc_ast::expand::allocator::AllocatorKind;
-use rustc_attr as attr;
-use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
-use rustc_data_structures::steal::Steal;
-use rustc_data_structures::svh::Svh;
+use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::AtomicU64;
-use rustc_data_structures::sync::Lrc;
-use rustc_data_structures::sync::WorkerLocal;
-use rustc_data_structures::unord::UnordSet;
-use rustc_errors::ErrorGuaranteed;
-use rustc_hir as hir;
-use rustc_hir::def::{DefKind, DocLinkResMap};
-use rustc_hir::def_id::{
- CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LocalDefIdMap, LocalDefIdSet,
-};
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::hir_id::OwnerId;
-use rustc_hir::lang_items::{LangItem, LanguageItems};
-use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
-use rustc_index::IndexVec;
-use rustc_query_system::ich::StableHashingContext;
+use rustc_query_system::dep_graph::DepNodeIndex;
+use rustc_query_system::dep_graph::SerializedDepNodeIndex;
pub(crate) use rustc_query_system::query::QueryJobId;
use rustc_query_system::query::*;
-use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
-use rustc_session::cstore::{CrateDepKind, CrateSource};
-use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
-use rustc_session::lint::LintExpectationId;
-use rustc_session::Limits;
-use rustc_span::symbol::Symbol;
+use rustc_query_system::HandleCycleError;
use rustc_span::{Span, DUMMY_SP};
-use rustc_target::abi;
-use rustc_target::spec::PanicStrategy;
-
-use std::marker::PhantomData;
-use std::mem;
use std::ops::Deref;
-use std::path::PathBuf;
-use std::sync::Arc;
pub struct QueryKeyStringCache {
pub def_id_cache: FxHashMap<DefId, StringId>,
@@ -103,6 +40,31 @@ pub struct QueryStruct<'tcx> {
Option<fn(TyCtxt<'tcx>, &mut CacheEncoder<'_, 'tcx>, &mut EncodedDepNodeIndex)>,
}
+pub struct DynamicQuery<'tcx, C: QueryCache> {
+ pub name: &'static str,
+ pub eval_always: bool,
+ pub dep_kind: rustc_middle::dep_graph::DepKind,
+ pub handle_cycle_error: HandleCycleError,
+ pub query_state: FieldOffset<QueryStates<'tcx>, QueryState<C::Key, crate::dep_graph::DepKind>>,
+ pub query_cache: FieldOffset<QueryCaches<'tcx>, C>,
+ pub cache_on_disk: fn(tcx: TyCtxt<'tcx>, key: &C::Key) -> bool,
+ pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value,
+ pub compute: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
+ pub can_load_from_disk: bool,
+ pub try_load_from_disk: fn(
+ tcx: TyCtxt<'tcx>,
+ key: &C::Key,
+ prev_index: SerializedDepNodeIndex,
+ index: DepNodeIndex,
+ ) -> Option<C::Value>,
+ pub loadable_from_disk:
+ fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool,
+ pub hash_result: HashResult<C::Value>,
+ pub value_from_cycle_error:
+ fn(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<crate::dep_graph::DepKind>]) -> C::Value,
+ pub format_value: fn(&C::Value) -> String,
+}
+
pub struct QuerySystemFns<'tcx> {
pub engine: QueryEngine,
pub local_providers: Providers,
@@ -120,6 +82,7 @@ pub struct QuerySystem<'tcx> {
pub states: QueryStates<'tcx>,
pub arenas: QueryArenas<'tcx>,
pub caches: QueryCaches<'tcx>,
+ pub dynamic_queries: DynamicQueries<'tcx>,
/// This provides access to the incremental compilation on-disk cache for query results.
/// Do not access this directly. It is only meant to be used by
@@ -130,23 +93,6 @@ pub struct QuerySystem<'tcx> {
pub fns: QuerySystemFns<'tcx>,
pub jobs: AtomicU64,
-
- // Since we erase query value types we tell the typesystem about them with `PhantomData`.
- _phantom_values: QueryPhantomValues<'tcx>,
-}
-
-impl<'tcx> QuerySystem<'tcx> {
- pub fn new(fns: QuerySystemFns<'tcx>, on_disk_cache: Option<OnDiskCache<'tcx>>) -> Self {
- QuerySystem {
- states: Default::default(),
- arenas: Default::default(),
- caches: Default::default(),
- on_disk_cache,
- fns,
- jobs: AtomicU64::new(1),
- _phantom_values: Default::default(),
- }
- }
}
#[derive(Copy, Clone)]
@@ -203,7 +149,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
#[inline]
-fn query_get_at<'tcx, Cache>(
+pub fn query_get_at<'tcx, Cache>(
tcx: TyCtxt<'tcx>,
execute_query: fn(TyCtxt<'tcx>, Span, Cache::Key, QueryMode) -> Option<Cache::Value>,
query_cache: &Cache,
@@ -221,7 +167,7 @@ where
}
#[inline]
-fn query_ensure<'tcx, Cache>(
+pub fn query_ensure<'tcx, Cache>(
tcx: TyCtxt<'tcx>,
execute_query: fn(TyCtxt<'tcx>, Span, Cache::Key, QueryMode) -> Option<Cache::Value>,
query_cache: &Cache,
@@ -428,11 +374,6 @@ macro_rules! define_callbacks {
}
#[derive(Default)]
- pub struct QueryPhantomValues<'tcx> {
- $($(#[$attr])* pub $name: PhantomData<query_values::$name<'tcx>>,)*
- }
-
- #[derive(Default)]
pub struct QueryCaches<'tcx> {
$($(#[$attr])* pub $name: query_storage::$name<'tcx>,)*
}
@@ -490,6 +431,12 @@ macro_rules! define_callbacks {
})*
}
+ pub struct DynamicQueries<'tcx> {
+ $(
+ pub $name: DynamicQuery<'tcx, query_storage::$name<'tcx>>,
+ )*
+ }
+
#[derive(Default)]
pub struct QueryStates<'tcx> {
$(
@@ -627,9 +574,6 @@ macro_rules! define_feedable {
// 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! }
-rustc_feedable_queries! { define_feedable! }
-
mod sealed {
use super::{DefId, LocalDefId, OwnerId};
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 8366567c2c3..2f0b07d4c71 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -281,9 +281,6 @@ pub enum ObligationCauseCode<'tcx> {
/// A type like `Box<Foo<'a> + 'b>` is WF only if `'b: 'a`.
ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),
- /// Obligation incurred due to an object cast.
- ObjectCastObligation(/* Concrete type */ Ty<'tcx>, /* Object type */ Ty<'tcx>),
-
/// Obligation incurred due to a coercion.
Coercion {
source: Ty<'tcx>,
@@ -580,11 +577,7 @@ pub enum SelectionError<'tcx> {
/// After a closure impl has selected, its "outputs" were evaluated
/// (which for closures includes the "input" type params) and they
/// didn't resolve. See `confirm_poly_trait_refs` for more.
- OutputTypeParameterMismatch(
- ty::PolyTraitRef<'tcx>,
- ty::PolyTraitRef<'tcx>,
- ty::error::TypeError<'tcx>,
- ),
+ OutputTypeParameterMismatch(Box<SelectionOutputTypeParameterMismatch<'tcx>>),
/// The trait pointed by `DefId` is not object safe.
TraitNotObjectSafe(DefId),
/// A given constant couldn't be evaluated.
@@ -596,6 +589,13 @@ pub enum SelectionError<'tcx> {
ErrorReporting,
}
+#[derive(Clone, Debug, TypeVisitable, Lift)]
+pub struct SelectionOutputTypeParameterMismatch<'tcx> {
+ pub found_trait_ref: ty::PolyTraitRef<'tcx>,
+ pub expected_trait_ref: ty::PolyTraitRef<'tcx>,
+ pub terr: ty::error::TypeError<'tcx>,
+}
+
/// When performing resolution, it is typically the case that there
/// can be one of three outcomes:
///
diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs
index 468c2c818b2..cbc68fde9d9 100644
--- a/compiler/rustc_middle/src/ty/_match.rs
+++ b/compiler/rustc_middle/src/ty/_match.rs
@@ -83,7 +83,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
(&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(self.tcx().ty_error(guar)),
- _ => relate::super_relate_tys(self, a, b),
+ _ => relate::structurally_relate_tys(self, a, b),
}
}
@@ -109,7 +109,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
_ => {}
}
- relate::super_relate_consts(self, a, b)
+ relate::structurally_relate_consts(self, a, b)
}
fn binders<T>(
diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs
index bfb740ab356..a39631da936 100644
--- a/compiler/rustc_middle/src/ty/abstract_const.rs
+++ b/compiler/rustc_middle/src/ty/abstract_const.rs
@@ -4,7 +4,6 @@ use crate::ty::{
TypeVisitableExt,
};
use rustc_errors::ErrorGuaranteed;
-use rustc_hir::def_id::DefId;
#[derive(Hash, Debug, Clone, Copy, Ord, PartialOrd, PartialEq, Eq)]
#[derive(TyDecodable, TyEncodable, HashStable, TypeVisitable, TypeFoldable)]
@@ -35,12 +34,6 @@ TrivialTypeTraversalAndLiftImpls! {
pub type BoundAbstractConst<'tcx> = Result<Option<EarlyBinder<ty::Const<'tcx>>>, ErrorGuaranteed>;
impl<'tcx> TyCtxt<'tcx> {
- /// Returns a const without substs applied
- pub fn bound_abstract_const(self, uv: DefId) -> BoundAbstractConst<'tcx> {
- let ac = self.thir_abstract_const(uv);
- Ok(ac?.map(|ac| EarlyBinder(ac)))
- }
-
pub fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, ac: T) -> T {
struct Expander<'tcx> {
tcx: TyCtxt<'tcx>,
@@ -59,8 +52,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> {
let ct = match c.kind() {
- ty::ConstKind::Unevaluated(uv) => match self.tcx.bound_abstract_const(uv.def) {
- Err(e) => self.tcx.const_error_with_guaranteed(c.ty(), e),
+ ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) {
+ Err(e) => self.tcx.const_error(c.ty(), e),
Ok(Some(bac)) => {
let substs = self.tcx.erase_regions(uv.substs);
let bac = bac.subst(self.tcx, substs);
diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs
index f29bf92b0ed..be7b2b7ec67 100644
--- a/compiler/rustc_middle/src/ty/closure.rs
+++ b/compiler/rustc_middle/src/ty/closure.rs
@@ -5,6 +5,7 @@ use crate::{mir, ty};
use std::fmt::Write;
+use crate::query::Providers;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, LangItem};
@@ -457,6 +458,6 @@ impl BorrowKind {
}
}
-pub fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers { closure_typeinfo, ..*providers }
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers { closure_typeinfo, ..*providers }
}
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index e7107c28bf4..1a4bd14815f 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -6,7 +6,6 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::LocalDefId;
use rustc_macros::HashStable;
-use std::fmt;
mod int;
mod kind;
@@ -21,15 +20,6 @@ pub use valtree::*;
#[rustc_pass_by_value]
pub struct Const<'tcx>(pub(super) Interned<'tcx, ConstData<'tcx>>);
-impl<'tcx> fmt::Debug for Const<'tcx> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // This reflects what `Const` looked liked before `Interned` was
- // introduced. We print it like this to avoid having to update expected
- // output in a lot of tests.
- write!(f, "Const {{ ty: {:?}, kind: {:?} }}", self.ty(), self.kind())
- }
-}
-
/// Typed constant value.
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, TyEncodable, TyDecodable)]
pub struct ConstData<'tcx> {
@@ -142,9 +132,7 @@ impl<'tcx> Const<'tcx> {
ty::ConstKind::Bound(debruijn, ty::BoundVar::from_u32(index)),
param_ty,
)),
- Some(rbv::ResolvedArg::Error(guar)) => {
- Some(tcx.const_error_with_guaranteed(param_ty, guar))
- }
+ Some(rbv::ResolvedArg::Error(guar)) => Some(tcx.const_error(param_ty, guar)),
arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", expr.hir_id),
}
}
@@ -228,7 +216,7 @@ impl<'tcx> Const<'tcx> {
if let Some(val) = self.kind().try_eval_for_typeck(tcx, param_env) {
match val {
Ok(val) => tcx.mk_const(val, self.ty()),
- Err(guar) => tcx.const_error_with_guaranteed(self.ty(), guar),
+ Err(guar) => tcx.const_error(self.ty(), guar),
}
} else {
// Either the constant isn't evaluatable or ValTree creation failed.
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 1ac2cd13982..1dd4f8a2437 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -42,7 +42,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
}
/// Represents a constant in Rust.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
+#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
#[derive(derive_more::From)]
pub enum ConstKind<'tcx> {
@@ -128,7 +128,7 @@ impl<'tcx> ConstKind<'tcx> {
}
/// An inference variable for a const, for use in const generics.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
+#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
pub enum InferConst<'tcx> {
/// Infer the value of the const.
Var(ty::ConstVid<'tcx>),
@@ -245,7 +245,7 @@ impl<'tcx> ConstKind<'tcx> {
// can leak through `val` into the const we return.
Ok(val) => Some(Ok(EvalResult::ValTree(val?))),
Err(ErrorHandled::TooGeneric) => None,
- Err(ErrorHandled::Reported(e)) => Some(Err(e)),
+ Err(ErrorHandled::Reported(e)) => Some(Err(e.into())),
}
}
EvalMode::Mir => {
@@ -256,7 +256,7 @@ impl<'tcx> ConstKind<'tcx> {
// can leak through `val` into the const we return.
Ok(val) => Some(Ok(EvalResult::ConstVal(val))),
Err(ErrorHandled::TooGeneric) => None,
- Err(ErrorHandled::Reported(e)) => Some(Err(e)),
+ Err(ErrorHandled::Reported(e)) => Some(Err(e.into())),
}
}
}
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index c2550572879..e84d0100a5c 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -14,15 +14,14 @@ use crate::middle::resolve_bound_vars;
use crate::middle::stability;
use crate::mir::interpret::{self, Allocation, ConstAllocation};
use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
-use crate::query::on_disk_cache::OnDiskCache;
+use crate::query::plumbing::QuerySystem;
use crate::query::LocalCrate;
+use crate::query::Providers;
+use crate::query::{IntoQueryParam, TyCtxtAt};
use crate::thir::Thir;
use crate::traits;
use crate::traits::solve;
use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData};
-use crate::ty::query::QuerySystem;
-use crate::ty::query::QuerySystemFns;
-use crate::ty::query::{self, TyCtxtAt};
use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid,
GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy,
@@ -81,8 +80,6 @@ use std::iter;
use std::mem;
use std::ops::{Bound, Deref};
-use super::query::IntoQueryParam;
-
const TINY_CONST_EVAL_LIMIT: Limit = Limit(20);
#[allow(rustc::usage_of_ty_tykind)]
@@ -496,7 +493,7 @@ pub struct GlobalCtxt<'tcx> {
///
/// FIXME(Centril): consider `dyn LintStoreMarker` once
/// we can upcast to `Any` for some additional type safety.
- pub lint_store: Lrc<dyn Any + sync::Sync + sync::Send>,
+ pub lint_store: Lrc<dyn Any + sync::DynSync + sync::DynSend>,
pub dep_graph: DepGraph,
@@ -513,7 +510,7 @@ pub struct GlobalCtxt<'tcx> {
untracked: Untracked,
- pub query_system: query::QuerySystem<'tcx>,
+ pub query_system: QuerySystem<'tcx>,
pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
// Internal caches for metadata decoding. No need to track deps on this.
@@ -648,14 +645,13 @@ impl<'tcx> TyCtxt<'tcx> {
/// reference to the context, to allow formatting values that need it.
pub fn create_global_ctxt(
s: &'tcx Session,
- lint_store: Lrc<dyn Any + sync::Send + sync::Sync>,
+ lint_store: Lrc<dyn Any + sync::DynSend + sync::DynSync>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
untracked: Untracked,
dep_graph: DepGraph,
- on_disk_cache: Option<OnDiskCache<'tcx>>,
query_kinds: &'tcx [DepKindStruct<'tcx>],
- query_system_fns: QuerySystemFns<'tcx>,
+ query_system: QuerySystem<'tcx>,
) -> GlobalCtxt<'tcx> {
let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
s.emit_fatal(err);
@@ -677,7 +673,7 @@ impl<'tcx> TyCtxt<'tcx> {
lifetimes: common_lifetimes,
consts: common_consts,
untracked,
- query_system: QuerySystem::new(query_system_fns, on_disk_cache),
+ query_system,
query_kinds,
ty_rcache: Default::default(),
pred_rcache: Default::default(),
@@ -735,17 +731,13 @@ impl<'tcx> TyCtxt<'tcx> {
/// Like [TyCtxt::ty_error] but for constants, with current `ErrorGuaranteed`
#[track_caller]
- pub fn const_error_with_guaranteed(
- self,
- ty: Ty<'tcx>,
- reported: ErrorGuaranteed,
- ) -> Const<'tcx> {
+ pub fn const_error(self, ty: Ty<'tcx>, reported: ErrorGuaranteed) -> Const<'tcx> {
self.mk_const(ty::ConstKind::Error(reported), ty)
}
/// Like [TyCtxt::ty_error] but for constants.
#[track_caller]
- pub fn const_error(self, ty: Ty<'tcx>) -> Const<'tcx> {
+ pub fn const_error_misc(self, ty: Ty<'tcx>) -> Const<'tcx> {
self.const_error_with_message(
ty,
DUMMY_SP,
@@ -1848,7 +1840,17 @@ impl<'tcx> TyCtxt<'tcx> {
let substs = substs.into_iter().map(Into::into);
#[cfg(debug_assertions)]
{
- let n = self.generics_of(_def_id).count();
+ let generics = self.generics_of(_def_id);
+
+ let n = if let DefKind::AssocTy = self.def_kind(_def_id)
+ && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(_def_id))
+ {
+ // If this is an inherent projection.
+
+ generics.params.len() + 1
+ } else {
+ generics.count()
+ };
assert_eq!(
(n, Some(n)),
substs.size_hint(),
@@ -2009,7 +2011,7 @@ impl<'tcx> TyCtxt<'tcx> {
debug_assert_matches!(
(kind, self.def_kind(alias_ty.def_id)),
(ty::Opaque, DefKind::OpaqueTy)
- | (ty::Projection, DefKind::AssocTy)
+ | (ty::Projection | ty::Inherent, DefKind::AssocTy)
| (ty::Opaque | ty::Projection, DefKind::ImplTraitPlaceholder)
);
self.mk_ty_from_kind(Alias(kind, alias_ty))
@@ -2451,7 +2453,7 @@ pub struct DeducedParamAttrs {
pub read_only: bool,
}
-pub fn provide(providers: &mut ty::query::Providers) {
+pub fn provide(providers: &mut Providers) {
providers.maybe_unused_trait_imports =
|tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
providers.names_imported_by_glob_use = |tcx, id| {
diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs
index fb0d909307e..5c1c419811e 100644
--- a/compiler/rustc_middle/src/ty/context/tls.rs
+++ b/compiler/rustc_middle/src/ty/context/tls.rs
@@ -1,7 +1,7 @@
use super::{GlobalCtxt, TyCtxt};
use crate::dep_graph::TaskDepsRef;
-use crate::ty::query;
+use crate::query::plumbing::QueryJobId;
use rustc_data_structures::sync::{self, Lock};
use rustc_errors::Diagnostic;
#[cfg(not(parallel_compiler))]
@@ -22,7 +22,7 @@ pub struct ImplicitCtxt<'a, 'tcx> {
/// The current query job, if any. This is updated by `JobOwner::start` in
/// `ty::query::plumbing` when executing a query.
- pub query: Option<query::QueryJobId>,
+ pub query: Option<QueryJobId>,
/// Where to store diagnostics for the current query job, if any.
/// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
@@ -94,8 +94,8 @@ where
f(None)
} else {
// We could get an `ImplicitCtxt` pointer from another thread.
- // Ensure that `ImplicitCtxt` is `Sync`.
- sync::assert_sync::<ImplicitCtxt<'_, '_>>();
+ // Ensure that `ImplicitCtxt` is `DynSync`.
+ sync::assert_dyn_sync::<ImplicitCtxt<'_, '_>>();
unsafe { f(Some(downcast(context))) }
}
diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs
index ad930d1e6b6..7895993ccff 100644
--- a/compiler/rustc_middle/src/ty/erase_regions.rs
+++ b/compiler/rustc_middle/src/ty/erase_regions.rs
@@ -1,8 +1,9 @@
+use crate::query::Providers;
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use crate::ty::{self, Ty, TyCtxt, TypeFlags, TypeVisitableExt};
-pub(super) fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers { erase_regions_ty, ..*providers };
+pub(super) fn provide(providers: &mut Providers) {
+ *providers = Providers { erase_regions_ty, ..*providers };
}
fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 1be61e16dbe..49ab9b79e96 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -265,7 +265,7 @@ impl<'tcx> Ty<'tcx> {
ty::Infer(ty::FreshTy(_)) => "fresh type".into(),
ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(),
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
- ty::Alias(ty::Projection, _) => "associated type".into(),
+ ty::Alias(ty::Projection | ty::Inherent, _) => "associated type".into(),
ty::Param(p) => format!("type parameter `{p}`").into(),
ty::Alias(ty::Opaque, ..) => if tcx.ty_is_opaque_future(self) { "future".into() } else { "opaque type".into() },
ty::Error(_) => "type error".into(),
@@ -312,7 +312,7 @@ impl<'tcx> Ty<'tcx> {
ty::Tuple(..) => "tuple".into(),
ty::Placeholder(..) => "higher-ranked type".into(),
ty::Bound(..) => "bound type variable".into(),
- ty::Alias(ty::Projection, _) => "associated type".into(),
+ ty::Alias(ty::Projection | ty::Inherent, _) => "associated type".into(),
ty::Param(_) => "type parameter".into(),
ty::Alias(ty::Opaque, ..) => "opaque type".into(),
}
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 68002bfcfbd..d64875a9f00 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -176,14 +176,14 @@ impl FlagComputation {
self.add_substs(substs);
}
- &ty::Alias(ty::Projection, data) => {
- self.add_flags(TypeFlags::HAS_TY_PROJECTION);
- self.add_alias_ty(data);
- }
+ &ty::Alias(kind, data) => {
+ self.add_flags(match kind {
+ ty::Projection => TypeFlags::HAS_TY_PROJECTION,
+ ty::Inherent => TypeFlags::HAS_TY_INHERENT,
+ ty::Opaque => TypeFlags::HAS_TY_OPAQUE,
+ });
- &ty::Alias(ty::Opaque, ty::AliasTy { substs, .. }) => {
- self.add_flags(TypeFlags::HAS_TY_OPAQUE);
- self.add_substs(substs);
+ self.add_alias_ty(data);
}
&ty::Dynamic(obj, r, _) => {
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index baef4ffeda7..99174bae3f6 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -103,7 +103,7 @@ impl GenericParamDef {
ty::GenericParamDefKind::Lifetime => tcx.mk_re_error_misc().into(),
ty::GenericParamDefKind::Type { .. } => tcx.ty_error_misc().into(),
ty::GenericParamDefKind::Const { .. } => {
- tcx.const_error(tcx.type_of(self.def_id).subst(tcx, preceding_substs)).into()
+ tcx.const_error_misc(tcx.type_of(self.def_id).subst(tcx, preceding_substs)).into()
}
}
}
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index 92a040068dd..4223502848e 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
@@ -43,6 +43,7 @@
//! This code should only compile in modules where the uninhabitedness of `Foo`
//! is visible.
+use crate::query::Providers;
use crate::ty::context::TyCtxt;
use crate::ty::{self, DefId, Ty, VariantDef, Visibility};
@@ -52,9 +53,8 @@ pub mod inhabited_predicate;
pub use inhabited_predicate::InhabitedPredicate;
-pub(crate) fn provide(providers: &mut ty::query::Providers) {
- *providers =
- ty::query::Providers { inhabited_predicate_adt, inhabited_predicate_type, ..*providers };
+pub(crate) fn provide(providers: &mut Providers) {
+ *providers = Providers { inhabited_predicate_adt, inhabited_predicate_type, ..*providers };
}
/// Returns an `InhabitedPredicate` that is generic over type parameters and
@@ -113,6 +113,12 @@ impl<'tcx> Ty<'tcx> {
}
Never => InhabitedPredicate::False,
Param(_) | Alias(ty::Projection, _) => InhabitedPredicate::GenericType(self),
+ // FIXME(inherent_associated_types): Most likely we can just map to `GenericType` like above.
+ // However it's unclear if the substs passed to `InhabitedPredicate::subst` are of the correct
+ // format, i.e. don't contain parent substs. If you hit this case, please verify this beforehand.
+ Alias(ty::Inherent, _) => {
+ bug!("unimplemented: inhabitedness checking for inherent projections")
+ }
Tuple(tys) if tys.is_empty() => InhabitedPredicate::True,
// use a query for more complex cases
Adt(..) | Array(..) | Tuple(_) => tcx.inhabited_predicate_type(self),
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index f2a2e67cf82..ba91e5aea5a 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1,5 +1,6 @@
use crate::fluent_generated as fluent;
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
+use crate::query::TyCtxtAt;
use crate::ty::normalize_erasing_regions::NormalizationError;
use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitableExt};
use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic};
@@ -324,7 +325,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
let non_zero = !ty.is_unsafe_ptr();
let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
match tail.kind() {
- ty::Param(_) | ty::Alias(ty::Projection, _) => {
+ ty::Param(_) | ty::Alias(ty::Projection | ty::Inherent, _) => {
debug_assert!(tail.has_non_region_param());
Ok(SizeSkeleton::Pointer { non_zero, tail: tcx.erase_regions(tail) })
}
@@ -543,20 +544,20 @@ impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> {
}
}
-impl<'tcx> HasDataLayout for ty::query::TyCtxtAt<'tcx> {
+impl<'tcx> HasDataLayout for TyCtxtAt<'tcx> {
#[inline]
fn data_layout(&self) -> &TargetDataLayout {
&self.data_layout
}
}
-impl<'tcx> HasTargetSpec for ty::query::TyCtxtAt<'tcx> {
+impl<'tcx> HasTargetSpec for TyCtxtAt<'tcx> {
fn target_spec(&self) -> &Target {
&self.sess.target
}
}
-impl<'tcx> HasTyCtxt<'tcx> for ty::query::TyCtxtAt<'tcx> {
+impl<'tcx> HasTyCtxt<'tcx> for TyCtxtAt<'tcx> {
#[inline]
fn tcx(&self) -> TyCtxt<'tcx> {
**self
@@ -683,7 +684,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxt<'tcx>> {
}
}
-impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> {
+impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxtAt<'tcx>> {
type LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;
#[inline]
diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs
index 30f036e471c..71911a5a618 100644
--- a/compiler/rustc_middle/src/ty/list.rs
+++ b/compiler/rustc_middle/src/ty/list.rs
@@ -199,6 +199,12 @@ impl<'a, T: Copy> IntoIterator for &'a List<T> {
unsafe impl<T: Sync> Sync for List<T> {}
+// We need this since `List` uses extern type `OpaqueListContents`.
+#[cfg(parallel_compiler)]
+use rustc_data_structures::sync::DynSync;
+#[cfg(parallel_compiler)]
+unsafe impl<T: DynSync> DynSync for List<T> {}
+
// Safety:
// Layouts of `Equivalent<T>` and `List<T>` are the same, modulo opaque tail,
// thus aligns of `Equivalent<T>` and `List<T>` must be the same.
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 88b084bbccb..be0d1e61a46 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -21,6 +21,7 @@ use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
use crate::metadata::ModChild;
use crate::middle::privacy::EffectiveVisibilities;
use crate::mir::{Body, GeneratorLayout};
+use crate::query::Providers;
use crate::traits::{self, Reveal};
use crate::ty;
use crate::ty::fast_reject::SimplifiedType;
@@ -121,7 +122,6 @@ pub mod inhabitedness;
pub mod layout;
pub mod normalize_erasing_regions;
pub mod print;
-pub mod query;
pub mod relate;
pub mod subst;
pub mod trait_def;
@@ -1004,7 +1004,7 @@ impl<'tcx> Term<'tcx> {
match self.unpack() {
TermKind::Ty(ty) => match ty.kind() {
ty::Alias(kind, alias_ty) => match kind {
- AliasKind::Projection => Some(*alias_ty),
+ AliasKind::Projection | AliasKind::Inherent => Some(*alias_ty),
AliasKind::Opaque => None,
},
_ => None,
@@ -1070,6 +1070,24 @@ impl ParamTerm {
}
}
+#[derive(Copy, Clone, Eq, PartialEq, Debug)]
+pub enum TermVid<'tcx> {
+ Ty(ty::TyVid),
+ Const(ty::ConstVid<'tcx>),
+}
+
+impl From<ty::TyVid> for TermVid<'_> {
+ fn from(value: ty::TyVid) -> Self {
+ TermVid::Ty(value)
+ }
+}
+
+impl<'tcx> From<ty::ConstVid<'tcx>> for TermVid<'tcx> {
+ fn from(value: ty::ConstVid<'tcx>) -> Self {
+ TermVid::Const(value)
+ }
+}
+
/// This kind of predicate has no *direct* correspondent in the
/// syntax, but it roughly corresponds to the syntactic forms:
///
@@ -2476,6 +2494,18 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
+ /// Returns the `DefId` of the item within which the `impl Trait` is declared.
+ /// For type-alias-impl-trait this is the `type` alias.
+ /// For impl-trait-in-assoc-type this is the assoc type.
+ /// For return-position-impl-trait this is the function.
+ pub fn impl_trait_parent(self, mut def_id: LocalDefId) -> LocalDefId {
+ // Find the surrounding item (type alias or assoc type)
+ while let DefKind::OpaqueTy = self.def_kind(def_id) {
+ def_id = self.local_parent(def_id);
+ }
+ def_id
+ }
+
pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
if self.def_kind(def_id) != DefKind::AssocFn {
return false;
@@ -2520,7 +2550,7 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<LocalDefId>
hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
Some(parent)
}
- hir::OpaqueTyOrigin::TyAlias => None,
+ hir::OpaqueTyOrigin::TyAlias { .. } => None,
};
}
}
@@ -2578,7 +2608,7 @@ pub fn ast_uint_ty(uty: UintTy) -> ast::UintTy {
}
}
-pub fn provide(providers: &mut ty::query::Providers) {
+pub fn provide(providers: &mut Providers) {
closure::provide(providers);
context::provide(providers);
erase_regions::provide(providers);
@@ -2587,7 +2617,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
print::provide(providers);
super::util::bug::provide(providers);
super::middle::provide(providers);
- *providers = ty::query::Providers {
+ *providers = Providers {
trait_impls_of: trait_def::trait_impls_of_provider,
incoherent_impls: trait_def::incoherent_impls_provider,
const_param_default: consts::const_param_default,
diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
index 9332b0430ff..a0c8d299f48 100644
--- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
+++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
@@ -32,7 +32,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))]
+ #[tracing::instrument(level = "debug", skip(self, param_env), ret)]
pub fn normalize_erasing_regions<T>(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T
where
T: TypeFoldable<TyCtxt<'tcx>>,
diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs
index 72710b78c93..1b336b7bfc6 100644
--- a/compiler/rustc_middle/src/ty/opaque_types.rs
+++ b/compiler/rustc_middle/src/ty/opaque_types.rs
@@ -207,14 +207,16 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
Some(GenericArgKind::Const(c1)) => c1,
Some(u) => panic!("const mapped to unexpected kind: {:?}", u),
None => {
- if !self.ignore_errors {
- self.tcx.sess.emit_err(ConstNotUsedTraitAlias {
+ let guar = self
+ .tcx
+ .sess
+ .create_err(ConstNotUsedTraitAlias {
ct: ct.to_string(),
span: self.span,
- });
- }
+ })
+ .emit_unless(self.ignore_errors);
- self.interner().const_error(ct.ty())
+ self.interner().const_error(ct.ty(), guar)
}
}
}
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index b7e780b94ef..4491d78648f 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1,5 +1,6 @@
use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
-use crate::ty::query::IntoQueryParam;
+use crate::query::IntoQueryParam;
+use crate::query::Providers;
use crate::ty::{
self, ConstInt, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable,
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
@@ -702,7 +703,7 @@ pub trait PrettyPrinter<'tcx>:
ty::Error(_) => p!("[type error]"),
ty::Param(ref param_ty) => p!(print(param_ty)),
ty::Bound(debruijn, bound_ty) => match bound_ty.kind {
- ty::BoundTyKind::Anon => self.pretty_print_bound_var(debruijn, bound_ty.var)?,
+ ty::BoundTyKind::Anon => debug_bound_var(&mut self, debruijn, bound_ty.var)?,
ty::BoundTyKind::Param(_, s) => match self.should_print_verbose() {
true if debruijn == ty::INNERMOST => p!(write("^{}", s)),
true => p!(write("^{}_{}", debruijn.index(), s)),
@@ -729,7 +730,7 @@ pub trait PrettyPrinter<'tcx>:
ty::Foreign(def_id) => {
p!(print_def_path(def_id, &[]));
}
- ty::Alias(ty::Projection, ref data) => {
+ ty::Alias(ty::Projection | ty::Inherent, ref data) => {
if !(self.should_print_verbose() || NO_QUERIES.with(|q| q.get()))
&& self.tcx().is_impl_trait_in_trait(data.def_id)
{
@@ -740,7 +741,7 @@ pub trait PrettyPrinter<'tcx>:
}
ty::Placeholder(placeholder) => match placeholder.bound.kind {
ty::BoundTyKind::Anon => {
- self.pretty_print_placeholder_var(placeholder.universe, placeholder.bound.var)?
+ debug_placeholder_var(&mut self, placeholder.universe, placeholder.bound.var)?;
}
ty::BoundTyKind::Param(_, name) => p!(write("{}", name)),
},
@@ -1163,30 +1164,6 @@ pub trait PrettyPrinter<'tcx>:
traits.entry(trait_ref).or_default().extend(proj_ty);
}
- fn pretty_print_bound_var(
- &mut self,
- debruijn: ty::DebruijnIndex,
- var: ty::BoundVar,
- ) -> Result<(), Self::Error> {
- if debruijn == ty::INNERMOST {
- write!(self, "^{}", var.index())
- } else {
- write!(self, "^{}_{}", debruijn.index(), var.index())
- }
- }
-
- fn pretty_print_placeholder_var(
- &mut self,
- ui: ty::UniverseIndex,
- var: ty::BoundVar,
- ) -> Result<(), Self::Error> {
- if ui == ty::UniverseIndex::ROOT {
- write!(self, "!{}", var.index())
- } else {
- write!(self, "!{}_{}", ui.index(), var.index())
- }
- }
-
fn ty_infer_name(&self, _: ty::TyVid) -> Option<Symbol> {
None
}
@@ -1320,7 +1297,7 @@ pub trait PrettyPrinter<'tcx>:
define_scoped_cx!(self);
if self.should_print_verbose() {
- p!(write("Const({:?}: {:?})", ct.kind(), ct.ty()));
+ p!(write("{:?}", ct));
return Ok(self);
}
@@ -1379,9 +1356,11 @@ pub trait PrettyPrinter<'tcx>:
}
ty::ConstKind::Bound(debruijn, bound_var) => {
- self.pretty_print_bound_var(debruijn, bound_var)?
+ debug_bound_var(&mut self, debruijn, bound_var)?
}
- ty::ConstKind::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
+ ty::ConstKind::Placeholder(placeholder) => {
+ debug_placeholder_var(&mut self, placeholder.universe, placeholder.bound)?;
+ },
// FIXME(generic_const_exprs):
// write out some legible representation of an abstract const?
ty::ConstKind::Expr(_) => p!("[const expr]"),
@@ -3054,8 +3033,8 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
map
}
-pub fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers { trimmed_def_paths, ..*providers };
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers { trimmed_def_paths, ..*providers };
}
#[derive(Default)]
@@ -3066,3 +3045,27 @@ pub struct OpaqueFnEntry<'tcx> {
fn_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
return_ty: Option<ty::Binder<'tcx, Term<'tcx>>>,
}
+
+pub fn debug_bound_var<T: std::fmt::Write>(
+ fmt: &mut T,
+ debruijn: ty::DebruijnIndex,
+ var: ty::BoundVar,
+) -> Result<(), std::fmt::Error> {
+ if debruijn == ty::INNERMOST {
+ write!(fmt, "^{}", var.index())
+ } else {
+ write!(fmt, "^{}_{}", debruijn.index(), var.index())
+ }
+}
+
+pub fn debug_placeholder_var<T: std::fmt::Write>(
+ fmt: &mut T,
+ universe: ty::UniverseIndex,
+ bound: ty::BoundVar,
+) -> Result<(), std::fmt::Error> {
+ if universe == ty::UniverseIndex::ROOT {
+ write!(fmt, "!{}", bound.index())
+ } else {
+ write!(fmt, "!{}_{}", universe.index(), bound.index())
+ }
+}
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 7f28ed6c263..3bbe6a23b66 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -388,24 +388,24 @@ impl<'tcx> Relate<'tcx> for Ty<'tcx> {
}
}
-/// The main "type relation" routine. Note that this does not handle
-/// inference artifacts, so you should filter those out before calling
-/// it.
-pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
+/// Relates `a` and `b` structurally, calling the relation for all nested values.
+/// Any semantic equality, e.g. of projections, and inference variables have to be
+/// handled by the caller.
+pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
relation: &mut R,
a: Ty<'tcx>,
b: Ty<'tcx>,
) -> RelateResult<'tcx, Ty<'tcx>> {
let tcx = relation.tcx();
- debug!("super_relate_tys: a={:?} b={:?}", a, b);
+ debug!("structurally_relate_tys: a={:?} b={:?}", a, b);
match (a.kind(), b.kind()) {
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
// The caller should handle these cases!
- bug!("var types encountered in super_relate_tys")
+ bug!("var types encountered in structurally_relate_tys")
}
(ty::Bound(..), _) | (_, ty::Bound(..)) => {
- bug!("bound types encountered in super_relate_tys")
+ bug!("bound types encountered in structurally_relate_tys")
}
(&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(tcx.ty_error(guar)),
@@ -550,6 +550,11 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
Ok(tcx.mk_projection(projection_ty.def_id, projection_ty.substs))
}
+ (&ty::Alias(ty::Inherent, a_data), &ty::Alias(ty::Inherent, b_data)) => {
+ let alias_ty = relation.relate(a_data, b_data)?;
+ Ok(tcx.mk_alias(ty::Inherent, tcx.mk_alias_ty(alias_ty.def_id, alias_ty.substs)))
+ }
+
(
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, substs: a_substs, .. }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, substs: b_substs, .. }),
@@ -570,15 +575,18 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
}
}
-/// The main "const relation" routine. Note that this does not handle
-/// inference artifacts, so you should filter those out before calling
-/// it.
-pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
+/// Relates `a` and `b` structurally, calling the relation for all nested values.
+/// Any semantic equality, e.g. of unevaluated consts, and inference variables have
+/// to be handled by the caller.
+///
+/// FIXME: This is not totally structual, which probably should be fixed.
+/// See the HACKs below.
+pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
relation: &mut R,
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);
+ debug!("{}.structurally_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b);
let tcx = relation.tcx();
// HACK(const_generics): We still need to eagerly evaluate consts when
@@ -597,7 +605,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
b = tcx.expand_abstract_consts(b);
}
- debug!("{}.super_relate_consts(normed_a = {:?}, normed_b = {:?})", relation.tag(), a, b);
+ debug!("{}.structurally_relate_consts(normed_a = {:?}, normed_b = {:?})", relation.tag(), a, b);
// Currently, the values that can be unified are primitive types,
// and those that derive both `PartialEq` and `Eq`, corresponding
@@ -605,7 +613,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
let is_match = match (a.kind(), b.kind()) {
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
// The caller should handle these cases!
- bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
+ bug!("var types encountered in structurally_relate_consts: {:?} {:?}", a, b)
}
(ty::ConstKind::Error(_), _) => return Ok(a),
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 29a3bc8bb97..16cb6c91046 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -192,6 +192,44 @@ impl<'tcx> fmt::Debug for AliasTy<'tcx> {
}
}
+impl<'tcx> fmt::Debug for ty::InferConst<'tcx> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ InferConst::Var(var) => write!(f, "{var:?}"),
+ InferConst::Fresh(var) => write!(f, "Fresh({var:?})"),
+ }
+ }
+}
+
+impl<'tcx> fmt::Debug for ty::Const<'tcx> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // This reflects what `Const` looked liked before `Interned` was
+ // introduced. We print it like this to avoid having to update expected
+ // output in a lot of tests.
+ write!(f, "Const {{ ty: {:?}, kind: {:?} }}", self.ty(), self.kind())
+ }
+}
+
+impl<'tcx> fmt::Debug for ty::ConstKind<'tcx> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ use ty::ConstKind::*;
+ match self {
+ Param(param) => write!(f, "{param:?}"),
+ Infer(var) => write!(f, "{var:?}"),
+ Bound(debruijn, var) => ty::print::debug_bound_var(f, *debruijn, *var),
+ Placeholder(placeholder) => {
+ ty::print::debug_placeholder_var(f, placeholder.universe, placeholder.bound)
+ }
+ Unevaluated(uv) => {
+ f.debug_tuple("Unevaluated").field(&uv.substs).field(&uv.def).finish()
+ }
+ Value(valtree) => write!(f, "{valtree:?}"),
+ Error(_) => write!(f, "[const error]"),
+ Expr(expr) => write!(f, "{expr:?}"),
+ }
+ }
+}
+
///////////////////////////////////////////////////////////////////////////
// Atomic structs
//
@@ -204,6 +242,7 @@ CloneLiftImpls! {
(),
bool,
usize,
+ u8,
u16,
u32,
u64,
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 646384eebc8..e6d51c4ec97 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1190,9 +1190,9 @@ where
/// Represents the projection of an associated type.
///
-/// For a projection, this would be `<Ty as Trait<...>>::N`.
-///
-/// For an opaque type, there is no explicit syntax.
+/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
+/// * For an inherent projection, this would be `Ty::N<...>`.
+/// * For an opaque type, there is no explicit syntax.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct AliasTy<'tcx> {
@@ -1201,12 +1201,16 @@ pub struct AliasTy<'tcx> {
/// For a projection, these are the substitutions for the trait and the
/// GAT substitutions, if there are any.
///
+ /// For an inherent projection, they consist of the self type and the GAT substitutions,
+ /// if there are any.
+ ///
/// For RPIT the substitutions are for the generics of the function,
/// while for TAIT it is used for the generic parameters of the alias.
pub substs: SubstsRef<'tcx>,
- /// The `DefId` of the `TraitItem` for the associated type `N` if this is a projection,
- /// or the `OpaqueType` item if this is an opaque.
+ /// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether
+ /// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if
+ /// this is an opaque.
///
/// During codegen, `tcx.type_of(def_id)` can be used to get the type of the
/// underlying type if the type is an opaque.
@@ -1224,6 +1228,7 @@ pub struct AliasTy<'tcx> {
impl<'tcx> AliasTy<'tcx> {
pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind {
match tcx.def_kind(self.def_id) {
+ DefKind::AssocTy if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) => ty::Inherent,
DefKind::AssocTy | DefKind::ImplTraitPlaceholder => ty::Projection,
DefKind::OpaqueTy => ty::Opaque,
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
@@ -1237,6 +1242,17 @@ impl<'tcx> AliasTy<'tcx> {
/// The following methods work only with associated type projections.
impl<'tcx> AliasTy<'tcx> {
+ pub fn self_ty(self) -> Ty<'tcx> {
+ self.substs.type_at(0)
+ }
+
+ pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
+ tcx.mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter().skip(1)))
+ }
+}
+
+/// The following methods work only with trait associated type projections.
+impl<'tcx> AliasTy<'tcx> {
pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId {
match tcx.def_kind(self.def_id) {
DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id),
@@ -1249,7 +1265,7 @@ impl<'tcx> AliasTy<'tcx> {
/// Extracts the underlying trait reference and own substs from this projection.
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
- /// then this function would return a `T: Iterator` trait reference and `['a]` as the own substs
+ /// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own substs
pub fn trait_ref_and_own_substs(
self,
tcx: TyCtxt<'tcx>,
@@ -1274,13 +1290,28 @@ impl<'tcx> AliasTy<'tcx> {
let def_id = self.trait_def_id(tcx);
ty::TraitRef::new(tcx, def_id, self.substs.truncate_to(tcx, tcx.generics_of(def_id)))
}
+}
- pub fn self_ty(self) -> Ty<'tcx> {
- self.substs.type_at(0)
- }
+/// The following methods work only with inherent associated type projections.
+impl<'tcx> AliasTy<'tcx> {
+ /// Transform the substitutions to have the given `impl` substs as the base and the GAT substs on top of that.
+ ///
+ /// Does the following transformation:
+ ///
+ /// ```text
+ /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m]
+ ///
+ /// I_i impl subst
+ /// P_j GAT subst
+ /// ```
+ pub fn rebase_substs_onto_impl(
+ self,
+ impl_substs: ty::SubstsRef<'tcx>,
+ tcx: TyCtxt<'tcx>,
+ ) -> ty::SubstsRef<'tcx> {
+ debug_assert_eq!(self.kind(tcx), ty::Inherent);
- pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
- tcx.mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter().skip(1)))
+ tcx.mk_substs_from_iter(impl_substs.into_iter().chain(self.substs.into_iter().skip(1)))
}
}
@@ -1677,7 +1708,9 @@ impl<'tcx> Region<'tcx> {
ty::ReErased => {
flags = flags | TypeFlags::HAS_RE_ERASED;
}
- ty::ReError(_) => {}
+ ty::ReError(_) => {
+ flags = flags | TypeFlags::HAS_FREE_REGIONS;
+ }
}
debug!("type_flags({:?}) = {:?}", self, flags);
@@ -2335,13 +2368,11 @@ impl<'tcx> Ty<'tcx> {
ty::Adt(def, _substs) => def.sized_constraint(tcx).0.is_empty(),
- ty::Alias(..) | ty::Param(_) => false,
+ ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => false,
ty::Infer(ty::TyVar(_)) => false,
- ty::Bound(..)
- | ty::Placeholder(..)
- | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
+ ty::Bound(..) | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("`is_trivially_sized` applied to unexpected type: {:?}", self)
}
}
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index e5b2d342452..eb903ebfd99 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -2,6 +2,7 @@
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::mir;
+use crate::query::Providers;
use crate::ty::layout::IntegerExt;
use crate::ty::{
self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
@@ -34,9 +35,14 @@ pub struct Discr<'tcx> {
/// Used as an input to [`TyCtxt::uses_unique_generic_params`].
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum IgnoreRegions {
- Yes,
+pub enum CheckRegions {
No,
+ /// Only permit early bound regions. This is useful for Adts which
+ /// can never have late bound regions.
+ OnlyEarlyBound,
+ /// Permit both late bound and early bound regions. Use this for functions,
+ /// which frequently have late bound regions.
+ Bound,
}
#[derive(Copy, Clone, Debug)]
@@ -468,21 +474,28 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn uses_unique_generic_params(
self,
substs: SubstsRef<'tcx>,
- ignore_regions: IgnoreRegions,
+ ignore_regions: CheckRegions,
) -> Result<(), NotUniqueParam<'tcx>> {
let mut seen = GrowableBitSet::default();
+ let mut seen_late = FxHashSet::default();
for arg in substs {
match arg.unpack() {
- GenericArgKind::Lifetime(lt) => {
- if ignore_regions == IgnoreRegions::No {
- let ty::ReEarlyBound(p) = lt.kind() else {
- return Err(NotUniqueParam::NotParam(lt.into()))
- };
+ GenericArgKind::Lifetime(lt) => match (ignore_regions, lt.kind()) {
+ (CheckRegions::Bound, ty::ReLateBound(di, reg)) => {
+ if !seen_late.insert((di, reg)) {
+ return Err(NotUniqueParam::DuplicateParam(lt.into()));
+ }
+ }
+ (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, ty::ReEarlyBound(p)) => {
if !seen.insert(p.index) {
return Err(NotUniqueParam::DuplicateParam(lt.into()));
}
}
- }
+ (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, _) => {
+ return Err(NotUniqueParam::NotParam(lt.into()));
+ }
+ (CheckRegions::No, _) => {}
+ },
GenericArgKind::Type(t) => match t.kind() {
ty::Param(p) => {
if !seen.insert(p.index) {
@@ -655,10 +668,10 @@ impl<'tcx> TyCtxt<'tcx> {
self,
def_id: DefId,
) -> impl Iterator<Item = ty::EarlyBinder<Ty<'tcx>>> {
- let generator_layout = &self.mir_generator_witnesses(def_id);
+ let generator_layout = self.mir_generator_witnesses(def_id);
generator_layout
- .field_tys
- .iter()
+ .as_ref()
+ .map_or_else(|| [].iter(), |l| l.field_tys.iter())
.filter(|decl| !decl.ignore_for_traits)
.map(|decl| ty::EarlyBinder(decl.ty))
}
@@ -1253,7 +1266,7 @@ pub enum ExplicitSelf<'tcx> {
impl<'tcx> ExplicitSelf<'tcx> {
/// Categorizes an explicit self declaration like `self: SomeType`
- /// into either `self`, `&self`, `&mut self`, `Box<self>`, or
+ /// into either `self`, `&self`, `&mut self`, `Box<Self>`, or
/// `Other`.
/// This is mainly used to require the arbitrary_self_types feature
/// in the case of `Other`, to improve error messages in the common cases,
@@ -1472,8 +1485,8 @@ pub fn is_intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic)
}
-pub fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers {
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers {
reveal_opaque_types_in_bounds,
is_doc_hidden,
is_doc_notable_trait,
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs
index 5eaa58d69ed..520bb55e031 100644
--- a/compiler/rustc_middle/src/ty/visit.rs
+++ b/compiler/rustc_middle/src/ty/visit.rs
@@ -49,6 +49,9 @@ pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> {
fn has_projections(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PROJECTION)
}
+ fn has_inherent_projections(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_TY_INHERENT)
+ }
fn has_opaque_types(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
}
diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs
index 3dfd0824f98..43ee0343f5a 100644
--- a/compiler/rustc_middle/src/util/bug.rs
+++ b/compiler/rustc_middle/src/util/bug.rs
@@ -48,6 +48,6 @@ pub fn trigger_delay_span_bug(tcx: TyCtxt<'_>, key: rustc_hir::def_id::DefId) {
);
}
-pub fn provide(providers: &mut crate::ty::query::Providers) {
- *providers = crate::ty::query::Providers { trigger_delay_span_bug, ..*providers };
+pub fn provide(providers: &mut crate::query::Providers) {
+ *providers = crate::query::Providers { trigger_delay_span_bug, ..*providers };
}
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index 931fe1b2433..b74422708ce 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -154,6 +154,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset))))
},
@call("mir_len", args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
+ @call("mir_copy_for_deref", args) => Ok(Rvalue::CopyForDeref(self.parse_place(args[0])?)),
ExprKind::Borrow { borrow_kind, arg } => Ok(
Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
),
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 59549435233..4d99ab4b0ec 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -52,7 +52,7 @@ pub fn as_constant_inner<'tcx>(
match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }) {
Ok(c) => c,
Err(LitToConstError::Reported(guar)) => {
- ConstantKind::Ty(tcx.const_error_with_guaranteed(ty, guar))
+ ConstantKind::Ty(tcx.const_error(ty, guar))
}
Err(LitToConstError::TypeError) => {
bug!("encountered type error in `lit_to_mir_constant`")
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 c385b00692f..0105a265ffb 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -481,9 +481,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}))))
}
- ExprKind::OffsetOf { container, fields } => {
- block.and(Rvalue::NullaryOp(NullOp::OffsetOf(fields), container))
- }
+ ExprKind::OffsetOf { container, fields } => block.and(Rvalue::NullaryOp(
+ NullOp::OffsetOf(fields),
+ this.tcx.erase_regions(container),
+ )),
ExprKind::Literal { .. }
| ExprKind::NamedConst { .. }
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 4926ff85de3..6df06df5c60 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -2241,6 +2241,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.var_debug_info.push(VarDebugInfo {
name,
source_info: debug_source_info,
+ references: 0,
value: VarDebugInfoContents::Place(for_arm_body.into()),
argument_index: None,
});
@@ -2260,6 +2261,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.var_debug_info.push(VarDebugInfo {
name,
source_info: debug_source_info,
+ references: 0,
value: VarDebugInfoContents::Place(ref_for_guard.into()),
argument_index: None,
});
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 4536ecf17b8..dbdb5b4a9a1 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -380,18 +380,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
);
}
- /// Compare two `&T` values using `<T as std::compare::PartialEq>::eq`
+ /// Compare two values using `<T as std::compare::PartialEq>::eq`.
+ /// If the values are already references, just call it directly, otherwise
+ /// take a reference to the values first and then call it.
fn non_scalar_compare(
&mut self,
block: BasicBlock,
make_target_blocks: impl FnOnce(&mut Self) -> Vec<BasicBlock>,
source_info: SourceInfo,
value: ConstantKind<'tcx>,
- place: Place<'tcx>,
+ mut val: Place<'tcx>,
mut ty: Ty<'tcx>,
) {
let mut expect = self.literal_operand(source_info.span, value);
- let mut val = Operand::Copy(place);
// If we're using `b"..."` as a pattern, we need to insert an
// unsizing coercion, as the byte string has the type `&[u8; N]`.
@@ -421,9 +422,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
source_info,
temp,
- Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), val, ty),
+ Rvalue::Cast(
+ CastKind::Pointer(PointerCast::Unsize),
+ Operand::Copy(val),
+ ty,
+ ),
);
- val = Operand::Move(temp);
+ val = temp;
}
if opt_ref_test_ty.is_some() {
let slice = self.temp(ty, source_info.span);
@@ -438,12 +443,36 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
- let ty::Ref(_, deref_ty, _) = *ty.kind() else {
- bug!("non_scalar_compare called on non-reference type: {}", ty);
- };
+ match *ty.kind() {
+ ty::Ref(_, deref_ty, _) => ty = deref_ty,
+ _ => {
+ // non_scalar_compare called on non-reference type
+ let temp = self.temp(ty, source_info.span);
+ self.cfg.push_assign(block, source_info, temp, Rvalue::Use(expect));
+ let ref_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, ty);
+ let ref_temp = self.temp(ref_ty, source_info.span);
+
+ self.cfg.push_assign(
+ block,
+ source_info,
+ ref_temp,
+ Rvalue::Ref(self.tcx.lifetimes.re_erased, BorrowKind::Shared, temp),
+ );
+ expect = Operand::Move(ref_temp);
+
+ let ref_temp = self.temp(ref_ty, source_info.span);
+ self.cfg.push_assign(
+ block,
+ source_info,
+ ref_temp,
+ Rvalue::Ref(self.tcx.lifetimes.re_erased, BorrowKind::Shared, val),
+ );
+ val = ref_temp;
+ }
+ }
let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span));
- let method = trait_method(self.tcx, eq_def_id, sym::eq, [deref_ty, deref_ty]);
+ let method = trait_method(self.tcx, eq_def_id, sym::eq, [ty, ty]);
let bool_ty = self.tcx.types.bool;
let eq_result = self.temp(bool_ty, source_info.span);
@@ -463,7 +492,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
literal: method,
})),
- args: vec![val, expect],
+ args: vec![Operand::Copy(val), expect],
destination: eq_result,
target: Some(eq_block),
unwind: UnwindAction::Continue,
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 3f006765a71..4e3e98b56e7 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -42,7 +42,9 @@ fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
// Ensure unsafeck and abstract const building is ran before we steal the THIR.
tcx.ensure_with_value().thir_check_unsafety(def);
tcx.ensure_with_value().thir_abstract_const(def);
- tcx.ensure_with_value().check_match(def);
+ if let Err(e) = tcx.check_match(def) {
+ return construct_error(tcx, def, e);
+ }
let body = match tcx.thir_body(def) {
Err(error_reported) => construct_error(tcx, def, error_reported),
@@ -796,6 +798,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
};
self.var_debug_info.push(VarDebugInfo {
name,
+ references: 0,
source_info: SourceInfo::outermost(captured_place.var_ident.span),
value: VarDebugInfoContents::Place(use_place),
argument_index: None,
@@ -826,6 +829,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.var_debug_info.push(VarDebugInfo {
name,
source_info,
+ references: 0,
value: VarDebugInfoContents::Place(arg_local.into()),
argument_index: Some(argument_index as u16 + 1),
});
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index 2765a107cf0..c964e62c9d0 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -22,7 +22,7 @@ mod errors;
mod lints;
pub mod thir;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
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 8cb3b00c9ad..ca25f83e643 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -26,8 +26,8 @@ use rustc_session::Session;
use rustc_span::hygiene::DesugaringKind;
use rustc_span::Span;
-pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) {
- let Ok((thir, expr)) = tcx.thir_body(def_id) else { return };
+pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
+ let (thir, expr) = tcx.thir_body(def_id)?;
let thir = thir.borrow();
let pattern_arena = TypedArena::default();
let mut visitor = MatchVisitor {
@@ -37,13 +37,16 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) {
lint_level: tcx.hir().local_def_id_to_hir_id(def_id),
let_source: LetSource::None,
pattern_arena: &pattern_arena,
+ error: Ok(()),
};
visitor.visit_expr(&thir[expr]);
+
for param in thir.params.iter() {
if let Some(box ref pattern) = param.pat {
visitor.check_irrefutable(pattern, "function argument", None);
}
}
+ visitor.error
}
fn create_e0004(
@@ -77,6 +80,7 @@ struct MatchVisitor<'a, 'p, 'tcx> {
lint_level: HirId,
let_source: LetSource,
pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
+ error: Result<(), ErrorGuaranteed>,
}
impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
@@ -276,9 +280,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
let [pat_field] = &subpatterns[..] else { bug!() };
self.check_irrefutable(&pat_field.pattern, "`for` loop binding", None);
} else {
- non_exhaustive_match(
+ self.error = Err(non_exhaustive_match(
&cx, self.thir, scrut_ty, scrut.span, witnesses, arms, expr_span,
- );
+ ));
}
}
}
@@ -406,7 +410,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
}
#[instrument(level = "trace", skip(self))]
- fn check_irrefutable(&self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) {
+ fn check_irrefutable(&mut self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) {
let mut cx = self.new_cx(self.lint_level, false);
let pattern = self.lower_pattern(&mut cx, pat);
@@ -475,7 +479,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
AdtDefinedHere { adt_def_span, ty, variants }
};
- self.tcx.sess.emit_err(PatternNotCovered {
+ self.error = Err(self.tcx.sess.emit_err(PatternNotCovered {
span: pat.span,
origin,
uncovered: Uncovered::new(pat.span, &cx, witnesses),
@@ -486,7 +490,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
let_suggestion,
misc_suggestion,
adt_defined_here,
- });
+ }));
}
}
@@ -628,7 +632,7 @@ fn non_exhaustive_match<'p, 'tcx>(
witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
arms: &[ArmId],
expr_span: Span,
-) {
+) -> ErrorGuaranteed {
let is_empty_match = arms.is_empty();
let non_empty_enum = match scrut_ty.kind() {
ty::Adt(def, _) => def.is_enum() && !def.variants().is_empty(),
@@ -640,13 +644,12 @@ fn non_exhaustive_match<'p, 'tcx>(
let pattern;
let patterns_len;
if is_empty_match && !non_empty_enum {
- cx.tcx.sess.emit_err(NonExhaustivePatternsTypeNotEmpty {
+ return cx.tcx.sess.emit_err(NonExhaustivePatternsTypeNotEmpty {
cx,
expr_span,
span: sp,
ty: scrut_ty,
});
- return;
} else {
// FIXME: migration of this diagnostic will require list support
let joined_patterns = joined_uncovered_patterns(cx, &witnesses);
@@ -797,7 +800,7 @@ fn non_exhaustive_match<'p, 'tcx>(
} else {
err.help(msg);
}
- err.emit();
+ err.emit()
}
pub(crate) fn joined_uncovered_patterns<'p, 'tcx>(
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 c73f8284ca5..b243f1dc8d0 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
@@ -62,21 +62,13 @@ struct ConstToPat<'tcx> {
treat_byte_string_as_slice: bool,
}
-mod fallback_to_const_ref {
- #[derive(Debug)]
- /// This error type signals that we encountered a non-struct-eq situation behind a reference.
- /// We bubble this up in order to get back to the reference destructuring and make that emit
- /// a const pattern instead of a deref pattern. This allows us to simply call `PartialEq::eq`
- /// on such patterns (since that function takes a reference) and not have to jump through any
- /// hoops to get a reference to the value.
- pub(super) struct FallbackToConstRef(());
-
- pub(super) fn fallback_to_const_ref(c2p: &super::ConstToPat<'_>) -> FallbackToConstRef {
- assert!(c2p.behind_reference.get());
- FallbackToConstRef(())
- }
-}
-use fallback_to_const_ref::{fallback_to_const_ref, FallbackToConstRef};
+/// This error type signals that we encountered a non-struct-eq situation.
+/// We bubble this up in order to get back to the reference destructuring and make that emit
+/// a const pattern instead of a deref pattern. This allows us to simply call `PartialEq::eq`
+/// on such patterns (since that function takes a reference) and not have to jump through any
+/// hoops to get a reference to the value.
+#[derive(Debug)]
+struct FallbackToConstRef;
impl<'tcx> ConstToPat<'tcx> {
fn new(
@@ -236,13 +228,13 @@ impl<'tcx> ConstToPat<'tcx> {
let kind = match cv.ty().kind() {
ty::Float(_) => {
- tcx.emit_spanned_lint(
- lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
- id,
- span,
- FloatPattern,
- );
- PatKind::Constant { value: cv }
+ tcx.emit_spanned_lint(
+ lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
+ id,
+ span,
+ FloatPattern,
+ );
+ return Err(FallbackToConstRef);
}
ty::Adt(adt_def, _) if adt_def.is_union() => {
// Matching on union fields is unsafe, we can't hide it in constants
@@ -289,7 +281,7 @@ impl<'tcx> ConstToPat<'tcx> {
// Since we are behind a reference, we can just bubble the error up so we get a
// constant at reference type, making it easy to let the fallback call
// `PartialEq::eq` on it.
- return Err(fallback_to_const_ref(self));
+ return Err(FallbackToConstRef);
}
ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty()) => {
debug!(
@@ -393,11 +385,11 @@ impl<'tcx> ConstToPat<'tcx> {
self.behind_reference.set(old);
val
}
- // Backwards compatibility hack: support references to non-structural types.
- // We'll lower
- // this pattern to a `PartialEq::eq` comparison and `PartialEq::eq` takes a
- // reference. This makes the rest of the matching logic simpler as it doesn't have
- // to figure out how to get a reference again.
+ // Backwards compatibility hack: support references to non-structural types,
+ // but hard error if we aren't behind a double reference. We could just use
+ // the fallback code path below, but that would allow *more* of this fishy
+ // code to compile, as then it only goes through the future incompat lint
+ // instead of a hard error.
ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => {
if self.behind_reference.get() {
if !self.saw_const_match_error.get()
@@ -411,7 +403,7 @@ impl<'tcx> ConstToPat<'tcx> {
IndirectStructuralMatch { non_sm_ty: *pointee_ty },
);
}
- PatKind::Constant { value: cv }
+ return Err(FallbackToConstRef);
} else {
if !self.saw_const_match_error.get() {
self.saw_const_match_error.set(true);
@@ -435,16 +427,9 @@ impl<'tcx> ConstToPat<'tcx> {
PatKind::Wild
} else {
let old = self.behind_reference.replace(true);
- // In case there are structural-match violations somewhere in this subpattern,
- // we fall back to a const pattern. If we do not do this, we may end up with
- // a !structural-match constant that is not of reference type, which makes it
- // very hard to invoke `PartialEq::eq` on it as a fallback.
- let val = match self.recur(tcx.deref_mir_constant(self.param_env.and(cv)), false) {
- Ok(subpattern) => PatKind::Deref { subpattern },
- Err(_) => PatKind::Constant { value: cv },
- };
+ let subpattern = self.recur(tcx.deref_mir_constant(self.param_env.and(cv)), false)?;
self.behind_reference.set(old);
- val
+ PatKind::Deref { subpattern }
}
}
},
@@ -452,7 +437,7 @@ impl<'tcx> ConstToPat<'tcx> {
PatKind::Constant { value: cv }
}
ty::RawPtr(pointee) if pointee.ty.is_sized(tcx, param_env) => {
- PatKind::Constant { value: cv }
+ return Err(FallbackToConstRef);
}
// FIXME: these can have very surprising behaviour where optimization levels or other
// compilation choices change the runtime behaviour of the match.
@@ -469,7 +454,7 @@ impl<'tcx> ConstToPat<'tcx> {
PointerPattern
);
}
- PatKind::Constant { value: cv }
+ return Err(FallbackToConstRef);
}
_ => {
self.saw_const_match_error.set(true);
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 9af13781312..6a77146138b 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -844,8 +844,8 @@ impl<'tcx> Constructor<'tcx> {
}
/// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is
- /// assumed to be built from `matrix.head_ctors()` with wildcards filtered out, and `self` is
- /// assumed to have been split from a wildcard.
+ /// assumed to be built from `matrix.head_ctors()` with wildcards and opaques filtered out,
+ /// and `self` is assumed to have been split from a wildcard.
fn is_covered_by_any<'p>(
&self,
pcx: &PatCtxt<'_, 'p, 'tcx>,
@@ -894,7 +894,7 @@ impl<'tcx> Constructor<'tcx> {
/// in `to_ctors`: in some cases we only return `Missing`.
#[derive(Debug)]
pub(super) struct SplitWildcard<'tcx> {
- /// Constructors seen in the matrix.
+ /// Constructors (other than wildcards and opaques) seen in the matrix.
matrix_ctors: Vec<Constructor<'tcx>>,
/// All the constructors for this type
all_ctors: SmallVec<[Constructor<'tcx>; 1]>,
@@ -1037,7 +1037,7 @@ impl<'tcx> SplitWildcard<'tcx> {
// Since `all_ctors` never contains wildcards, this won't recurse further.
self.all_ctors =
self.all_ctors.iter().flat_map(|ctor| ctor.split(pcx, ctors.clone())).collect();
- self.matrix_ctors = ctors.filter(|c| !c.is_wildcard()).cloned().collect();
+ self.matrix_ctors = ctors.filter(|c| !matches!(c, Wildcard | Opaque)).cloned().collect();
}
/// Whether there are any value constructors for this type that are not present in the matrix.
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index f229b10c447..e5b63506906 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -288,6 +288,22 @@
//!
//! The details are not necessary to understand this file, so we explain them in
//! [`super::deconstruct_pat`]. Splitting is done by the [`Constructor::split`] function.
+//!
+//! # Constants in patterns
+//!
+//! There are two kinds of constants in patterns:
+//!
+//! * literals (`1`, `true`, `"foo"`)
+//! * named or inline consts (`FOO`, `const { 5 + 6 }`)
+//!
+//! The latter are converted into other patterns with literals at the leaves. For example
+//! `const_to_pat(const { [1, 2, 3] })` becomes an `Array(vec![Const(1), Const(2), Const(3)])`
+//! pattern. This gets problematic when comparing the constant via `==` would behave differently
+//! from matching on the constant converted to a pattern. Situations like that can occur, when
+//! the user implements `PartialEq` manually, and thus could make `==` behave arbitrarily different.
+//! In order to honor the `==` implementation, constants of types that implement `PartialEq` manually
+//! stay as a full constant and become an `Opaque` pattern. These `Opaque` patterns do not participate
+//! in exhaustiveness, specialization or overlap checking.
use self::ArmType::*;
use self::Usefulness::*;
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 2e68c794356..18895072c3b 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -276,6 +276,7 @@ where
assert_eq!(self.elaborator.param_env().reveal(), Reveal::All);
let field_ty =
tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs));
+
(tcx.mk_place_field(base_place, field, field_ty), subpath)
})
.collect()
diff --git a/compiler/rustc_mir_dataflow/src/framework/lattice.rs b/compiler/rustc_mir_dataflow/src/framework/lattice.rs
index af44a4329bf..3952f44ad48 100644
--- a/compiler/rustc_mir_dataflow/src/framework/lattice.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/lattice.rs
@@ -75,12 +75,12 @@ pub trait MeetSemiLattice: Eq {
/// A set that has a "bottom" element, which is less than or equal to any other element.
pub trait HasBottom {
- fn bottom() -> Self;
+ const BOTTOM: Self;
}
/// A set that has a "top" element, which is greater than or equal to any other element.
pub trait HasTop {
- fn top() -> Self;
+ const TOP: Self;
}
/// A `bool` is a "two-point" lattice with `true` as the top element and `false` as the bottom:
@@ -113,15 +113,11 @@ impl MeetSemiLattice for bool {
}
impl HasBottom for bool {
- fn bottom() -> Self {
- false
- }
+ const BOTTOM: Self = false;
}
impl HasTop for bool {
- fn top() -> Self {
- true
- }
+ const TOP: Self = true;
}
/// A tuple (or list) of lattices is itself a lattice whose least upper bound is the concatenation
@@ -274,13 +270,9 @@ impl<T: Clone + Eq> MeetSemiLattice for FlatSet<T> {
}
impl<T> HasBottom for FlatSet<T> {
- fn bottom() -> Self {
- Self::Bottom
- }
+ const BOTTOM: Self = Self::Bottom;
}
impl<T> HasTop for FlatSet<T> {
- fn top() -> Self {
- Self::Top
- }
+ const TOP: Self = Self::Top;
}
diff --git a/compiler/rustc_mir_dataflow/src/impls/mod.rs b/compiler/rustc_mir_dataflow/src/impls/mod.rs
index 2a0aff55083..171db6965ac 100644
--- a/compiler/rustc_mir_dataflow/src/impls/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/mod.rs
@@ -26,7 +26,7 @@ pub use self::borrowed_locals::borrowed_locals;
pub use self::borrowed_locals::MaybeBorrowedLocals;
pub use self::liveness::MaybeLiveLocals;
pub use self::liveness::MaybeTransitiveLiveLocals;
-pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageLive};
+pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageDead, MaybeStorageLive};
/// `MaybeInitializedPlaces` tracks all places that might be
/// initialized upon reaching a particular point in the control flow
diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
index 4a5d9d52010..463ce083a64 100644
--- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
@@ -74,6 +74,73 @@ impl<'tcx, 'a> crate::GenKillAnalysis<'tcx> for MaybeStorageLive<'a> {
}
}
+#[derive(Clone)]
+pub struct MaybeStorageDead {
+ always_live_locals: BitSet<Local>,
+}
+
+impl MaybeStorageDead {
+ pub fn new(always_live_locals: BitSet<Local>) -> Self {
+ MaybeStorageDead { always_live_locals }
+ }
+}
+
+impl<'tcx> crate::AnalysisDomain<'tcx> for MaybeStorageDead {
+ type Domain = BitSet<Local>;
+
+ const NAME: &'static str = "maybe_storage_dead";
+
+ fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
+ // bottom = live
+ BitSet::new_empty(body.local_decls.len())
+ }
+
+ fn initialize_start_block(&self, body: &mir::Body<'tcx>, on_entry: &mut Self::Domain) {
+ assert_eq!(body.local_decls.len(), self.always_live_locals.domain_size());
+ // Do not iterate on return place and args, as they are trivially always live.
+ for local in body.vars_and_temps_iter() {
+ if !self.always_live_locals.contains(local) {
+ on_entry.insert(local);
+ }
+ }
+ }
+}
+
+impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageDead {
+ type Idx = Local;
+
+ fn statement_effect(
+ &self,
+ trans: &mut impl GenKill<Self::Idx>,
+ stmt: &mir::Statement<'tcx>,
+ _: Location,
+ ) {
+ match stmt.kind {
+ StatementKind::StorageLive(l) => trans.kill(l),
+ StatementKind::StorageDead(l) => trans.gen(l),
+ _ => (),
+ }
+ }
+
+ fn terminator_effect(
+ &self,
+ _trans: &mut impl GenKill<Self::Idx>,
+ _: &mir::Terminator<'tcx>,
+ _: Location,
+ ) {
+ // Terminators have no effect
+ }
+
+ fn call_return_effect(
+ &self,
+ _trans: &mut impl GenKill<Self::Idx>,
+ _block: BasicBlock,
+ _return_places: CallReturnPlaces<'_, 'tcx>,
+ ) {
+ // Nothing to do when a call returns successfully
+ }
+}
+
type BorrowedLocalsResults<'a, 'tcx> = ResultsRefCursor<'a, 'a, 'tcx, MaybeBorrowedLocals>;
/// Dataflow analysis that determines whether each local requires storage at a
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index fdff1ec788d..b74d06e5ae8 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -32,9 +32,12 @@
//! Because of that, we can assume that the only way to change the value behind a tracked place is
//! by direct assignment.
+use std::collections::VecDeque;
use std::fmt::{Debug, Formatter};
+use std::ops::Range;
use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_index::bit_set::BitSet;
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
@@ -65,8 +68,8 @@ pub trait ValueAnalysis<'tcx> {
StatementKind::Assign(box (place, rvalue)) => {
self.handle_assign(*place, rvalue, state);
}
- StatementKind::SetDiscriminant { box ref place, .. } => {
- state.flood_discr(place.as_ref(), self.map());
+ StatementKind::SetDiscriminant { box place, variant_index } => {
+ self.handle_set_discriminant(*place, *variant_index, state);
}
StatementKind::Intrinsic(box intrinsic) => {
self.handle_intrinsic(intrinsic, state);
@@ -74,11 +77,11 @@ pub trait ValueAnalysis<'tcx> {
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
// StorageLive leaves the local in an uninitialized state.
// StorageDead makes it UB to access the local afterwards.
- state.flood_with(Place::from(*local).as_ref(), self.map(), Self::Value::bottom());
+ state.flood_with(Place::from(*local).as_ref(), self.map(), Self::Value::BOTTOM);
}
StatementKind::Deinit(box place) => {
// Deinit makes the place uninitialized.
- state.flood_with(place.as_ref(), self.map(), Self::Value::bottom());
+ state.flood_with(place.as_ref(), self.map(), Self::Value::BOTTOM);
}
StatementKind::Retag(..) => {
// We don't track references.
@@ -92,6 +95,24 @@ pub trait ValueAnalysis<'tcx> {
}
}
+ fn handle_set_discriminant(
+ &self,
+ place: Place<'tcx>,
+ variant_index: VariantIdx,
+ state: &mut State<Self::Value>,
+ ) {
+ self.super_set_discriminant(place, variant_index, state)
+ }
+
+ fn super_set_discriminant(
+ &self,
+ place: Place<'tcx>,
+ _variant_index: VariantIdx,
+ state: &mut State<Self::Value>,
+ ) {
+ state.flood_discr(place.as_ref(), self.map());
+ }
+
fn handle_intrinsic(
&self,
intrinsic: &NonDivergingIntrinsic<'tcx>,
@@ -103,16 +124,18 @@ pub trait ValueAnalysis<'tcx> {
fn super_intrinsic(
&self,
intrinsic: &NonDivergingIntrinsic<'tcx>,
- state: &mut State<Self::Value>,
+ _state: &mut State<Self::Value>,
) {
match intrinsic {
NonDivergingIntrinsic::Assume(..) => {
// Could use this, but ignoring it is sound.
}
- NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { dst, .. }) => {
- if let Some(place) = dst.place() {
- state.flood(place.as_ref(), self.map());
- }
+ NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
+ dst: _,
+ src: _,
+ count: _,
+ }) => {
+ // This statement represents `*dst = *src`, `count` times.
}
}
}
@@ -154,7 +177,7 @@ pub trait ValueAnalysis<'tcx> {
Rvalue::CopyForDeref(place) => self.handle_operand(&Operand::Copy(*place), state),
Rvalue::Ref(..) | Rvalue::AddressOf(..) => {
// We don't track such places.
- ValueOrPlace::top()
+ ValueOrPlace::TOP
}
Rvalue::Repeat(..)
| Rvalue::ThreadLocalRef(..)
@@ -168,7 +191,7 @@ pub trait ValueAnalysis<'tcx> {
| Rvalue::Aggregate(..)
| Rvalue::ShallowInitBox(..) => {
// No modification is possible through these r-values.
- ValueOrPlace::top()
+ ValueOrPlace::TOP
}
}
}
@@ -196,7 +219,7 @@ pub trait ValueAnalysis<'tcx> {
self.map()
.find(place.as_ref())
.map(ValueOrPlace::Place)
- .unwrap_or(ValueOrPlace::top())
+ .unwrap_or(ValueOrPlace::TOP)
}
}
}
@@ -214,7 +237,7 @@ pub trait ValueAnalysis<'tcx> {
_constant: &Constant<'tcx>,
_state: &mut State<Self::Value>,
) -> Self::Value {
- Self::Value::top()
+ Self::Value::TOP
}
/// The effect of a successful function call return should not be
@@ -229,7 +252,7 @@ pub trait ValueAnalysis<'tcx> {
// Effect is applied by `handle_call_return`.
}
TerminatorKind::Drop { place, .. } => {
- state.flood_with(place.as_ref(), self.map(), Self::Value::bottom());
+ state.flood_with(place.as_ref(), self.map(), Self::Value::BOTTOM);
}
TerminatorKind::Yield { .. } => {
// They would have an effect, but are not allowed in this phase.
@@ -307,7 +330,7 @@ impl<'tcx, T: ValueAnalysis<'tcx>> AnalysisDomain<'tcx> for ValueAnalysisWrapper
fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) {
// The initial state maps all tracked places of argument projections to ⊤ and the rest to ⊥.
assert!(matches!(state.0, StateData::Unreachable));
- let values = IndexVec::from_elem_n(T::Value::bottom(), self.0.map().value_count);
+ let values = IndexVec::from_elem_n(T::Value::BOTTOM, self.0.map().value_count);
*state = State(StateData::Reachable(values));
for arg in body.args_iter() {
state.flood(PlaceRef { local: arg, projection: &[] }, self.0.map());
@@ -437,7 +460,7 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
}
pub fn flood_all(&mut self) {
- self.flood_all_with(V::top())
+ self.flood_all_with(V::TOP)
}
pub fn flood_all_with(&mut self, value: V) {
@@ -447,28 +470,24 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
pub fn flood_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) {
let StateData::Reachable(values) = &mut self.0 else { return };
- map.for_each_aliasing_place(place, None, &mut |place| {
- if let Some(vi) = map.places[place].value_index {
- values[vi] = value.clone();
- }
+ map.for_each_aliasing_place(place, None, &mut |vi| {
+ values[vi] = value.clone();
});
}
pub fn flood(&mut self, place: PlaceRef<'_>, map: &Map) {
- self.flood_with(place, map, V::top())
+ self.flood_with(place, map, V::TOP)
}
pub fn flood_discr_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) {
let StateData::Reachable(values) = &mut self.0 else { return };
- map.for_each_aliasing_place(place, Some(TrackElem::Discriminant), &mut |place| {
- if let Some(vi) = map.places[place].value_index {
- values[vi] = value.clone();
- }
+ map.for_each_aliasing_place(place, Some(TrackElem::Discriminant), &mut |vi| {
+ values[vi] = value.clone();
});
}
pub fn flood_discr(&mut self, place: PlaceRef<'_>, map: &Map) {
- self.flood_discr_with(place, map, V::top())
+ self.flood_discr_with(place, map, V::TOP)
}
/// Low-level method that assigns to a place.
@@ -538,14 +557,14 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
/// Retrieve the value stored for a place, or ⊤ if it is not tracked.
pub fn get(&self, place: PlaceRef<'_>, map: &Map) -> V {
- map.find(place).map(|place| self.get_idx(place, map)).unwrap_or(V::top())
+ map.find(place).map(|place| self.get_idx(place, map)).unwrap_or(V::TOP)
}
/// Retrieve the value stored for a place, or ⊤ if it is not tracked.
pub fn get_discr(&self, place: PlaceRef<'_>, map: &Map) -> V {
match map.find_discr(place) {
Some(place) => self.get_idx(place, map),
- None => V::top(),
+ None => V::TOP,
}
}
@@ -553,11 +572,11 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
pub fn get_idx(&self, place: PlaceIndex, map: &Map) -> V {
match &self.0 {
StateData::Reachable(values) => {
- map.places[place].value_index.map(|v| values[v].clone()).unwrap_or(V::top())
+ map.places[place].value_index.map(|v| values[v].clone()).unwrap_or(V::TOP)
}
StateData::Unreachable => {
// Because this is unreachable, we can return any value we want.
- V::bottom()
+ V::BOTTOM
}
}
}
@@ -588,6 +607,9 @@ pub struct Map {
projections: FxHashMap<(PlaceIndex, TrackElem), PlaceIndex>,
places: IndexVec<PlaceIndex, PlaceInfo>,
value_count: usize,
+ // The Range corresponds to a slice into `inner_values_buffer`.
+ inner_values: IndexVec<PlaceIndex, Range<usize>>,
+ inner_values_buffer: Vec<ValueIndex>,
}
impl Map {
@@ -597,6 +619,8 @@ impl Map {
projections: FxHashMap::default(),
places: IndexVec::new(),
value_count: 0,
+ inner_values: IndexVec::new(),
+ inner_values_buffer: Vec::new(),
}
}
@@ -608,12 +632,12 @@ impl Map {
pub fn from_filter<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
- filter: impl FnMut(Ty<'tcx>) -> bool,
- place_limit: Option<usize>,
+ filter: impl Fn(Ty<'tcx>) -> bool,
+ value_limit: Option<usize>,
) -> Self {
let mut map = Self::new();
let exclude = excluded_locals(body);
- map.register_with_filter(tcx, body, filter, exclude, place_limit);
+ map.register_with_filter(tcx, body, filter, exclude, value_limit);
debug!("registered {} places ({} nodes in total)", map.value_count, map.places.len());
map
}
@@ -623,51 +647,90 @@ impl Map {
&mut self,
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
- mut filter: impl FnMut(Ty<'tcx>) -> bool,
+ filter: impl Fn(Ty<'tcx>) -> bool,
exclude: BitSet<Local>,
- place_limit: Option<usize>,
+ value_limit: Option<usize>,
) {
- // We use this vector as stack, pushing and popping projections.
- let mut projection = Vec::new();
+ let mut worklist = VecDeque::with_capacity(value_limit.unwrap_or(body.local_decls.len()));
+
+ // Start by constructing the places for each bare local.
+ self.locals = IndexVec::from_elem(None, &body.local_decls);
for (local, decl) in body.local_decls.iter_enumerated() {
- if !exclude.contains(local) {
- self.register_with_filter_rec(
- tcx,
- local,
- &mut projection,
- decl.ty,
- &mut filter,
- place_limit,
- );
+ if exclude.contains(local) {
+ continue;
}
+
+ // Create a place for the local.
+ debug_assert!(self.locals[local].is_none());
+ let place = self.places.push(PlaceInfo::new(None));
+ self.locals[local] = Some(place);
+
+ // And push the eventual children places to the worklist.
+ self.register_children(tcx, place, decl.ty, &filter, &mut worklist);
}
+
+ // `place.elem1.elem2` with type `ty`.
+ // `elem1` is either `Some(Variant(i))` or `None`.
+ while let Some((mut place, elem1, elem2, ty)) = worklist.pop_front() {
+ // The user requires a bound on the number of created values.
+ if let Some(value_limit) = value_limit && self.value_count >= value_limit {
+ break
+ }
+
+ // Create a place for this projection.
+ for elem in [elem1, Some(elem2)].into_iter().flatten() {
+ place = *self.projections.entry((place, elem)).or_insert_with(|| {
+ // Prepend new child to the linked list.
+ let next = self.places.push(PlaceInfo::new(Some(elem)));
+ self.places[next].next_sibling = self.places[place].first_child;
+ self.places[place].first_child = Some(next);
+ next
+ });
+ }
+
+ // And push the eventual children places to the worklist.
+ self.register_children(tcx, place, ty, &filter, &mut worklist);
+ }
+
+ // Pre-compute the tree of ValueIndex nested in each PlaceIndex.
+ // `inner_values_buffer[inner_values[place]]` is the set of all the values
+ // reachable by projecting `place`.
+ self.inner_values_buffer = Vec::with_capacity(self.value_count);
+ self.inner_values = IndexVec::from_elem(0..0, &self.places);
+ for local in body.local_decls.indices() {
+ if let Some(place) = self.locals[local] {
+ self.cache_preorder_invoke(place);
+ }
+ }
+
+ // Trim useless places.
+ for opt_place in self.locals.iter_mut() {
+ if let Some(place) = *opt_place && self.inner_values[place].is_empty() {
+ *opt_place = None;
+ }
+ }
+ #[allow(rustc::potential_query_instability)]
+ self.projections.retain(|_, child| !self.inner_values[*child].is_empty());
}
/// Potentially register the (local, projection) place and its fields, recursively.
///
/// Invariant: The projection must only contain trackable elements.
- fn register_with_filter_rec<'tcx>(
+ fn register_children<'tcx>(
&mut self,
tcx: TyCtxt<'tcx>,
- local: Local,
- projection: &mut Vec<PlaceElem<'tcx>>,
+ place: PlaceIndex,
ty: Ty<'tcx>,
- filter: &mut impl FnMut(Ty<'tcx>) -> bool,
- place_limit: Option<usize>,
+ filter: &impl Fn(Ty<'tcx>) -> bool,
+ worklist: &mut VecDeque<(PlaceIndex, Option<TrackElem>, TrackElem, Ty<'tcx>)>,
) {
- if let Some(place_limit) = place_limit && self.value_count >= place_limit {
- return
- }
-
- // We know that the projection only contains trackable elements.
- let place = self.make_place(local, projection).unwrap();
-
// Allocate a value slot if it doesn't have one, and the user requested one.
if self.places[place].value_index.is_none() && filter(ty) {
self.places[place].value_index = Some(self.value_count.into());
self.value_count += 1;
}
+ // For enums, directly create the `Discriminant`, as that's their main use.
if ty.is_enum() {
let discr_ty = ty.discriminant_ty(tcx);
if filter(discr_ty) {
@@ -692,46 +755,32 @@ impl Map {
// Recurse with all fields of this place.
iter_fields(ty, tcx, ty::ParamEnv::reveal_all(), |variant, field, ty| {
- if let Some(variant) = variant {
- projection.push(PlaceElem::Downcast(None, variant));
- let _ = self.make_place(local, projection);
- projection.push(PlaceElem::Field(field, ty));
- self.register_with_filter_rec(tcx, local, projection, ty, filter, place_limit);
- projection.pop();
- projection.pop();
- return;
- }
- projection.push(PlaceElem::Field(field, ty));
- self.register_with_filter_rec(tcx, local, projection, ty, filter, place_limit);
- projection.pop();
+ worklist.push_back((
+ place,
+ variant.map(TrackElem::Variant),
+ TrackElem::Field(field),
+ ty,
+ ))
});
}
- /// Tries to add the place to the map, without allocating a value slot.
- ///
- /// Can fail if the projection contains non-trackable elements.
- fn make_place<'tcx>(
- &mut self,
- local: Local,
- projection: &[PlaceElem<'tcx>],
- ) -> Result<PlaceIndex, ()> {
- // Get the base index of the local.
- let mut index =
- *self.locals.get_or_insert_with(local, || self.places.push(PlaceInfo::new(None)));
-
- // Apply the projection.
- for &elem in projection {
- let elem = elem.try_into()?;
- index = *self.projections.entry((index, elem)).or_insert_with(|| {
- // Prepend new child to the linked list.
- let next = self.places.push(PlaceInfo::new(Some(elem)));
- self.places[next].next_sibling = self.places[index].first_child;
- self.places[index].first_child = Some(next);
- next
- });
+ /// Precompute the list of values inside `root` and store it inside
+ /// as a slice within `inner_values_buffer`.
+ fn cache_preorder_invoke(&mut self, root: PlaceIndex) {
+ let start = self.inner_values_buffer.len();
+ if let Some(vi) = self.places[root].value_index {
+ self.inner_values_buffer.push(vi);
+ }
+
+ // We manually iterate instead of using `children` as we need to mutate `self`.
+ let mut next_child = self.places[root].first_child;
+ while let Some(child) = next_child {
+ ensure_sufficient_stack(|| self.cache_preorder_invoke(child));
+ next_child = self.places[child].next_sibling;
}
- Ok(index)
+ let end = self.inner_values_buffer.len();
+ self.inner_values[root] = start..end;
}
/// Returns the number of tracked places, i.e., those for which a value can be stored.
@@ -750,7 +799,7 @@ impl Map {
place: PlaceRef<'_>,
extra: impl IntoIterator<Item = TrackElem>,
) -> Option<PlaceIndex> {
- let mut index = *self.locals.get(place.local)?.as_ref()?;
+ let mut index = *self.locals[place.local].as_ref()?;
for &elem in place.projection {
index = self.apply(index, elem.try_into().ok()?)?;
@@ -784,17 +833,17 @@ impl Map {
///
/// `tail_elem` allows to support discriminants that are not a place in MIR, but that we track
/// as such.
- pub fn for_each_aliasing_place(
+ fn for_each_aliasing_place(
&self,
place: PlaceRef<'_>,
tail_elem: Option<TrackElem>,
- f: &mut impl FnMut(PlaceIndex),
+ f: &mut impl FnMut(ValueIndex),
) {
- if place.is_indirect() {
+ if place.has_deref() {
// We do not track indirect places.
return;
}
- let Some(&Some(mut index)) = self.locals.get(place.local) else {
+ let Some(mut index) = self.locals[place.local] else {
// The local is not tracked at all, so it does not alias anything.
return;
};
@@ -805,7 +854,9 @@ impl Map {
.chain(tail_elem.map(Ok).into_iter());
for elem in elems {
// A field aliases the parent place.
- f(index);
+ if let Some(vi) = self.places[index].value_index {
+ f(vi);
+ }
let Ok(elem) = elem else { return };
let sub = self.apply(index, elem);
@@ -819,7 +870,7 @@ impl Map {
return;
}
}
- self.preorder_invoke(index, f);
+ self.for_each_value_inside(index, f);
}
/// Invoke the given function on all the descendants of the given place, except one branch.
@@ -827,7 +878,7 @@ impl Map {
&self,
parent: PlaceIndex,
preserved_child: Option<PlaceIndex>,
- f: &mut impl FnMut(PlaceIndex),
+ f: &mut impl FnMut(ValueIndex),
) {
for sibling in self.children(parent) {
let elem = self.places[sibling].proj_elem;
@@ -837,16 +888,17 @@ impl Map {
// Only invalidate the other variants, the current one is fine.
&& Some(sibling) != preserved_child
{
- self.preorder_invoke(sibling, f);
+ self.for_each_value_inside(sibling, f);
}
}
}
- /// Invoke a function on the given place and all descendants.
- fn preorder_invoke(&self, root: PlaceIndex, f: &mut impl FnMut(PlaceIndex)) {
- f(root);
- for child in self.children(root) {
- self.preorder_invoke(child, f);
+ /// Invoke a function on each value in the given place and all descendants.
+ fn for_each_value_inside(&self, root: PlaceIndex, f: &mut impl FnMut(ValueIndex)) {
+ let range = self.inner_values[root].clone();
+ let values = &self.inner_values_buffer[range];
+ for &v in values {
+ f(v)
}
}
}
@@ -909,9 +961,7 @@ pub enum ValueOrPlace<V> {
}
impl<V: HasTop> ValueOrPlace<V> {
- pub fn top() -> Self {
- ValueOrPlace::Value(V::top())
- }
+ pub const TOP: Self = ValueOrPlace::Value(V::TOP);
}
/// The set of projection elements that can be used by a tracked place.
diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml
index 962536669e0..eca5f98a2c0 100644
--- a/compiler/rustc_mir_transform/Cargo.toml
+++ b/compiler/rustc_mir_transform/Cargo.toml
@@ -24,6 +24,8 @@ rustc_session = { path = "../rustc_session" }
rustc_target = { path = "../rustc_target" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_span = { path = "../rustc_span" }
+rustc_fluent_macro = { path = "../rustc_fluent_macro" }
+rustc_macros = { path = "../rustc_macros" }
[dev-dependencies]
coverage_test_macros = { path = "src/coverage/test_macros" }
diff --git a/compiler/rustc_mir_transform/messages.ftl b/compiler/rustc_mir_transform/messages.ftl
new file mode 100644
index 00000000000..8c85cb5f76d
--- /dev/null
+++ b/compiler/rustc_mir_transform/messages.ftl
@@ -0,0 +1,66 @@
+mir_transform_const_modify = attempting to modify a `const` item
+ .note = each usage of a `const` item creates a new temporary; the original `const` item will not be modified
+
+mir_transform_const_mut_borrow = taking a mutable reference to a `const` item
+ .note = each usage of a `const` item creates a new temporary
+ .note2 = the mutable reference will refer to this temporary, not the original `const` item
+ .note3 = mutable reference created due to call to this method
+
+mir_transform_const_defined_here = `const` item defined here
+
+mir_transform_unaligned_packed_ref = reference to packed field is unaligned
+ .note = packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
+ .note_ub = creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ .help = copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+mir_transform_unused_unsafe = unnecessary `unsafe` block
+ .label = because it's nested under this `unsafe` block
+
+mir_transform_requires_unsafe = {$details} is unsafe and requires unsafe {$op_in_unsafe_fn_allowed ->
+ [true] function or block
+ *[false] block
+ }
+ .not_inherited = items do not inherit unsafety from separate enclosing items
+
+mir_transform_call_to_unsafe_label = call to unsafe function
+mir_transform_call_to_unsafe_note = consult the function's documentation for information on how to avoid undefined behavior
+mir_transform_use_of_asm_label = use of inline assembly
+mir_transform_use_of_asm_note = inline assembly is entirely unchecked and can cause undefined behavior
+mir_transform_initializing_valid_range_label = initializing type with `rustc_layout_scalar_valid_range` attr
+mir_transform_initializing_valid_range_note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
+mir_transform_const_ptr2int_label = cast of pointer to int
+mir_transform_const_ptr2int_note = casting pointers to integers in constants
+mir_transform_use_of_static_mut_label = use of mutable static
+mir_transform_use_of_static_mut_note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+mir_transform_use_of_extern_static_label = use of extern static
+mir_transform_use_of_extern_static_note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+mir_transform_deref_ptr_label = dereference of raw pointer
+mir_transform_deref_ptr_note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+mir_transform_union_access_label = access to union field
+mir_transform_union_access_note = the field may not be properly initialized: using uninitialized data will cause undefined behavior
+mir_transform_mutation_layout_constrained_label = mutation of layout constrained field
+mir_transform_mutation_layout_constrained_note = mutating layout constrained fields cannot statically be checked for valid values
+mir_transform_mutation_layout_constrained_borrow_label = borrow of layout constrained field with interior mutability
+mir_transform_mutation_layout_constrained_borrow_note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+mir_transform_target_feature_call_label = call to function with `#[target_feature]`
+mir_transform_target_feature_call_note = can only be called if the required target features are available
+
+mir_transform_unsafe_op_in_unsafe_fn = {$details} is unsafe and requires unsafe block (error E0133)
+
+mir_transform_arithmetic_overflow = this arithmetic operation will overflow
+mir_transform_operation_will_panic = this operation will panic at runtime
+
+mir_transform_ffi_unwind_call = call to {$foreign ->
+ [true] foreign function
+ *[false] function pointer
+ } with FFI-unwind ABI
+
+mir_transform_fn_item_ref = taking a reference to a function item does not give a function pointer
+ .suggestion = cast `{$ident}` to obtain a function pointer
+
+mir_transform_must_not_suspend = {$pre}`{$def_path}`{$post} held across a suspend point, but should not be
+ .label = the value is held across this suspend point
+ .note = {$reason}
+ .help = consider using a block (`{"{ ... }"}`) to shrink the value's scope, ending before the suspend point
+
+mir_transform_simd_shuffle_last_const = last argument of `simd_shuffle` is required to be a `const` item
diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
index 57b24c9c552..b79150737d6 100644
--- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
+++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
@@ -1,11 +1,12 @@
-use rustc_errors::{DiagnosticBuilder, DiagnosticMessage};
+use rustc_hir::HirId;
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::CONST_ITEM_MUTATION;
use rustc_span::def_id::DefId;
+use rustc_span::Span;
-use crate::MirLint;
+use crate::{errors, MirLint};
pub struct CheckConstItemMutation;
@@ -58,16 +59,14 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> {
}
}
- fn lint_const_item_usage(
+ /// If we should lint on this usage, return the [`HirId`], source [`Span`]
+ /// and [`Span`] of the const item to use in the lint.
+ fn should_lint_const_item_usage(
&self,
place: &Place<'tcx>,
const_item: DefId,
location: Location,
- msg: impl Into<DiagnosticMessage>,
- decorate: impl for<'a, 'b> FnOnce(
- &'a mut DiagnosticBuilder<'b, ()>,
- ) -> &'a mut DiagnosticBuilder<'b, ()>,
- ) {
+ ) -> Option<(HirId, Span, Span)> {
// Don't lint on borrowing/assigning when a dereference is involved.
// If we 'leave' the temporary via a dereference, we must
// be modifying something else
@@ -83,16 +82,9 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> {
.assert_crate_local()
.lint_root;
- self.tcx.struct_span_lint_hir(
- CONST_ITEM_MUTATION,
- lint_root,
- source_info.span,
- msg,
- |lint| {
- decorate(lint)
- .span_note(self.tcx.def_span(const_item), "`const` item defined here")
- },
- );
+ Some((lint_root, source_info.span, self.tcx.def_span(const_item)))
+ } else {
+ None
}
}
}
@@ -104,10 +96,14 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> {
// Assigning directly to a constant (e.g. `FOO = true;`) is a hard error,
// so emitting a lint would be redundant.
if !lhs.projection.is_empty() {
- if let Some(def_id) = self.is_const_item_without_destructor(lhs.local) {
- self.lint_const_item_usage(&lhs, def_id, loc, "attempting to modify a `const` item",|lint| {
- lint.note("each usage of a `const` item creates a new temporary; the original `const` item will not be modified")
- })
+ if let Some(def_id) = self.is_const_item_without_destructor(lhs.local)
+ && let Some((lint_root, span, item)) = self.should_lint_const_item_usage(&lhs, def_id, loc) {
+ self.tcx.emit_spanned_lint(
+ CONST_ITEM_MUTATION,
+ lint_root,
+ span,
+ errors::ConstMutate::Modify { konst: item }
+ );
}
}
// We are looking for MIR of the form:
@@ -143,17 +139,22 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> {
});
let lint_loc =
if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc };
- self.lint_const_item_usage(place, def_id, lint_loc, "taking a mutable reference to a `const` item", |lint| {
- lint
- .note("each usage of a `const` item creates a new temporary")
- .note("the mutable reference will refer to this temporary, not the original `const` item");
-
- if let Some((method_did, _substs)) = method_did {
- lint.span_note(self.tcx.def_span(method_did), "mutable reference created due to call to this method");
- }
- lint
- });
+ let method_call = if let Some((method_did, _)) = method_did {
+ Some(self.tcx.def_span(method_did))
+ } else {
+ None
+ };
+ if let Some((lint_root, span, item)) =
+ self.should_lint_const_item_usage(place, def_id, lint_loc)
+ {
+ self.tcx.emit_spanned_lint(
+ CONST_ITEM_MUTATION,
+ lint_root,
+ span,
+ errors::ConstMutate::MutBorrow { method_call, konst: item },
+ );
+ }
}
}
self.super_rvalue(rvalue, loc);
diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs
index b9bc89fcf8f..2e6cf603d59 100644
--- a/compiler/rustc_mir_transform/src/check_packed_ref.rs
+++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs
@@ -1,10 +1,9 @@
-use rustc_errors::struct_span_err;
use rustc_middle::mir::visit::{PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt};
-use crate::util;
use crate::MirLint;
+use crate::{errors, util};
pub struct CheckPackedRef;
@@ -49,25 +48,7 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> {
// shouldn't do.
span_bug!(self.source_info.span, "builtin derive created an unaligned reference");
} else {
- struct_span_err!(
- self.tcx.sess,
- self.source_info.span,
- E0793,
- "reference to packed field is unaligned"
- )
- .note(
- "packed structs are only aligned by one byte, and many modern architectures \
- penalize unaligned field accesses"
- )
- .note(
- "creating a misaligned reference is undefined behavior (even if that \
- reference is never dereferenced)",
- ).help(
- "copy the field contents to a local variable, or replace the \
- reference with a raw pointer and use `read_unaligned`/`write_unaligned` \
- (loads and stores via `*p` must be properly aligned even when using raw pointers)"
- )
- .emit();
+ self.tcx.sess.emit_err(errors::UnalignedPackedRef { span: self.source_info.span });
}
}
}
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index ce6d865a7dc..069514d8a3b 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -1,5 +1,4 @@
use rustc_data_structures::unord::{UnordItems, UnordSet};
-use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -8,13 +7,15 @@ use rustc_hir::intravisit;
use rustc_hir::{BlockCheckMode, ExprKind, Node};
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
use rustc_session::lint::Level;
use std::ops::Bound;
+use crate::errors;
+
pub struct UnsafetyChecker<'a, 'tcx> {
body: &'a Body<'tcx>,
body_did: LocalDefId,
@@ -509,21 +510,12 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def: LocalDefId) -> &UnsafetyCheckResu
fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) {
let span = tcx.sess.source_map().guess_head_span(tcx.hir().span(id));
- let msg = "unnecessary `unsafe` block";
- tcx.struct_span_lint_hir(UNUSED_UNSAFE, id, span, msg, |lint| {
- lint.span_label(span, msg);
- match kind {
- UnusedUnsafe::Unused => {}
- UnusedUnsafe::InUnsafeBlock(id) => {
- lint.span_label(
- tcx.sess.source_map().guess_head_span(tcx.hir().span(id)),
- "because it's nested under this `unsafe` block",
- );
- }
- }
-
- lint
- });
+ let nested_parent = if let UnusedUnsafe::InUnsafeBlock(id) = kind {
+ Some(tcx.sess.source_map().guess_head_span(tcx.hir().span(id)))
+ } else {
+ None
+ };
+ tcx.emit_spanned_lint(UNUSED_UNSAFE, id, span, errors::UnusedUnsafe { span, nested_parent });
}
pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
@@ -537,26 +529,11 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let UnsafetyCheckResult { violations, unused_unsafes, .. } = tcx.unsafety_check_result(def_id);
for &UnsafetyViolation { source_info, lint_root, kind, details } in violations.iter() {
- let (description, note) = details.description_and_note();
+ let details = errors::RequiresUnsafeDetail { violation: details, span: source_info.span };
match kind {
UnsafetyViolationKind::General => {
- // once
- let unsafe_fn_msg = if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) {
- " function or"
- } else {
- ""
- };
-
- let mut err = struct_span_err!(
- tcx.sess,
- source_info.span,
- E0133,
- "{} is unsafe and requires unsafe{} block",
- description,
- unsafe_fn_msg,
- );
- err.span_label(source_info.span, description).note(note);
+ let op_in_unsafe_fn_allowed = unsafe_op_in_unsafe_fn_allowed(tcx, lint_root);
let note_non_inherited = tcx.hir().parent_iter(lint_root).find(|(id, node)| {
if let Node::Expr(block) = node
&& let ExprKind::Block(block, _) = block.kind
@@ -572,22 +549,23 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
false
}
});
- if let Some((id, _)) = note_non_inherited {
- let span = tcx.hir().span(id);
- err.span_label(
- tcx.sess.source_map().guess_head_span(span),
- "items do not inherit unsafety from separate enclosing items",
- );
- }
-
- err.emit();
+ let enclosing = if let Some((id, _)) = note_non_inherited {
+ Some(tcx.sess.source_map().guess_head_span(tcx.hir().span(id)))
+ } else {
+ None
+ };
+ tcx.sess.emit_err(errors::RequiresUnsafe {
+ span: source_info.span,
+ enclosing,
+ details,
+ op_in_unsafe_fn_allowed,
+ });
}
- UnsafetyViolationKind::UnsafeFn => tcx.struct_span_lint_hir(
+ UnsafetyViolationKind::UnsafeFn => tcx.emit_spanned_lint(
UNSAFE_OP_IN_UNSAFE_FN,
lint_root,
source_info.span,
- format!("{} is unsafe and requires unsafe block (error E0133)", description,),
- |lint| lint.span_label(source_info.span, description).note(note),
+ errors::UnsafeOpInUnsafeFn { details },
),
}
}
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index 7f995c69a48..a5d18fff89b 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -806,6 +806,24 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
}
}
+ fn process_projection_elem(
+ &mut self,
+ elem: PlaceElem<'tcx>,
+ _: Location,
+ ) -> Option<PlaceElem<'tcx>> {
+ if let PlaceElem::Index(local) = elem
+ && let Some(value) = self.get_const(local.into())
+ && self.should_const_prop(&value)
+ && let interpret::Operand::Immediate(interpret::Immediate::Scalar(scalar)) = *value
+ && let Ok(offset) = scalar.to_target_usize(&self.tcx)
+ && let Some(min_length) = offset.checked_add(1)
+ {
+ Some(PlaceElem::ConstantIndex { offset, min_length, from_end: false })
+ } else {
+ None
+ }
+ }
+
fn visit_assign(
&mut self,
place: &mut Place<'tcx>,
diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index a4049d08d7b..adb09c509d2 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -1,6 +1,8 @@
//! Propagates constants for early reporting of statically known
//! assertion failures
+use std::fmt::Debug;
+
use either::Left;
use rustc_const_eval::interpret::Immediate;
@@ -17,7 +19,6 @@ use rustc_middle::ty::InternalSubsts;
use rustc_middle::ty::{
self, ConstInt, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt,
};
-use rustc_session::lint;
use rustc_span::Span;
use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout};
use rustc_trait_selection::traits;
@@ -25,6 +26,7 @@ use rustc_trait_selection::traits;
use crate::const_prop::CanConstProp;
use crate::const_prop::ConstPropMachine;
use crate::const_prop::ConstPropMode;
+use crate::errors::AssertLint;
use crate::MirLint;
/// The maximum number of bytes that we'll allocate space for a local or the return value.
@@ -311,18 +313,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
}
}
- fn report_assert_as_lint(
- &self,
- lint: &'static lint::Lint,
- location: Location,
- message: &'static str,
- panic: AssertKind<impl std::fmt::Debug>,
- ) {
- let source_info = self.body().source_info(location);
+ fn report_assert_as_lint(&self, source_info: &SourceInfo, lint: AssertLint<impl Debug>) {
if let Some(lint_root) = self.lint_root(*source_info) {
- self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, message, |lint| {
- lint.span_label(source_info.span, format!("{:?}", panic))
- });
+ self.tcx.emit_spanned_lint(lint.lint(), lint_root, source_info.span, lint);
}
}
@@ -335,11 +328,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// `AssertKind` only has an `OverflowNeg` variant, so make sure that is
// appropriate to use.
assert_eq!(op, UnOp::Neg, "Neg is the only UnOp that can overflow");
+ let source_info = self.body().source_info(location);
self.report_assert_as_lint(
- lint::builtin::ARITHMETIC_OVERFLOW,
- location,
- "this arithmetic operation will overflow",
- AssertKind::OverflowNeg(val.to_const_int()),
+ source_info,
+ AssertLint::ArithmeticOverflow(
+ source_info.span,
+ AssertKind::OverflowNeg(val.to_const_int()),
+ ),
);
return None;
}
@@ -370,23 +365,23 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
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 {:?}", location);
+ let source_info = self.body().source_info(location);
+ let panic = AssertKind::Overflow(
+ op,
+ match l {
+ Some(l) => l.to_const_int(),
+ // Invent a dummy value, the diagnostic ignores it anyway
+ None => ConstInt::new(
+ ScalarInt::try_from_uint(1_u8, left_size).unwrap(),
+ left_ty.is_signed(),
+ left_ty.is_ptr_sized_integral(),
+ ),
+ },
+ r.to_const_int(),
+ );
self.report_assert_as_lint(
- lint::builtin::ARITHMETIC_OVERFLOW,
- location,
- "this arithmetic operation will overflow",
- AssertKind::Overflow(
- op,
- match l {
- Some(l) => l.to_const_int(),
- // Invent a dummy value, the diagnostic ignores it anyway
- None => ConstInt::new(
- ScalarInt::try_from_uint(1_u8, left_size).unwrap(),
- left_ty.is_signed(),
- left_ty.is_ptr_sized_integral(),
- ),
- },
- r.to_const_int(),
- ),
+ source_info,
+ AssertLint::ArithmeticOverflow(source_info.span, panic),
);
return None;
}
@@ -398,11 +393,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
let (_res, overflow, _ty) = this.ecx.overflowing_binary_op(op, &l, &r)?;
Ok(overflow)
})? {
+ let source_info = self.body().source_info(location);
self.report_assert_as_lint(
- lint::builtin::ARITHMETIC_OVERFLOW,
- location,
- "this arithmetic operation will overflow",
- AssertKind::Overflow(op, l.to_const_int(), r.to_const_int()),
+ source_info,
+ AssertLint::ArithmeticOverflow(
+ source_info.span,
+ AssertKind::Overflow(op, l.to_const_int(), r.to_const_int()),
+ ),
);
return None;
}
@@ -543,11 +540,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// Need proper const propagator for these.
_ => return None,
};
+ let source_info = self.body().source_info(location);
self.report_assert_as_lint(
- lint::builtin::UNCONDITIONAL_PANIC,
- location,
- "this operation will panic at runtime",
- msg,
+ source_info,
+ AssertLint::UnconditionalPanic(source_info.span, msg),
);
}
diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs
index 3922ed2fbf7..319f3a79705 100644
--- a/compiler/rustc_mir_transform/src/copy_prop.rs
+++ b/compiler/rustc_mir_transform/src/copy_prop.rs
@@ -33,9 +33,8 @@ impl<'tcx> MirPass<'tcx> for CopyProp {
}
fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
- let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
let borrowed_locals = borrowed_locals(body);
- let ssa = SsaLocals::new(tcx, param_env, body, &borrowed_locals);
+ let ssa = SsaLocals::new(body);
let fully_moved = fully_moved_locals(&ssa, body);
debug!(?fully_moved);
@@ -76,7 +75,7 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
fn fully_moved_locals(ssa: &SsaLocals, body: &Body<'_>) -> BitSet<Local> {
let mut fully_moved = BitSet::new_filled(body.local_decls.len());
- for (_, rvalue) in ssa.assignments(body) {
+ for (_, rvalue, _) in ssa.assignments(body) {
let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) | Rvalue::CopyForDeref(place))
= rvalue
else { continue };
@@ -163,20 +162,22 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
}
fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, loc: Location) {
- match stmt.kind {
- // When removing storage statements, we need to remove both (#107511).
- StatementKind::StorageLive(l) | StatementKind::StorageDead(l)
- if self.storage_to_remove.contains(l) =>
- {
- stmt.make_nop()
- }
- StatementKind::Assign(box (ref place, ref mut rvalue))
- if place.as_local().is_some() =>
- {
- // Do not replace assignments.
- self.visit_rvalue(rvalue, loc)
- }
- _ => self.super_statement(stmt, loc),
+ // When removing storage statements, we need to remove both (#107511).
+ if let StatementKind::StorageLive(l) | StatementKind::StorageDead(l) = stmt.kind
+ && self.storage_to_remove.contains(l)
+ {
+ stmt.make_nop();
+ return
+ }
+
+ self.super_statement(stmt, loc);
+
+ // Do not leave tautological assignments around.
+ if let StatementKind::Assign(box (lhs, ref rhs)) = stmt.kind
+ && let Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)) | Rvalue::CopyForDeref(rhs) = *rhs
+ && lhs == rhs
+ {
+ stmt.make_nop();
}
}
}
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index bf01b45eb40..74b4b4a07c5 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -2,7 +2,7 @@ use super::*;
use rustc_middle::mir::coverage::*;
use rustc_middle::mir::{self, Body, Coverage, CoverageInfo};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::def_id::DefId;
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 254b704f9fc..7adfc9dff2a 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -79,22 +79,22 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
&self.map
}
- fn handle_statement(&self, statement: &Statement<'tcx>, state: &mut State<Self::Value>) {
- match statement.kind {
- StatementKind::SetDiscriminant { box ref place, variant_index } => {
- state.flood_discr(place.as_ref(), &self.map);
- if self.map.find_discr(place.as_ref()).is_some() {
- let enum_ty = place.ty(self.local_decls, self.tcx).ty;
- if let Some(discr) = self.eval_discriminant(enum_ty, variant_index) {
- state.assign_discr(
- place.as_ref(),
- ValueOrPlace::Value(FlatSet::Elem(discr)),
- &self.map,
- );
- }
- }
+ fn handle_set_discriminant(
+ &self,
+ place: Place<'tcx>,
+ variant_index: VariantIdx,
+ state: &mut State<Self::Value>,
+ ) {
+ state.flood_discr(place.as_ref(), &self.map);
+ if self.map.find_discr(place.as_ref()).is_some() {
+ let enum_ty = place.ty(self.local_decls, self.tcx).ty;
+ if let Some(discr) = self.eval_discriminant(enum_ty, variant_index) {
+ state.assign_discr(
+ place.as_ref(),
+ ValueOrPlace::Value(FlatSet::Elem(discr)),
+ &self.map,
+ );
}
- _ => self.super_statement(statement, state),
}
}
@@ -208,8 +208,8 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
_ => unreachable!(),
}
.map(|result| ValueOrPlace::Value(self.wrap_immediate(result, *ty)))
- .unwrap_or(ValueOrPlace::top()),
- _ => ValueOrPlace::top(),
+ .unwrap_or(ValueOrPlace::TOP),
+ _ => ValueOrPlace::TOP,
},
Rvalue::BinaryOp(op, box (left, right)) => {
// Overflows must be ignored here.
diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
index 8ee08c5be34..a133c9d4782 100644
--- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
+++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
@@ -8,7 +8,7 @@
use rustc_hir::def_id::LocalDefId;
use rustc_index::bit_set::BitSet;
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
-use rustc_middle::mir::{Body, Local, Location, Operand, Terminator, TerminatorKind, RETURN_PLACE};
+use rustc_middle::mir::{Body, Location, Operand, Place, Terminator, TerminatorKind, RETURN_PLACE};
use rustc_middle::ty::{self, DeducedParamAttrs, Ty, TyCtxt};
use rustc_session::config::OptLevel;
@@ -29,31 +29,31 @@ impl DeduceReadOnly {
}
impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
- fn visit_local(&mut self, local: Local, mut context: PlaceContext, _: Location) {
+ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
// We're only interested in arguments.
- if local == RETURN_PLACE || local.index() > self.mutable_args.domain_size() {
+ if place.local == RETURN_PLACE || place.local.index() > self.mutable_args.domain_size() {
return;
}
- // Replace place contexts that are moves with copies. This is safe in all cases except
- // function argument position, which we already handled in `visit_terminator()` by using the
- // ArgumentChecker. See the comment in that method for more details.
- //
- // In the future, we might want to move this out into a separate pass, but for now let's
- // just do it on the fly because that's faster.
- if matches!(context, PlaceContext::NonMutatingUse(NonMutatingUseContext::Move)) {
- context = PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy);
- }
-
- match context {
- PlaceContext::MutatingUse(..)
- | PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => {
+ let mark_as_mutable = match context {
+ PlaceContext::MutatingUse(..) => {
// This is a mutation, so mark it as such.
- self.mutable_args.insert(local.index() - 1);
+ true
+ }
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) => {
+ // Whether mutating though a `&raw const` is allowed is still undecided, so we
+ // disable any sketchy `readonly` optimizations for now.
+ // But we only need to do this if the pointer would point into the argument.
+ !place.is_indirect()
}
PlaceContext::NonMutatingUse(..) | PlaceContext::NonUse(..) => {
// Not mutating, so it's fine.
+ false
}
+ };
+
+ if mark_as_mutable {
+ self.mutable_args.insert(place.local.index() - 1);
}
}
diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs
new file mode 100644
index 00000000000..602e40d5131
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/errors.rs
@@ -0,0 +1,245 @@
+use rustc_errors::{
+ DecorateLint, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler, IntoDiagnostic,
+};
+use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
+use rustc_middle::mir::{AssertKind, UnsafetyViolationDetails};
+use rustc_session::lint::{self, Lint};
+use rustc_span::Span;
+
+#[derive(LintDiagnostic)]
+pub(crate) enum ConstMutate {
+ #[diag(mir_transform_const_modify)]
+ #[note]
+ Modify {
+ #[note(mir_transform_const_defined_here)]
+ konst: Span,
+ },
+ #[diag(mir_transform_const_mut_borrow)]
+ #[note]
+ #[note(mir_transform_note2)]
+ MutBorrow {
+ #[note(mir_transform_note3)]
+ method_call: Option<Span>,
+ #[note(mir_transform_const_defined_here)]
+ konst: Span,
+ },
+}
+
+#[derive(Diagnostic)]
+#[diag(mir_transform_unaligned_packed_ref, code = "E0793")]
+#[note]
+#[note(mir_transform_note_ub)]
+#[help]
+pub(crate) struct UnalignedPackedRef {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(mir_transform_unused_unsafe)]
+pub(crate) struct UnusedUnsafe {
+ #[label(mir_transform_unused_unsafe)]
+ pub span: Span,
+ #[label]
+ pub nested_parent: Option<Span>,
+}
+
+pub(crate) struct RequiresUnsafe {
+ pub span: Span,
+ pub details: RequiresUnsafeDetail,
+ pub enclosing: Option<Span>,
+ pub op_in_unsafe_fn_allowed: bool,
+}
+
+// The primary message for this diagnostic should be '{$label} is unsafe and...',
+// so we need to eagerly translate the label here, which isn't supported by the derive API
+// We could also exhaustively list out the primary messages for all unsafe violations,
+// but this would result in a lot of duplication.
+impl<'sess, G: EmissionGuarantee> IntoDiagnostic<'sess, G> for RequiresUnsafe {
+ #[track_caller]
+ fn into_diagnostic(self, handler: &'sess Handler) -> DiagnosticBuilder<'sess, G> {
+ let mut diag =
+ handler.struct_diagnostic(crate::fluent_generated::mir_transform_requires_unsafe);
+ diag.code(rustc_errors::DiagnosticId::Error("E0133".to_string()));
+ diag.set_span(self.span);
+ diag.span_label(self.span, self.details.label());
+ diag.note(self.details.note());
+ let desc = handler.eagerly_translate_to_string(self.details.label(), [].into_iter());
+ diag.set_arg("details", desc);
+ diag.set_arg("op_in_unsafe_fn_allowed", self.op_in_unsafe_fn_allowed);
+ if let Some(sp) = self.enclosing {
+ diag.span_label(sp, crate::fluent_generated::mir_transform_not_inherited);
+ }
+ diag
+ }
+}
+
+#[derive(Copy, Clone)]
+pub(crate) struct RequiresUnsafeDetail {
+ pub span: Span,
+ pub violation: UnsafetyViolationDetails,
+}
+
+impl RequiresUnsafeDetail {
+ fn note(self) -> DiagnosticMessage {
+ use UnsafetyViolationDetails::*;
+ match self.violation {
+ CallToUnsafeFunction => crate::fluent_generated::mir_transform_call_to_unsafe_note,
+ UseOfInlineAssembly => crate::fluent_generated::mir_transform_use_of_asm_note,
+ InitializingTypeWith => {
+ crate::fluent_generated::mir_transform_initializing_valid_range_note
+ }
+ CastOfPointerToInt => crate::fluent_generated::mir_transform_const_ptr2int_note,
+ UseOfMutableStatic => crate::fluent_generated::mir_transform_use_of_static_mut_note,
+ UseOfExternStatic => crate::fluent_generated::mir_transform_use_of_extern_static_note,
+ DerefOfRawPointer => crate::fluent_generated::mir_transform_deref_ptr_note,
+ AccessToUnionField => crate::fluent_generated::mir_transform_union_access_note,
+ MutationOfLayoutConstrainedField => {
+ crate::fluent_generated::mir_transform_mutation_layout_constrained_note
+ }
+ BorrowOfLayoutConstrainedField => {
+ crate::fluent_generated::mir_transform_mutation_layout_constrained_borrow_note
+ }
+ CallToFunctionWith => crate::fluent_generated::mir_transform_target_feature_call_note,
+ }
+ }
+
+ fn label(self) -> DiagnosticMessage {
+ use UnsafetyViolationDetails::*;
+ match self.violation {
+ CallToUnsafeFunction => crate::fluent_generated::mir_transform_call_to_unsafe_label,
+ UseOfInlineAssembly => crate::fluent_generated::mir_transform_use_of_asm_label,
+ InitializingTypeWith => {
+ crate::fluent_generated::mir_transform_initializing_valid_range_label
+ }
+ CastOfPointerToInt => crate::fluent_generated::mir_transform_const_ptr2int_label,
+ UseOfMutableStatic => crate::fluent_generated::mir_transform_use_of_static_mut_label,
+ UseOfExternStatic => crate::fluent_generated::mir_transform_use_of_extern_static_label,
+ DerefOfRawPointer => crate::fluent_generated::mir_transform_deref_ptr_label,
+ AccessToUnionField => crate::fluent_generated::mir_transform_union_access_label,
+ MutationOfLayoutConstrainedField => {
+ crate::fluent_generated::mir_transform_mutation_layout_constrained_label
+ }
+ BorrowOfLayoutConstrainedField => {
+ crate::fluent_generated::mir_transform_mutation_layout_constrained_borrow_label
+ }
+ CallToFunctionWith => crate::fluent_generated::mir_transform_target_feature_call_label,
+ }
+ }
+}
+
+pub(crate) struct UnsafeOpInUnsafeFn {
+ pub details: RequiresUnsafeDetail,
+}
+
+impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn {
+ #[track_caller]
+ fn decorate_lint<'b>(
+ self,
+ diag: &'b mut DiagnosticBuilder<'a, ()>,
+ ) -> &'b mut DiagnosticBuilder<'a, ()> {
+ let desc = diag
+ .handler()
+ .expect("lint should not yet be emitted")
+ .eagerly_translate_to_string(self.details.label(), [].into_iter());
+ diag.set_arg("details", desc);
+ diag.span_label(self.details.span, self.details.label());
+ diag.note(self.details.note());
+ diag
+ }
+
+ fn msg(&self) -> DiagnosticMessage {
+ crate::fluent_generated::mir_transform_unsafe_op_in_unsafe_fn
+ }
+}
+
+pub(crate) enum AssertLint<P> {
+ ArithmeticOverflow(Span, AssertKind<P>),
+ UnconditionalPanic(Span, AssertKind<P>),
+}
+
+impl<'a, P: std::fmt::Debug> DecorateLint<'a, ()> for AssertLint<P> {
+ fn decorate_lint<'b>(
+ self,
+ diag: &'b mut DiagnosticBuilder<'a, ()>,
+ ) -> &'b mut DiagnosticBuilder<'a, ()> {
+ diag.span_label(self.span(), format!("{:?}", self.panic()));
+ diag
+ }
+
+ fn msg(&self) -> DiagnosticMessage {
+ match self {
+ AssertLint::ArithmeticOverflow(..) => {
+ crate::fluent_generated::mir_transform_arithmetic_overflow
+ }
+ AssertLint::UnconditionalPanic(..) => {
+ crate::fluent_generated::mir_transform_operation_will_panic
+ }
+ }
+ }
+}
+
+impl<P> AssertLint<P> {
+ pub fn lint(&self) -> &'static Lint {
+ match self {
+ AssertLint::ArithmeticOverflow(..) => lint::builtin::ARITHMETIC_OVERFLOW,
+ AssertLint::UnconditionalPanic(..) => lint::builtin::UNCONDITIONAL_PANIC,
+ }
+ }
+ pub fn span(&self) -> Span {
+ match self {
+ AssertLint::ArithmeticOverflow(sp, _) | AssertLint::UnconditionalPanic(sp, _) => *sp,
+ }
+ }
+ pub fn panic(&self) -> &AssertKind<P> {
+ match self {
+ AssertLint::ArithmeticOverflow(_, p) | AssertLint::UnconditionalPanic(_, p) => p,
+ }
+ }
+}
+
+#[derive(LintDiagnostic)]
+#[diag(mir_transform_ffi_unwind_call)]
+pub(crate) struct FfiUnwindCall {
+ #[label(mir_transform_ffi_unwind_call)]
+ pub span: Span,
+ pub foreign: bool,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(mir_transform_fn_item_ref)]
+pub(crate) struct FnItemRef {
+ #[suggestion(code = "{sugg}", applicability = "unspecified")]
+ pub span: Span,
+ pub sugg: String,
+ pub ident: String,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(mir_transform_must_not_suspend)]
+pub(crate) struct MustNotSupend<'a> {
+ #[label]
+ pub yield_sp: Span,
+ #[subdiagnostic]
+ pub reason: Option<MustNotSuspendReason>,
+ #[help]
+ pub src_sp: Span,
+ pub pre: &'a str,
+ pub def_path: String,
+ pub post: &'a str,
+}
+
+#[derive(Subdiagnostic)]
+#[note(mir_transform_note)]
+pub(crate) struct MustNotSuspendReason {
+ #[primary_span]
+ pub span: Span,
+ pub reason: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(mir_transform_simd_shuffle_last_const)]
+pub(crate) struct SimdShuffleLastConst {
+ #[primary_span]
+ pub span: Span,
+}
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index db68adc8bc9..58cc161ddcc 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -1,13 +1,15 @@
use rustc_hir::def_id::{LocalDefId, LOCAL_CRATE};
use rustc_middle::mir::*;
use rustc_middle::query::LocalCrate;
+use rustc_middle::query::Providers;
use rustc_middle::ty::layout;
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::FFI_UNWIND_CALLS;
use rustc_target::spec::abi::Abi;
use rustc_target::spec::PanicStrategy;
+use crate::errors;
+
fn abi_can_unwind(abi: Abi) -> bool {
use Abi::*;
match abi {
@@ -107,13 +109,13 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
.lint_root;
let span = terminator.source_info.span;
- let msg = match fn_def_id {
- Some(_) => "call to foreign function with FFI-unwind ABI",
- None => "call to function pointer with FFI-unwind ABI",
- };
- tcx.struct_span_lint_hir(FFI_UNWIND_CALLS, lint_root, span, msg, |lint| {
- lint.span_label(span, msg)
- });
+ let foreign = fn_def_id.is_some();
+ tcx.emit_spanned_lint(
+ FFI_UNWIND_CALLS,
+ lint_root,
+ span,
+ errors::FfiUnwindCall { span, foreign },
+ );
tainted = true;
}
diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs
index f26c6de9648..5989dbebf2d 100644
--- a/compiler/rustc_mir_transform/src/function_item_references.rs
+++ b/compiler/rustc_mir_transform/src/function_item_references.rs
@@ -1,5 +1,4 @@
use itertools::Itertools;
-use rustc_errors::Applicability;
use rustc_hir::def_id::DefId;
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::*;
@@ -8,7 +7,7 @@ use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES;
use rustc_span::{symbol::sym, Span};
use rustc_target::spec::abi::Abi;
-use crate::MirLint;
+use crate::{errors, MirLint};
pub struct FunctionItemReferences;
@@ -174,27 +173,21 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
let num_args = fn_sig.inputs().map_bound(|inputs| inputs.len()).skip_binder();
let variadic = if fn_sig.c_variadic() { ", ..." } else { "" };
let ret = if fn_sig.output().skip_binder().is_unit() { "" } else { " -> _" };
- self.tcx.struct_span_lint_hir(
+ let sugg = format!(
+ "{} as {}{}fn({}{}){}",
+ if params.is_empty() { ident.clone() } else { format!("{}::<{}>", ident, params) },
+ unsafety,
+ abi,
+ vec!["_"; num_args].join(", "),
+ variadic,
+ ret,
+ );
+
+ self.tcx.emit_spanned_lint(
FUNCTION_ITEM_REFERENCES,
lint_root,
span,
- "taking a reference to a function item does not give a function pointer",
- |lint| {
- lint.span_suggestion(
- span,
- format!("cast `{}` to obtain a function pointer", ident),
- format!(
- "{} as {}{}fn({}{}){}",
- if params.is_empty() { ident } else { format!("{}::<{}>", ident, params) },
- unsafety,
- abi,
- vec!["_"; num_args].join(", "),
- variadic,
- ret,
- ),
- Applicability::Unspecified,
- )
- },
+ errors::FnItemRef { span, sugg, ident },
);
}
}
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 9e16c400f14..891e446942e 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -51,6 +51,7 @@
//! Otherwise it drops all the values in scope at the last suspension point.
use crate::deref_separator::deref_finder;
+use crate::errors;
use crate::simplify;
use crate::MirPass;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -1396,7 +1397,7 @@ fn create_cases<'tcx>(
pub(crate) fn mir_generator_witnesses<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
-) -> GeneratorLayout<'tcx> {
+) -> Option<GeneratorLayout<'tcx>> {
assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir);
let (body, _) = tcx.mir_promoted(def_id);
@@ -1409,6 +1410,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
// Get the interior types and substs which typeck computed
let movable = match *gen_ty.kind() {
ty::Generator(_, _, movability) => movability == hir::Movability::Movable,
+ ty::Error(_) => return None,
_ => span_bug!(body.span, "unexpected generator type {}", gen_ty),
};
@@ -1424,7 +1426,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
check_suspend_tys(tcx, &generator_layout, &body);
- generator_layout
+ Some(generator_layout)
}
impl<'tcx> MirPass<'tcx> for StateTransform {
@@ -1891,36 +1893,21 @@ fn check_must_not_suspend_def(
data: SuspendCheckData<'_>,
) -> bool {
if let Some(attr) = tcx.get_attr(def_id, sym::must_not_suspend) {
- let msg = rustc_errors::DelayDm(|| {
- format!(
- "{}`{}`{} held across a suspend point, but should not be",
- data.descr_pre,
- tcx.def_path_str(def_id),
- data.descr_post,
- )
+ let reason = attr.value_str().map(|s| errors::MustNotSuspendReason {
+ span: data.source_span,
+ reason: s.as_str().to_string(),
});
- tcx.struct_span_lint_hir(
+ tcx.emit_spanned_lint(
rustc_session::lint::builtin::MUST_NOT_SUSPEND,
hir_id,
data.source_span,
- msg,
- |lint| {
- // add span pointing to the offending yield/await
- lint.span_label(data.yield_span, "the value is held across this suspend point");
-
- // Add optional reason note
- if let Some(note) = attr.value_str() {
- // FIXME(guswynn): consider formatting this better
- lint.span_note(data.source_span, note.as_str());
- }
-
- // Add some quick suggestions on what to do
- // FIXME: can `drop` work as a suggestion here as well?
- lint.span_help(
- data.source_span,
- "consider using a block (`{ ... }`) \
- to shrink the value's scope, ending before the suspend point",
- )
+ errors::MustNotSupend {
+ yield_sp: data.yield_span,
+ reason,
+ src_sp: data.source_span,
+ pre: data.descr_pre,
+ def_path: tcx.def_path_str(def_id),
+ post: data.descr_post,
},
);
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index ece20d8d3e6..12f955d46bd 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -7,6 +7,7 @@ use rustc_index::Idx;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
+use rustc_middle::ty::TypeVisitableExt;
use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
use rustc_session::config::OptLevel;
use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span};
@@ -168,7 +169,7 @@ impl<'tcx> Inliner<'tcx> {
let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id());
self.check_codegen_attributes(callsite, callee_attrs)?;
self.check_mir_is_available(caller_body, &callsite.callee)?;
- let callee_body = self.tcx.instance_mir(callsite.callee.def);
+ let callee_body = try_instance_mir(self.tcx, callsite.callee.def)?;
self.check_mir_body(callsite, callee_body, callee_attrs)?;
if !self.tcx.consider_optimizing(|| {
@@ -1128,3 +1129,27 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
}
}
}
+
+#[instrument(skip(tcx), level = "debug")]
+fn try_instance_mir<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ instance: InstanceDef<'tcx>,
+) -> Result<&'tcx Body<'tcx>, &'static str> {
+ match instance {
+ ty::InstanceDef::DropGlue(_, Some(ty)) => match ty.kind() {
+ ty::Adt(def, substs) => {
+ let fields = def.all_fields();
+ for field in fields {
+ let field_ty = field.ty(tcx, substs);
+ if field_ty.has_param() && field_ty.has_projections() {
+ return Err("cannot build drop shim for polymorphic type");
+ }
+ }
+
+ Ok(tcx.instance_mir(instance))
+ }
+ _ => Ok(tcx.instance_mir(instance)),
+ },
+ _ => Ok(tcx.instance_mir(instance)),
+ }
+}
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index 6bff535586a..e4dc617620e 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -5,7 +5,6 @@ use crate::MirPass;
use rustc_hir::Mutability;
use rustc_middle::mir::*;
use rustc_middle::ty::layout::ValidityRequirement;
-use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt};
use rustc_span::symbol::Symbol;
use rustc_target::abi::FieldIdx;
@@ -163,18 +162,6 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
return;
}
- // Transmuting a fieldless enum to its repr is a discriminant read
- if let ty::Adt(adt_def, ..) = operand_ty.kind()
- && adt_def.is_enum()
- && adt_def.is_payloadfree()
- && let Some(place) = operand.place()
- && let Some(repr_int) = adt_def.repr().int
- && repr_int.to_ty(self.tcx) == *cast_ty
- {
- *rvalue = Rvalue::Discriminant(place);
- return;
- }
-
// Transmuting a transparent struct/union to a field's type is a projection
if let ty::Adt(adt_def, substs) = operand_ty.kind()
&& adt_def.repr().transparent()
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index f25a9f042c4..65864dc016f 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -1,4 +1,6 @@
#![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#![feature(box_patterns)]
#![feature(drain_filter)]
#![feature(let_chains)]
@@ -32,7 +34,7 @@ use rustc_middle::mir::{
MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
Statement, StatementKind, TerminatorKind, START_BLOCK,
};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_span::sym;
use rustc_trait_selection::traits;
@@ -69,6 +71,7 @@ pub mod dump_mir;
mod early_otherwise_branch;
mod elaborate_box_derefs;
mod elaborate_drops;
+mod errors;
mod ffi_unwind_calls;
mod function_item_references;
mod generator;
@@ -81,6 +84,7 @@ mod match_branches;
mod multiple_return_terminators;
mod normalize_array_len;
mod nrvo;
+mod ref_prop;
mod remove_noop_landing_pads;
mod remove_storage_markers;
mod remove_uninit_drops;
@@ -105,6 +109,11 @@ use rustc_const_eval::transform::promote_consts;
use rustc_const_eval::transform::validate;
use rustc_mir_dataflow::rustc_peek;
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_fluent_macro::fluent_messages;
+
+fluent_messages! { "../messages.ftl" }
+
pub fn provide(providers: &mut Providers) {
check_unsafety::provide(providers);
coverage::query::provide(providers);
@@ -551,6 +560,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
&separate_const_switch::SeparateConstSwitch,
&simplify::SimplifyLocals::BeforeConstProp,
&copy_prop::CopyProp,
+ &ref_prop::ReferencePropagation,
&const_prop::ConstProp,
&dataflow_const_prop::DataflowConstProp,
//
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index 69ba4840146..dae01e41e5f 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -1,6 +1,6 @@
//! Lowers intrinsic calls
-use crate::MirPass;
+use crate::{errors, MirPass};
use rustc_middle::mir::*;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -310,11 +310,7 @@ fn resolve_rust_intrinsic<'tcx>(
}
fn validate_simd_shuffle<'tcx>(tcx: TyCtxt<'tcx>, args: &[Operand<'tcx>], span: Span) {
- match &args[2] {
- Operand::Constant(_) => {} // all good
- _ => {
- let msg = "last argument of `simd_shuffle` is required to be a `const` item";
- tcx.sess.span_err(span, msg);
- }
+ if !matches!(args[2], Operand::Constant(_)) {
+ tcx.sess.emit_err(errors::SimdShuffleLastConst { span });
}
}
diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs
index b3b831bb4ab..3d61d33ce35 100644
--- a/compiler/rustc_mir_transform/src/normalize_array_len.rs
+++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs
@@ -7,7 +7,6 @@ use rustc_index::IndexVec;
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt};
-use rustc_mir_dataflow::impls::borrowed_locals;
pub struct NormalizeArrayLen;
@@ -24,9 +23,7 @@ impl<'tcx> MirPass<'tcx> for NormalizeArrayLen {
}
fn normalize_array_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
- let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
- let borrowed_locals = borrowed_locals(body);
- let ssa = SsaLocals::new(tcx, param_env, body, &borrowed_locals);
+ let ssa = SsaLocals::new(body);
let slice_lengths = compute_slice_length(tcx, &ssa, body);
debug!(?slice_lengths);
@@ -41,7 +38,7 @@ fn compute_slice_length<'tcx>(
) -> IndexVec<Local, Option<ty::Const<'tcx>>> {
let mut slice_lengths = IndexVec::from_elem(None, &body.local_decls);
- for (local, rvalue) in ssa.assignments(body) {
+ for (local, rvalue, _) in ssa.assignments(body) {
match rvalue {
Rvalue::Cast(
CastKind::Pointer(ty::adjustment::PointerCast::Unsize),
diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs
index b6e73eaad50..85b26220b1e 100644
--- a/compiler/rustc_mir_transform/src/nrvo.rs
+++ b/compiler/rustc_mir_transform/src/nrvo.rs
@@ -34,7 +34,8 @@ pub struct RenameReturnPlace;
impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
- sess.mir_opt_level() > 0
+ // #111005
+ sess.mir_opt_level() > 0 && sess.opts.unstable_opts.unsound_mir_opts
}
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) {
diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs
new file mode 100644
index 00000000000..bbd9f76ba5c
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/ref_prop.rs
@@ -0,0 +1,408 @@
+use rustc_data_structures::fx::FxHashSet;
+use rustc_index::bit_set::BitSet;
+use rustc_index::IndexVec;
+use rustc_middle::mir::visit::*;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
+use rustc_mir_dataflow::impls::MaybeStorageDead;
+use rustc_mir_dataflow::storage::always_storage_live_locals;
+use rustc_mir_dataflow::Analysis;
+
+use crate::ssa::{SsaLocals, StorageLiveLocals};
+use crate::MirPass;
+
+/// Propagate references using SSA analysis.
+///
+/// MIR building may produce a lot of borrow-dereference patterns.
+///
+/// This pass aims to transform the following pattern:
+/// _1 = &raw? mut? PLACE;
+/// _3 = *_1;
+/// _4 = &raw? mut? *_1;
+///
+/// Into
+/// _1 = &raw? mut? PLACE;
+/// _3 = PLACE;
+/// _4 = &raw? mut? PLACE;
+///
+/// where `PLACE` is a direct or an indirect place expression.
+///
+/// There are 3 properties that need to be upheld for this transformation to be legal:
+/// - place stability: `PLACE` must refer to the same memory wherever it appears;
+/// - pointer liveness: we must not introduce dereferences of dangling pointers;
+/// - `&mut` borrow uniqueness.
+///
+/// # Stability
+///
+/// If `PLACE` is an indirect projection, if its of the form `(*LOCAL).PROJECTIONS` where:
+/// - `LOCAL` is SSA;
+/// - all projections in `PROJECTIONS` have a stable offset (no dereference and no indexing).
+///
+/// If `PLACE` is a direct projection of a local, we consider it as constant if:
+/// - the local is always live, or it has a single `StorageLive`;
+/// - all projections have a stable offset.
+///
+/// # Liveness
+///
+/// When performing a substitution, we must take care not to introduce uses of dangling locals.
+/// To ensure this, we walk the body with the `MaybeStorageDead` dataflow analysis:
+/// - if we want to replace `*x` by reborrow `*y` and `y` may be dead, we allow replacement and
+/// mark storage statements on `y` for removal;
+/// - if we want to replace `*x` by non-reborrow `y` and `y` must be live, we allow replacement;
+/// - if we want to replace `*x` by non-reborrow `y` and `y` may be dead, we do not replace.
+///
+/// # Uniqueness
+///
+/// For `&mut` borrows, we also need to preserve the uniqueness property:
+/// we must avoid creating a state where we interleave uses of `*_1` and `_2`.
+/// To do it, we only perform full substitution of mutable borrows:
+/// we replace either all or none of the occurrences of `*_1`.
+///
+/// Some care has to be taken when `_1` is copied in other locals.
+/// _1 = &raw? mut? _2;
+/// _3 = *_1;
+/// _4 = _1
+/// _5 = *_4
+/// In such cases, fully substituting `_1` means fully substituting all of the copies.
+///
+/// For immutable borrows, we do not need to preserve such uniqueness property,
+/// so we perform all the possible substitutions without removing the `_1 = &_2` statement.
+pub struct ReferencePropagation;
+
+impl<'tcx> MirPass<'tcx> for ReferencePropagation {
+ fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
+ sess.mir_opt_level() >= 4
+ }
+
+ #[instrument(level = "trace", skip(self, tcx, body))]
+ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+ debug!(def_id = ?body.source.def_id());
+ while propagate_ssa(tcx, body) {}
+ }
+}
+
+fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
+ let ssa = SsaLocals::new(body);
+
+ let mut replacer = compute_replacement(tcx, body, &ssa);
+ debug!(?replacer.targets);
+ debug!(?replacer.allowed_replacements);
+ debug!(?replacer.storage_to_remove);
+
+ replacer.visit_body_preserves_cfg(body);
+
+ if replacer.any_replacement {
+ crate::simplify::remove_unused_definitions(body);
+ }
+
+ replacer.any_replacement
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+enum Value<'tcx> {
+ /// Not a pointer, or we can't know.
+ Unknown,
+ /// We know the value to be a pointer to this place.
+ /// The boolean indicates whether the reference is mutable, subject the uniqueness rule.
+ Pointer(Place<'tcx>, bool),
+}
+
+/// For each local, save the place corresponding to `*local`.
+#[instrument(level = "trace", skip(tcx, body))]
+fn compute_replacement<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ body: &Body<'tcx>,
+ ssa: &SsaLocals,
+) -> Replacer<'tcx> {
+ let always_live_locals = always_storage_live_locals(body);
+
+ // Compute which locals have a single `StorageLive` statement ever.
+ let storage_live = StorageLiveLocals::new(body, &always_live_locals);
+
+ // Compute `MaybeStorageDead` dataflow to check that we only replace when the pointee is
+ // definitely live.
+ let mut maybe_dead = MaybeStorageDead::new(always_live_locals)
+ .into_engine(tcx, body)
+ .iterate_to_fixpoint()
+ .into_results_cursor(body);
+
+ // Map for each local to the pointee.
+ let mut targets = IndexVec::from_elem(Value::Unknown, &body.local_decls);
+ // Set of locals for which we will remove their storage statement. This is useful for
+ // reborrowed references.
+ let mut storage_to_remove = BitSet::new_empty(body.local_decls.len());
+
+ let fully_replacable_locals = fully_replacable_locals(ssa);
+
+ // Returns true iff we can use `place` as a pointee.
+ //
+ // Note that we only need to verify that there is a single `StorageLive` statement, and we do
+ // not need to verify that it dominates all uses of that local.
+ //
+ // Consider the three statements:
+ // SL : StorageLive(a)
+ // DEF: b = &raw? mut? a
+ // USE: stuff that uses *b
+ //
+ // First, we recall that DEF is checked to dominate USE. Now imagine for the sake of
+ // contradiction there is a DEF -> SL -> USE path. Consider two cases:
+ //
+ // - DEF dominates SL. We always have UB the first time control flow reaches DEF,
+ // because the storage of `a` is dead. Since DEF dominates USE, that means we cannot
+ // reach USE and so our optimization is ok.
+ //
+ // - DEF does not dominate SL. Then there is a `START_BLOCK -> SL` path not including DEF.
+ // But we can extend this path to USE, meaning there is also a `START_BLOCK -> USE` path not
+ // including DEF. This violates the DEF dominates USE condition, and so is impossible.
+ let is_constant_place = |place: Place<'_>| {
+ // We only allow `Deref` as the first projection, to avoid surprises.
+ if place.projection.first() == Some(&PlaceElem::Deref) {
+ // `place == (*some_local).xxx`, it is constant only if `some_local` is constant.
+ // We approximate constness using SSAness.
+ ssa.is_ssa(place.local) && place.projection[1..].iter().all(PlaceElem::is_stable_offset)
+ } else {
+ storage_live.has_single_storage(place.local)
+ && place.projection[..].iter().all(PlaceElem::is_stable_offset)
+ }
+ };
+
+ let mut can_perform_opt = |target: Place<'tcx>, loc: Location| {
+ if target.projection.first() == Some(&PlaceElem::Deref) {
+ // We are creating a reborrow. As `place.local` is a reference, removing the storage
+ // statements should not make it much harder for LLVM to optimize.
+ storage_to_remove.insert(target.local);
+ true
+ } else {
+ // This is a proper dereference. We can only allow it if `target` is live.
+ maybe_dead.seek_after_primary_effect(loc);
+ let maybe_dead = maybe_dead.contains(target.local);
+ !maybe_dead
+ }
+ };
+
+ for (local, rvalue, location) in ssa.assignments(body) {
+ debug!(?local);
+
+ // Only visit if we have something to do.
+ let Value::Unknown = targets[local] else { bug!() };
+
+ let ty = body.local_decls[local].ty;
+
+ // If this is not a reference or pointer, do nothing.
+ if !ty.is_any_ptr() {
+ debug!("not a reference or pointer");
+ continue;
+ }
+
+ // Whether the current local is subject to the uniqueness rule.
+ let needs_unique = ty.is_mutable_ptr();
+
+ // If this a mutable reference that we cannot fully replace, mark it as unknown.
+ if needs_unique && !fully_replacable_locals.contains(local) {
+ debug!("not fully replaceable");
+ continue;
+ }
+
+ debug!(?rvalue);
+ match rvalue {
+ // This is a copy, just use the value we have in store for the previous one.
+ // As we are visiting in `assignment_order`, ie. reverse postorder, `rhs` should
+ // have been visited before.
+ Rvalue::Use(Operand::Copy(place) | Operand::Move(place))
+ | Rvalue::CopyForDeref(place) => {
+ if let Some(rhs) = place.as_local() && ssa.is_ssa(rhs) {
+ let target = targets[rhs];
+ // Only see through immutable reference and pointers, as we do not know yet if
+ // mutable references are fully replaced.
+ if !needs_unique && matches!(target, Value::Pointer(..)) {
+ targets[local] = target;
+ } else {
+ targets[local] = Value::Pointer(tcx.mk_place_deref(rhs.into()), needs_unique);
+ }
+ }
+ }
+ Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
+ let mut place = *place;
+ // Try to see through `place` in order to collapse reborrow chains.
+ if place.projection.first() == Some(&PlaceElem::Deref)
+ && let Value::Pointer(target, inner_needs_unique) = targets[place.local]
+ // Only see through immutable reference and pointers, as we do not know yet if
+ // mutable references are fully replaced.
+ && !inner_needs_unique
+ // Only collapse chain if the pointee is definitely live.
+ && can_perform_opt(target, location)
+ {
+ place = target.project_deeper(&place.projection[1..], tcx);
+ }
+ assert_ne!(place.local, local);
+ if is_constant_place(place) {
+ targets[local] = Value::Pointer(place, needs_unique);
+ }
+ }
+ // We do not know what to do, so keep as not-a-pointer.
+ _ => {}
+ }
+ }
+
+ debug!(?targets);
+
+ let mut finder = ReplacementFinder {
+ targets: &mut targets,
+ can_perform_opt,
+ allowed_replacements: FxHashSet::default(),
+ };
+ let reachable_blocks = traversal::reachable_as_bitset(body);
+ for (bb, bbdata) in body.basic_blocks.iter_enumerated() {
+ // Only visit reachable blocks as we rely on dataflow.
+ if reachable_blocks.contains(bb) {
+ finder.visit_basic_block_data(bb, bbdata);
+ }
+ }
+
+ let allowed_replacements = finder.allowed_replacements;
+ return Replacer {
+ tcx,
+ targets,
+ storage_to_remove,
+ allowed_replacements,
+ fully_replacable_locals,
+ any_replacement: false,
+ };
+
+ struct ReplacementFinder<'a, 'tcx, F> {
+ targets: &'a mut IndexVec<Local, Value<'tcx>>,
+ can_perform_opt: F,
+ allowed_replacements: FxHashSet<(Local, Location)>,
+ }
+
+ impl<'tcx, F> Visitor<'tcx> for ReplacementFinder<'_, 'tcx, F>
+ where
+ F: FnMut(Place<'tcx>, Location) -> bool,
+ {
+ fn visit_place(&mut self, place: &Place<'tcx>, ctxt: PlaceContext, loc: Location) {
+ if matches!(ctxt, PlaceContext::NonUse(_)) {
+ // There is no need to check liveness for non-uses.
+ return;
+ }
+
+ if place.projection.first() != Some(&PlaceElem::Deref) {
+ // This is not a dereference, nothing to do.
+ return;
+ }
+
+ let mut place = place.as_ref();
+ loop {
+ if let Value::Pointer(target, needs_unique) = self.targets[place.local] {
+ let perform_opt = (self.can_perform_opt)(target, loc);
+ debug!(?place, ?target, ?needs_unique, ?perform_opt);
+
+ // This a reborrow chain, recursively allow the replacement.
+ //
+ // This also allows to detect cases where `target.local` is not replacable,
+ // and mark it as such.
+ if let &[PlaceElem::Deref] = &target.projection[..] {
+ assert!(perform_opt);
+ self.allowed_replacements.insert((target.local, loc));
+ place.local = target.local;
+ continue;
+ } else if perform_opt {
+ self.allowed_replacements.insert((target.local, loc));
+ } else if needs_unique {
+ // This mutable reference is not fully replacable, so drop it.
+ self.targets[place.local] = Value::Unknown;
+ }
+ }
+
+ break;
+ }
+ }
+ }
+}
+
+/// Compute the set of locals that can be fully replaced.
+///
+/// We consider a local to be replacable iff it's only used in a `Deref` projection `*_local` or
+/// non-use position (like storage statements and debuginfo).
+fn fully_replacable_locals(ssa: &SsaLocals) -> BitSet<Local> {
+ let mut replacable = BitSet::new_empty(ssa.num_locals());
+
+ // First pass: for each local, whether its uses can be fully replaced.
+ for local in ssa.locals() {
+ if ssa.num_direct_uses(local) == 0 {
+ replacable.insert(local);
+ }
+ }
+
+ // Second pass: a local can only be fully replaced if all its copies can.
+ ssa.meet_copy_equivalence(&mut replacable);
+
+ replacable
+}
+
+/// Utility to help performing subtitution of `*pattern` by `target`.
+struct Replacer<'tcx> {
+ tcx: TyCtxt<'tcx>,
+ targets: IndexVec<Local, Value<'tcx>>,
+ storage_to_remove: BitSet<Local>,
+ allowed_replacements: FxHashSet<(Local, Location)>,
+ any_replacement: bool,
+ fully_replacable_locals: BitSet<Local>,
+}
+
+impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
+ fn tcx(&self) -> TyCtxt<'tcx> {
+ self.tcx
+ }
+
+ fn visit_var_debug_info(&mut self, debuginfo: &mut VarDebugInfo<'tcx>) {
+ if let VarDebugInfoContents::Place(ref mut place) = debuginfo.value
+ && place.projection.is_empty()
+ && let Value::Pointer(target, _) = self.targets[place.local]
+ && target.projection.iter().all(|p| p.can_use_in_debuginfo())
+ {
+ if let Some((&PlaceElem::Deref, rest)) = target.projection.split_last() {
+ *place = Place::from(target.local).project_deeper(rest, self.tcx);
+ self.any_replacement = true;
+ } else if self.fully_replacable_locals.contains(place.local)
+ && let Some(references) = debuginfo.references.checked_add(1)
+ {
+ debuginfo.references = references;
+ *place = target;
+ self.any_replacement = true;
+ }
+ }
+ }
+
+ fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) {
+ if place.projection.first() != Some(&PlaceElem::Deref) {
+ return;
+ }
+
+ loop {
+ if let Value::Pointer(target, _) = self.targets[place.local] {
+ let perform_opt = matches!(ctxt, PlaceContext::NonUse(_))
+ || self.allowed_replacements.contains(&(target.local, loc));
+
+ if perform_opt {
+ *place = target.project_deeper(&place.projection[1..], self.tcx);
+ self.any_replacement = true;
+ continue;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, loc: Location) {
+ match stmt.kind {
+ StatementKind::StorageLive(l) | StatementKind::StorageDead(l)
+ if self.storage_to_remove.contains(l) =>
+ {
+ stmt.make_nop();
+ }
+ // Do not remove assignments as they may still be useful for debuginfo.
+ _ => self.super_statement(stmt, loc),
+ }
+ }
+}
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 19d07fab0b9..7c47d8814db 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -2,7 +2,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_middle::mir::*;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::InternalSubsts;
use rustc_middle::ty::{self, EarlyBinder, GeneratorSubsts, Ty, TyCtxt};
use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs
index ec8d42c1652..2b404efccc7 100644
--- a/compiler/rustc_mir_transform/src/ssa.rs
+++ b/compiler/rustc_mir_transform/src/ssa.rs
@@ -1,3 +1,10 @@
+//! We denote as "SSA" the set of locals that verify the following properties:
+//! 1/ They are only assigned-to once, either as a function parameter, or in an assign statement;
+//! 2/ This single assignment dominates all uses;
+//!
+//! As a consequence of rule 2, we consider that borrowed locals are not SSA, even if they are
+//! `Freeze`, as we do not track that the assignment dominates all uses of the borrow.
+
use either::Either;
use rustc_data_structures::graph::dominators::Dominators;
use rustc_index::bit_set::BitSet;
@@ -5,7 +12,6 @@ use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::middle::resolve_bound_vars::Set1;
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
-use rustc_middle::ty::{ParamEnv, TyCtxt};
#[derive(Debug)]
pub struct SsaLocals {
@@ -17,6 +23,9 @@ pub struct SsaLocals {
assignment_order: Vec<Local>,
/// Copy equivalence classes between locals. See `copy_classes` for documentation.
copy_classes: IndexVec<Local, Local>,
+ /// Number of "direct" uses of each local, ie. uses that are not dereferences.
+ /// We ignore non-uses (Storage statements, debuginfo).
+ direct_uses: IndexVec<Local, u32>,
}
/// We often encounter MIR bodies with 1 or 2 basic blocks. In those cases, it's unnecessary to
@@ -26,48 +35,48 @@ struct SmallDominators {
inner: Option<Dominators<BasicBlock>>,
}
-trait DomExt {
- fn dominates(self, _other: Self, dominators: &SmallDominators) -> bool;
-}
-
-impl DomExt for Location {
- fn dominates(self, other: Location, dominators: &SmallDominators) -> bool {
- if self.block == other.block {
- self.statement_index <= other.statement_index
+impl SmallDominators {
+ fn dominates(&self, first: Location, second: Location) -> bool {
+ if first.block == second.block {
+ first.statement_index <= second.statement_index
+ } else if let Some(inner) = &self.inner {
+ inner.dominates(first.block, second.block)
} else {
- dominators.dominates(self.block, other.block)
+ first.block < second.block
}
}
-}
-impl SmallDominators {
- fn dominates(&self, dom: BasicBlock, node: BasicBlock) -> bool {
- if let Some(inner) = &self.inner { inner.dominates(dom, node) } else { dom < node }
+ fn check_dominates(&mut self, set: &mut Set1<LocationExtended>, loc: Location) {
+ let assign_dominates = match *set {
+ Set1::Empty | Set1::Many => false,
+ Set1::One(LocationExtended::Arg) => true,
+ Set1::One(LocationExtended::Plain(assign)) => {
+ self.dominates(assign.successor_within_block(), loc)
+ }
+ };
+ // We are visiting a use that is not dominated by an assignment.
+ // Either there is a cycle involved, or we are reading for uninitialized local.
+ // Bail out.
+ if !assign_dominates {
+ *set = Set1::Many;
+ }
}
}
impl SsaLocals {
- pub fn new<'tcx>(
- tcx: TyCtxt<'tcx>,
- param_env: ParamEnv<'tcx>,
- body: &Body<'tcx>,
- borrowed_locals: &BitSet<Local>,
- ) -> SsaLocals {
+ pub fn new<'tcx>(body: &Body<'tcx>) -> SsaLocals {
let assignment_order = Vec::with_capacity(body.local_decls.len());
let assignments = IndexVec::from_elem(Set1::Empty, &body.local_decls);
let dominators =
if body.basic_blocks.len() > 2 { Some(body.basic_blocks.dominators()) } else { None };
let dominators = SmallDominators { inner: dominators };
- let mut visitor = SsaVisitor { assignments, assignment_order, dominators };
- for (local, decl) in body.local_decls.iter_enumerated() {
- if matches!(body.local_kind(local), LocalKind::Arg) {
- visitor.assignments[local] = Set1::One(LocationExtended::Arg);
- }
- if borrowed_locals.contains(local) && !decl.ty.is_freeze(tcx, param_env) {
- visitor.assignments[local] = Set1::Many;
- }
+ let direct_uses = IndexVec::from_elem(0, &body.local_decls);
+ let mut visitor = SsaVisitor { assignments, assignment_order, dominators, direct_uses };
+
+ for local in body.args_iter() {
+ visitor.assignments[local] = Set1::One(LocationExtended::Arg);
}
if body.basic_blocks.len() > 2 {
@@ -85,36 +94,52 @@ impl SsaLocals {
}
debug!(?visitor.assignments);
+ debug!(?visitor.direct_uses);
visitor
.assignment_order
.retain(|&local| matches!(visitor.assignments[local], Set1::One(_)));
debug!(?visitor.assignment_order);
- let copy_classes = compute_copy_classes(&visitor, body);
-
- SsaLocals {
+ let mut ssa = SsaLocals {
assignments: visitor.assignments,
assignment_order: visitor.assignment_order,
- copy_classes,
- }
+ direct_uses: visitor.direct_uses,
+ // This is filled by `compute_copy_classes`.
+ copy_classes: IndexVec::default(),
+ };
+ compute_copy_classes(&mut ssa, body);
+ ssa
+ }
+
+ pub fn num_locals(&self) -> usize {
+ self.assignments.len()
+ }
+
+ pub fn locals(&self) -> impl Iterator<Item = Local> {
+ self.assignments.indices()
}
pub fn is_ssa(&self, local: Local) -> bool {
matches!(self.assignments[local], Set1::One(_))
}
+ /// Return the number of uses if a local that are not "Deref".
+ pub fn num_direct_uses(&self, local: Local) -> u32 {
+ self.direct_uses[local]
+ }
+
pub fn assignments<'a, 'tcx>(
&'a self,
body: &'a Body<'tcx>,
- ) -> impl Iterator<Item = (Local, &'a Rvalue<'tcx>)> + 'a {
+ ) -> impl Iterator<Item = (Local, &'a Rvalue<'tcx>, Location)> + 'a {
self.assignment_order.iter().filter_map(|&local| {
if let Set1::One(LocationExtended::Plain(loc)) = self.assignments[local] {
// `loc` must point to a direct assignment to `local`.
let Either::Left(stmt) = body.stmt_at(loc) else { bug!() };
let Some((target, rvalue)) = stmt.kind.as_assign() else { bug!() };
assert_eq!(target.as_local(), Some(local));
- Some((local, rvalue))
+ Some((local, rvalue, loc))
} else {
None
}
@@ -177,44 +202,29 @@ struct SsaVisitor {
dominators: SmallDominators,
assignments: IndexVec<Local, Set1<LocationExtended>>,
assignment_order: Vec<Local>,
-}
-
-impl SsaVisitor {
- fn check_assignment_dominates(&mut self, local: Local, loc: Location) {
- let set = &mut self.assignments[local];
- let assign_dominates = match *set {
- Set1::Empty | Set1::Many => false,
- Set1::One(LocationExtended::Arg) => true,
- Set1::One(LocationExtended::Plain(assign)) => {
- assign.successor_within_block().dominates(loc, &self.dominators)
- }
- };
- // We are visiting a use that is not dominated by an assignment.
- // Either there is a cycle involved, or we are reading for uninitialized local.
- // Bail out.
- if !assign_dominates {
- *set = Set1::Many;
- }
- }
+ direct_uses: IndexVec<Local, u32>,
}
impl<'tcx> Visitor<'tcx> for SsaVisitor {
fn visit_local(&mut self, local: Local, ctxt: PlaceContext, loc: Location) {
match ctxt {
- PlaceContext::MutatingUse(MutatingUseContext::Store) => {
- self.assignments[local].insert(LocationExtended::Plain(loc));
- if let Set1::One(_) = self.assignments[local] {
- // Only record if SSA-like, to avoid growing the vector needlessly.
- self.assignment_order.push(local);
- }
- }
+ PlaceContext::MutatingUse(MutatingUseContext::Projection)
+ | PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => bug!(),
// Anything can happen with raw pointers, so remove them.
- PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf)
- | PlaceContext::MutatingUse(_) => self.assignments[local] = Set1::Many,
- // Immutable borrows are taken into account in `SsaLocals::new` by
- // removing non-freeze locals.
+ // We do not verify that all uses of the borrow dominate the assignment to `local`,
+ // so we have to remove them too.
+ PlaceContext::NonMutatingUse(
+ NonMutatingUseContext::SharedBorrow
+ | NonMutatingUseContext::ShallowBorrow
+ | NonMutatingUseContext::UniqueBorrow
+ | NonMutatingUseContext::AddressOf,
+ )
+ | PlaceContext::MutatingUse(_) => {
+ self.assignments[local] = Set1::Many;
+ }
PlaceContext::NonMutatingUse(_) => {
- self.check_assignment_dominates(local, loc);
+ self.dominators.check_dominates(&mut self.assignments[local], loc);
+ self.direct_uses[local] += 1;
}
PlaceContext::NonUse(_) => {}
}
@@ -224,58 +234,113 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor {
if place.projection.first() == Some(&PlaceElem::Deref) {
// Do not do anything for storage statements and debuginfo.
if ctxt.is_use() {
- // A use through a `deref` only reads from the local, and cannot write to it.
- let new_ctxt = PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection);
+ // Only change the context if it is a real use, not a "use" in debuginfo.
+ let new_ctxt = PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy);
self.visit_projection(place.as_ref(), new_ctxt, loc);
- self.check_assignment_dominates(place.local, loc);
+ self.dominators.check_dominates(&mut self.assignments[place.local], loc);
}
return;
+ } else {
+ self.visit_projection(place.as_ref(), ctxt, loc);
+ self.visit_local(place.local, ctxt, loc);
}
- self.super_place(place, ctxt, loc);
+ }
+
+ fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, loc: Location) {
+ if let Some(local) = place.as_local() {
+ self.assignments[local].insert(LocationExtended::Plain(loc));
+ if let Set1::One(_) = self.assignments[local] {
+ // Only record if SSA-like, to avoid growing the vector needlessly.
+ self.assignment_order.push(local);
+ }
+ } else {
+ self.visit_place(place, PlaceContext::MutatingUse(MutatingUseContext::Store), loc);
+ }
+ self.visit_rvalue(rvalue, loc);
}
}
#[instrument(level = "trace", skip(ssa, body))]
-fn compute_copy_classes(ssa: &SsaVisitor, body: &Body<'_>) -> IndexVec<Local, Local> {
+fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) {
+ let mut direct_uses = std::mem::take(&mut ssa.direct_uses);
let mut copies = IndexVec::from_fn_n(|l| l, body.local_decls.len());
- for &local in &ssa.assignment_order {
- debug!(?local);
-
- if local == RETURN_PLACE {
- // `_0` is special, we cannot rename it.
- continue;
- }
-
- // This is not SSA: mark that we don't know the value.
- debug!(assignments = ?ssa.assignments[local]);
- let Set1::One(LocationExtended::Plain(loc)) = ssa.assignments[local] else { continue };
-
- // `loc` must point to a direct assignment to `local`.
- let Either::Left(stmt) = body.stmt_at(loc) else { bug!() };
- let Some((_target, rvalue)) = stmt.kind.as_assign() else { bug!() };
- assert_eq!(_target.as_local(), Some(local));
-
+ for (local, rvalue, _) in ssa.assignments(body) {
let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) | Rvalue::CopyForDeref(place))
= rvalue
else { continue };
let Some(rhs) = place.as_local() else { continue };
- let Set1::One(_) = ssa.assignments[rhs] else { continue };
+ if !ssa.is_ssa(rhs) {
+ continue;
+ }
// We visit in `assignment_order`, ie. reverse post-order, so `rhs` has been
// visited before `local`, and we just have to copy the representing local.
- copies[local] = copies[rhs];
+ let head = copies[rhs];
+
+ if local == RETURN_PLACE {
+ // `_0` is special, we cannot rename it. Instead, rename the class of `rhs` to
+ // `RETURN_PLACE`. This is only possible if the class head is a temporary, not an
+ // argument.
+ if body.local_kind(head) != LocalKind::Temp {
+ continue;
+ }
+ for h in copies.iter_mut() {
+ if *h == head {
+ *h = RETURN_PLACE;
+ }
+ }
+ } else {
+ copies[local] = head;
+ }
+ direct_uses[rhs] -= 1;
}
debug!(?copies);
+ debug!(?direct_uses);
// Invariant: `copies` must point to the head of an equivalence class.
#[cfg(debug_assertions)]
for &head in copies.iter() {
assert_eq!(copies[head], head);
}
+ debug_assert_eq!(copies[RETURN_PLACE], RETURN_PLACE);
+
+ ssa.direct_uses = direct_uses;
+ ssa.copy_classes = copies;
+}
+
+#[derive(Debug)]
+pub(crate) struct StorageLiveLocals {
+ /// Set of "StorageLive" statements for each local.
+ storage_live: IndexVec<Local, Set1<LocationExtended>>,
+}
+
+impl StorageLiveLocals {
+ pub(crate) fn new(
+ body: &Body<'_>,
+ always_storage_live_locals: &BitSet<Local>,
+ ) -> StorageLiveLocals {
+ let mut storage_live = IndexVec::from_elem(Set1::Empty, &body.local_decls);
+ for local in always_storage_live_locals.iter() {
+ storage_live[local] = Set1::One(LocationExtended::Arg);
+ }
+ for (block, bbdata) in body.basic_blocks.iter_enumerated() {
+ for (statement_index, statement) in bbdata.statements.iter().enumerate() {
+ if let StatementKind::StorageLive(local) = statement.kind {
+ storage_live[local]
+ .insert(LocationExtended::Plain(Location { block, statement_index }));
+ }
+ }
+ }
+ debug!(?storage_live);
+ StorageLiveLocals { storage_live }
+ }
- copies
+ #[inline]
+ pub(crate) fn has_single_storage(&self, local: Local) -> bool {
+ matches!(self.storage_live[local], Set1::One(_))
+ }
}
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 55c937b305a..35b154b7b34 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -185,9 +185,9 @@ use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar};
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
use rustc_middle::mir::visit::Visitor as MirVisitor;
use rustc_middle::mir::{self, Local, Location};
+use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast};
use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::query::TyCtxtAt;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::{
self, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt,
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index 7253acf61e6..ecc50c3f664 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -12,9 +12,9 @@ extern crate rustc_middle;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
use rustc_hir::lang_items::LangItem;
+use rustc_middle::query::{Providers, TyCtxtAt};
use rustc_middle::traits;
use rustc_middle::ty::adjustment::CustomCoerceUnsized;
-use rustc_middle::ty::query::{Providers, TyCtxtAt};
use rustc_middle::ty::{self, Ty};
mod collector;
diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs
index 993e35c7fd2..c10180ee3f4 100644
--- a/compiler/rustc_monomorphize/src/partitioning/mod.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs
@@ -106,8 +106,8 @@ use rustc_hir::def_id::{DefIdSet, LOCAL_CRATE};
use rustc_middle::mir;
use rustc_middle::mir::mono::MonoItem;
use rustc_middle::mir::mono::{CodegenUnit, Linkage};
+use rustc_middle::query::Providers;
use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath};
use rustc_span::symbol::Symbol;
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index ddc62d9c390..88a3e028527 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -11,9 +11,9 @@ use rustc_middle::mir::{
visit::{TyContext, Visitor},
Constant, ConstantKind, Local, LocalDecl, Location,
};
+use rustc_middle::query::Providers;
use rustc_middle::ty::{
self,
- query::Providers,
subst::SubstsRef,
visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor},
Const, Ty, TyCtxt, UnusedGenericParams,
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index cd296dca133..2d0f466e236 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -257,6 +257,10 @@ parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are inva
.tuple_exception_line_2 = on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access
.tuple_exception_line_3 = see issue #60210 <https://github.com/rust-lang/rust/issues/60210> for more information
+parse_expected_builtin_ident = expected identifier after `builtin #`
+
+parse_unknown_builtin_construct = unknown `builtin #` construct `{$name}`
+
parse_non_string_abi_literal = non-string ABI literal
.suggestion = specify the ABI with a string literal
@@ -339,6 +343,7 @@ parse_expected_identifier = expected identifier
parse_sugg_escape_identifier = escape `{$ident_name}` to use it as an identifier
parse_sugg_remove_comma = remove this comma
+parse_sugg_add_let_for_stmt = you might have meant to introduce a new binding
parse_expected_semi_found_reserved_identifier_str = expected `;`, found reserved identifier `{$token}`
parse_expected_semi_found_keyword_str = expected `;`, found keyword `{$token}`
@@ -473,6 +478,11 @@ parse_missing_for_in_trait_impl = missing `for` in a trait impl
parse_expected_trait_in_trait_impl_found_type = expected a trait, found type
+parse_extra_impl_keyword_in_trait_impl = unexpected `impl` keyword
+ .suggestion = remove the extra `impl`
+ .note = this is parsed as an `impl Trait` type, but a trait is expected at this position
+
+
parse_non_item_in_item_list = non-item in item list
.suggestion_use_const_not_let = consider using `const` instead of `let` for associated const
.label_list_start = item list starts here
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 010a13aefa4..84494eab855 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -907,6 +907,18 @@ pub(crate) struct SuggRemoveComma {
}
#[derive(Subdiagnostic)]
+#[suggestion(
+ parse_sugg_add_let_for_stmt,
+ style = "verbose",
+ applicability = "maybe-incorrect",
+ code = "let "
+)]
+pub(crate) struct SuggAddMissingLetStmt {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(Subdiagnostic)]
pub(crate) enum ExpectedIdentifierFound {
#[label(parse_expected_identifier_found_reserved_identifier)]
ReservedIdentifier(#[primary_span] Span),
@@ -1508,6 +1520,16 @@ pub(crate) struct ExpectedTraitInTraitImplFoundType {
}
#[derive(Diagnostic)]
+#[diag(parse_extra_impl_keyword_in_trait_impl)]
+pub(crate) struct ExtraImplKeywordInTraitImpl {
+ #[primary_span]
+ #[suggestion(code = "", applicability = "maybe-incorrect")]
+ pub extra_impl_kw: Span,
+ #[note]
+ pub impl_trait_span: Span,
+}
+
+#[derive(Diagnostic)]
#[diag(parse_bounds_not_allowed_on_trait_aliases)]
pub(crate) struct BoundsNotAllowedOnTraitAliases {
#[primary_span]
@@ -2644,3 +2666,18 @@ pub(crate) struct MalformedCfgAttr {
pub span: Span,
pub sugg: &'static str,
}
+
+#[derive(Diagnostic)]
+#[diag(parse_unknown_builtin_construct)]
+pub(crate) struct UnknownBuiltinConstruct {
+ #[primary_span]
+ pub span: Span,
+ pub name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_expected_builtin_ident)]
+pub(crate) struct ExpectedBuiltinIdent {
+ #[primary_span]
+ pub span: Span,
+}
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 36883bd2172..3002f23da75 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -13,7 +13,7 @@ use crate::errors::{
IncorrectUseOfAwait, ParenthesesInForHead, ParenthesesInForHeadSugg,
PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst,
StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens,
- StructLiteralNeedingParensSugg, SuggEscapeIdentifier, SuggRemoveComma,
+ StructLiteralNeedingParensSugg, SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma,
UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead,
};
@@ -32,8 +32,8 @@ use rustc_ast::{
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{
- pluralize, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed,
- FatalError, Handler, IntoDiagnostic, MultiSpan, PResult,
+ pluralize, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage,
+ ErrorGuaranteed, FatalError, Handler, IntoDiagnostic, MultiSpan, PResult,
};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::source_map::Spanned;
@@ -1006,6 +1006,31 @@ impl<'a> Parser<'a> {
Err(e)
}
+ /// Suggest add the missing `let` before the identifier in stmt
+ /// `a: Ty = 1` -> `let a: Ty = 1`
+ pub(super) fn suggest_add_missing_let_for_stmt(
+ &mut self,
+ err: &mut DiagnosticBuilder<'a, ErrorGuaranteed>,
+ ) {
+ if self.token == token::Colon {
+ let prev_span = self.prev_token.span.shrink_to_lo();
+ let snapshot = self.create_snapshot_for_diagnostic();
+ self.bump();
+ match self.parse_ty() {
+ Ok(_) => {
+ if self.token == token::Eq {
+ let sugg = SuggAddMissingLetStmt { span: prev_span };
+ sugg.add_to_diagnostic(err);
+ }
+ }
+ Err(e) => {
+ e.cancel();
+ }
+ }
+ self.restore_snapshot(snapshot);
+ }
+ }
+
/// Check to see if a pair of chained operators looks like an attempt at chained comparison,
/// e.g. `1 < x <= 3`. If so, suggest either splitting the comparison into two, or
/// parenthesising the leftmost comparison.
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 018eddea4b0..ee712a8e1b5 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1180,6 +1180,10 @@ impl<'a> Parser<'a> {
self.restore_snapshot(snapshot);
let close_paren = self.prev_token.span;
let span = lo.to(close_paren);
+ // filter shorthand fields
+ let fields: Vec<_> =
+ fields.into_iter().filter(|field| !field.is_shorthand).collect();
+
if !fields.is_empty() &&
// `token.kind` should not be compared here.
// This is because the `snapshot.token.kind` is treated as the same as
@@ -1300,6 +1304,8 @@ impl<'a> Parser<'a> {
})
} else if self.check(&token::OpenDelim(Delimiter::Bracket)) {
self.parse_expr_array_or_repeat(Delimiter::Bracket)
+ } else if self.is_builtin() {
+ self.parse_expr_builtin()
} else if self.check_path() {
self.parse_expr_path_start()
} else if self.check_keyword(kw::Move)
@@ -1766,6 +1772,61 @@ impl<'a> Parser<'a> {
self.maybe_recover_from_bad_qpath(expr)
}
+ /// Parse `builtin # ident(args,*)`.
+ fn parse_expr_builtin(&mut self) -> PResult<'a, P<Expr>> {
+ self.parse_builtin(|this, lo, ident| {
+ if ident.name == sym::offset_of {
+ return Ok(Some(this.parse_expr_offset_of(lo)?));
+ }
+
+ Ok(None)
+ })
+ }
+
+ pub(crate) fn parse_builtin<T>(
+ &mut self,
+ parse: impl FnOnce(&mut Parser<'a>, Span, Ident) -> PResult<'a, Option<T>>,
+ ) -> PResult<'a, T> {
+ let lo = self.token.span;
+
+ self.bump(); // `builtin`
+ self.bump(); // `#`
+
+ let Some((ident, false)) = self.token.ident() else {
+ let err = errors::ExpectedBuiltinIdent { span: self.token.span }
+ .into_diagnostic(&self.sess.span_diagnostic);
+ return Err(err);
+ };
+ self.sess.gated_spans.gate(sym::builtin_syntax, ident.span);
+ self.bump();
+
+ self.expect(&TokenKind::OpenDelim(Delimiter::Parenthesis))?;
+ let ret = if let Some(res) = parse(self, lo, ident)? {
+ Ok(res)
+ } else {
+ let err = errors::UnknownBuiltinConstruct { span: lo.to(ident.span), name: ident.name }
+ .into_diagnostic(&self.sess.span_diagnostic);
+ return Err(err);
+ };
+ self.expect(&TokenKind::CloseDelim(Delimiter::Parenthesis))?;
+
+ ret
+ }
+
+ pub(crate) fn parse_expr_offset_of(&mut self, lo: Span) -> PResult<'a, P<Expr>> {
+ let container = self.parse_ty()?;
+ self.expect(&TokenKind::Comma)?;
+
+ let seq_sep = SeqSep { sep: Some(token::Dot), trailing_sep_allowed: false };
+ let (fields, _trailing, _recovered) = self.parse_seq_to_before_end(
+ &TokenKind::CloseDelim(Delimiter::Parenthesis),
+ seq_sep,
+ Parser::parse_field_name,
+ )?;
+ let span = lo.to(self.token.span);
+ Ok(self.mk_expr(span, ExprKind::OffsetOf(container, fields.to_vec().into())))
+ }
+
/// Returns a string literal if the next token is a string literal.
/// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
/// and returns `None` if the next token is not literal at all.
@@ -2835,6 +2896,10 @@ impl<'a> Parser<'a> {
})
}
+ pub(crate) fn is_builtin(&self) -> bool {
+ self.token.is_keyword(kw::Builtin) && self.look_ahead(1, |t| *t == token::Pound)
+ }
+
/// Parses a `try {...}` expression (`try` token already eaten).
fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, P<Expr>> {
let (attrs, body) = self.parse_inner_attrs_and_block()?;
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index e6d0f9fbc76..cd779b0b43e 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -453,6 +453,8 @@ impl<'a> Parser<'a> {
// `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
// `<` (LIFETIME|IDENT) `=` - generic parameter with a default
// `<` const - generic const parameter
+ // `<` IDENT `?` - RECOVERY for `impl<T ?Bound` missing a `:`, meant to
+ // avoid the `T?` to `Option<T>` recovery for types.
// The only truly ambiguous case is
// `<` IDENT `>` `::` IDENT ...
// we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
@@ -463,6 +465,9 @@ impl<'a> Parser<'a> {
|| self.look_ahead(start + 1, |t| t.is_lifetime() || t.is_ident())
&& self.look_ahead(start + 2, |t| {
matches!(t.kind, token::Gt | token::Comma | token::Colon | token::Eq)
+ // Recovery-only branch -- this could be removed,
+ // since it only affects diagnostics currently.
+ || matches!(t.kind, token::Question)
})
|| self.is_keyword_ahead(start + 1, &[kw::Const]))
}
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 6ca88200dc5..dc18d400f1e 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -265,6 +265,9 @@ impl<'a> Parser<'a> {
// UNION ITEM
self.bump(); // `union`
self.parse_item_union()?
+ } else if self.is_builtin() {
+ // BUILTIN# ITEM
+ return self.parse_item_builtin();
} else if self.eat_keyword(kw::Macro) {
// MACROS 2.0 ITEM
self.parse_item_decl_macro(lo)?
@@ -434,6 +437,11 @@ impl<'a> Parser<'a> {
}
}
+ fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemInfo>> {
+ // To be expanded
+ return Ok(None);
+ }
+
/// Parses an item macro, e.g., `item!();`.
fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
@@ -595,10 +603,24 @@ impl<'a> Parser<'a> {
let path = match ty_first.kind {
// This notably includes paths passed through `ty` macro fragments (#46438).
TyKind::Path(None, path) => path,
- _ => {
- self.sess.emit_err(errors::ExpectedTraitInTraitImplFoundType {
- span: ty_first.span,
- });
+ other => {
+ if let TyKind::ImplTrait(_, bounds) = other
+ && let [bound] = bounds.as_slice()
+ {
+ // Suggest removing extra `impl` keyword:
+ // `impl<T: Default> impl Default for Wrapper<T>`
+ // ^^^^^
+ let extra_impl_kw = ty_first.span.until(bound.span());
+ self.sess
+ .emit_err(errors::ExtraImplKeywordInTraitImpl {
+ extra_impl_kw,
+ impl_trait_span: ty_first.span
+ });
+ } else {
+ self.sess.emit_err(errors::ExpectedTraitInTraitImplFoundType {
+ span: ty_first.span,
+ });
+ }
err_path(ty_first.span)
}
};
@@ -1262,6 +1284,7 @@ impl<'a> Parser<'a> {
}
}
+ let prev_span = self.prev_token.span;
let id = self.parse_ident()?;
let mut generics = self.parse_generics()?;
generics.where_clause = self.parse_where_clause()?;
@@ -1273,10 +1296,28 @@ impl<'a> Parser<'a> {
(thin_vec![], false)
} else {
self.parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant()).map_err(
- |mut e| {
- e.span_label(id.span, "while parsing this enum");
+ |mut err| {
+ err.span_label(id.span, "while parsing this enum");
+ if self.token == token::Colon {
+ let snapshot = self.create_snapshot_for_diagnostic();
+ self.bump();
+ match self.parse_ty() {
+ Ok(_) => {
+ err.span_suggestion_verbose(
+ prev_span,
+ "perhaps you meant to use `struct` here",
+ "struct".to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ Err(e) => {
+ e.cancel();
+ }
+ }
+ self.restore_snapshot(snapshot);
+ }
self.recover_stmt();
- e
+ err
},
)?
};
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 1c17de337e8..03279124177 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -90,7 +90,11 @@ impl<'a> Parser<'a> {
attrs,
errors::InvalidVariableDeclarationSub::UseLetNotVar,
)?
- } else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() {
+ } else if self.check_path()
+ && !self.token.is_qpath_start()
+ && !self.is_path_start_item()
+ && !self.is_builtin()
+ {
// 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
// that starts like a path (1 token), but it fact not a path.
@@ -99,7 +103,13 @@ impl<'a> Parser<'a> {
ForceCollect::Yes => {
self.collect_tokens_no_attrs(|this| this.parse_stmt_path_start(lo, attrs))?
}
- ForceCollect::No => self.parse_stmt_path_start(lo, attrs)?,
+ ForceCollect::No => match self.parse_stmt_path_start(lo, attrs) {
+ Ok(stmt) => stmt,
+ Err(mut err) => {
+ self.suggest_add_missing_let_for_stmt(&mut err);
+ return Err(err);
+ }
+ },
}
} else if let Some(item) = self.parse_item_common(
attrs.clone(),
@@ -555,7 +565,6 @@ impl<'a> Parser<'a> {
if self.token == token::Colon {
// if next token is following a colon, it's likely a path
// and we can suggest a path separator
- let ident_span = self.prev_token.span;
self.bump();
if self.token.span.lo() == self.prev_token.span.hi() {
err.span_suggestion_verbose(
@@ -565,14 +574,6 @@ impl<'a> Parser<'a> {
Applicability::MaybeIncorrect,
);
}
- if self.look_ahead(1, |token| token == &token::Eq) {
- err.span_suggestion_verbose(
- ident_span.shrink_to_lo(),
- "you might have meant to introduce a new binding",
- "let ",
- Applicability::MaybeIncorrect,
- );
- }
if self.sess.unstable_features.is_nightly_build() {
// FIXME(Nilstrieb): Remove this again after a few months.
err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>");
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 06aa2737915..455d7b89f9c 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -19,9 +19,9 @@ use rustc_hir::{
use rustc_hir::{MethodKind, Target, Unsafety};
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
+use rustc_middle::query::Providers;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::{
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index 6742722ce52..2357b0aadef 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -12,7 +12,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{self, Visitor};
use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::parse::feature_err;
use rustc_span::{sym, Span, Symbol};
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 3ae5b45d330..7812dcde44c 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -12,7 +12,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Node, PatKind, TyKind};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::privacy::Level;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint;
use rustc_span::symbol::{sym, Symbol};
diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs
index 72371b9950b..8ea95b3f383 100644
--- a/compiler/rustc_passes/src/debugger_visualizer.rs
+++ b/compiler/rustc_passes/src/debugger_visualizer.rs
@@ -6,8 +6,8 @@ use rustc_data_structures::sync::Lrc;
use rustc_expand::base::resolve_path;
use rustc_hir as hir;
use rustc_hir::HirId;
+use rustc_middle::query::{LocalCrate, Providers};
use rustc_middle::ty::TyCtxt;
-use rustc_middle::{query::LocalCrate, ty::query::Providers};
use rustc_span::{sym, DebuggerVisualizerFile, DebuggerVisualizerType};
use crate::errors::DebugVisualizerUnreadable;
diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs
index eb6ea673c85..d8b9f4fae87 100644
--- a/compiler/rustc_passes/src/diagnostic_items.rs
+++ b/compiler/rustc_passes/src/diagnostic_items.rs
@@ -13,7 +13,7 @@ use rustc_ast as ast;
use rustc_hir::diagnostic_items::DiagnosticItems;
use rustc_hir::OwnerId;
use rustc_middle::query::LocalCrate;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::symbol::{sym, Symbol};
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index e3e4b73efa3..ffd8f77b78b 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -4,7 +4,7 @@ use rustc_errors::error_code;
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::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{sigpipe, CrateType, EntryFnType};
use rustc_session::parse::feature_err;
diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs
index fdd0e5dab70..476394f30cc 100644
--- a/compiler/rustc_passes/src/lang_items.rs
+++ b/compiler/rustc_passes/src/lang_items.rs
@@ -22,7 +22,7 @@ use rustc_middle::ty::TyCtxt;
use rustc_session::cstore::ExternCrate;
use rustc_span::{symbol::kw::Empty, Span};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
pub(crate) enum Duplicate {
Plain,
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 8b7338e29aa..0da4b294648 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -22,7 +22,7 @@ extern crate tracing;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
mod check_attr;
mod check_const;
diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs
index f4da1aaec11..44174b1b89d 100644
--- a/compiler/rustc_passes/src/lib_features.rs
+++ b/compiler/rustc_passes/src/lib_features.rs
@@ -9,7 +9,7 @@ use rustc_attr::{rust_version_symbol, VERSION_PLACEHOLDER};
use rustc_hir::intravisit::Visitor;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::lib_features::LibFeatures;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::Symbol;
use rustc_span::{sym, Span};
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 6758024419d..63b1578d43f 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -94,7 +94,7 @@ use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet};
use rustc_index::IndexVec;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt};
use rustc_session::lint;
use rustc_span::symbol::{kw, sym, Symbol};
diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs
index b4cf19e4a34..73cfe68e7f2 100644
--- a/compiler/rustc_passes/src/loops.rs
+++ b/compiler/rustc_passes/src/loops.rs
@@ -6,7 +6,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Destination, Movability, Node};
use rustc_middle::hir::map::Map;
use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_span::hygiene::DesugaringKind;
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index cf8d9300a11..a849d61edfe 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -6,7 +6,7 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::{ExprKind, InlineAsmOperand, StmtKind};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI;
use rustc_span::symbol::sym;
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index a5f7b07fe52..160528e4074 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -13,7 +13,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::Node;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::middle::privacy::{self, Level};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::config::CrateType;
use rustc_target::spec::abi::Abi;
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 9615f283ff4..f9060328f48 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -16,7 +16,8 @@ use rustc_hir::{FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::middle::stability::{AllowUnstable, DeprecationEntry, Index};
-use rustc_middle::ty::{query::Providers, TyCtxt};
+use rustc_middle::query::Providers;
+use rustc_middle::ty::TyCtxt;
use rustc_session::lint;
use rustc_session::lint::builtin::{INEFFECTIVE_UNSTABLE_TRAIT_IMPL, USELESS_DEPRECATED};
use rustc_span::symbol::{sym, Symbol};
diff --git a/compiler/rustc_passes/src/upvars.rs b/compiler/rustc_passes/src/upvars.rs
index 605cf0a93b8..d87df706cc8 100644
--- a/compiler/rustc_passes/src/upvars.rs
+++ b/compiler/rustc_passes/src/upvars.rs
@@ -5,7 +5,7 @@ use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{self, HirId};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_span::Span;
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index b738ce35ada..7b39cb0a068 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -26,8 +26,8 @@ use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind};
use rustc_middle::bug;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
+use rustc_middle::query::Providers;
use rustc_middle::span_bug;
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{self, Const, GenericParamDefKind};
use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
@@ -243,6 +243,39 @@ where
// This will also visit substs if necessary, so we don't need to recurse.
return self.visit_projection_ty(proj);
}
+ ty::Alias(ty::Inherent, data) => {
+ if self.def_id_visitor.skip_assoc_tys() {
+ // Visitors searching for minimal visibility/reachability want to
+ // conservatively approximate associated types like `Type::Alias`
+ // as visible/reachable even if `Type` is private.
+ // Ideally, associated types should be substituted in the same way as
+ // free type aliases, but this isn't done yet.
+ return ControlFlow::Continue(());
+ }
+
+ self.def_id_visitor.visit_def_id(
+ data.def_id,
+ "associated type",
+ &LazyDefPathStr { def_id: data.def_id, tcx },
+ )?;
+
+ struct LazyDefPathStr<'tcx> {
+ def_id: DefId,
+ tcx: TyCtxt<'tcx>,
+ }
+ impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", self.tcx.def_path_str(self.def_id))
+ }
+ }
+
+ // This will also visit substs if necessary, so we don't need to recurse.
+ return if self.def_id_visitor.shallow() {
+ ControlFlow::Continue(())
+ } else {
+ data.substs.iter().try_for_each(|subst| subst.visit_with(self))
+ };
+ }
ty::Dynamic(predicates, ..) => {
// All traits in the list are considered the "primary" part of the type
// and are visited by shallow visitors.
@@ -706,7 +739,10 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
}
hir::ItemKind::Impl(ref impl_) => {
for impl_item_ref in impl_.items {
- self.update(impl_item_ref.id.owner_id.def_id, item_ev, Level::Direct);
+ let def_id = impl_item_ref.id.owner_id.def_id;
+ let nominal_vis =
+ impl_.of_trait.is_none().then(|| self.tcx.local_visibility(def_id));
+ self.update_eff_vis(def_id, item_ev, nominal_vis, Level::Direct);
}
}
hir::ItemKind::Trait(.., trait_item_refs) => {
diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml
index b107a3f03fe..e596993465c 100644
--- a/compiler/rustc_query_impl/Cargo.toml
+++ b/compiler/rustc_query_impl/Cargo.toml
@@ -7,6 +7,8 @@ edition = "2021"
[dependencies]
+memoffset = { version = "0.6.0", features = ["unstable_const"] }
+field-offset = "0.3.5"
measureme = "10.0.0"
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index 82b335f4b4b..b76734dd072 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -3,11 +3,12 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
// this shouldn't be necessary, but the check for `&mut _` is too naive and denies returning a function pointer that takes a mut ref
#![feature(const_mut_refs)]
+#![feature(const_refs_to_cell)]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(rustc_attrs)]
#![recursion_limit = "256"]
-#![allow(rustc::potential_query_instability)]
+#![allow(rustc::potential_query_instability, unused_parens)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
@@ -15,16 +16,28 @@
extern crate rustc_middle;
use crate::plumbing::{encode_all_query_results, try_mark_green};
+use field_offset::offset_of;
+use rustc_data_structures::stable_hasher::HashStable;
+use rustc_data_structures::sync::AtomicU64;
use rustc_middle::arena::Arena;
+use rustc_middle::dep_graph::DepNodeIndex;
use rustc_middle::dep_graph::{self, DepKind, DepKindStruct};
use rustc_middle::query::erase::{erase, restore, Erase};
+use rustc_middle::query::on_disk_cache::OnDiskCache;
+use rustc_middle::query::plumbing::{DynamicQuery, QuerySystem, QuerySystemFns};
use rustc_middle::query::AsLocalKey;
-use rustc_middle::ty::query::{
+use rustc_middle::query::{
query_keys, query_provided, query_provided_to_value, query_storage, query_values,
+ DynamicQueries, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates,
};
-use rustc_middle::ty::query::{ExternProviders, Providers, QueryEngine, QuerySystemFns};
use rustc_middle::ty::TyCtxt;
use rustc_query_system::dep_graph::SerializedDepNodeIndex;
+use rustc_query_system::ich::StableHashingContext;
+use rustc_query_system::query::{
+ get_query_incr, get_query_non_incr, HashResult, QueryCache, QueryConfig, QueryInfo, QueryMap,
+ QueryMode, QueryState,
+};
+use rustc_query_system::HandleCycleError;
use rustc_query_system::Value;
use rustc_span::Span;
@@ -32,31 +45,183 @@ use rustc_span::Span;
mod plumbing;
pub use crate::plumbing::QueryCtxt;
-pub use rustc_query_system::query::QueryConfig;
-use rustc_query_system::query::*;
-
mod profiling_support;
pub use self::profiling_support::alloc_self_profile_query_strings;
-/// This is implemented per query and restoring query values from their erased state.
-trait QueryConfigRestored<'tcx>: QueryConfig<QueryCtxt<'tcx>> + Default {
- type RestoredValue;
+struct DynamicConfig<
+ 'tcx,
+ C: QueryCache,
+ const ANON: bool,
+ const DEPTH_LIMIT: bool,
+ const FEEDABLE: bool,
+> {
+ dynamic: &'tcx DynamicQuery<'tcx, C>,
+}
- fn restore(value: <Self as QueryConfig<QueryCtxt<'tcx>>>::Value) -> Self::RestoredValue;
+impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Copy
+ for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
+{
+}
+impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Clone
+ for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
+{
+ fn clone(&self) -> Self {
+ DynamicConfig { dynamic: self.dynamic }
+ }
}
-rustc_query_append! { define_queries! }
+impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool>
+ QueryConfig<QueryCtxt<'tcx>> for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
+where
+ for<'a> C::Key: HashStable<StableHashingContext<'a>>,
+{
+ type Key = C::Key;
+ type Value = C::Value;
+ type Cache = C;
+
+ #[inline(always)]
+ fn name(self) -> &'static str {
+ self.dynamic.name
+ }
+
+ #[inline(always)]
+ fn cache_on_disk(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool {
+ (self.dynamic.cache_on_disk)(tcx, key)
+ }
+
+ #[inline(always)]
+ fn query_state<'a>(self, qcx: QueryCtxt<'tcx>) -> &'a QueryState<Self::Key, DepKind>
+ where
+ QueryCtxt<'tcx>: 'a,
+ {
+ self.dynamic.query_state.apply(&qcx.tcx.query_system.states)
+ }
+
+ #[inline(always)]
+ fn query_cache<'a>(self, qcx: QueryCtxt<'tcx>) -> &'a Self::Cache
+ where
+ 'tcx: 'a,
+ {
+ self.dynamic.query_cache.apply(&qcx.tcx.query_system.caches)
+ }
+
+ #[inline(always)]
+ fn execute_query(self, tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value {
+ (self.dynamic.execute_query)(tcx, key)
+ }
+
+ #[inline(always)]
+ fn compute(self, qcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value {
+ (self.dynamic.compute)(qcx.tcx, key)
+ }
+
+ #[inline(always)]
+ fn try_load_from_disk(
+ self,
+ qcx: QueryCtxt<'tcx>,
+ key: &Self::Key,
+ prev_index: SerializedDepNodeIndex,
+ index: DepNodeIndex,
+ ) -> Option<Self::Value> {
+ if self.dynamic.can_load_from_disk {
+ (self.dynamic.try_load_from_disk)(qcx.tcx, key, prev_index, index)
+ } else {
+ None
+ }
+ }
+
+ #[inline]
+ fn loadable_from_disk(
+ self,
+ qcx: QueryCtxt<'tcx>,
+ key: &Self::Key,
+ index: SerializedDepNodeIndex,
+ ) -> bool {
+ (self.dynamic.loadable_from_disk)(qcx.tcx, key, index)
+ }
+
+ fn value_from_cycle_error(
+ self,
+ tcx: TyCtxt<'tcx>,
+ cycle: &[QueryInfo<DepKind>],
+ ) -> Self::Value {
+ (self.dynamic.value_from_cycle_error)(tcx, cycle)
+ }
+
+ #[inline(always)]
+ fn format_value(self) -> fn(&Self::Value) -> String {
+ self.dynamic.format_value
+ }
+
+ #[inline(always)]
+ fn anon(self) -> bool {
+ ANON
+ }
+
+ #[inline(always)]
+ fn eval_always(self) -> bool {
+ self.dynamic.eval_always
+ }
+
+ #[inline(always)]
+ fn depth_limit(self) -> bool {
+ DEPTH_LIMIT
+ }
+
+ #[inline(always)]
+ fn feedable(self) -> bool {
+ FEEDABLE
+ }
+
+ #[inline(always)]
+ fn dep_kind(self) -> DepKind {
+ self.dynamic.dep_kind
+ }
+
+ #[inline(always)]
+ fn handle_cycle_error(self) -> HandleCycleError {
+ self.dynamic.handle_cycle_error
+ }
+
+ #[inline(always)]
+ fn hash_result(self) -> HashResult<Self::Value> {
+ self.dynamic.hash_result
+ }
+}
-pub fn query_system_fns<'tcx>(
+/// This is implemented per query. It allows restoring query values from their erased state
+/// and constructing a QueryConfig.
+trait QueryConfigRestored<'tcx> {
+ type RestoredValue;
+ type Config: QueryConfig<QueryCtxt<'tcx>>;
+
+ fn config(tcx: TyCtxt<'tcx>) -> Self::Config;
+ fn restore(value: <Self::Config as QueryConfig<QueryCtxt<'tcx>>>::Value)
+ -> Self::RestoredValue;
+}
+
+pub fn query_system<'tcx>(
local_providers: Providers,
extern_providers: ExternProviders,
-) -> QuerySystemFns<'tcx> {
- QuerySystemFns {
- engine: engine(),
- local_providers,
- extern_providers,
- query_structs: make_dep_kind_array!(query_structs).to_vec(),
- encode_query_results: encode_all_query_results,
- try_mark_green: try_mark_green,
+ on_disk_cache: Option<OnDiskCache<'tcx>>,
+ incremental: bool,
+) -> QuerySystem<'tcx> {
+ QuerySystem {
+ states: Default::default(),
+ arenas: Default::default(),
+ caches: Default::default(),
+ dynamic_queries: dynamic_queries(),
+ on_disk_cache,
+ fns: QuerySystemFns {
+ engine: engine(incremental),
+ local_providers,
+ extern_providers,
+ query_structs: make_dep_kind_array!(query_structs).to_vec(),
+ encode_query_results: encode_all_query_results,
+ try_mark_green: try_mark_green,
+ },
+ jobs: AtomicU64::new(1),
}
}
+
+rustc_query_append! { define_queries! }
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index 9f8ac7ccd0b..79d8abc4b69 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -4,6 +4,7 @@
use crate::rustc_middle::dep_graph::DepContext;
use crate::rustc_middle::ty::TyEncoder;
+use crate::QueryConfigRestored;
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
use rustc_data_structures::sync::Lock;
use rustc_errors::Diagnostic;
@@ -265,14 +266,14 @@ macro_rules! hash_result {
}
macro_rules! call_provider {
- ([][$qcx:expr, $name:ident, $key:expr]) => {{
- ($qcx.query_system.fns.local_providers.$name)($qcx, $key)
+ ([][$tcx:expr, $name:ident, $key:expr]) => {{
+ ($tcx.query_system.fns.local_providers.$name)($tcx, $key)
}};
- ([(separate_provide_extern) $($rest:tt)*][$qcx:expr, $name:ident, $key:expr]) => {{
+ ([(separate_provide_extern) $($rest:tt)*][$tcx:expr, $name:ident, $key:expr]) => {{
if let Some(key) = $key.as_local_key() {
- ($qcx.query_system.fns.local_providers.$name)($qcx, key)
+ ($tcx.query_system.fns.local_providers.$name)($tcx, key)
} else {
- ($qcx.query_system.fns.extern_providers.$name)($qcx, $key)
+ ($tcx.query_system.fns.extern_providers.$name)($tcx, $key)
}
}};
([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
@@ -341,7 +342,7 @@ pub(crate) fn create_query_frame<
}
pub(crate) fn encode_query_results<'a, 'tcx, Q>(
- query: Q,
+ query: Q::Config,
qcx: QueryCtxt<'tcx>,
encoder: &mut CacheEncoder<'a, 'tcx>,
query_result_index: &mut EncodedDepNodeIndex,
@@ -392,12 +393,26 @@ pub(crate) fn loadable_from_disk<'tcx>(tcx: TyCtxt<'tcx>, id: SerializedDepNodeI
pub(crate) fn try_load_from_disk<'tcx, V>(
tcx: TyCtxt<'tcx>,
- id: SerializedDepNodeIndex,
+ prev_index: SerializedDepNodeIndex,
+ index: DepNodeIndex,
) -> Option<V>
where
V: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
{
- tcx.query_system.on_disk_cache.as_ref()?.try_load_query_result(tcx, id)
+ let on_disk_cache = tcx.query_system.on_disk_cache.as_ref()?;
+
+ let prof_timer = tcx.prof.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 value = tcx
+ .dep_graph
+ .with_query_deserialization(|| on_disk_cache.try_load_query_result(tcx, prev_index));
+
+ prof_timer.finish_with_query_invocation_id(index.into());
+
+ value
}
fn force_from_dep_node<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool
@@ -434,10 +449,9 @@ where
pub(crate) fn query_callback<'tcx, Q>(is_anon: bool, is_eval_always: bool) -> DepKindStruct<'tcx>
where
- Q: QueryConfig<QueryCtxt<'tcx>> + Default,
- Q::Key: DepNodeParams<TyCtxt<'tcx>>,
+ Q: QueryConfigRestored<'tcx>,
{
- let fingerprint_style = Q::Key::fingerprint_style();
+ let fingerprint_style = <Q::Config as QueryConfig<QueryCtxt<'tcx>>>::Key::fingerprint_style();
if is_anon || !fingerprint_style.reconstructible() {
return DepKindStruct {
@@ -453,9 +467,11 @@ where
is_anon,
is_eval_always,
fingerprint_style,
- force_from_dep_node: Some(|tcx, dep_node| force_from_dep_node(Q::default(), tcx, dep_node)),
+ force_from_dep_node: Some(|tcx, dep_node| {
+ force_from_dep_node(Q::config(tcx), tcx, dep_node)
+ }),
try_load_from_on_disk_cache: Some(|tcx, dep_node| {
- try_load_from_on_disk_cache(Q::default(), tcx, dep_node)
+ try_load_from_on_disk_cache(Q::config(tcx), tcx, dep_node)
}),
}
}
@@ -478,7 +494,7 @@ macro_rules! define_queries {
(
$($(#[$attr:meta])*
[$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
- mod get_query {
+ mod get_query_incr {
use super::*;
$(
@@ -490,8 +506,8 @@ macro_rules! define_queries {
key: query_keys::$name<'tcx>,
mode: QueryMode,
) -> Option<Erase<query_values::$name<'tcx>>> {
- get_query(
- queries::$name::default(),
+ get_query_incr(
+ queries::$name::config(tcx),
QueryCtxt::new(tcx),
span,
key,
@@ -501,9 +517,37 @@ macro_rules! define_queries {
)*
}
- pub(crate) fn engine() -> QueryEngine {
- QueryEngine {
- $($name: get_query::$name,)*
+ mod get_query_non_incr {
+ use super::*;
+
+ $(
+ #[inline(always)]
+ #[tracing::instrument(level = "trace", skip(tcx))]
+ pub(super) fn $name<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ span: Span,
+ key: query_keys::$name<'tcx>,
+ __mode: QueryMode,
+ ) -> Option<Erase<query_values::$name<'tcx>>> {
+ Some(get_query_non_incr(
+ queries::$name::config(tcx),
+ QueryCtxt::new(tcx),
+ span,
+ key,
+ ))
+ }
+ )*
+ }
+
+ pub(crate) fn engine(incremental: bool) -> QueryEngine {
+ if incremental {
+ QueryEngine {
+ $($name: get_query_incr::$name,)*
+ }
+ } else {
+ QueryEngine {
+ $($name: get_query_non_incr::$name,)*
+ }
}
}
@@ -519,146 +563,91 @@ macro_rules! define_queries {
)*
}
- $(impl<'tcx> QueryConfig<QueryCtxt<'tcx>> for queries::$name<'tcx> {
- type Key = query_keys::$name<'tcx>;
- type Value = Erase<query_values::$name<'tcx>>;
-
- #[inline(always)]
- fn name(self) -> &'static str {
- stringify!($name)
- }
-
- #[inline]
- fn format_value(self) -> fn(&Self::Value) -> String {
- |value| format!("{:?}", restore::<query_values::$name<'tcx>>(*value))
- }
-
- #[inline]
- fn cache_on_disk(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool {
- ::rustc_middle::query::cached::$name(tcx, key)
- }
-
- type Cache = query_storage::$name<'tcx>;
-
- #[inline(always)]
- fn query_state<'a>(self, tcx: QueryCtxt<'tcx>) -> &'a QueryState<Self::Key, crate::dep_graph::DepKind>
- where QueryCtxt<'tcx>: 'a
- {
- &tcx.query_system.states.$name
- }
-
- #[inline(always)]
- fn query_cache<'a>(self, tcx: QueryCtxt<'tcx>) -> &'a Self::Cache
- where 'tcx:'a
- {
- &tcx.query_system.caches.$name
- }
-
- fn execute_query(self, tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value {
- erase(tcx.$name(key))
- }
-
- #[inline]
- #[allow(unused_variables)]
- fn compute(self, qcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value {
- query_provided_to_value::$name(
- qcx.tcx,
- call_provider!([$($modifiers)*][qcx.tcx, $name, key])
- )
- }
+ #[allow(nonstandard_style)]
+ mod dynamic_query {
+ use super::*;
- #[inline]
- fn try_load_from_disk(
- self,
- _qcx: QueryCtxt<'tcx>,
- _key: &Self::Key
- ) -> rustc_query_system::query::TryLoadFromDisk<QueryCtxt<'tcx>, Self::Value> {
- should_ever_cache_on_disk!([$($modifiers)*] {
- if ::rustc_middle::query::cached::$name(_qcx.tcx, _key) {
- Some(|qcx: QueryCtxt<'tcx>, dep_node| {
- let value = $crate::plumbing::try_load_from_disk::<query_provided::$name<'tcx>>(
- qcx.tcx,
- dep_node
- );
- value.map(|value| query_provided_to_value::$name(qcx.tcx, value))
- })
- } else {
- None
+ $(
+ pub(super) fn $name<'tcx>() -> DynamicQuery<'tcx, query_storage::$name<'tcx>> {
+ DynamicQuery {
+ name: stringify!($name),
+ eval_always: is_eval_always!([$($modifiers)*]),
+ dep_kind: dep_graph::DepKind::$name,
+ handle_cycle_error: handle_cycle_error!([$($modifiers)*]),
+ query_state: offset_of!(QueryStates<'tcx> => $name),
+ query_cache: offset_of!(QueryCaches<'tcx> => $name),
+ cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key),
+ execute_query: |tcx, key| erase(tcx.$name(key)),
+ compute: |tcx, key| query_provided_to_value::$name(
+ tcx,
+ call_provider!([$($modifiers)*][tcx, $name, key])
+ ),
+ can_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] true false),
+ try_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] {
+ |tcx, key, prev_index, index| {
+ if ::rustc_middle::query::cached::$name(tcx, key) {
+ let value = $crate::plumbing::try_load_from_disk::<query_provided::$name<'tcx>>(
+ tcx,
+ prev_index,
+ index,
+ );
+ value.map(|value| query_provided_to_value::$name(tcx, value))
+ } else {
+ None
+ }
+ }
+ } {
+ |_tcx, _key, _prev_index, _index| None
+ }),
+ value_from_cycle_error: |tcx, cycle| {
+ let result: query_values::$name<'tcx> = Value::from_cycle_error(tcx, cycle);
+ erase(result)
+ },
+ loadable_from_disk: |_tcx, _key, _index| {
+ should_ever_cache_on_disk!([$($modifiers)*] {
+ ::rustc_middle::query::cached::$name(_tcx, _key) &&
+ $crate::plumbing::loadable_from_disk(_tcx, _index)
+ } {
+ false
+ })
+ },
+ hash_result: hash_result!([$($modifiers)*][query_values::$name<'tcx>]),
+ format_value: |value| format!("{:?}", restore::<query_values::$name<'tcx>>(*value)),
}
- } {
- None
- })
- }
-
- #[inline]
- fn loadable_from_disk(
- self,
- _qcx: QueryCtxt<'tcx>,
- _key: &Self::Key,
- _index: SerializedDepNodeIndex,
- ) -> bool {
- should_ever_cache_on_disk!([$($modifiers)*] {
- self.cache_on_disk(_qcx.tcx, _key) &&
- $crate::plumbing::loadable_from_disk(_qcx.tcx, _index)
- } {
- false
- })
- }
-
- #[inline]
- fn value_from_cycle_error(
- self,
- tcx: TyCtxt<'tcx>,
- cycle: &[QueryInfo<DepKind>],
- ) -> Self::Value {
- let result: query_values::$name<'tcx> = Value::from_cycle_error(tcx, cycle);
- erase(result)
- }
-
- #[inline(always)]
- fn anon(self) -> bool {
- is_anon!([$($modifiers)*])
- }
-
- #[inline(always)]
- fn eval_always(self) -> bool {
- is_eval_always!([$($modifiers)*])
- }
-
- #[inline(always)]
- fn depth_limit(self) -> bool {
- depth_limit!([$($modifiers)*])
- }
-
- #[inline(always)]
- fn feedable(self) -> bool {
- feedable!([$($modifiers)*])
- }
+ }
+ )*
+ }
- #[inline(always)]
- fn dep_kind(self) -> rustc_middle::dep_graph::DepKind {
- dep_graph::DepKind::$name
- }
+ $(impl<'tcx> QueryConfigRestored<'tcx> for queries::$name<'tcx> {
+ type RestoredValue = query_values::$name<'tcx>;
+ type Config = DynamicConfig<
+ 'tcx,
+ query_storage::$name<'tcx>,
+ { is_anon!([$($modifiers)*]) },
+ { depth_limit!([$($modifiers)*]) },
+ { feedable!([$($modifiers)*]) },
+ >;
#[inline(always)]
- fn handle_cycle_error(self) -> rustc_query_system::HandleCycleError {
- handle_cycle_error!([$($modifiers)*])
+ fn config(tcx: TyCtxt<'tcx>) -> Self::Config {
+ DynamicConfig {
+ dynamic: &tcx.query_system.dynamic_queries.$name,
+ }
}
#[inline(always)]
- fn hash_result(self) -> rustc_query_system::query::HashResult<Self::Value> {
- hash_result!([$($modifiers)*][query_values::$name<'tcx>])
+ fn restore(value: <Self::Config as QueryConfig<QueryCtxt<'tcx>>>::Value) -> Self::RestoredValue {
+ restore::<query_values::$name<'tcx>>(value)
}
})*
- $(impl<'tcx> QueryConfigRestored<'tcx> for queries::$name<'tcx> {
- type RestoredValue = query_values::$name<'tcx>;
-
- #[inline(always)]
- fn restore(value: <Self as QueryConfig<QueryCtxt<'tcx>>>::Value) -> Self::RestoredValue {
- restore::<query_values::$name<'tcx>>(value)
+ pub fn dynamic_queries<'tcx>() -> DynamicQueries<'tcx> {
+ DynamicQueries {
+ $(
+ $name: dynamic_query::$name(),
+ )*
}
- })*
+ }
#[allow(nonstandard_style)]
mod query_callbacks {
@@ -727,9 +716,9 @@ macro_rules! define_queries {
mod query_structs {
use super::*;
- use rustc_middle::ty::query::QueryStruct;
- use rustc_middle::ty::query::QueryKeyStringCache;
+ use rustc_middle::query::plumbing::{QueryKeyStringCache, QueryStruct};
use rustc_middle::dep_graph::DepKind;
+ use crate::QueryConfigRestored;
pub(super) const fn dummy_query_struct<'tcx>() -> QueryStruct<'tcx> {
fn noop_try_collect_active_jobs(_: TyCtxt<'_>, _: &mut QueryMap<DepKind>) -> Option<()> {
@@ -774,7 +763,7 @@ macro_rules! define_queries {
},
encode_query_results: expand_if_cached!([$($modifiers)*], |tcx, encoder, query_result_index|
$crate::plumbing::encode_query_results::<super::queries::$name<'tcx>>(
- super::queries::$name::default(),
+ super::queries::$name::config(tcx),
QueryCtxt::new(tcx),
encoder,
query_result_index,
diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs
index 7d9306f8087..e042ee62dfe 100644
--- a/compiler/rustc_query_impl/src/profiling_support.rs
+++ b/compiler/rustc_query_impl/src/profiling_support.rs
@@ -2,7 +2,7 @@ use measureme::{StringComponent, StringId};
use rustc_data_structures::profiling::SelfProfiler;
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
use rustc_hir::definitions::DefPathData;
-use rustc_middle::ty::query::QueryKeyStringCache;
+use rustc_middle::query::plumbing::QueryKeyStringCache;
use rustc_middle::ty::TyCtxt;
use rustc_query_system::query::QueryCache;
use std::fmt::Debug;
diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs
index bb9ea50a1ea..7e47d701205 100644
--- a/compiler/rustc_query_system/src/query/config.rs
+++ b/compiler/rustc_query_system/src/query/config.rs
@@ -4,6 +4,7 @@ use crate::dep_graph::{DepNode, DepNodeParams, SerializedDepNodeIndex};
use crate::error::HandleCycleError;
use crate::ich::StableHashingContext;
use crate::query::caches::QueryCache;
+use crate::query::DepNodeIndex;
use crate::query::{QueryContext, QueryInfo, QueryState};
use rustc_data_structures::fingerprint::Fingerprint;
@@ -12,8 +13,6 @@ use std::hash::Hash;
pub type HashResult<V> = Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>;
-pub type TryLoadFromDisk<Qcx, V> = Option<fn(Qcx, SerializedDepNodeIndex) -> Option<V>>;
-
pub trait QueryConfig<Qcx: QueryContext>: Copy {
fn name(self) -> &'static str;
@@ -43,7 +42,13 @@ pub trait QueryConfig<Qcx: QueryContext>: Copy {
fn compute(self, tcx: Qcx, key: Self::Key) -> Self::Value;
- fn try_load_from_disk(self, qcx: Qcx, idx: &Self::Key) -> TryLoadFromDisk<Qcx, Self::Value>;
+ fn try_load_from_disk(
+ self,
+ tcx: Qcx,
+ key: &Self::Key,
+ prev_index: SerializedDepNodeIndex,
+ index: DepNodeIndex,
+ ) -> Option<Self::Value>;
fn loadable_from_disk(self, qcx: Qcx, key: &Self::Key, idx: SerializedDepNodeIndex) -> bool;
diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs
index fa1f51b04da..f7619d75be7 100644
--- a/compiler/rustc_query_system/src/query/mod.rs
+++ b/compiler/rustc_query_system/src/query/mod.rs
@@ -12,7 +12,7 @@ pub use self::caches::{
};
mod config;
-pub use self::config::{HashResult, QueryConfig, TryLoadFromDisk};
+pub use self::config::{HashResult, QueryConfig};
use crate::dep_graph::DepKind;
use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 3b17c665fb7..dbfe62ae6e9 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -312,7 +312,7 @@ where
}
#[inline(never)]
-fn try_execute_query<Q, Qcx>(
+fn try_execute_query<Q, Qcx, const INCR: bool>(
query: Q,
qcx: Qcx,
span: Span,
@@ -355,7 +355,7 @@ where
// Drop the lock before we start executing the query
drop(state_lock);
- execute_job(query, qcx, state, key, id, dep_node)
+ execute_job::<_, _, INCR>(query, qcx, state, key, id, dep_node)
}
Entry::Occupied(mut entry) => {
match entry.get_mut() {
@@ -383,7 +383,7 @@ where
}
#[inline(always)]
-fn execute_job<Q, Qcx>(
+fn execute_job<Q, Qcx, const INCR: bool>(
query: Q,
qcx: Qcx,
state: &QueryState<Q::Key, Qcx::DepKind>,
@@ -398,9 +398,19 @@ where
// Use `JobOwner` so the query will be poisoned if executing it panics.
let job_owner = JobOwner { state, key };
- let (result, dep_node_index) = match qcx.dep_context().dep_graph().data() {
- None => execute_job_non_incr(query, qcx, key, id),
- Some(data) => execute_job_incr(query, qcx, data, key, dep_node, id),
+ debug_assert_eq!(qcx.dep_context().dep_graph().is_fully_enabled(), INCR);
+
+ let (result, dep_node_index) = if INCR {
+ execute_job_incr(
+ query,
+ qcx,
+ qcx.dep_context().dep_graph().data().unwrap(),
+ key,
+ dep_node,
+ id,
+ )
+ } else {
+ execute_job_non_incr(query, qcx, key, id)
};
let cache = query.query_cache(qcx);
@@ -564,59 +574,44 @@ where
// First we try to load the result from the on-disk cache.
// Some things are never cached on disk.
- if let Some(try_load_from_disk) = query.try_load_from_disk(qcx, &key) {
- let prof_timer = qcx.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 = qcx
- .dep_context()
- .dep_graph()
- .with_query_deserialization(|| try_load_from_disk(qcx, prev_dep_node_index));
-
- prof_timer.finish_with_query_invocation_id(dep_node_index.into());
-
- if let Some(result) = result {
- if std::intrinsics::unlikely(
- qcx.dep_context().sess().opts.unstable_opts.query_dep_graph,
- ) {
- dep_graph_data.mark_debug_loaded_from_disk(*dep_node)
- }
-
- let prev_fingerprint = dep_graph_data.prev_fingerprint_of(prev_dep_node_index);
- // If `-Zincremental-verify-ich` is specified, re-hash results from
- // the cache and make sure that they have the expected fingerprint.
- //
- // If not, we still seek to verify a subset of fingerprints loaded
- // from disk. Re-hashing results is fairly expensive, so we can't
- // currently afford to verify every hash. This subset should still
- // give us some coverage of potential bugs though.
- let try_verify = prev_fingerprint.split().1.as_u64() % 32 == 0;
- if std::intrinsics::unlikely(
- try_verify || qcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich,
- ) {
- incremental_verify_ich(
- *qcx.dep_context(),
- dep_graph_data,
- &result,
- prev_dep_node_index,
- query.hash_result(),
- query.format_value(),
- );
- }
+ if let Some(result) = query.try_load_from_disk(qcx, key, prev_dep_node_index, dep_node_index) {
+ if std::intrinsics::unlikely(qcx.dep_context().sess().opts.unstable_opts.query_dep_graph) {
+ dep_graph_data.mark_debug_loaded_from_disk(*dep_node)
+ }
- return Some((result, dep_node_index));
+ let prev_fingerprint = dep_graph_data.prev_fingerprint_of(prev_dep_node_index);
+ // If `-Zincremental-verify-ich` is specified, re-hash results from
+ // the cache and make sure that they have the expected fingerprint.
+ //
+ // If not, we still seek to verify a subset of fingerprints loaded
+ // from disk. Re-hashing results is fairly expensive, so we can't
+ // currently afford to verify every hash. This subset should still
+ // give us some coverage of potential bugs though.
+ let try_verify = prev_fingerprint.split().1.as_u64() % 32 == 0;
+ if std::intrinsics::unlikely(
+ try_verify || qcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich,
+ ) {
+ incremental_verify_ich(
+ *qcx.dep_context(),
+ dep_graph_data,
+ &result,
+ prev_dep_node_index,
+ query.hash_result(),
+ query.format_value(),
+ );
}
- // We always expect to find a cached result for things that
- // can be forced from `DepNode`.
- debug_assert!(
- !qcx.dep_context().fingerprint_style(dep_node.kind).reconstructible(),
- "missing on-disk cache entry for reconstructible {dep_node:?}"
- );
+ return Some((result, dep_node_index));
}
+ // We always expect to find a cached result for things that
+ // can be forced from `DepNode`.
+ debug_assert!(
+ !query.cache_on_disk(*qcx.dep_context(), key)
+ || !qcx.dep_context().fingerprint_style(dep_node.kind).reconstructible(),
+ "missing on-disk cache entry for {dep_node:?}"
+ );
+
// Sanity check for the logic in `ensure`: if the node is green and the result loadable,
// we should actually be able to load it.
debug_assert!(
@@ -799,7 +794,18 @@ pub enum QueryMode {
}
#[inline(always)]
-pub fn get_query<Q, Qcx>(
+pub fn get_query_non_incr<Q, Qcx>(query: Q, qcx: Qcx, span: Span, key: Q::Key) -> Q::Value
+where
+ Q: QueryConfig<Qcx>,
+ Qcx: QueryContext,
+{
+ debug_assert!(!qcx.dep_context().dep_graph().is_fully_enabled());
+
+ ensure_sufficient_stack(|| try_execute_query::<Q, Qcx, false>(query, qcx, span, key, None).0)
+}
+
+#[inline(always)]
+pub fn get_query_incr<Q, Qcx>(
query: Q,
qcx: Qcx,
span: Span,
@@ -810,6 +816,8 @@ where
Q: QueryConfig<Qcx>,
Qcx: QueryContext,
{
+ debug_assert!(qcx.dep_context().dep_graph().is_fully_enabled());
+
let dep_node = if let QueryMode::Ensure { check_cache } = mode {
let (must_run, dep_node) = ensure_must_run(query, qcx, &key, check_cache);
if !must_run {
@@ -820,8 +828,9 @@ where
None
};
- let (result, dep_node_index) =
- ensure_sufficient_stack(|| try_execute_query(query, qcx, span, key, dep_node));
+ let (result, dep_node_index) = ensure_sufficient_stack(|| {
+ try_execute_query::<_, _, true>(query, qcx, span, key, dep_node)
+ });
if let Some(dep_node_index) = dep_node_index {
qcx.dep_context().dep_graph().read_index(dep_node_index)
}
@@ -846,5 +855,7 @@ pub fn force_query<Q, Qcx>(
debug_assert!(!query.anon());
- ensure_sufficient_stack(|| try_execute_query(query, qcx, DUMMY_SP, key, Some(dep_node)));
+ ensure_sufficient_stack(|| {
+ try_execute_query::<_, _, true>(query, qcx, DUMMY_SP, key, Some(dep_node))
+ });
}
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 32409499047..345255c4c69 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -145,6 +145,15 @@ resolve_param_in_ty_of_const_param =
the type of const parameters must not depend on other generic parameters
.label = the type must not depend on the parameter `{$name}`
+resolve_type_param_in_ty_of_const_param =
+ type parameters may not be used in the type of const parameters
+
+resolve_const_param_in_ty_of_const_param =
+ const parameters may not be used in the type of const parameters
+
+resolve_lifetime_param_in_ty_of_const_param =
+ lifetime parameters may not be used in the type of const parameters
+
resolve_self_in_generic_param_default =
generic parameters cannot use `Self` in their defaults
.label = `Self` in generic parameter default
@@ -156,12 +165,15 @@ resolve_param_in_non_trivial_anon_const =
resolve_param_in_non_trivial_anon_const_help =
use `#![feature(generic_const_exprs)]` to allow generic const expressions
-resolve_param_in_non_trivial_anon_const_sub_type =
+resolve_type_param_in_non_trivial_anon_const =
type parameters may not be used in const expressions
-resolve_param_in_non_trivial_anon_const_sub_non_type =
+resolve_const_param_in_non_trivial_anon_const =
const parameters may only be used as standalone arguments, i.e. `{$name}`
+resolve_lifetime_param_in_non_trivial_anon_const =
+ lifetime parameters may not be used in const expressions
+
resolve_unreachable_label =
use of unreachable label `{$name}`
.label = unreachable label `{$name}`
@@ -187,6 +199,10 @@ resolve_invalid_asm_sym =
.label = is a local variable
.help = `sym` operands must refer to either a function or a static
+resolve_lowercase_self =
+ attempt to use a non-constant value in a constant
+ .suggestion = try using `Self`
+
resolve_trait_impl_duplicate =
duplicate definitions with name `{$name}`:
.label = duplicate definition
@@ -233,3 +249,16 @@ resolve_macro_use_extern_crate_self = `#[macro_use]` is not supported on `extern
resolve_accessible_unsure = not sure whether the path is accessible or not
.note = the type may have associated items, but we are currently not checking them
+
+resolve_param_in_enum_discriminant =
+ generic parameters may not be used in enum discriminant values
+ .label = cannot perform const operation using `{$name}`
+
+resolve_type_param_in_enum_discriminant =
+ type parameters may not be used in enum discriminant values
+
+resolve_const_param_in_enum_discriminant =
+ const parameters may not be used in enum discriminant values
+
+resolve_lifetime_param_in_enum_discriminant =
+ lifetime parameters may not be used in enum discriminant values
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index fae7d549592..59eda9db97f 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -550,7 +550,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let sm = self.tcx.sess.source_map();
let def_id = match outer_res {
- Res::SelfTyParam { .. } | Res::SelfCtor(_) => {
+ Res::SelfTyParam { .. } => {
err.span_label(span, "can't use `Self` here");
return err;
}
@@ -864,18 +864,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ResolutionError::ForwardDeclaredGenericParam => {
self.tcx.sess.create_err(errs::ForwardDeclaredGenericParam { span })
}
- ResolutionError::ParamInTyOfConstParam(name) => {
- self.tcx.sess.create_err(errs::ParamInTyOfConstParam { span, name })
- }
- ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
+ ResolutionError::ParamInTyOfConstParam { name, param_kind: is_type } => self
+ .tcx
+ .sess
+ .create_err(errs::ParamInTyOfConstParam { span, name, param_kind: is_type }),
+ ResolutionError::ParamInNonTrivialAnonConst { name, param_kind: is_type } => {
self.tcx.sess.create_err(errs::ParamInNonTrivialAnonConst {
span,
name,
- sub_is_type: if is_type {
- errs::ParamInNonTrivialAnonConstIsType::AType
- } else {
- errs::ParamInNonTrivialAnonConstIsType::NotAType { name }
- },
+ param_kind: is_type,
help: self
.tcx
.sess
@@ -883,6 +880,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
.then_some(errs::ParamInNonTrivialAnonConstHelp),
})
}
+ ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self
+ .tcx
+ .sess
+ .create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }),
ResolutionError::SelfInGenericParamDefault => {
self.tcx.sess.create_err(errs::SelfInGenericParamDefault { span })
}
@@ -947,6 +948,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ResolutionError::InvalidAsmSym => {
self.tcx.sess.create_err(errs::InvalidAsmSym { span })
}
+ ResolutionError::LowercaseSelf => {
+ self.tcx.sess.create_err(errs::LowercaseSelf { span })
+ }
}
}
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 4f9f1c7e856..2ab55f12637 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -326,6 +326,18 @@ pub(crate) struct ParamInTyOfConstParam {
#[label]
pub(crate) span: Span,
pub(crate) name: Symbol,
+ #[subdiagnostic]
+ pub(crate) param_kind: Option<ParamKindInTyOfConstParam>,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum ParamKindInTyOfConstParam {
+ #[note(resolve_type_param_in_ty_of_const_param)]
+ Type,
+ #[note(resolve_const_param_in_ty_of_const_param)]
+ Const,
+ #[note(resolve_lifetime_param_in_ty_of_const_param)]
+ Lifetime,
}
#[derive(Diagnostic)]
@@ -344,7 +356,7 @@ pub(crate) struct ParamInNonTrivialAnonConst {
pub(crate) span: Span,
pub(crate) name: Symbol,
#[subdiagnostic]
- pub(crate) sub_is_type: ParamInNonTrivialAnonConstIsType,
+ pub(crate) param_kind: ParamKindInNonTrivialAnonConst,
#[subdiagnostic]
pub(crate) help: Option<ParamInNonTrivialAnonConstHelp>,
}
@@ -354,11 +366,13 @@ pub(crate) struct ParamInNonTrivialAnonConst {
pub(crate) struct ParamInNonTrivialAnonConstHelp;
#[derive(Subdiagnostic)]
-pub(crate) enum ParamInNonTrivialAnonConstIsType {
- #[note(resolve_param_in_non_trivial_anon_const_sub_type)]
- AType,
- #[help(resolve_param_in_non_trivial_anon_const_sub_non_type)]
- NotAType { name: Symbol },
+pub(crate) enum ParamKindInNonTrivialAnonConst {
+ #[note(resolve_type_param_in_non_trivial_anon_const)]
+ Type,
+ #[help(resolve_const_param_in_non_trivial_anon_const)]
+ Const { name: Symbol },
+ #[note(resolve_lifetime_param_in_non_trivial_anon_const)]
+ Lifetime,
}
#[derive(Diagnostic)]
@@ -429,6 +443,14 @@ pub(crate) struct InvalidAsmSym {
}
#[derive(Diagnostic)]
+#[diag(resolve_lowercase_self)]
+pub(crate) struct LowercaseSelf {
+ #[primary_span]
+ #[suggestion(code = "Self", applicability = "maybe-incorrect", style = "short")]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
#[diag(resolve_trait_impl_duplicate, code = "E0201")]
pub(crate) struct TraitImplDuplicate {
#[primary_span]
@@ -539,3 +561,24 @@ pub(crate) struct CfgAccessibleUnsure {
#[primary_span]
pub(crate) span: Span,
}
+
+#[derive(Diagnostic)]
+#[diag(resolve_param_in_enum_discriminant)]
+pub(crate) struct ParamInEnumDiscriminant {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) name: Symbol,
+ #[subdiagnostic]
+ pub(crate) param_kind: ParamKindInEnumDiscriminant,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum ParamKindInEnumDiscriminant {
+ #[note(resolve_type_param_in_enum_discriminant)]
+ Type,
+ #[note(resolve_const_param_in_enum_discriminant)]
+ Const,
+ #[note(resolve_lifetime_param_in_enum_discriminant)]
+ Lifetime,
+}
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 2db1d83d4fd..f065c4ddd2e 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -13,8 +13,9 @@ use rustc_span::{Span, DUMMY_SP};
use std::ptr;
+use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
use crate::late::{
- ConstantHasGenerics, ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind,
+ ConstantHasGenerics, HasGenericParams, NoConstantGenericsReason, PathSource, Rib, RibKind,
};
use crate::macros::{sub_namespace_match, MacroRulesScope};
use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
@@ -1125,35 +1126,38 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
RibKind::ConstantItem(_, item) => {
// Still doesn't deal with upvars
if let Some(span) = finalize {
- let (span, resolution_error) =
- if let Some((ident, constant_item_kind)) = item {
- let kind_str = match constant_item_kind {
- ConstantItemKind::Const => "const",
- ConstantItemKind::Static => "static",
- };
- (
- span,
- AttemptToUseNonConstantValueInConstant(
- ident, "let", kind_str,
- ),
- )
- } else {
- (
- rib_ident.span,
- AttemptToUseNonConstantValueInConstant(
- original_rib_ident_def,
- "const",
- "let",
- ),
- )
- };
+ let (span, resolution_error) = match item {
+ None if rib_ident.as_str() == "self" => (span, LowercaseSelf),
+ None => (
+ rib_ident.span,
+ AttemptToUseNonConstantValueInConstant(
+ original_rib_ident_def,
+ "const",
+ "let",
+ ),
+ ),
+ Some((ident, kind)) => (
+ span,
+ AttemptToUseNonConstantValueInConstant(
+ ident,
+ "let",
+ kind.as_str(),
+ ),
+ ),
+ };
self.report_error(span, resolution_error);
}
return Res::Err;
}
RibKind::ConstParamTy => {
if let Some(span) = finalize {
- self.report_error(span, ParamInTyOfConstParam(rib_ident.name));
+ self.report_error(
+ span,
+ ParamInTyOfConstParam {
+ name: rib_ident.name,
+ param_kind: None,
+ },
+ );
}
return Res::Err;
}
@@ -1170,10 +1174,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
return Res::Err;
}
}
- Res::Def(DefKind::TyParam, _)
- | Res::SelfTyParam { .. }
- | Res::SelfTyAlias { .. }
- | Res::SelfCtor(_) => {
+ Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
for rib in ribs {
let has_generic_params: HasGenericParams = match rib.kind {
RibKind::Normal
@@ -1188,11 +1189,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
RibKind::ConstantItem(trivial, _) => {
- let features = self.tcx.sess.features_untracked();
- // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
- if !(trivial == ConstantHasGenerics::Yes
- || features.generic_const_exprs)
- {
+ if let ConstantHasGenerics::No(cause) = trivial {
// 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
@@ -1210,13 +1207,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
} else {
if let Some(span) = finalize {
- self.report_error(
- span,
- ResolutionError::ParamInNonTrivialAnonConst {
- name: rib_ident.name,
- is_type: true,
- },
- );
+ let error = match cause {
+ NoConstantGenericsReason::IsEnumDiscriminant => {
+ ResolutionError::ParamInEnumDiscriminant {
+ name: rib_ident.name,
+ param_kind: ParamKindInEnumDiscriminant::Type,
+ }
+ }
+ NoConstantGenericsReason::NonTrivialConstArg => {
+ ResolutionError::ParamInNonTrivialAnonConst {
+ name: rib_ident.name,
+ param_kind:
+ ParamKindInNonTrivialAnonConst::Type,
+ }
+ }
+ };
+ self.report_error(span, error);
self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
}
@@ -1233,7 +1239,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let Some(span) = finalize {
self.report_error(
span,
- ResolutionError::ParamInTyOfConstParam(rib_ident.name),
+ ResolutionError::ParamInTyOfConstParam {
+ name: rib_ident.name,
+ param_kind: Some(errors::ParamKindInTyOfConstParam::Type),
+ },
);
}
return Res::Err;
@@ -1264,20 +1273,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
| RibKind::ForwardGenericParamBan => continue,
RibKind::ConstantItem(trivial, _) => {
- let features = self.tcx.sess.features_untracked();
- // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
- if !(trivial == ConstantHasGenerics::Yes
- || features.generic_const_exprs)
- {
+ if let ConstantHasGenerics::No(cause) = trivial {
if let Some(span) = finalize {
- self.report_error(
- span,
- ResolutionError::ParamInNonTrivialAnonConst {
- name: rib_ident.name,
- is_type: false,
- },
- );
- self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
+ let error = match cause {
+ NoConstantGenericsReason::IsEnumDiscriminant => {
+ ResolutionError::ParamInEnumDiscriminant {
+ name: rib_ident.name,
+ param_kind: ParamKindInEnumDiscriminant::Const,
+ }
+ }
+ NoConstantGenericsReason::NonTrivialConstArg => {
+ ResolutionError::ParamInNonTrivialAnonConst {
+ name: rib_ident.name,
+ param_kind: ParamKindInNonTrivialAnonConst::Const {
+ name: rib_ident.name,
+ },
+ }
+ }
+ };
+ self.report_error(span, error);
}
return Res::Err;
@@ -1291,7 +1305,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let Some(span) = finalize {
self.report_error(
span,
- ResolutionError::ParamInTyOfConstParam(rib_ident.name),
+ ResolutionError::ParamInTyOfConstParam {
+ name: rib_ident.name,
+ param_kind: Some(errors::ParamKindInTyOfConstParam::Const),
+ },
);
}
return Res::Err;
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 6f5d54bcf87..c053ea222a0 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -66,6 +66,15 @@ enum IsRepeatExpr {
Yes,
}
+/// Describes whether an `AnonConst` is a type level const arg or
+/// some other form of anon const (i.e. inline consts or enum discriminants)
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+enum AnonConstKind {
+ EnumDiscriminant,
+ InlineConst,
+ ConstArg(IsRepeatExpr),
+}
+
impl PatternSource {
fn descr(self) -> &'static str {
match self {
@@ -105,7 +114,7 @@ pub(crate) enum HasGenericParams {
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(crate) enum ConstantHasGenerics {
Yes,
- No,
+ No(NoConstantGenericsReason),
}
impl ConstantHasGenerics {
@@ -114,12 +123,42 @@ impl ConstantHasGenerics {
}
}
+/// Reason for why an anon const is not allowed to reference generic parameters
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub(crate) enum NoConstantGenericsReason {
+ /// Const arguments are only allowed to use generic parameters when:
+ /// - `feature(generic_const_exprs)` is enabled
+ /// or
+ /// - the const argument is a sole const generic paramater, i.e. `foo::<{ N }>()`
+ ///
+ /// If neither of the above are true then this is used as the cause.
+ NonTrivialConstArg,
+ /// Enum discriminants are not allowed to reference generic parameters ever, this
+ /// is used when an anon const is in the following position:
+ ///
+ /// ```rust,compile_fail
+ /// enum Foo<const N: isize> {
+ /// Variant = { N }, // this anon const is not allowed to use generics
+ /// }
+ /// ```
+ IsEnumDiscriminant,
+}
+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(crate) enum ConstantItemKind {
Const,
Static,
}
+impl ConstantItemKind {
+ pub(crate) fn as_str(&self) -> &'static str {
+ match self {
+ Self::Const => "const",
+ Self::Static => "static",
+ }
+ }
+}
+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum RecordPartialRes {
Yes,
@@ -273,15 +312,18 @@ enum LifetimeRibKind {
/// Signal we cannot find which should be the anonymous lifetime.
ElisionFailure,
- /// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const
- /// generics. We are disallowing this until we can decide on how we want to handle non-'static
- /// lifetimes in const generics. See issue #74052 for discussion.
- ConstGeneric,
+ /// This rib forbids usage of generic parameters inside of const parameter types.
+ ///
+ /// While this is desirable to support eventually, it is difficult to do and so is
+ /// currently forbidden. See rust-lang/project-const-generics#28 for more info.
+ ConstParamTy,
- /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
- /// This function will emit an error if `generic_const_exprs` is not enabled, the body
- /// identified by `body_id` is an anonymous constant and `lifetime_ref` is non-static.
- AnonConst,
+ /// Usage of generic parameters is forbidden in various positions for anon consts:
+ /// - const arguments when `generic_const_exprs` is not enabled
+ /// - enum discriminant values
+ ///
+ /// This rib emits an error when a lifetime would resolve to a lifetime parameter.
+ ConcreteAnonConst(NoConstantGenericsReason),
/// This rib acts as a barrier to forbid reference to lifetimes of a parent item.
Item,
@@ -648,13 +690,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
self.resolve_block(block);
self.parent_scope.macro_rules = old_macro_rules;
}
- fn visit_anon_const(&mut self, constant: &'ast AnonConst) {
- // We deal with repeat expressions explicitly in `resolve_expr`.
- self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
- this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
- this.resolve_anon_const(constant, IsRepeatExpr::No);
- })
- })
+ fn visit_anon_const(&mut self, _constant: &'ast AnonConst) {
+ bug!("encountered anon const without a manual call to `resolve_anon_const`");
}
fn visit_expr(&mut self, expr: &'ast Expr) {
self.resolve_expr(expr, None);
@@ -676,7 +713,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
fn visit_ty(&mut self, ty: &'ast Ty) {
let prev = self.diagnostic_metadata.current_trait_object;
let prev_ty = self.diagnostic_metadata.current_type_path;
- match ty.kind {
+ match &ty.kind {
TyKind::Ref(None, _) => {
// Elided lifetime in reference: we resolve as if there was some lifetime `'_` with
// NodeId `ty.id`.
@@ -685,7 +722,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
self.resolve_elided_lifetime(ty.id, span);
visit::walk_ty(self, ty);
}
- TyKind::Path(ref qself, ref path) => {
+ TyKind::Path(qself, path) => {
self.diagnostic_metadata.current_type_path = Some(ty);
self.smart_resolve_path(ty.id, &qself, path, PathSource::Type);
@@ -730,11 +767,11 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
visit::walk_ty(self, ty);
self.lifetime_elision_candidates = candidates;
}
- TyKind::TraitObject(ref bounds, ..) => {
+ TyKind::TraitObject(bounds, ..) => {
self.diagnostic_metadata.current_trait_object = Some(&bounds[..]);
visit::walk_ty(self, ty)
}
- TyKind::BareFn(ref bare_fn) => {
+ TyKind::BareFn(bare_fn) => {
let span = ty.span.shrink_to_lo().to(bare_fn.decl_span.shrink_to_lo());
self.with_generic_param_rib(
&bare_fn.generic_params,
@@ -769,6 +806,13 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
},
)
}
+ TyKind::Array(element_ty, length) => {
+ self.visit_ty(element_ty);
+ self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No));
+ }
+ TyKind::Typeof(ct) => {
+ self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No))
+ }
_ => visit::walk_ty(self, ty),
}
self.diagnostic_metadata.current_trait_object = prev;
@@ -994,36 +1038,25 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
// namespace first, and if that fails we try again in the value namespace. If
// resolution in the value namespace succeeds, we have an generic const argument on
// our hands.
- if let TyKind::Path(ref qself, ref path) = ty.kind {
+ if let TyKind::Path(None, ref path) = ty.kind {
// We cannot disambiguate multi-segment paths right now as that requires type
// checking.
- if path.segments.len() == 1 && path.segments[0].args.is_none() {
+ if path.is_potential_trivial_const_arg() {
let mut check_ns = |ns| {
self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns)
.is_some()
};
if !check_ns(TypeNS) && check_ns(ValueNS) {
- // This must be equivalent to `visit_anon_const`, but we cannot call it
- // directly due to visitor lifetimes so we have to copy-paste some code.
- //
- // Note that we might not be inside of an repeat expression here,
- // but considering that `IsRepeatExpr` is only relevant for
- // non-trivial constants this is doesn't matter.
- self.with_constant_rib(
- IsRepeatExpr::No,
- ConstantHasGenerics::Yes,
- None,
+ self.resolve_anon_const_manual(
+ true,
+ AnonConstKind::ConstArg(IsRepeatExpr::No),
|this| {
this.smart_resolve_path(
ty.id,
- qself,
+ &None,
path,
PathSource::Expr(None),
);
-
- if let Some(ref qself) = *qself {
- this.visit_ty(&qself.ty);
- }
this.visit_path(path, ty.id);
},
);
@@ -1037,7 +1070,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
self.visit_ty(ty);
}
GenericArg::Lifetime(lt) => self.visit_lifetime(lt, visit::LifetimeCtxt::GenericArg),
- GenericArg::Const(ct) => self.visit_anon_const(ct),
+ GenericArg::Const(ct) => {
+ self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No))
+ }
}
self.diagnostic_metadata.currently_processing_generics = prev;
}
@@ -1053,7 +1088,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
match constraint.kind {
AssocConstraintKind::Equality { ref term } => match term {
Term::Ty(ty) => self.visit_ty(ty),
- Term::Const(c) => self.visit_anon_const(c),
+ Term::Const(c) => {
+ self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No))
+ }
},
AssocConstraintKind::Bound { ref bounds } => {
walk_list!(self, visit_param_bound, bounds, BoundKind::Bound);
@@ -1102,8 +1139,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
| LifetimeRibKind::AnonymousReportError
| LifetimeRibKind::Elided(_)
| LifetimeRibKind::ElisionFailure
- | LifetimeRibKind::AnonConst
- | LifetimeRibKind::ConstGeneric => {}
+ | LifetimeRibKind::ConcreteAnonConst(_)
+ | LifetimeRibKind::ConstParamTy => {}
}
}
}
@@ -1164,7 +1201,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
InlineAsmOperand::Const { anon_const, .. } => {
// Although this is `DefKind::AnonConst`, it is allowed to reference outer
// generic parameters like an inline const.
- self.resolve_inline_const(anon_const);
+ self.resolve_anon_const(anon_const, AnonConstKind::InlineConst);
}
InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym),
}
@@ -1188,6 +1225,10 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
visit::walk_variant(self, v)
}
+ fn visit_variant_discr(&mut self, discr: &'ast AnonConst) {
+ self.resolve_anon_const(discr, AnonConstKind::EnumDiscriminant);
+ }
+
fn visit_field_def(&mut self, f: &'ast FieldDef) {
self.resolve_doc_links(&f.attrs, MaybeExported::Ok(f.id));
visit::walk_field_def(self, f)
@@ -1386,7 +1427,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));
this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy));
- this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
+ this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {
this.visit_ty(ty)
});
this.ribs[TypeNS].pop().unwrap();
@@ -1395,9 +1436,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
if let Some(ref expr) = default {
this.ribs[TypeNS].push(forward_ty_ban_rib);
this.ribs[ValueNS].push(forward_const_ban_rib);
- this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
- this.resolve_anon_const(expr, IsRepeatExpr::No)
- });
+ this.resolve_anon_const(
+ expr,
+ AnonConstKind::ConstArg(IsRepeatExpr::No),
+ );
forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap();
forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap();
}
@@ -1449,7 +1491,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
if let Some(&(_, res)) = rib.bindings.get(&normalized_ident) {
self.record_lifetime_res(lifetime.id, res, LifetimeElisionCandidate::Named);
- if let LifetimeRes::Param { param, .. } = res {
+ if let LifetimeRes::Param { param, binder } = res {
match self.lifetime_uses.entry(param) {
Entry::Vacant(v) => {
debug!("First use of {:?} at {:?}", res, ident.span);
@@ -1463,10 +1505,16 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
LifetimeRibKind::Item
| LifetimeRibKind::AnonymousReportError
| LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many),
- // An anonymous lifetime is legal here, go ahead.
- LifetimeRibKind::AnonymousCreateParameter { .. } => {
- Some(LifetimeUseSet::One { use_span: ident.span, use_ctxt })
- }
+ // An anonymous lifetime is legal here, and bound to the right
+ // place, go ahead.
+ LifetimeRibKind::AnonymousCreateParameter {
+ binder: anon_binder,
+ ..
+ } => Some(if binder == anon_binder {
+ LifetimeUseSet::One { use_span: ident.span, use_ctxt }
+ } else {
+ LifetimeUseSet::Many
+ }),
// Only report if eliding the lifetime would have the same
// semantics.
LifetimeRibKind::Elided(r) => Some(if res == r {
@@ -1475,8 +1523,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
LifetimeUseSet::Many
}),
LifetimeRibKind::Generics { .. }
- | LifetimeRibKind::ConstGeneric => None,
- LifetimeRibKind::AnonConst => {
+ | LifetimeRibKind::ConstParamTy => None,
+ LifetimeRibKind::ConcreteAnonConst(_) => {
span_bug!(ident.span, "unexpected rib kind: {:?}", rib.kind)
}
})
@@ -1495,8 +1543,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
match rib.kind {
LifetimeRibKind::Item => break,
- LifetimeRibKind::ConstGeneric => {
- self.emit_non_static_lt_in_const_generic_error(lifetime);
+ LifetimeRibKind::ConstParamTy => {
+ self.emit_non_static_lt_in_const_param_ty_error(lifetime);
self.record_lifetime_res(
lifetime.id,
LifetimeRes::Error,
@@ -1504,8 +1552,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
);
return;
}
- LifetimeRibKind::AnonConst => {
- self.maybe_emit_forbidden_non_static_lifetime_error(lifetime);
+ LifetimeRibKind::ConcreteAnonConst(cause) => {
+ self.emit_forbidden_non_static_lifetime_error(cause, lifetime);
self.record_lifetime_res(
lifetime.id,
LifetimeRes::Error,
@@ -1604,9 +1652,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
return;
}
LifetimeRibKind::Item => break,
- LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstGeneric => {}
- LifetimeRibKind::AnonConst => {
- // There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`.
+ LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {}
+ LifetimeRibKind::ConcreteAnonConst(_) => {
+ // There is always an `Elided(LifetimeRes::Infer)` inside an `AnonConst`.
span_bug!(lifetime.ident.span, "unexpected rib kind: {:?}", rib.kind)
}
}
@@ -1826,9 +1874,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
break;
}
- LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstGeneric => {}
- LifetimeRibKind::AnonConst => {
- // There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`.
+ LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {}
+ LifetimeRibKind::ConcreteAnonConst(_) => {
+ // There is always an `Elided(LifetimeRes::Infer)` inside an `AnonConst`.
span_bug!(elided_lifetime_span, "unexpected rib kind: {:?}", rib.kind)
}
}
@@ -2560,7 +2608,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
}
- // HACK(min_const_generics,const_evaluatable_unchecked): We
+ // HACK(min_const_generics, generic_const_exprs): We
// want to keep allowing `[0; std::mem::size_of::<*mut T>()]`
// with a future compat lint for now. We do this by adding an
// additional special case for repeat expressions.
@@ -2576,18 +2624,26 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
item: Option<(Ident, ConstantItemKind)>,
f: impl FnOnce(&mut Self),
) {
- self.with_rib(ValueNS, RibKind::ConstantItem(may_use_generics, item), |this| {
- this.with_rib(
- TypeNS,
- RibKind::ConstantItem(
- may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes),
- item,
- ),
- |this| {
- this.with_label_rib(RibKind::ConstantItem(may_use_generics, item), f);
- },
- )
- });
+ let f = |this: &mut Self| {
+ this.with_rib(ValueNS, RibKind::ConstantItem(may_use_generics, item), |this| {
+ this.with_rib(
+ TypeNS,
+ RibKind::ConstantItem(
+ may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes),
+ item,
+ ),
+ |this| {
+ this.with_label_rib(RibKind::ConstantItem(may_use_generics, item), f);
+ },
+ )
+ })
+ };
+
+ if let ConstantHasGenerics::No(cause) = may_use_generics {
+ self.with_lifetime_rib(LifetimeRibKind::ConcreteAnonConst(cause), f)
+ } else {
+ f(self)
+ }
}
fn with_current_self_type<T>(&mut self, self_type: &Ty, f: impl FnOnce(&mut Self) -> T) -> T {
@@ -3487,10 +3543,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
//
// Similar thing, for types, happens in `report_errors` above.
let report_errors_for_call = |this: &mut Self, parent_err: Spanned<ResolutionError<'a>>| {
- if !source.is_call() {
- return Some(parent_err);
- }
-
// Before we start looking for candidates, we have to get our hands
// on the type user is trying to perform invocation on; basically:
// we're transforming `HashMap::new` into just `HashMap`.
@@ -3924,24 +3976,54 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
debug!("(resolving block) leaving block");
}
- fn resolve_anon_const(&mut self, constant: &'ast AnonConst, is_repeat: IsRepeatExpr) {
- debug!("resolve_anon_const {:?} is_repeat: {:?}", constant, is_repeat);
- self.with_constant_rib(
- is_repeat,
- if constant.value.is_potential_trivial_const_param() {
- ConstantHasGenerics::Yes
- } else {
- ConstantHasGenerics::No
- },
- None,
- |this| visit::walk_anon_const(this, constant),
+ fn resolve_anon_const(&mut self, constant: &'ast AnonConst, anon_const_kind: AnonConstKind) {
+ debug!(
+ "resolve_anon_const(constant: {:?}, anon_const_kind: {:?})",
+ constant, anon_const_kind
);
+
+ self.resolve_anon_const_manual(
+ constant.value.is_potential_trivial_const_arg(),
+ anon_const_kind,
+ |this| this.resolve_expr(&constant.value, None),
+ )
}
- fn resolve_inline_const(&mut self, constant: &'ast AnonConst) {
- debug!("resolve_anon_const {constant:?}");
- self.with_constant_rib(IsRepeatExpr::No, ConstantHasGenerics::Yes, None, |this| {
- visit::walk_anon_const(this, constant)
+ /// There are a few places that we need to resolve an anon const but we did not parse an
+ /// anon const so cannot provide an `&'ast AnonConst`. Right now this is just unbraced
+ /// const arguments that were parsed as type arguments, and `legact_const_generics` which
+ /// parse as normal function argument expressions. To avoid duplicating the code for resolving
+ /// an anon const we have this function which lets the caller manually call `resolve_expr` or
+ /// `smart_resolve_path`.
+ fn resolve_anon_const_manual(
+ &mut self,
+ is_trivial_const_arg: bool,
+ anon_const_kind: AnonConstKind,
+ resolve_expr: impl FnOnce(&mut Self),
+ ) {
+ let is_repeat_expr = match anon_const_kind {
+ AnonConstKind::ConstArg(is_repeat_expr) => is_repeat_expr,
+ _ => IsRepeatExpr::No,
+ };
+
+ let may_use_generics = match anon_const_kind {
+ AnonConstKind::EnumDiscriminant => {
+ ConstantHasGenerics::No(NoConstantGenericsReason::IsEnumDiscriminant)
+ }
+ AnonConstKind::InlineConst => ConstantHasGenerics::Yes,
+ AnonConstKind::ConstArg(_) => {
+ if self.r.tcx.features().generic_const_exprs || is_trivial_const_arg {
+ ConstantHasGenerics::Yes
+ } else {
+ ConstantHasGenerics::No(NoConstantGenericsReason::NonTrivialConstArg)
+ }
+ }
+ };
+
+ self.with_constant_rib(is_repeat_expr, may_use_generics, None, |this| {
+ this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
+ resolve_expr(this);
+ });
});
}
@@ -4046,17 +4128,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// Constant arguments need to be treated as AnonConst since
// that is how they will be later lowered to HIR.
if const_args.contains(&idx) {
- self.with_constant_rib(
- IsRepeatExpr::No,
- if argument.is_potential_trivial_const_param() {
- ConstantHasGenerics::Yes
- } else {
- ConstantHasGenerics::No
- },
- None,
- |this| {
- this.resolve_expr(argument, None);
- },
+ self.resolve_anon_const_manual(
+ argument.is_potential_trivial_const_arg(),
+ AnonConstKind::ConstArg(IsRepeatExpr::No),
+ |this| this.resolve_expr(argument, None),
);
} else {
self.resolve_expr(argument, None);
@@ -4115,14 +4190,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
}
ExprKind::Repeat(ref elem, ref ct) => {
self.visit_expr(elem);
- self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
- this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
- this.resolve_anon_const(ct, IsRepeatExpr::Yes)
- })
- });
+ self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::Yes));
}
ExprKind::ConstBlock(ref ct) => {
- self.resolve_inline_const(ct);
+ self.resolve_anon_const(ct, AnonConstKind::InlineConst);
}
ExprKind::Index(ref elem, ref idx) => {
self.resolve_expr(elem, Some(expr));
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 42d498c7ee0..c9131d8c8a9 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1,7 +1,7 @@
use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion};
use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind};
use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet};
-use crate::path_names_to_string;
+use crate::{errors, path_names_to_string};
use crate::{Module, ModuleKind, ModuleOrUniformRoot};
use crate::{PathResult, PathSource, Segment};
@@ -22,7 +22,6 @@ use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
use rustc_hir::PrimTy;
use rustc_session::lint;
-use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
@@ -35,6 +34,8 @@ use std::ops::Deref;
use thin_vec::ThinVec;
+use super::NoConstantGenericsReason;
+
type Res = def::Res<ast::NodeId>;
/// A field or associated item from self type suggested in case of resolution failure.
@@ -2316,37 +2317,56 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
}
- pub(crate) fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) {
- struct_span_err!(
- self.r.tcx.sess,
- lifetime_ref.ident.span,
- E0771,
- "use of non-static lifetime `{}` in const generic",
- lifetime_ref.ident
- )
- .note(
- "for more information, see issue #74052 \
- <https://github.com/rust-lang/rust/issues/74052>",
- )
- .emit();
+ pub(crate) fn emit_non_static_lt_in_const_param_ty_error(&self, lifetime_ref: &ast::Lifetime) {
+ self.r
+ .tcx
+ .sess
+ .create_err(errors::ParamInTyOfConstParam {
+ span: lifetime_ref.ident.span,
+ name: lifetime_ref.ident.name,
+ param_kind: Some(errors::ParamKindInTyOfConstParam::Lifetime),
+ })
+ .emit();
}
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
/// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
/// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
- pub(crate) fn maybe_emit_forbidden_non_static_lifetime_error(
+ pub(crate) fn emit_forbidden_non_static_lifetime_error(
&self,
+ cause: NoConstantGenericsReason,
lifetime_ref: &ast::Lifetime,
) {
- let feature_active = self.r.tcx.sess.features_untracked().generic_const_exprs;
- if !feature_active {
- feature_err(
- &self.r.tcx.sess.parse_sess,
- sym::generic_const_exprs,
- lifetime_ref.ident.span,
- "a non-static lifetime is not allowed in a `const`",
- )
- .emit();
+ match cause {
+ NoConstantGenericsReason::IsEnumDiscriminant => {
+ self.r
+ .tcx
+ .sess
+ .create_err(errors::ParamInEnumDiscriminant {
+ span: lifetime_ref.ident.span,
+ name: lifetime_ref.ident.name,
+ param_kind: errors::ParamKindInEnumDiscriminant::Lifetime,
+ })
+ .emit();
+ }
+ NoConstantGenericsReason::NonTrivialConstArg => {
+ assert!(!self.r.tcx.features().generic_const_exprs);
+ self.r
+ .tcx
+ .sess
+ .create_err(errors::ParamInNonTrivialAnonConst {
+ span: lifetime_ref.ident.span,
+ name: lifetime_ref.ident.name,
+ param_kind: errors::ParamKindInNonTrivialAnonConst::Lifetime,
+ help: self
+ .r
+ .tcx
+ .sess
+ .is_nightly_build()
+ .then_some(errors::ParamInNonTrivialAnonConstHelp),
+ })
+ .emit();
+ }
}
}
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index e46463579fe..323b78fcd98 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -21,6 +21,9 @@
#[macro_use]
extern crate tracing;
+use errors::{
+ ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst, ParamKindInTyOfConstParam,
+};
use rustc_arena::{DroplessArena, TypedArena};
use rustc_ast::node_id::NodeMap;
use rustc_ast::{self as ast, attr, NodeId, CRATE_NODE_ID};
@@ -44,6 +47,7 @@ use rustc_index::IndexVec;
use rustc_metadata::creader::{CStore, CrateLoader};
use rustc_middle::metadata::ModChild;
use rustc_middle::middle::privacy::EffectiveVisibilities;
+use rustc_middle::query::Providers;
use rustc_middle::span_bug;
use rustc_middle::ty::{self, MainDefinition, RegisteredTools, TyCtxt};
use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs};
@@ -223,11 +227,15 @@ enum ResolutionError<'a> {
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
ForwardDeclaredGenericParam,
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
- ParamInTyOfConstParam(Symbol),
+ ParamInTyOfConstParam { name: Symbol, param_kind: Option<ParamKindInTyOfConstParam> },
/// generic parameters must not be used inside const evaluations.
///
/// This error is only emitted when using `min_const_generics`.
- ParamInNonTrivialAnonConst { name: Symbol, is_type: bool },
+ ParamInNonTrivialAnonConst { name: Symbol, param_kind: ParamKindInNonTrivialAnonConst },
+ /// generic parameters must not be used inside enum discriminants.
+ ///
+ /// This error is emitted even with `generic_const_exprs`.
+ ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant },
/// Error E0735: generic parameters with a default cannot use `Self`
SelfInGenericParamDefault,
/// Error E0767: use of unreachable label
@@ -244,6 +252,8 @@ enum ResolutionError<'a> {
TraitImplDuplicate { name: Symbol, trait_item_span: Span, old_span: Span },
/// Inline asm `sym` operand must refer to a `fn` or `static`.
InvalidAsmSym,
+ /// `self` used instead of `Self` in a generic parameter
+ LowercaseSelf,
}
enum VisResolutionError<'a> {
@@ -2017,6 +2027,6 @@ impl Finalize {
}
}
-pub fn provide(providers: &mut ty::query::Providers) {
+pub fn provide(providers: &mut Providers) {
providers.registered_tools = macros::registered_tools;
}
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index 6b559cb5b2f..0ffc537eee0 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -1,4 +1,4 @@
-use crate::leb128::{self, largest_max_leb128_len};
+use crate::leb128;
use crate::serialize::{Decodable, Decoder, Encodable, Encoder};
use std::fs::File;
use std::io::{self, Write};
@@ -14,6 +14,9 @@ use std::ptr;
pub type FileEncodeResult = Result<usize, io::Error>;
+/// The size of the buffer in `FileEncoder`.
+const BUF_SIZE: usize = 8192;
+
/// `FileEncoder` encodes data to file via fixed-size buffer.
///
/// There used to be a `MemEncoder` type that encoded all the data into a
@@ -35,26 +38,12 @@ pub struct FileEncoder {
impl FileEncoder {
pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Self> {
- const DEFAULT_BUF_SIZE: usize = 8192;
- FileEncoder::with_capacity(path, DEFAULT_BUF_SIZE)
- }
-
- pub fn with_capacity<P: AsRef<Path>>(path: P, capacity: usize) -> io::Result<Self> {
- // Require capacity at least as large as the largest LEB128 encoding
- // here, so that we don't have to check or handle this on every write.
- assert!(capacity >= largest_max_leb128_len());
-
- // Require capacity small enough such that some capacity checks can be
- // done using guaranteed non-overflowing add rather than sub, which
- // shaves an instruction off those code paths (on x86 at least).
- assert!(capacity <= usize::MAX - largest_max_leb128_len());
-
// Create the file for reading and writing, because some encoders do both
// (e.g. the metadata encoder when -Zmeta-stats is enabled)
let file = File::options().read(true).write(true).create(true).truncate(true).open(path)?;
Ok(FileEncoder {
- buf: Box::new_uninit_slice(capacity),
+ buf: Box::new_uninit_slice(BUF_SIZE),
buffered: 0,
flushed: 0,
file,
@@ -160,18 +149,10 @@ impl FileEncoder {
}
#[inline]
- fn capacity(&self) -> usize {
- self.buf.len()
- }
-
- #[inline]
fn write_one(&mut self, value: u8) {
- // We ensure this during `FileEncoder` construction.
- debug_assert!(self.capacity() >= 1);
-
let mut buffered = self.buffered;
- if std::intrinsics::unlikely(buffered >= self.capacity()) {
+ if std::intrinsics::unlikely(buffered + 1 > BUF_SIZE) {
self.flush();
buffered = 0;
}
@@ -187,13 +168,12 @@ impl FileEncoder {
#[inline]
fn write_all(&mut self, buf: &[u8]) {
- let capacity = self.capacity();
let buf_len = buf.len();
- if std::intrinsics::likely(buf_len <= capacity) {
+ if std::intrinsics::likely(buf_len <= BUF_SIZE) {
let mut buffered = self.buffered;
- if std::intrinsics::unlikely(buf_len > capacity - buffered) {
+ if std::intrinsics::unlikely(buffered + buf_len > BUF_SIZE) {
self.flush();
buffered = 0;
}
@@ -271,13 +251,11 @@ macro_rules! write_leb128 {
fn $this_fn(&mut self, v: $int_ty) {
const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>();
- // We ensure this during `FileEncoder` construction.
- debug_assert!(self.capacity() >= MAX_ENCODED_LEN);
-
let mut buffered = self.buffered;
- // This can't overflow. See assertion in `FileEncoder::with_capacity`.
- if std::intrinsics::unlikely(buffered + MAX_ENCODED_LEN > self.capacity()) {
+ // This can't overflow because BUF_SIZE and MAX_ENCODED_LEN are both
+ // quite small.
+ if std::intrinsics::unlikely(buffered + MAX_ENCODED_LEN > BUF_SIZE) {
self.flush();
buffered = 0;
}
diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml
index 3477b97438c..3af83aaaaa8 100644
--- a/compiler/rustc_session/Cargo.toml
+++ b/compiler/rustc_session/Cargo.toml
@@ -25,7 +25,7 @@ termize = "0.1.1"
libc = "0.2"
[target.'cfg(windows)'.dependencies.windows]
-version = "0.46.0"
+version = "0.48.0"
features = [
"Win32_Foundation",
"Win32_System_LibraryLoader",
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index aa3cb03bad8..e2b8d3eea2d 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1060,6 +1060,9 @@ fn default_configuration(sess: &Session) -> CrateConfig {
if sess.opts.debug_assertions {
ret.insert((sym::debug_assertions, None));
}
+ if sess.overflow_checks() {
+ ret.insert((sym::overflow_checks, None));
+ }
// JUSTIFICATION: before wrapper fn is available
#[allow(rustc::bad_opt_access)]
if sess.opts.crate_types.contains(&CrateType::ProcMacro) {
@@ -1209,6 +1212,7 @@ impl CrateCheckConfig {
sym::windows,
sym::proc_macro,
sym::debug_assertions,
+ sym::overflow_checks,
sym::target_thread_local,
] {
self.expecteds.entry(name).or_insert_with(no_values);
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index dd1721801f3..dc475e8c6d5 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -6,7 +6,8 @@ use crate::search_paths::PathKind;
use crate::utils::NativeLibKind;
use crate::Session;
use rustc_ast as ast;
-use rustc_data_structures::sync::{self, AppendOnlyIndexVec, MetadataRef, RwLock};
+use rustc_data_structures::owned_slice::OwnedSlice;
+use rustc_data_structures::sync::{self, AppendOnlyIndexVec, RwLock};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, StableCrateId, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions};
use rustc_span::hygiene::{ExpnHash, ExpnId};
@@ -203,11 +204,11 @@ pub enum ExternCrateSource {
/// metadata in library -- this trait just serves to decouple rustc_metadata from
/// the archive reader, which depends on LLVM.
pub trait MetadataLoader: std::fmt::Debug {
- fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String>;
- fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String>;
+ fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>;
+ fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>;
}
-pub type MetadataLoaderDyn = dyn MetadataLoader + Send + Sync;
+pub type MetadataLoaderDyn = dyn MetadataLoader + Send + Sync + sync::DynSend + sync::DynSync;
/// A store of Rust crates, through which their metadata can be accessed.
///
@@ -252,7 +253,7 @@ pub trait CrateStore: std::fmt::Debug {
fn import_source_files(&self, sess: &Session, cnum: CrateNum);
}
-pub type CrateStoreDyn = dyn CrateStore + sync::Sync + sync::Send;
+pub type CrateStoreDyn = dyn CrateStore + sync::DynSync + sync::DynSend;
pub struct Untracked {
pub cstore: RwLock<Box<CrateStoreDyn>>,
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index 7fdbd48d563..3988416d0c7 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -135,13 +135,13 @@ fn current_dll_path() -> Result<PathBuf, String> {
use windows::{
core::PCWSTR,
- Win32::Foundation::HINSTANCE,
+ Win32::Foundation::HMODULE,
Win32::System::LibraryLoader::{
GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
},
};
- let mut module = HINSTANCE::default();
+ let mut module = HMODULE::default();
unsafe {
GetModuleHandleExW(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 5cbd7f98b6b..5976b9aa3e7 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1720,6 +1720,10 @@ options! {
#[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)"),
+ staticlib_allow_rdylib_deps: bool = (false, parse_bool, [TRACKED],
+ "allow staticlibs to have rust dylib dependencies"),
+ staticlib_prefer_dynamic: bool = (false, parse_bool, [TRACKED],
+ "prefer dynamic linking to static linking for staticlibs (default: no)"),
strict_init_checks: bool = (false, parse_bool, [TRACKED],
"control if mem::uninitialized and mem::zeroed panic on more UB"),
strip: Strip = (Strip::None, parse_strip, [UNTRACKED],
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index 54d474db038..b00f0a1c153 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))]
+#![feature(local_key_cell_methods)]
+#![feature(ptr_metadata)]
pub mod rustc_internal;
pub mod stable_mir;
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 5998c8b6500..609a04d263c 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -3,30 +3,49 @@
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
//! until stable MIR is complete.
-use std::sync::RwLock;
-
-use crate::stable_mir;
+use crate::{
+ rustc_smir::Tables,
+ stable_mir::{self, with},
+};
+use rustc_middle::ty::TyCtxt;
pub use rustc_span::def_id::{CrateNum, DefId};
-static DEF_ID_MAP: RwLock<Vec<DefId>> = RwLock::new(Vec::new());
+fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R {
+ let mut ret = None;
+ with(|tables| tables.rustc_tables(&mut |t| ret = Some(f(t))));
+ ret.unwrap()
+}
pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId {
- DEF_ID_MAP.read().unwrap()[item.0]
+ with_tables(|t| t.item_def_id(item))
}
pub fn crate_item(did: DefId) -> stable_mir::CrateItem {
- // FIXME: this becomes inefficient when we have too many ids
- let mut map = DEF_ID_MAP.write().unwrap();
- for (i, &d) in map.iter().enumerate() {
- if d == did {
- return stable_mir::CrateItem(i);
+ with_tables(|t| t.crate_item(did))
+}
+
+impl<'tcx> Tables<'tcx> {
+ pub fn item_def_id(&self, item: &stable_mir::CrateItem) -> DefId {
+ self.def_ids[item.0]
+ }
+
+ pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
+ // FIXME: this becomes inefficient when we have too many ids
+ for (i, &d) in self.def_ids.iter().enumerate() {
+ if d == did {
+ return stable_mir::CrateItem(i);
+ }
}
+ let id = self.def_ids.len();
+ self.def_ids.push(did);
+ stable_mir::CrateItem(id)
}
- let id = map.len();
- map.push(did);
- stable_mir::CrateItem(id)
}
pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
item.id.into()
}
+
+pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
+ crate::stable_mir::run(Tables { tcx, def_ids: vec![], types: vec![] }, f);
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 241cd182059..6af43f5d3f3 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -7,41 +7,107 @@
//!
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
-use crate::{
- rustc_internal::{crate_item, item_def_id},
- stable_mir::{self},
-};
-use rustc_middle::ty::{tls::with, TyCtxt};
-use rustc_span::def_id::{CrateNum, LOCAL_CRATE};
+use crate::stable_mir::{self, ty::TyKind, Context};
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
use tracing::debug;
-/// Get information about the local crate.
-pub fn local_crate() -> stable_mir::Crate {
- with(|tcx| smir_crate(tcx, LOCAL_CRATE))
-}
+impl<'tcx> Context for Tables<'tcx> {
+ fn local_crate(&self) -> stable_mir::Crate {
+ smir_crate(self.tcx, LOCAL_CRATE)
+ }
-/// Retrieve a list of all external crates.
-pub fn external_crates() -> Vec<stable_mir::Crate> {
- with(|tcx| tcx.crates(()).iter().map(|crate_num| smir_crate(tcx, *crate_num)).collect())
-}
+ fn external_crates(&self) -> Vec<stable_mir::Crate> {
+ self.tcx.crates(()).iter().map(|crate_num| smir_crate(self.tcx, *crate_num)).collect()
+ }
-/// Find a crate with the given name.
-pub fn find_crate(name: &str) -> Option<stable_mir::Crate> {
- with(|tcx| {
- [LOCAL_CRATE].iter().chain(tcx.crates(()).iter()).find_map(|crate_num| {
- let crate_name = tcx.crate_name(*crate_num).to_string();
- (name == crate_name).then(|| smir_crate(tcx, *crate_num))
+ fn find_crate(&self, name: &str) -> Option<stable_mir::Crate> {
+ [LOCAL_CRATE].iter().chain(self.tcx.crates(()).iter()).find_map(|crate_num| {
+ let crate_name = self.tcx.crate_name(*crate_num).to_string();
+ (name == crate_name).then(|| smir_crate(self.tcx, *crate_num))
})
- })
+ }
+
+ fn all_local_items(&mut self) -> stable_mir::CrateItems {
+ self.tcx.mir_keys(()).iter().map(|item| self.crate_item(item.to_def_id())).collect()
+ }
+ fn entry_fn(&mut self) -> Option<stable_mir::CrateItem> {
+ Some(self.crate_item(self.tcx.entry_fn(())?.0))
+ }
+ fn mir_body(&mut self, item: &stable_mir::CrateItem) -> stable_mir::mir::Body {
+ let def_id = self.item_def_id(item);
+ let mir = self.tcx.optimized_mir(def_id);
+ stable_mir::mir::Body {
+ blocks: mir
+ .basic_blocks
+ .iter()
+ .map(|block| stable_mir::mir::BasicBlock {
+ terminator: rustc_terminator_to_terminator(block.terminator()),
+ statements: block.statements.iter().map(rustc_statement_to_statement).collect(),
+ })
+ .collect(),
+ locals: mir.local_decls.iter().map(|decl| self.intern_ty(decl.ty)).collect(),
+ }
+ }
+
+ fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>)) {
+ f(self)
+ }
+
+ fn ty_kind(&mut self, ty: crate::stable_mir::ty::Ty) -> TyKind {
+ self.rustc_ty_to_ty(self.types[ty.0])
+ }
}
-/// Retrieve all items of the local crate that have a MIR associated with them.
-pub fn all_local_items() -> stable_mir::CrateItems {
- with(|tcx| tcx.mir_keys(()).iter().map(|item| crate_item(item.to_def_id())).collect())
+pub struct Tables<'tcx> {
+ pub tcx: TyCtxt<'tcx>,
+ pub def_ids: Vec<DefId>,
+ pub types: Vec<Ty<'tcx>>,
}
-pub fn entry_fn() -> Option<stable_mir::CrateItem> {
- with(|tcx| Some(crate_item(tcx.entry_fn(())?.0)))
+impl<'tcx> Tables<'tcx> {
+ fn rustc_ty_to_ty(&mut self, ty: Ty<'tcx>) -> TyKind {
+ match ty.kind() {
+ ty::Bool => TyKind::Bool,
+ ty::Char => todo!(),
+ ty::Int(_) => todo!(),
+ ty::Uint(_) => todo!(),
+ ty::Float(_) => todo!(),
+ ty::Adt(_, _) => todo!(),
+ ty::Foreign(_) => todo!(),
+ ty::Str => todo!(),
+ ty::Array(_, _) => todo!(),
+ ty::Slice(_) => todo!(),
+ ty::RawPtr(_) => todo!(),
+ ty::Ref(_, _, _) => todo!(),
+ ty::FnDef(_, _) => todo!(),
+ ty::FnPtr(_) => todo!(),
+ ty::Placeholder(..) => todo!(),
+ ty::Dynamic(_, _, _) => todo!(),
+ ty::Closure(_, _) => todo!(),
+ ty::Generator(_, _, _) => todo!(),
+ ty::GeneratorWitness(_) => todo!(),
+ ty::GeneratorWitnessMIR(_, _) => todo!(),
+ ty::Never => todo!(),
+ ty::Tuple(fields) => {
+ TyKind::Tuple(fields.iter().map(|ty| self.intern_ty(ty)).collect())
+ }
+ ty::Alias(_, _) => todo!(),
+ ty::Param(_) => todo!(),
+ ty::Bound(_, _) => todo!(),
+ ty::Infer(_) => todo!(),
+ ty::Error(_) => todo!(),
+ }
+ }
+
+ fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty {
+ if let Some(id) = self.types.iter().position(|&t| t == ty) {
+ return stable_mir::ty::Ty(id);
+ }
+ let id = self.types.len();
+ self.types.push(ty);
+ stable_mir::ty::Ty(id)
+ }
}
/// Build a stable mir crate from a given crate number.
@@ -52,23 +118,6 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local }
}
-pub fn mir_body(item: &stable_mir::CrateItem) -> stable_mir::mir::Body {
- with(|tcx| {
- let def_id = item_def_id(item);
- let mir = tcx.optimized_mir(def_id);
- stable_mir::mir::Body {
- blocks: mir
- .basic_blocks
- .iter()
- .map(|block| stable_mir::mir::BasicBlock {
- terminator: rustc_terminator_to_terminator(block.terminator()),
- statements: block.statements.iter().map(rustc_statement_to_statement).collect(),
- })
- .collect(),
- }
- })
-}
-
fn rustc_statement_to_statement(
s: &rustc_middle::mir::Statement<'_>,
) -> stable_mir::mir::Statement {
diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs
index 4baf3f1f75e..6328c35aa59 100644
--- a/compiler/rustc_smir/src/stable_mir/mir/body.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs
@@ -1,6 +1,9 @@
+use crate::stable_mir::ty::Ty;
+
#[derive(Clone, Debug)]
pub struct Body {
pub blocks: Vec<BasicBlock>,
+ pub locals: Vec<Ty>,
}
#[derive(Clone, Debug)]
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
index 1d2efb5eab9..612777b9c75 100644
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ b/compiler/rustc_smir/src/stable_mir/mod.rs
@@ -11,7 +11,14 @@
//! There shouldn't be any direct references to internal compiler constructs in this module.
//! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`.
+use std::cell::Cell;
+
+use crate::rustc_smir::Tables;
+
+use self::ty::{Ty, TyKind};
+
pub mod mir;
+pub mod ty;
/// Use String for now but we should replace it.
pub type Symbol = String;
@@ -41,7 +48,7 @@ pub struct CrateItem(pub(crate) DefId);
impl CrateItem {
pub fn body(&self) -> mir::Body {
- crate::rustc_smir::mir_body(self)
+ with(|cx| cx.mir_body(self))
}
}
@@ -49,25 +56,72 @@ impl CrateItem {
/// crate defines that. This is usually `main`, but could be
/// `start` if the crate is a no-std crate.
pub fn entry_fn() -> Option<CrateItem> {
- crate::rustc_smir::entry_fn()
+ with(|cx| cx.entry_fn())
}
/// Access to the local crate.
pub fn local_crate() -> Crate {
- crate::rustc_smir::local_crate()
+ with(|cx| cx.local_crate())
}
/// Try to find a crate with the given name.
pub fn find_crate(name: &str) -> Option<Crate> {
- crate::rustc_smir::find_crate(name)
+ with(|cx| cx.find_crate(name))
}
/// Try to find a crate with the given name.
pub fn external_crates() -> Vec<Crate> {
- crate::rustc_smir::external_crates()
+ with(|cx| cx.external_crates())
}
/// Retrieve all items in the local crate that have a MIR associated with them.
pub fn all_local_items() -> CrateItems {
- crate::rustc_smir::all_local_items()
+ with(|cx| cx.all_local_items())
+}
+
+pub trait Context {
+ fn entry_fn(&mut self) -> Option<CrateItem>;
+ /// Retrieve all items of the local crate that have a MIR associated with them.
+ fn all_local_items(&mut self) -> CrateItems;
+ fn mir_body(&mut self, item: &CrateItem) -> mir::Body;
+ /// Get information about the local crate.
+ fn local_crate(&self) -> Crate;
+ /// Retrieve a list of all external crates.
+ fn external_crates(&self) -> Vec<Crate>;
+
+ /// Find a crate with the given name.
+ fn find_crate(&self, name: &str) -> Option<Crate>;
+
+ /// Obtain the representation of a type.
+ fn ty_kind(&mut self, ty: Ty) -> TyKind;
+
+ /// HACK: Until we have fully stable consumers, we need an escape hatch
+ /// to get `DefId`s out of `CrateItem`s.
+ fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>));
+}
+
+thread_local! {
+ /// A thread local variable that stores a pointer to the tables mapping between TyCtxt
+ /// datastructures and stable MIR datastructures.
+ static TLV: Cell<*mut ()> = const { Cell::new(std::ptr::null_mut()) };
+}
+
+pub fn run(mut context: impl Context, f: impl FnOnce()) {
+ assert!(TLV.get().is_null());
+ fn g<'a>(mut context: &mut (dyn Context + 'a), f: impl FnOnce()) {
+ TLV.set(&mut context as *mut &mut _ as _);
+ f();
+ TLV.replace(std::ptr::null_mut());
+ }
+ g(&mut context, f);
+}
+
+/// Loads the current context and calls a function with it.
+/// Do not nest these, as that will ICE.
+pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
+ let ptr = TLV.replace(std::ptr::null_mut()) as *mut &mut dyn Context;
+ assert!(!ptr.is_null());
+ let ret = f(unsafe { *ptr });
+ TLV.set(ptr as _);
+ ret
}
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
new file mode 100644
index 00000000000..f27801b0f6c
--- /dev/null
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -0,0 +1,15 @@
+use super::with;
+
+#[derive(Copy, Clone, Debug)]
+pub struct Ty(pub usize);
+
+impl Ty {
+ pub fn kind(&self) -> TyKind {
+ with(|context| context.ty_kind(*self))
+ }
+}
+
+pub enum TyKind {
+ Bool,
+ Tuple(Vec<Ty>),
+}
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 7bbab34c69a..97cb734619e 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -20,6 +20,7 @@
#![feature(min_specialization)]
#![feature(rustc_attrs)]
#![feature(let_chains)]
+#![feature(round_char_boundary)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 1294a8b8e6b..11ea5fe4ddf 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -14,7 +14,9 @@ pub use crate::*;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{Hash128, Hash64, StableHasher};
-use rustc_data_structures::sync::{AtomicU32, Lrc, MappedReadGuard, ReadGuard, RwLock};
+use rustc_data_structures::sync::{
+ AtomicU32, IntoDynSyncSend, Lrc, MappedReadGuard, ReadGuard, RwLock,
+};
use std::cmp;
use std::hash::Hash;
use std::path::{self, Path, PathBuf};
@@ -176,7 +178,7 @@ pub struct SourceMap {
used_address_space: AtomicU32,
files: RwLock<SourceMapFiles>,
- file_loader: Box<dyn FileLoader + Sync + Send>,
+ file_loader: IntoDynSyncSend<Box<dyn FileLoader + Sync + Send>>,
// This is used to apply the file path remapping as specified via
// `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`.
path_mapping: FilePathMapping,
@@ -202,7 +204,7 @@ impl SourceMap {
SourceMap {
used_address_space: AtomicU32::new(0),
files: Default::default(),
- file_loader,
+ file_loader: IntoDynSyncSend(file_loader),
path_mapping,
hash_kind,
}
@@ -1017,36 +1019,19 @@ impl SourceMap {
let src = local_begin.sf.external_src.borrow();
- // We need to extend the snippet to the end of the src rather than to end_index so when
- // searching forwards for boundaries we've got somewhere to search.
- let snippet = if let Some(ref src) = local_begin.sf.src {
- &src[start_index..]
+ let snippet = if let Some(src) = &local_begin.sf.src {
+ src
} else if let Some(src) = src.get_source() {
- &src[start_index..]
+ src
} else {
return 1;
};
- debug!("snippet=`{:?}`", snippet);
- let mut target = if forwards { end_index + 1 } else { end_index - 1 };
- debug!("initial target=`{:?}`", target);
-
- while !snippet.is_char_boundary(target - start_index) && target < source_len {
- target = if forwards {
- target + 1
- } else {
- match target.checked_sub(1) {
- Some(target) => target,
- None => {
- break;
- }
- }
- };
- debug!("target=`{:?}`", target);
+ if forwards {
+ (snippet.ceil_char_boundary(end_index + 1) - end_index) as u32
+ } else {
+ (end_index - snippet.floor_char_boundary(end_index - 1)) as u32
}
- debug!("final target=`{:?}`", target);
-
- if forwards { (target - end_index) as u32 } else { (end_index - target) as u32 }
}
pub fn get_source_file(&self, filename: &FileName) -> Option<Lrc<SourceFile>> {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index b97ec6c684b..874d578fe1d 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -95,6 +95,7 @@ symbols! {
// Weak keywords, have special meaning only in specific contexts.
Auto: "auto",
+ Builtin: "builtin",
Catch: "catch",
Default: "default",
MacroRules: "macro_rules",
@@ -163,6 +164,7 @@ symbols! {
Capture,
Center,
Clone,
+ ConstParamTy,
Context,
Continue,
Copy,
@@ -440,6 +442,7 @@ symbols! {
breakpoint,
bridge,
bswap,
+ builtin_syntax,
c_str,
c_str_literals,
c_unwind,
@@ -461,6 +464,7 @@ symbols! {
cfg_doctest,
cfg_eval,
cfg_hide,
+ cfg_overflow_checks,
cfg_panic,
cfg_sanitize,
cfg_target_abi,
@@ -1031,6 +1035,7 @@ symbols! {
non_exhaustive_omitted_patterns_lint,
non_lifetime_binders,
non_modrs_mods,
+ none,
nontemporal_store,
noop_method_borrow,
noop_method_clone,
@@ -1062,6 +1067,7 @@ symbols! {
or_patterns,
other,
out,
+ overflow_checks,
overlapping_marker_traits,
owned_box,
packed,
@@ -1578,6 +1584,7 @@ symbols! {
unrestricted_attribute_tokens,
unsafe_block_in_unsafe_fn,
unsafe_cell,
+ unsafe_cell_from_mut,
unsafe_no_drop_flag,
unsafe_pin_internals,
unsize,
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index c97406868b6..692542da78e 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -107,7 +107,7 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Instance, TyCtxt};
use rustc_session::config::SymbolManglingVersion;
diff --git a/compiler/rustc_symbol_mangling/src/typeid.rs b/compiler/rustc_symbol_mangling/src/typeid.rs
index 81dbff9ea4e..cda16e3a3f5 100644
--- a/compiler/rustc_symbol_mangling/src/typeid.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid.rs
@@ -4,7 +4,7 @@
/// For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler,
/// see design document in the tracking issue #89653.
use bitflags::bitflags;
-use rustc_middle::ty::{FnSig, Ty, TyCtxt};
+use rustc_middle::ty::{FnSig, Instance, Ty, TyCtxt};
use rustc_target::abi::call::FnAbi;
use std::hash::Hasher;
use twox_hash::XxHash64;
@@ -38,6 +38,15 @@ pub fn typeid_for_fnsig<'tcx>(
typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, options)
}
+/// Returns a type metadata identifier for the specified Instance.
+pub fn typeid_for_instance<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ instance: &Instance<'tcx>,
+ options: TypeIdOptions,
+) -> String {
+ typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options)
+}
+
/// Returns a KCFI type metadata identifier for the specified FnAbi.
pub fn kcfi_typeid_for_fnabi<'tcx>(
tcx: TyCtxt<'tcx>,
@@ -63,3 +72,16 @@ pub fn kcfi_typeid_for_fnsig<'tcx>(
hash.write(typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, options).as_bytes());
hash.finish() as u32
}
+
+/// Returns a KCFI type metadata identifier for the specified Instance.
+pub fn kcfi_typeid_for_instance<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ instance: &Instance<'tcx>,
+ options: TypeIdOptions,
+) -> u32 {
+ // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the
+ // xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.)
+ let mut hash: XxHash64 = Default::default();
+ hash.write(typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options).as_bytes());
+ hash.finish() as u32
+}
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 5310ef26da7..c281aa7e83a 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
@@ -14,8 +14,8 @@ use rustc_errors::DiagnosticMessage;
use rustc_hir as hir;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use rustc_middle::ty::{
- self, Const, ExistentialPredicate, FloatTy, FnSig, IntTy, List, Region, RegionKind, TermKind,
- Ty, TyCtxt, UintTy,
+ self, Const, ExistentialPredicate, FloatTy, FnSig, Instance, IntTy, List, Region, RegionKind,
+ TermKind, Ty, TyCtxt, UintTy,
};
use rustc_span::def_id::DefId;
use rustc_span::sym;
@@ -1010,3 +1010,56 @@ pub fn typeid_for_fnsig<'tcx>(
typeid
}
+
+/// Returns a type metadata identifier for the specified Instance using the Itanium C++ ABI with
+/// vendor extended type qualifiers and types for Rust types that are not used at the FFI boundary.
+pub fn typeid_for_instance<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ instance: &Instance<'tcx>,
+ options: TypeIdOptions,
+) -> String {
+ let fn_abi = tcx
+ .fn_abi_of_instance(tcx.param_env(instance.def_id()).and((*instance, ty::List::empty())))
+ .unwrap_or_else(|instance| {
+ bug!("typeid_for_instance: couldn't get fn_abi of instance {:?}", instance)
+ });
+
+ // If this instance is a method and self is a reference, get the impl it belongs to
+ let impl_def_id = tcx.impl_of_method(instance.def_id());
+ if impl_def_id.is_some() && !fn_abi.args.is_empty() && fn_abi.args[0].layout.ty.is_ref() {
+ // If this impl is not an inherent impl, get the trait it implements
+ if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id.unwrap()) {
+ // Transform the concrete self into a reference to a trait object
+ let existential_predicate = trait_ref.map_bound(|trait_ref| {
+ ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(
+ tcx, trait_ref,
+ ))
+ });
+ let existential_predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(
+ existential_predicate.skip_binder(),
+ )]);
+ // Is the concrete self mutable?
+ let self_ty = if fn_abi.args[0].layout.ty.is_mutable_ptr() {
+ tcx.mk_mut_ref(
+ tcx.lifetimes.re_erased,
+ tcx.mk_dynamic(existential_predicates, tcx.lifetimes.re_erased, ty::Dyn),
+ )
+ } else {
+ tcx.mk_imm_ref(
+ tcx.lifetimes.re_erased,
+ tcx.mk_dynamic(existential_predicates, tcx.lifetimes.re_erased, ty::Dyn),
+ )
+ };
+
+ // Replace the concrete self in an fn_abi clone by the reference to a trait object
+ let mut fn_abi = fn_abi.clone();
+ // HACK(rcvalle): It is okay to not replace or update the entire ArgAbi here because the
+ // other fields are never used.
+ fn_abi.args[0].layout.ty = self_ty;
+
+ return typeid_for_fnabi(tcx, &fn_abi, options);
+ }
+ }
+
+ typeid_for_fnabi(tcx, &fn_abi, options)
+}
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 52159a7b06a..1ae11f5671c 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -28,7 +28,7 @@ mod x86;
mod x86_64;
mod x86_win64;
-#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)]
+#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub enum PassMode {
/// Ignore the argument.
///
@@ -211,7 +211,7 @@ impl Uniform {
}
}
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
+#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct CastTarget {
pub prefix: [Option<Reg>; 8],
pub rest: Uniform,
@@ -458,7 +458,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
/// Information about how to pass an argument to,
/// or return a value from, a function, under some ABI.
-#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)]
+#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct ArgAbi<'a, Ty> {
pub layout: TyAndLayout<'a, Ty>,
pub mode: PassMode,
@@ -605,7 +605,7 @@ pub enum Conv {
///
/// I will do my best to describe this structure, but these
/// comments are reverse-engineered and may be inaccurate. -NDM
-#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)]
+#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct FnAbi<'a, Ty> {
/// The LLVM types of each argument.
pub args: Box<[ArgAbi<'a, Ty>]>,
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 705966f5237..e60b8e78e5d 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -882,8 +882,8 @@ impl InlineAsmClobberAbi {
_ => Err(&["C", "system", "efiapi"]),
},
InlineAsmArch::LoongArch64 => match name {
- "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::LoongArch),
- _ => Err(&["C", "system", "efiapi"]),
+ "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
+ _ => Err(&["C", "system"]),
},
_ => Err(&[]),
}
diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl
index 14eb4a5502d..8fea3fc140d 100644
--- a/compiler/rustc_trait_selection/messages.ftl
+++ b/compiler/rustc_trait_selection/messages.ftl
@@ -20,3 +20,5 @@ trait_selection_negative_positive_conflict = found both positive and negative im
.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}`
+
+trait_selection_inherent_projection_normalization_overflow = overflow evaluating associated type `{$ty}`
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index df7c4df1868..54e22cc3d7f 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -89,3 +89,11 @@ impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> {
diag
}
}
+
+#[derive(Diagnostic)]
+#[diag(trait_selection_inherent_projection_normalization_overflow)]
+pub struct InherentProjectionNormalizationOverflow {
+ #[primary_span]
+ pub span: Span,
+ pub ty: String,
+}
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index bacb0e32efc..25cc82f01d5 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -8,6 +8,7 @@ use rustc_data_structures::fx::FxIndexSet;
use rustc_hir::def_id::DefId;
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::util::elaborate;
+use rustc_infer::traits::Reveal;
use rustc_middle::traits::solve::{CanonicalResponse, Certainty, Goal, MaybeCause, QueryResult};
use rustc_middle::ty::fast_reject::TreatProjections;
use rustc_middle::ty::TypeFoldable;
@@ -87,7 +88,9 @@ pub(super) enum CandidateSource {
}
/// Methods used to assemble candidates for either trait or projection goals.
-pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq {
+pub(super) trait GoalKind<'tcx>:
+ TypeFoldable<TyCtxt<'tcx>> + Copy + Eq + std::fmt::Display
+{
fn self_ty(self) -> Ty<'tcx>;
fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx>;
@@ -96,6 +99,17 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq {
fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId;
+ // Try equating an assumption predicate against a goal's predicate. If it
+ // holds, then execute the `then` callback, which should do any additional
+ // work, then produce a response (typically by executing
+ // [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
+ fn probe_and_match_goal_against_assumption(
+ ecx: &mut EvalCtxt<'_, 'tcx>,
+ goal: Goal<'tcx, Self>,
+ assumption: ty::Predicate<'tcx>,
+ then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
+ ) -> QueryResult<'tcx>;
+
// Consider a clause, which consists of a "assumption" and some "requirements",
// to satisfy a goal. If the requirements hold, then attempt to satisfy our
// goal by equating it with the assumption.
@@ -104,7 +118,26 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq {
goal: Goal<'tcx, Self>,
assumption: ty::Predicate<'tcx>,
requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
- ) -> QueryResult<'tcx>;
+ ) -> QueryResult<'tcx> {
+ Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
+ ecx.add_goals(requirements);
+ ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+ })
+ }
+
+ /// Consider a bound originating from the item bounds of an alias. For this we
+ /// require that the well-formed requirements of the self type of the goal
+ /// are "satisfied from the param-env".
+ /// See [`EvalCtxt::validate_alias_bound_self_from_param_env`].
+ fn consider_alias_bound_candidate(
+ ecx: &mut EvalCtxt<'_, 'tcx>,
+ goal: Goal<'tcx, Self>,
+ assumption: ty::Predicate<'tcx>,
+ ) -> QueryResult<'tcx> {
+ Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
+ ecx.validate_alias_bound_self_from_param_env(goal)
+ })
+ }
// Consider a clause specifically for a `dyn Trait` self type. This requires
// additionally checking all of the supertraits and object bounds to hold,
@@ -113,7 +146,25 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq {
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
assumption: ty::Predicate<'tcx>,
- ) -> QueryResult<'tcx>;
+ ) -> QueryResult<'tcx> {
+ Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
+ let tcx = ecx.tcx();
+ let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
+ bug!("expected object type in `consider_object_bound_candidate`");
+ };
+ ecx.add_goals(
+ structural_traits::predicates_for_object_candidate(
+ &ecx,
+ goal.param_env,
+ goal.predicate.trait_ref(tcx),
+ bounds,
+ )
+ .into_iter()
+ .map(|pred| goal.with(tcx, pred)),
+ );
+ ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+ })
+ }
fn consider_impl_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
@@ -463,7 +514,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
for assumption in self.tcx().item_bounds(alias_ty.def_id).subst(self.tcx(), alias_ty.substs)
{
- match G::consider_implied_clause(self, goal, assumption, []) {
+ match G::consider_alias_bound_candidate(self, goal, assumption) {
Ok(result) => {
candidates.push(Candidate { source: CandidateSource::AliasBound, result })
}
@@ -472,6 +523,105 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
}
}
+ /// Check that we are allowed to use an alias bound originating from the self
+ /// type of this goal. This means something different depending on the self type's
+ /// alias kind.
+ ///
+ /// * Projection: Given a goal with a self type such as `<Ty as Trait>::Assoc`,
+ /// we require that the bound `Ty: Trait` can be proven using either a nested alias
+ /// bound candidate, or a param-env candidate.
+ ///
+ /// * Opaque: The param-env must be in `Reveal::UserFacing` mode. Otherwise,
+ /// the goal should be proven by using the hidden type instead.
+ #[instrument(level = "debug", skip(self), ret)]
+ pub(super) fn validate_alias_bound_self_from_param_env<G: GoalKind<'tcx>>(
+ &mut self,
+ goal: Goal<'tcx, G>,
+ ) -> QueryResult<'tcx> {
+ match *goal.predicate.self_ty().kind() {
+ ty::Alias(ty::Projection, projection_ty) => {
+ let mut param_env_candidates = vec![];
+ let self_trait_ref = projection_ty.trait_ref(self.tcx());
+
+ if self_trait_ref.self_ty().is_ty_var() {
+ return self
+ .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
+ }
+
+ let trait_goal: Goal<'_, ty::TraitPredicate<'tcx>> = goal.with(
+ self.tcx(),
+ ty::TraitPredicate {
+ trait_ref: self_trait_ref,
+ constness: ty::BoundConstness::NotConst,
+ polarity: ty::ImplPolarity::Positive,
+ },
+ );
+
+ self.assemble_param_env_candidates(trait_goal, &mut param_env_candidates);
+ // FIXME: We probably need some sort of recursion depth check here.
+ // Can't come up with an example yet, though, and the worst case
+ // we can have is a compiler stack overflow...
+ self.assemble_alias_bound_candidates(trait_goal, &mut param_env_candidates);
+
+ // FIXME: We must also consider alias-bound candidates for a peculiar
+ // class of built-in candidates that I'll call "defaulted" built-ins.
+ //
+ // For example, we always know that `T: Pointee` is implemented, but
+ // we do not always know what `<T as Pointee>::Metadata` actually is,
+ // similar to if we had a user-defined impl with a `default type ...`.
+ // For these traits, since we're not able to always normalize their
+ // associated types to a concrete type, we must consider their alias bounds
+ // instead, so we can prove bounds such as `<T as Pointee>::Metadata: Copy`.
+ self.assemble_alias_bound_candidates_for_builtin_impl_default_items(
+ trait_goal,
+ &mut param_env_candidates,
+ );
+
+ self.merge_candidates(param_env_candidates)
+ }
+ ty::Alias(ty::Opaque, _opaque_ty) => match goal.param_env.reveal() {
+ Reveal::UserFacing => {
+ self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+ }
+ Reveal::All => return Err(NoSolution),
+ },
+ _ => bug!("only expected to be called on alias tys"),
+ }
+ }
+
+ /// Assemble a subset of builtin impl candidates for a class of candidates called
+ /// "defaulted" built-in traits.
+ ///
+ /// For example, we always know that `T: Pointee` is implemented, but we do not
+ /// always know what `<T as Pointee>::Metadata` actually is! See the comment in
+ /// [`EvalCtxt::validate_alias_bound_self_from_param_env`] for more detail.
+ #[instrument(level = "debug", skip_all)]
+ fn assemble_alias_bound_candidates_for_builtin_impl_default_items<G: GoalKind<'tcx>>(
+ &mut self,
+ goal: Goal<'tcx, G>,
+ candidates: &mut Vec<Candidate<'tcx>>,
+ ) {
+ let lang_items = self.tcx().lang_items();
+ let trait_def_id = goal.predicate.trait_def_id(self.tcx());
+
+ // You probably shouldn't add anything to this list unless you
+ // know what you're doing.
+ let result = if lang_items.pointee_trait() == Some(trait_def_id) {
+ G::consider_builtin_pointee_candidate(self, goal)
+ } else if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
+ G::consider_builtin_discriminant_kind_candidate(self, goal)
+ } else {
+ Err(NoSolution)
+ };
+
+ match result {
+ Ok(result) => {
+ candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
+ }
+ Err(NoSolution) => (),
+ }
+ }
+
#[instrument(level = "debug", skip_all)]
fn assemble_object_bound_candidates<G: GoalKind<'tcx>>(
&mut self,
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index 996dc329dcb..0ede32c753c 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -33,7 +33,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
ty::Dynamic(..)
| ty::Param(..)
| ty::Foreign(..)
- | ty::Alias(ty::Projection, ..)
+ | ty::Alias(ty::Projection | ty::Inherent, ..)
| ty::Placeholder(..)
| ty::Bound(..)
| ty::Infer(_) => {
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index e5d51064c8d..d3228074421 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -56,11 +56,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
self.trait_def_id(tcx)
}
- fn consider_implied_clause(
+ fn probe_and_match_goal_against_assumption(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
assumption: ty::Predicate<'tcx>,
- requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
+ then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
) -> QueryResult<'tcx> {
if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
&& poly_projection_pred.projection_def_id() == goal.predicate.def_id()
@@ -75,49 +75,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
)?;
ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term)
.expect("expected goal term to be fully unconstrained");
- ecx.add_goals(requirements);
- ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
- })
- } else {
- Err(NoSolution)
- }
- }
-
- fn consider_object_bound_candidate(
- ecx: &mut EvalCtxt<'_, 'tcx>,
- goal: Goal<'tcx, Self>,
- assumption: ty::Predicate<'tcx>,
- ) -> QueryResult<'tcx> {
- if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
- && poly_projection_pred.projection_def_id() == goal.predicate.def_id()
- {
- ecx.probe(|ecx| {
- let tcx = ecx.tcx();
-
- let assumption_projection_pred =
- ecx.instantiate_binder_with_infer(poly_projection_pred);
- ecx.eq(
- goal.param_env,
- goal.predicate.projection_ty,
- assumption_projection_pred.projection_ty,
- )?;
-
- let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
- bug!("expected object type in `consider_object_bound_candidate`");
- };
- ecx.add_goals(
- structural_traits::predicates_for_object_candidate(
- &ecx,
- goal.param_env,
- goal.predicate.projection_ty.trait_ref(tcx),
- bounds,
- )
- .into_iter()
- .map(|pred| goal.with(tcx, pred)),
- );
- ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term)
- .expect("expected goal term to be fully unconstrained");
- ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+ then(ecx)
})
} else {
Err(NoSolution)
@@ -166,10 +124,24 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
};
if !assoc_def.item.defaultness(tcx).has_value() {
- tcx.sess.delay_span_bug(
+ let guar = tcx.sess.delay_span_bug(
tcx.def_span(assoc_def.item.def_id),
"missing value for assoc item in impl",
);
+ let error_term = match assoc_def.item.kind {
+ ty::AssocKind::Const => tcx
+ .const_error(
+ tcx.type_of(goal.predicate.def_id())
+ .subst(tcx, goal.predicate.projection_ty.substs),
+ guar,
+ )
+ .into(),
+ ty::AssocKind::Type => tcx.ty_error(guar).into(),
+ ty::AssocKind::Fn => unreachable!(),
+ };
+ ecx.eq(goal.param_env, goal.predicate.term, error_term)
+ .expect("expected goal term to be fully unconstrained");
+ return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
}
// Getting the right substitutions here is complex, e.g. given:
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 6c98fadd148..dcfa33ae842 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -78,11 +78,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
})
}
- fn consider_implied_clause(
+ fn probe_and_match_goal_against_assumption(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
assumption: ty::Predicate<'tcx>,
- requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
+ then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
) -> QueryResult<'tcx> {
if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
&& poly_trait_pred.def_id() == goal.predicate.def_id()
@@ -97,48 +97,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
goal.predicate.trait_ref,
assumption_trait_pred.trait_ref,
)?;
- ecx.add_goals(requirements);
- ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
- })
- } else {
- Err(NoSolution)
- }
- }
-
- fn consider_object_bound_candidate(
- ecx: &mut EvalCtxt<'_, 'tcx>,
- goal: Goal<'tcx, Self>,
- assumption: ty::Predicate<'tcx>,
- ) -> QueryResult<'tcx> {
- if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
- && poly_trait_pred.def_id() == goal.predicate.def_id()
- && poly_trait_pred.polarity() == goal.predicate.polarity
- {
- // FIXME: Constness and polarity
- ecx.probe(|ecx| {
- let assumption_trait_pred =
- ecx.instantiate_binder_with_infer(poly_trait_pred);
- ecx.eq(
- goal.param_env,
- goal.predicate.trait_ref,
- assumption_trait_pred.trait_ref,
- )?;
-
- let tcx = ecx.tcx();
- let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
- bug!("expected object type in `consider_object_bound_candidate`");
- };
- ecx.add_goals(
- structural_traits::predicates_for_object_candidate(
- &ecx,
- goal.param_env,
- goal.predicate.trait_ref,
- bounds,
- )
- .into_iter()
- .map(|pred| goal.with(tcx, pred)),
- );
- ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+ then(ecx)
})
} else {
Err(NoSolution)
@@ -655,7 +614,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
ty::Dynamic(..)
| ty::Param(..)
| ty::Foreign(..)
- | ty::Alias(ty::Projection, ..)
+ | ty::Alias(ty::Projection | ty::Inherent, ..)
| ty::Placeholder(..) => Some(Err(NoSolution)),
ty::Infer(_) | ty::Bound(_, _) => bug!("unexpected type `{self_ty}`"),
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 6b080a132f3..183c2401fc3 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -801,7 +801,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
span: tcx.def_span(unevaluated.def),
unevaluated: unevaluated,
});
- Err(ErrorHandled::Reported(reported))
+ Err(ErrorHandled::Reported(reported.into()))
}
Err(err) => Err(err),
}
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index b7690f79933..969e5fa64b0 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -322,7 +322,9 @@ fn negative_impl(tcx: TyCtxt<'_>, impl1_def_id: DefId, impl2_def_id: DefId) -> b
let selcx = &mut SelectionContext::new(&infcx);
let impl2_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl2_def_id);
let (subject2, obligations) =
- impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs);
+ impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs, |_, _| {
+ ObligationCause::dummy()
+ });
!equate(&infcx, impl_env, subject1, subject2, obligations, impl1_def_id)
}
@@ -673,7 +675,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'tcx> {
| ty::RawPtr(..)
| ty::Never
| ty::Tuple(..)
- | ty::Alias(ty::Projection, ..) => self.found_non_local_ty(ty),
+ | ty::Alias(ty::Projection | ty::Inherent, ..) => self.found_non_local_ty(ty),
ty::Param(..) => self.found_param_ty(ty),
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 9d99d30d45c..bd1ea43a78e 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -79,7 +79,7 @@ pub fn is_const_evaluatable<'tcx>(
"Missing value for constant, but no error reported?",
)))
}
- Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
+ Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e.into())),
Ok(_) => Ok(()),
}
}
@@ -147,7 +147,7 @@ pub fn is_const_evaluatable<'tcx>(
Err(err)
}
- Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
+ Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e.into())),
Ok(_) => Ok(()),
}
}
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 afb64da8b61..f5f2fe54217 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -28,6 +28,7 @@ use rustc_hir::{GenericParam, Item, Node};
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::infer::{InferOk, TypeTrace};
use rustc_middle::traits::select::OverflowError;
+use rustc_middle::traits::SelectionOutputTypeParameterMismatch;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
@@ -796,9 +797,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.span_label(span, explanation);
}
- if let ObligationCauseCode::ObjectCastObligation(concrete_ty, obj_ty) = obligation.cause.code().peel_derives() &&
- Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
- self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty);
+ if let ObligationCauseCode::Coercion { source, target } =
+ *obligation.cause.code().peel_derives()
+ {
+ if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
+ self.suggest_borrowing_for_object_cast(
+ &mut err,
+ &root_obligation,
+ source,
+ target,
+ );
+ }
}
let UnsatisfiedConst(unsatisfied_const) = self
@@ -1087,17 +1096,21 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
}
- OutputTypeParameterMismatch(
+ OutputTypeParameterMismatch(box SelectionOutputTypeParameterMismatch {
found_trait_ref,
expected_trait_ref,
- terr @ TypeError::CyclicTy(_),
- ) => self.report_type_parameter_mismatch_cyclic_type_error(
+ terr: terr @ TypeError::CyclicTy(_),
+ }) => self.report_type_parameter_mismatch_cyclic_type_error(
&obligation,
found_trait_ref,
expected_trait_ref,
terr,
),
- OutputTypeParameterMismatch(found_trait_ref, expected_trait_ref, _) => {
+ OutputTypeParameterMismatch(box SelectionOutputTypeParameterMismatch {
+ found_trait_ref,
+ expected_trait_ref,
+ terr: _,
+ }) => {
match self.report_type_parameter_mismatch_error(
&obligation,
span,
@@ -1505,7 +1518,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
| ObligationCauseCode::BindingObligation(_, _)
| ObligationCauseCode::ExprItemObligation(..)
| ObligationCauseCode::ExprBindingObligation(..)
- | ObligationCauseCode::ObjectCastObligation(..)
+ | ObligationCauseCode::Coercion { .. }
| ObligationCauseCode::OpaqueType
);
@@ -1687,13 +1700,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ty::Tuple(..) => Some(10),
ty::Param(..) => Some(11),
ty::Alias(ty::Projection, ..) => Some(12),
- ty::Alias(ty::Opaque, ..) => Some(13),
- ty::Never => Some(14),
- ty::Adt(..) => Some(15),
- ty::Generator(..) => Some(16),
- ty::Foreign(..) => Some(17),
- ty::GeneratorWitness(..) => Some(18),
- ty::GeneratorWitnessMIR(..) => Some(19),
+ ty::Alias(ty::Inherent, ..) => Some(13),
+ ty::Alias(ty::Opaque, ..) => Some(14),
+ ty::Never => Some(15),
+ ty::Adt(..) => Some(16),
+ ty::Generator(..) => Some(17),
+ ty::Foreign(..) => Some(18),
+ ty::GeneratorWitness(..) => Some(19),
+ ty::GeneratorWitnessMIR(..) => Some(20),
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None,
}
}
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 53bf38c0a34..ea17f23434b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1442,8 +1442,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err: &mut Diagnostic,
obligation: &PredicateObligation<'tcx>,
self_ty: Ty<'tcx>,
- object_ty: Ty<'tcx>,
+ target_ty: Ty<'tcx>,
) {
+ let ty::Ref(_, object_ty, hir::Mutability::Not) = target_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);
@@ -1458,7 +1459,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.span_suggestion(
obligation.cause.span.shrink_to_lo(),
format!(
- "consider borrowing the value, since `&{self_ty}` can be coerced into `{object_ty}`"
+ "consider borrowing the value, since `&{self_ty}` can be coerced into `{target_ty}`"
),
"&",
Applicability::MaybeIncorrect,
@@ -2446,10 +2447,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
&& generator_did.is_local()
// Try to avoid cycles.
&& !generator_within_in_progress_typeck
+ && let Some(generator_info) = self.tcx.mir_generator_witnesses(generator_did)
{
- let generator_info = &self.tcx.mir_generator_witnesses(generator_did);
debug!(?generator_info);
-
'find_source: for (variant, source_info) in
generator_info.variant_fields.iter().zip(&generator_info.variant_source_info)
{
@@ -2851,30 +2851,27 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.span_note(tcx.def_span(item_def_id), descr);
}
}
- ObligationCauseCode::ObjectCastObligation(concrete_ty, object_ty) => {
- let (concrete_ty, concrete_file) =
- self.tcx.short_ty_string(self.resolve_vars_if_possible(concrete_ty));
- let (object_ty, object_file) =
- self.tcx.short_ty_string(self.resolve_vars_if_possible(object_ty));
+ ObligationCauseCode::Coercion { source, target } => {
+ let (source, source_file) =
+ self.tcx.short_ty_string(self.resolve_vars_if_possible(source));
+ let (target, target_file) =
+ self.tcx.short_ty_string(self.resolve_vars_if_possible(target));
err.note(with_forced_trimmed_paths!(format!(
- "required for the cast from `{concrete_ty}` to the object type `{object_ty}`",
+ "required for the cast from `{source}` to `{target}`",
)));
- if let Some(file) = concrete_file {
+ if let Some(file) = source_file {
err.note(format!(
- "the full name for the casted type has been written to '{}'",
+ "the full name for the source type has been written to '{}'",
file.display(),
));
}
- if let Some(file) = object_file {
+ if let Some(file) = target_file {
err.note(format!(
- "the full name for the object type has been written to '{}'",
+ "the full name for the target type has been written to '{}'",
file.display(),
));
}
}
- ObligationCauseCode::Coercion { source: _, target } => {
- err.note(format!("required by cast to type `{}`", self.ty_to_string(target)));
- }
ObligationCauseCode::RepeatElementCopy { is_const_fn } => {
err.note(
"the `Copy` trait is required because this value will be copied for each element of the array",
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 43196d1e629..2f85c32b575 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -615,7 +615,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
(Err(ErrorHandled::Reported(reported)), _)
| (_, Err(ErrorHandled::Reported(reported))) => ProcessResult::Error(
CodeSelectionError(SelectionError::NotConstEvaluatable(
- NotConstEvaluatable::Error(reported),
+ NotConstEvaluatable::Error(reported.into()),
)),
),
(Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => {
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index d8e5725d3ca..223cdc48f0b 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -26,6 +26,7 @@ use crate::infer::{InferCtxt, TyCtxtInferExt};
use crate::traits::error_reporting::TypeErrCtxtExt as _;
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_errors::ErrorGuaranteed;
+use rustc_middle::query::Providers;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeSuperVisitable};
@@ -49,12 +50,15 @@ pub use self::object_safety::astconv_object_safety_violations;
pub use self::object_safety::is_vtable_safe_method;
pub use self::object_safety::MethodViolationCode;
pub use self::object_safety::ObjectSafetyViolation;
-pub use self::project::{normalize_projection_type, NormalizeExt};
+pub use self::project::NormalizeExt;
+pub use self::project::{normalize_inherent_projection, normalize_projection_type};
pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
pub use self::specialize::specialization_graph::FutureCompatOverlapError;
pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
-pub use self::specialize::{specialization_graph, translate_substs, OverlapError};
+pub use self::specialize::{
+ specialization_graph, translate_substs, translate_substs_with_cause, OverlapError,
+};
pub use self::structural_match::{
search_for_adt_const_param_violation, search_for_structural_match_violation,
};
@@ -495,10 +499,10 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI
false
}
-pub fn provide(providers: &mut ty::query::Providers) {
+pub fn provide(providers: &mut Providers) {
object_safety::provide(providers);
vtable::provide(providers);
- *providers = ty::query::Providers {
+ *providers = Providers {
specialization_graph_of: specialize::specialization_graph_provider,
specializes: specialize::specializes,
subst_and_check_impossible_predicates,
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 06d9c10386e..c81bf6ebc2e 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -16,6 +16,7 @@ use crate::traits::{self, Obligation, ObligationCause};
use rustc_errors::{DelayDm, FatalError, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
+use rustc_middle::query::Providers;
use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
use rustc_middle::ty::{
self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
@@ -947,7 +948,6 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>(
})
}
-pub fn provide(providers: &mut ty::query::Providers) {
- *providers =
- ty::query::Providers { object_safety_violations, check_is_object_safe, ..*providers };
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers { object_safety_violations, check_is_object_safe, ..*providers };
}
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 8c74860cdf3..8e684b7ac23 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -16,6 +16,7 @@ use super::{
};
use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
+use crate::errors::InherentProjectionNormalizationOverflow;
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
use crate::traits::error_reporting::TypeErrCtxtExt as _;
@@ -370,10 +371,14 @@ pub(crate) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
reveal: Reveal,
) -> bool {
match reveal {
- Reveal::UserFacing => value
- .has_type_flags(ty::TypeFlags::HAS_TY_PROJECTION | ty::TypeFlags::HAS_CT_PROJECTION),
+ Reveal::UserFacing => value.has_type_flags(
+ ty::TypeFlags::HAS_TY_PROJECTION
+ | ty::TypeFlags::HAS_TY_INHERENT
+ | ty::TypeFlags::HAS_CT_PROJECTION,
+ ),
Reveal::All => value.has_type_flags(
ty::TypeFlags::HAS_TY_PROJECTION
+ | ty::TypeFlags::HAS_TY_INHERENT
| ty::TypeFlags::HAS_TY_OPAQUE
| ty::TypeFlags::HAS_CT_PROJECTION,
),
@@ -616,6 +621,51 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
);
normalized_ty
}
+
+ ty::Inherent if !data.has_escaping_bound_vars() => {
+ // This branch is *mostly* just an optimization: when we don't
+ // have escaping bound vars, we don't need to replace them with
+ // placeholders (see branch below). *Also*, we know that we can
+ // register an obligation to *later* project, since we know
+ // there won't be bound vars there.
+
+ let data = data.fold_with(self);
+
+ // FIXME(inherent_associated_types): Do we need to honor `self.eager_inference_replacement`
+ // here like `ty::Projection`?
+ normalize_inherent_projection(
+ self.selcx,
+ self.param_env,
+ data,
+ self.cause.clone(),
+ self.depth,
+ &mut self.obligations,
+ )
+ }
+
+ ty::Inherent => {
+ let infcx = self.selcx.infcx;
+ let (data, mapped_regions, mapped_types, mapped_consts) =
+ BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
+ let data = data.fold_with(self);
+ let ty = normalize_inherent_projection(
+ self.selcx,
+ self.param_env,
+ data,
+ self.cause.clone(),
+ self.depth,
+ &mut self.obligations,
+ );
+
+ PlaceholderReplacer::replace_placeholders(
+ infcx,
+ mapped_regions,
+ mapped_types,
+ mapped_consts,
+ &self.universes,
+ ty,
+ )
+ }
}
}
@@ -1204,6 +1254,115 @@ fn normalize_to_error<'a, 'tcx>(
Normalized { value: new_value, obligations: vec![trait_obligation] }
}
+/// Confirm and normalize the given inherent projection.
+#[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
+pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
+ selcx: &'a mut SelectionContext<'b, 'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ alias_ty: ty::AliasTy<'tcx>,
+ cause: ObligationCause<'tcx>,
+ depth: usize,
+ obligations: &mut Vec<PredicateObligation<'tcx>>,
+) -> Ty<'tcx> {
+ let tcx = selcx.tcx();
+
+ if !tcx.recursion_limit().value_within_limit(depth) {
+ // Halt compilation because it is important that overflows never be masked.
+ tcx.sess.emit_fatal(InherentProjectionNormalizationOverflow {
+ span: cause.span,
+ ty: alias_ty.to_string(),
+ });
+ }
+
+ let substs = compute_inherent_assoc_ty_substs(
+ selcx,
+ param_env,
+ alias_ty,
+ cause.clone(),
+ depth,
+ obligations,
+ );
+
+ // Register the obligations arising from the impl and from the associated type itself.
+ let predicates = tcx.predicates_of(alias_ty.def_id).instantiate(tcx, substs);
+ for (predicate, span) in predicates {
+ let predicate = normalize_with_depth_to(
+ selcx,
+ param_env,
+ cause.clone(),
+ depth + 1,
+ predicate,
+ obligations,
+ );
+
+ let nested_cause = ObligationCause::new(
+ cause.span,
+ cause.body_id,
+ // FIXME(inherent_associated_types): Since we can't pass along the self type to the
+ // cause code, inherent projections will be printed with identity substitutions in
+ // diagnostics which is not ideal.
+ // Consider creating separate cause codes for this specific situation.
+ if span.is_dummy() {
+ super::ItemObligation(alias_ty.def_id)
+ } else {
+ super::BindingObligation(alias_ty.def_id, span)
+ },
+ );
+
+ obligations.push(Obligation::with_depth(
+ tcx,
+ nested_cause,
+ depth + 1,
+ param_env,
+ predicate,
+ ));
+ }
+
+ let ty = tcx.type_of(alias_ty.def_id).subst(tcx, substs);
+
+ let mut ty = selcx.infcx.resolve_vars_if_possible(ty);
+ if ty.has_projections() {
+ ty = normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, ty, obligations);
+ }
+
+ ty
+}
+
+pub fn compute_inherent_assoc_ty_substs<'a, 'b, 'tcx>(
+ selcx: &'a mut SelectionContext<'b, 'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ alias_ty: ty::AliasTy<'tcx>,
+ cause: ObligationCause<'tcx>,
+ depth: usize,
+ obligations: &mut Vec<PredicateObligation<'tcx>>,
+) -> ty::SubstsRef<'tcx> {
+ let tcx = selcx.tcx();
+
+ let impl_def_id = tcx.parent(alias_ty.def_id);
+ let impl_substs = selcx.infcx.fresh_substs_for_item(cause.span, impl_def_id);
+
+ let impl_ty = tcx.type_of(impl_def_id).subst(tcx, impl_substs);
+ let impl_ty =
+ normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, impl_ty, obligations);
+
+ // Infer the generic parameters of the impl by unifying the
+ // impl type with the self type of the projection.
+ let self_ty = alias_ty.self_ty();
+ match selcx.infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, impl_ty, self_ty) {
+ Ok(mut ok) => obligations.append(&mut ok.obligations),
+ Err(_) => {
+ tcx.sess.delay_span_bug(
+ cause.span,
+ format!(
+ "{self_ty:?} was a subtype of {impl_ty:?} during selection but now it is not"
+ ),
+ );
+ }
+ }
+
+ alias_ty.rebase_substs_onto_impl(impl_substs, tcx)
+}
+
enum Projected<'tcx> {
Progress(Progress<'tcx>),
NoProgress(ty::Term<'tcx>),
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index a986a9b6a71..8bf934cb78a 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -257,11 +257,11 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
ty::Opaque => ty.try_super_fold_with(self)?,
- ty::Projection => {
+ ty::Projection | ty::Inherent => {
// See note in `rustc_trait_selection::traits::project`
- let tcx = self.infcx.tcx;
let infcx = self.infcx;
+ let tcx = infcx.tcx;
// Just an optimization: When we don't have escaping bound vars,
// we don't need to replace them with placeholders.
let (data, maps) = if data.has_escaping_bound_vars() {
@@ -276,12 +276,15 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
let mut orig_values = OriginalQueryValues::default();
// HACK(matthewjasper) `'static` is special-cased in selection,
// so we cannot canonicalize it.
- let c_data = self
- .infcx
+ let c_data = infcx
.canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
debug!("QueryNormalizer: c_data = {:#?}", c_data);
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
- let result = tcx.normalize_projection_ty(c_data)?;
+ let result = match kind {
+ ty::Projection => tcx.normalize_projection_ty(c_data),
+ ty::Inherent => tcx.normalize_inherent_projection_ty(c_data),
+ _ => unreachable!(),
+ }?;
// We don't expect ambiguity.
if result.is_ambiguous() {
// Rustdoc normalizes possibly not well-formed types, so only
@@ -294,8 +297,8 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
}
return Err(NoSolution);
}
- let InferOk { value: result, obligations } =
- self.infcx.instantiate_query_response_and_region_obligations(
+ let InferOk { value: result, obligations } = infcx
+ .instantiate_query_response_and_region_obligations(
self.cause,
self.param_env,
&orig_values,
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 33f502f8182..a8fb55df2d3 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -498,7 +498,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// this trait and type.
}
ty::Param(..)
- | ty::Alias(ty::Projection, ..)
+ | ty::Alias(ty::Projection | ty::Inherent, ..)
| ty::Placeholder(..)
| ty::Bound(..) => {
// In these cases, we don't know what the actual
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 422285d9474..6a648294efd 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -10,6 +10,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
+use rustc_middle::traits::SelectionOutputTypeParameterMismatch;
use rustc_middle::ty::{
self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate,
TraitRef, Ty, TyCtxt, TypeVisitableExt,
@@ -28,9 +29,9 @@ use crate::traits::{
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData,
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData,
- ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation,
- Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
- SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented,
+ ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, Obligation,
+ ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError,
+ TraitNotObjectSafe, TraitObligation, Unimplemented,
};
use super::BuiltinImplConditions;
@@ -811,7 +812,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_poly_trait_refs(
&mut self,
obligation: &TraitObligation<'tcx>,
- expected_trait_ref: ty::PolyTraitRef<'tcx>,
+ self_ty_trait_ref: ty::PolyTraitRef<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
let obligation_trait_ref = obligation.predicate.to_poly_trait_ref();
// Normalize the obligation and expected trait refs together, because why not
@@ -822,7 +823,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
- (obligation_trait_ref, expected_trait_ref),
+ (obligation_trait_ref, self_ty_trait_ref),
)
});
@@ -834,7 +835,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligations.extend(nested);
obligations
})
- .map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
+ .map_err(|terr| {
+ OutputTypeParameterMismatch(Box::new(SelectionOutputTypeParameterMismatch {
+ expected_trait_ref: obligation_trait_ref,
+ found_trait_ref: expected_trait_ref,
+ terr,
+ }))
+ })
}
fn confirm_trait_upcasting_unsize_candidate(
@@ -898,16 +905,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map_err(|_| Unimplemented)?;
nested.extend(obligations);
- // Register one obligation for 'a: 'b.
- let cause = ObligationCause::new(
- obligation.cause.span,
- obligation.cause.body_id,
- ObjectCastObligation(source, target),
- );
let outlives = ty::OutlivesPredicate(r_a, r_b);
nested.push(Obligation::with_depth(
tcx,
- cause,
+ obligation.cause.clone(),
obligation.recursion_depth + 1,
obligation.param_env,
obligation.predicate.rebind(outlives),
@@ -998,15 +999,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
nested.extend(obligations);
// Register one obligation for 'a: 'b.
- let cause = ObligationCause::new(
- obligation.cause.span,
- obligation.cause.body_id,
- ObjectCastObligation(source, target),
- );
let outlives = ty::OutlivesPredicate(r_a, r_b);
nested.push(Obligation::with_depth(
tcx,
- cause,
+ obligation.cause.clone(),
obligation.recursion_depth + 1,
obligation.param_env,
obligation.predicate.rebind(outlives),
@@ -1020,16 +1016,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return Err(TraitNotObjectSafe(did));
}
- let cause = ObligationCause::new(
- obligation.cause.span,
- obligation.cause.body_id,
- ObjectCastObligation(source, target),
- );
-
let predicate_to_obligation = |predicate| {
Obligation::with_depth(
tcx,
- cause.clone(),
+ obligation.cause.clone(),
obligation.recursion_depth + 1,
obligation.param_env,
predicate,
@@ -1049,7 +1039,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
);
// We can only make objects from sized types.
- let tr = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, cause.span, [source]);
+ let tr = ty::TraitRef::from_lang_item(
+ tcx,
+ LangItem::Sized,
+ obligation.cause.span,
+ [source],
+ );
nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));
// If the type is `Foo + 'a`, ensure that the type
@@ -1268,7 +1263,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// If we have a projection type, make sure to normalize it so we replace it
// with a fresh infer variable
- ty::Alias(ty::Projection, ..) => {
+ ty::Alias(ty::Projection | ty::Inherent, ..) => {
let predicate = normalize_with_depth_to(
self,
obligation.param_env,
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 246d3ea2ef2..b72ff5b78e4 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2315,7 +2315,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
| ty::Dynamic(..)
| ty::Param(..)
| ty::Foreign(..)
- | ty::Alias(ty::Projection, ..)
+ | ty::Alias(ty::Projection | ty::Inherent, ..)
| ty::Bound(..)
| ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("asked to assemble constituent types of unexpected type: {:?}", t);
@@ -2647,14 +2647,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
let predicates = predicates.instantiate_own(tcx, substs);
let mut obligations = Vec::with_capacity(predicates.len());
for (index, (predicate, span)) in predicates.into_iter().enumerate() {
- let cause = cause.clone().derived_cause(parent_trait_pred, |derived| {
- ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
- derived,
- impl_or_alias_def_id: def_id,
- impl_def_predicate_index: Some(index),
- span,
- }))
- });
+ let cause =
+ if Some(parent_trait_pred.def_id()) == tcx.lang_items().coerce_unsized_trait() {
+ cause.clone()
+ } else {
+ cause.clone().derived_cause(parent_trait_pred, |derived| {
+ ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
+ derived,
+ impl_or_alias_def_id: def_id,
+ impl_def_predicate_index: Some(index),
+ span,
+ }))
+ })
+ };
let predicate = normalize_with_depth_to(
self,
param_env,
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 233d35aed38..9a4b72013b8 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -83,6 +83,30 @@ pub fn translate_substs<'tcx>(
source_substs: SubstsRef<'tcx>,
target_node: specialization_graph::Node,
) -> SubstsRef<'tcx> {
+ translate_substs_with_cause(
+ infcx,
+ param_env,
+ source_impl,
+ source_substs,
+ target_node,
+ |_, _| ObligationCause::dummy(),
+ )
+}
+
+/// Like [translate_substs], but obligations from the parent implementation
+/// are registered with the provided `ObligationCause`.
+///
+/// This is for reporting *region* errors from those bounds. Type errors should
+/// not happen because the specialization graph already checks for those, and
+/// will result in an ICE.
+pub fn translate_substs_with_cause<'tcx>(
+ infcx: &InferCtxt<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ source_impl: DefId,
+ source_substs: SubstsRef<'tcx>,
+ target_node: specialization_graph::Node,
+ cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
+) -> SubstsRef<'tcx> {
debug!(
"translate_substs({:?}, {:?}, {:?}, {:?})",
param_env, source_impl, source_substs, target_node
@@ -99,14 +123,13 @@ pub fn translate_substs<'tcx>(
return source_substs;
}
- fulfill_implication(infcx, param_env, source_trait_ref, target_impl).unwrap_or_else(
- |()| {
+ fulfill_implication(infcx, param_env, source_trait_ref, source_impl, target_impl, cause)
+ .unwrap_or_else(|()| {
bug!(
"When translating substitutions from {source_impl:?} to {target_impl:?}, \
the expected specialization failed to hold"
)
- },
- )
+ })
}
specialization_graph::Node::Trait(..) => source_trait_ref.substs,
};
@@ -153,20 +176,12 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
// Create an infcx, taking the predicates of impl1 as assumptions:
let infcx = tcx.infer_ctxt().build();
- let impl1_trait_ref =
- match traits::fully_normalize(&infcx, ObligationCause::dummy(), penv, impl1_trait_ref) {
- Ok(impl1_trait_ref) => impl1_trait_ref,
- Err(_errors) => {
- tcx.sess.delay_span_bug(
- tcx.def_span(impl1_def_id),
- format!("failed to fully normalize {impl1_trait_ref}"),
- );
- impl1_trait_ref
- }
- };
// Attempt to prove that impl2 applies, given all of the above.
- fulfill_implication(&infcx, penv, impl1_trait_ref, impl2_def_id).is_ok()
+ fulfill_implication(&infcx, penv, impl1_trait_ref, impl1_def_id, impl2_def_id, |_, _| {
+ ObligationCause::dummy()
+ })
+ .is_ok()
}
/// Attempt to fulfill all obligations of `target_impl` after unification with
@@ -178,23 +193,41 @@ fn fulfill_implication<'tcx>(
infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
source_trait_ref: ty::TraitRef<'tcx>,
+ source_impl: DefId,
target_impl: DefId,
+ error_cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
) -> Result<SubstsRef<'tcx>, ()> {
debug!(
"fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)",
param_env, source_trait_ref, target_impl
);
+ let source_trait_ref = match traits::fully_normalize(
+ &infcx,
+ ObligationCause::dummy(),
+ param_env,
+ source_trait_ref,
+ ) {
+ Ok(source_trait_ref) => source_trait_ref,
+ Err(_errors) => {
+ infcx.tcx.sess.delay_span_bug(
+ infcx.tcx.def_span(source_impl),
+ format!("failed to fully normalize {source_trait_ref}"),
+ );
+ source_trait_ref
+ }
+ };
+
let source_trait = ImplSubject::Trait(source_trait_ref);
let selcx = &mut SelectionContext::new(&infcx);
let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
let (target_trait, obligations) =
- util::impl_subject_and_oblig(selcx, param_env, target_impl, target_substs);
+ util::impl_subject_and_oblig(selcx, param_env, target_impl, target_substs, error_cause);
// do the impls unify? If not, no specialization.
let Ok(InferOk { obligations: more_obligations, .. }) =
- infcx.at(&ObligationCause::dummy(), param_env, ).eq(DefineOpaqueTypes::No,source_trait, target_trait)
+ infcx.at(&ObligationCause::dummy(), param_env).eq(DefineOpaqueTypes::No, source_trait, target_trait)
else {
debug!(
"fulfill_implication: {:?} does not unify with {:?}",
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 7b7e297c64b..82f3df40198 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -197,6 +197,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
param_env: ty::ParamEnv<'tcx>,
impl_def_id: DefId,
impl_substs: SubstsRef<'tcx>,
+ cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
) -> (ImplSubject<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) {
let subject = selcx.tcx().impl_subject(impl_def_id);
let subject = subject.subst(selcx.tcx(), impl_substs);
@@ -208,8 +209,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
let predicates = predicates.instantiate(selcx.tcx(), impl_substs);
let InferOk { value: predicates, obligations: normalization_obligations2 } =
selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(predicates);
- let impl_obligations =
- super::predicates_for_generics(|_, _| ObligationCause::dummy(), param_env, predicates);
+ let impl_obligations = super::predicates_for_generics(cause, param_env, predicates);
let impl_obligations = impl_obligations
.chain(normalization_obligations1.into_iter())
diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs
index f7a3126b4aa..cc674ceee3d 100644
--- a/compiler/rustc_trait_selection/src/traits/vtable.rs
+++ b/compiler/rustc_trait_selection/src/traits/vtable.rs
@@ -4,6 +4,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_infer::traits::util::PredicateSet;
use rustc_infer::traits::ImplSource;
+use rustc_middle::query::Providers;
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::InternalSubsts;
use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, VtblEntry};
@@ -379,8 +380,8 @@ pub(crate) fn count_own_vtable_entries<'tcx>(
tcx.own_existential_vtable_entries(trait_ref.def_id()).len()
}
-pub(super) fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers {
+pub(super) fn provide(providers: &mut Providers) {
+ *providers = Providers {
own_existential_vtable_entries,
vtable_entries,
vtable_trait_upcasting_coercion_new_vptr_slot,
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 22710c7c059..086ab32b520 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -58,15 +58,8 @@ pub fn obligations<'tcx>(
GenericArgKind::Lifetime(..) => return Some(Vec::new()),
};
- let mut wf = WfPredicates {
- tcx: infcx.tcx,
- param_env,
- body_id,
- span,
- out: vec![],
- recursion_depth,
- item: None,
- };
+ let mut wf =
+ WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth, item: None };
wf.compute(arg);
debug!("wf::obligations({:?}, body_id={:?}) = {:?}", arg, body_id, wf.out);
@@ -91,7 +84,7 @@ pub fn unnormalized_obligations<'tcx>(
debug_assert_eq!(arg, infcx.resolve_vars_if_possible(arg));
let mut wf = WfPredicates {
- tcx: infcx.tcx,
+ infcx,
param_env,
body_id: CRATE_DEF_ID,
span: DUMMY_SP,
@@ -116,7 +109,7 @@ pub fn trait_obligations<'tcx>(
item: &'tcx hir::Item<'tcx>,
) -> Vec<traits::PredicateObligation<'tcx>> {
let mut wf = WfPredicates {
- tcx: infcx.tcx,
+ infcx,
param_env,
body_id,
span,
@@ -138,7 +131,7 @@ pub fn predicate_obligations<'tcx>(
span: Span,
) -> Vec<traits::PredicateObligation<'tcx>> {
let mut wf = WfPredicates {
- tcx: infcx.tcx,
+ infcx,
param_env,
body_id,
span,
@@ -190,8 +183,8 @@ pub fn predicate_obligations<'tcx>(
wf.normalize(infcx)
}
-struct WfPredicates<'tcx> {
- tcx: TyCtxt<'tcx>,
+struct WfPredicates<'a, 'tcx> {
+ infcx: &'a InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
body_id: LocalDefId,
span: Span,
@@ -290,9 +283,9 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
}
}
-impl<'tcx> WfPredicates<'tcx> {
+impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
- self.tcx
+ self.infcx.tcx
}
fn cause(&self, code: traits::ObligationCauseCode<'tcx>) -> traits::ObligationCause<'tcx> {
@@ -325,7 +318,7 @@ impl<'tcx> WfPredicates<'tcx> {
/// Pushes the obligations required for `trait_ref` to be WF into `self.out`.
fn compute_trait_pred(&mut self, trait_pred: &ty::TraitPredicate<'tcx>, elaborate: Elaborate) {
- let tcx = self.tcx;
+ let tcx = self.tcx();
let trait_ref = &trait_pred.trait_ref;
// Negative trait predicates don't require supertraits to hold, just
@@ -369,7 +362,6 @@ impl<'tcx> WfPredicates<'tcx> {
self.out.extend(obligations);
}
- let tcx = self.tcx();
self.out.extend(
trait_ref
.substs
@@ -436,13 +428,45 @@ impl<'tcx> WfPredicates<'tcx> {
let obligations = self.nominal_obligations_without_const(data.def_id, data.substs);
self.out.extend(obligations);
+ self.compute_projection_substs(data.substs);
+ }
+
+ fn compute_inherent_projection(&mut self, data: ty::AliasTy<'tcx>) {
+ // An inherent projection is well-formed if
+ //
+ // (a) its predicates hold (*)
+ // (b) its substs are wf
+ //
+ // (*) The predicates of an inherent associated type include the
+ // predicates of the impl that it's contained in.
+
+ if !data.self_ty().has_escaping_bound_vars() {
+ // FIXME(inherent_associated_types): Should this happen inside of a snapshot?
+ // FIXME(inherent_associated_types): This is incompatible with the new solver and lazy norm!
+ let substs = traits::project::compute_inherent_assoc_ty_substs(
+ &mut traits::SelectionContext::new(self.infcx),
+ self.param_env,
+ data,
+ self.cause(traits::WellFormed(None)),
+ self.recursion_depth,
+ &mut self.out,
+ );
+ // Inherent projection types do not require const predicates.
+ let obligations = self.nominal_obligations_without_const(data.def_id, substs);
+ self.out.extend(obligations);
+ }
+
+ self.compute_projection_substs(data.substs);
+ }
+
+ fn compute_projection_substs(&mut self, substs: SubstsRef<'tcx>) {
let tcx = self.tcx();
let cause = self.cause(traits::WellFormed(None));
let param_env = self.param_env;
let depth = self.recursion_depth;
self.out.extend(
- data.substs
+ substs
.iter()
.filter(|arg| {
matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
@@ -464,9 +488,9 @@ impl<'tcx> WfPredicates<'tcx> {
if !subty.has_escaping_bound_vars() {
let cause = self.cause(cause);
let trait_ref =
- ty::TraitRef::from_lang_item(self.tcx, LangItem::Sized, cause.span, [subty]);
+ ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [subty]);
self.out.push(traits::Obligation::with_depth(
- self.tcx,
+ self.tcx(),
cause,
self.recursion_depth,
self.param_env,
@@ -605,6 +629,10 @@ impl<'tcx> WfPredicates<'tcx> {
walker.skip_current_subtree(); // Subtree handled by compute_projection.
self.compute_projection(data);
}
+ ty::Alias(ty::Inherent, data) => {
+ walker.skip_current_subtree(); // Subtree handled by compute_inherent_projection.
+ self.compute_inherent_projection(data);
+ }
ty::Adt(def, substs) => {
// WfNominalType
@@ -697,7 +725,7 @@ impl<'tcx> WfPredicates<'tcx> {
// All of the requirements on type parameters
// have already been checked for `impl Trait` in
// return position. We do need to check type-alias-impl-trait though.
- if self.tcx.is_type_alias_impl_trait(def_id) {
+ if self.tcx().is_type_alias_impl_trait(def_id) {
let obligations = self.nominal_obligations(def_id, substs);
self.out.extend(obligations);
}
@@ -767,15 +795,15 @@ impl<'tcx> WfPredicates<'tcx> {
substs: SubstsRef<'tcx>,
remap_constness: bool,
) -> Vec<traits::PredicateObligation<'tcx>> {
- let predicates = self.tcx.predicates_of(def_id);
+ let predicates = self.tcx().predicates_of(def_id);
let mut origins = vec![def_id; predicates.predicates.len()];
let mut head = predicates;
while let Some(parent) = head.parent {
- head = self.tcx.predicates_of(parent);
+ head = self.tcx().predicates_of(parent);
origins.extend(iter::repeat(parent).take(head.predicates.len()));
}
- let predicates = predicates.instantiate(self.tcx, substs);
+ let predicates = predicates.instantiate(self.tcx(), substs);
trace!("{:#?}", predicates);
debug_assert_eq!(predicates.predicates.len(), origins.len());
@@ -788,10 +816,10 @@ impl<'tcx> WfPredicates<'tcx> {
};
let cause = self.cause(code);
if remap_constness {
- pred = pred.without_const(self.tcx);
+ pred = pred.without_const(self.tcx());
}
traits::Obligation::with_depth(
- self.tcx,
+ self.tcx(),
cause,
self.recursion_depth,
self.param_env,
@@ -856,7 +884,7 @@ impl<'tcx> WfPredicates<'tcx> {
// Note: in fact we only permit builtin traits, not `Bar<'d>`, I
// am looking forward to the future here.
if !data.has_escaping_bound_vars() && !region.has_escaping_bound_vars() {
- let implicit_bounds = object_region_bounds(self.tcx, data);
+ let implicit_bounds = object_region_bounds(self.tcx(), data);
let explicit_bound = region;
@@ -866,7 +894,7 @@ impl<'tcx> WfPredicates<'tcx> {
let outlives =
ty::Binder::dummy(ty::OutlivesPredicate(explicit_bound, implicit_bound));
self.out.push(traits::Obligation::with_depth(
- self.tcx,
+ self.tcx(),
cause,
self.recursion_depth,
self.param_env,
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index 4d225e36b22..2f9e480d8bd 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -372,6 +372,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
substitution: substs.lower_into(interner),
}))
}
+ ty::Alias(ty::Inherent, _) => unimplemented!(),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
opaque_ty_id: chalk_ir::OpaqueTyId(def_id),
diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs
index a5ebc26a8bc..8834449c9a4 100644
--- a/compiler/rustc_traits/src/chalk/mod.rs
+++ b/compiler/rustc_traits/src/chalk/mod.rs
@@ -7,8 +7,8 @@ pub(crate) mod db;
pub(crate) mod lowering;
use rustc_middle::infer::canonical::{CanonicalTyVarKind, CanonicalVarKind};
+use rustc_middle::query::Providers;
use rustc_middle::traits::ChalkRustInterner;
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitable};
use rustc_infer::infer::canonical::{
diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs
index fcdffc7468b..83f6c7d07fe 100644
--- a/compiler/rustc_traits/src/dropck_outlives.rs
+++ b/compiler/rustc_traits/src/dropck_outlives.rs
@@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
use rustc_infer::infer::TyCtxtInferExt;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::InternalSubsts;
use rustc_middle::ty::{self, EarlyBinder, ParamEnvAnd, Ty, TyCtxt};
use rustc_span::source_map::{Span, DUMMY_SP};
diff --git a/compiler/rustc_traits/src/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs
index e94c8efe69a..149dffc7e31 100644
--- a/compiler/rustc_traits/src/evaluate_obligation.rs
+++ b/compiler/rustc_traits/src/evaluate_obligation.rs
@@ -1,5 +1,5 @@
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
use rustc_span::source_map::DUMMY_SP;
use rustc_trait_selection::traits::query::CanonicalPredicateGoal;
diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs
index f5bba14d2fb..0c2bb863e1f 100644
--- a/compiler/rustc_traits/src/implied_outlives_bounds.rs
+++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs
@@ -6,7 +6,7 @@ use rustc_infer::infer::canonical::{self, Canonical};
use rustc_infer::infer::outlives::components::{push_outlives_components, Component};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::query::OutlivesBound;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::source_map::DUMMY_SP;
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs
index 8bea5588ae7..b0f9c57154f 100644
--- a/compiler/rustc_traits/src/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
@@ -23,7 +23,7 @@ mod type_op;
pub use type_op::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_cause};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
pub fn provide(p: &mut Providers) {
dropck_outlives::provide(p);
diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs
index 5da0f16c2bf..94c33efaeff 100644
--- a/compiler/rustc_traits/src/normalize_erasing_regions.rs
+++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs
@@ -1,6 +1,6 @@
use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::query::Providers;
use rustc_middle::traits::query::NoSolution;
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
use rustc_trait_selection::traits::{Normalized, ObligationCause};
diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs
index e805eb42821..b552ba41acd 100644
--- a/compiler/rustc_traits/src/normalize_projection_ty.rs
+++ b/compiler/rustc_traits/src/normalize_projection_ty.rs
@@ -1,6 +1,6 @@
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
use rustc_infer::infer::TyCtxtInferExt;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
use rustc_trait_selection::infer::InferCtxtBuilderExt;
use rustc_trait_selection::traits::query::{
@@ -10,7 +10,7 @@ use rustc_trait_selection::traits::{self, ObligationCause, SelectionContext};
use std::sync::atomic::Ordering;
pub(crate) fn provide(p: &mut Providers) {
- *p = Providers { normalize_projection_ty, ..*p };
+ *p = Providers { normalize_projection_ty, normalize_inherent_projection_ty, ..*p };
}
fn normalize_projection_ty<'tcx>(
@@ -42,3 +42,30 @@ fn normalize_projection_ty<'tcx>(
},
)
}
+
+fn normalize_inherent_projection_ty<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ goal: CanonicalProjectionGoal<'tcx>,
+) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution> {
+ debug!("normalize_provider(goal={:#?})", goal);
+
+ tcx.infer_ctxt().enter_canonical_trait_query(
+ &goal,
+ |ocx, ParamEnvAnd { param_env, value: goal }| {
+ let selcx = &mut SelectionContext::new(ocx.infcx);
+ let cause = ObligationCause::dummy();
+ let mut obligations = vec![];
+ let answer = traits::normalize_inherent_projection(
+ selcx,
+ param_env,
+ goal,
+ cause,
+ 0,
+ &mut obligations,
+ );
+ ocx.register_obligations(obligations);
+
+ Ok(NormalizationResult { normalized_ty: answer })
+ },
+ )
+}
diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs
index 19622112f2a..70dc7ccec63 100644
--- a/compiler/rustc_traits/src/type_op.rs
+++ b/compiler/rustc_traits/src/type_op.rs
@@ -2,7 +2,7 @@ use rustc_hir as hir;
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
use rustc_infer::traits::ObligationCauseCode;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{ParamEnvAnd, Predicate};
use rustc_middle::ty::{UserSelfTy, UserSubsts, UserType};
diff --git a/compiler/rustc_ty_utils/messages.ftl b/compiler/rustc_ty_utils/messages.ftl
index 15a14112f4a..5bc3e3c00c9 100644
--- a/compiler/rustc_ty_utils/messages.ftl
+++ b/compiler/rustc_ty_utils/messages.ftl
@@ -55,3 +55,11 @@ ty_utils_multiple_array_fields_simd_type = monomorphising SIMD type `{$ty}` with
ty_utils_oversized_simd_type = monomorphising SIMD type `{$ty}` of length greater than {$max_lanes}
ty_utils_non_primitive_simd_type = monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}`
+
+ty_utils_impl_trait_duplicate_arg = non-defining opaque type use in defining scope
+ .label = generic argument `{$arg}` used twice
+ .note = for this opaque type
+
+ty_utils_impl_trait_not_param = non-defining opaque type use in defining scope
+ .label = argument `{$arg}` is not a generic parameter
+ .note = for this opaque type
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 271284b2d81..442d041a8a7 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -1,5 +1,6 @@
use rustc_hir as hir;
use rustc_hir::lang_items::LangItem;
+use rustc_middle::query::Providers;
use rustc_middle::ty::layout::{
fn_can_unwind, FnAbiError, HasParamEnv, HasTyCtxt, LayoutCx, LayoutOf, TyAndLayout,
};
@@ -14,8 +15,8 @@ use rustc_target::spec::abi::Abi as SpecAbi;
use std::iter;
-pub fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers { fn_abi_of_fn_ptr, fn_abi_of_instance, ..*providers };
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers { fn_abi_of_fn_ptr, fn_abi_of_instance, ..*providers };
}
// NOTE(eddyb) this is private to avoid using it from outside of
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 9029ba2a51a..ed574f22e61 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -4,11 +4,12 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
use rustc_hir::definitions::DefPathData;
use rustc_hir::intravisit::{self, Visitor};
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, ImplTraitInTraitData, InternalSubsts, TyCtxt};
use rustc_span::symbol::kw;
-pub fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers {
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers {
associated_item,
associated_item_def_ids,
associated_items,
diff --git a/compiler/rustc_ty_utils/src/common_traits.rs b/compiler/rustc_ty_utils/src/common_traits.rs
index 3b1abdcb24f..51b908881eb 100644
--- a/compiler/rustc_ty_utils/src/common_traits.rs
+++ b/compiler/rustc_ty_utils/src/common_traits.rs
@@ -2,6 +2,7 @@
use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_trait_selection::traits;
@@ -32,12 +33,6 @@ fn is_item_raw<'tcx>(
traits::type_known_to_meet_bound_modulo_regions(&infcx, param_env, ty, trait_def_id)
}
-pub(crate) fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers {
- is_copy_raw,
- is_sized_raw,
- is_freeze_raw,
- is_unpin_raw,
- ..*providers
- };
+pub(crate) fn provide(providers: &mut Providers) {
+ *providers = Providers { is_copy_raw, is_sized_raw, is_freeze_raw, is_unpin_raw, ..*providers };
}
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index b08a92570ed..1219bb40098 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -2,6 +2,7 @@ use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
+use rustc_middle::query::Providers;
use rustc_middle::thir::visit;
use rustc_middle::thir::visit::Visitor;
use rustc_middle::ty::abstract_const::CastKind;
@@ -115,9 +116,7 @@ fn recurse_build<'tcx>(
let sp = node.span;
match tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) {
Ok(c) => c,
- Err(LitToConstError::Reported(guar)) => {
- tcx.const_error_with_guaranteed(node.ty, guar)
- }
+ Err(LitToConstError::Reported(guar)) => tcx.const_error(node.ty, guar),
Err(LitToConstError::TypeError) => {
bug!("encountered type error in lit_to_const")
}
@@ -394,7 +393,7 @@ impl<'a, 'tcx> visit::Visitor<'a, 'tcx> for IsThirPolymorphic<'a, 'tcx> {
pub fn thir_abstract_const(
tcx: TyCtxt<'_>,
def: LocalDefId,
-) -> Result<Option<ty::Const<'_>>, ErrorGuaranteed> {
+) -> Result<Option<ty::EarlyBinder<ty::Const<'_>>>, ErrorGuaranteed> {
if !tcx.features().generic_const_exprs {
return Ok(None);
}
@@ -420,9 +419,9 @@ pub fn thir_abstract_const(
let root_span = body.exprs[body_id].span;
- Some(recurse_build(tcx, body, body_id, root_span)).transpose()
+ Ok(Some(ty::EarlyBinder(recurse_build(tcx, body, body_id, root_span)?)))
}
-pub fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers { destructure_const, thir_abstract_const, ..*providers };
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers { destructure_const, thir_abstract_const, ..*providers };
}
diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs
index 3d3fc50e6e5..553bf40ef3a 100644
--- a/compiler/rustc_ty_utils/src/errors.rs
+++ b/compiler/rustc_ty_utils/src/errors.rs
@@ -1,7 +1,7 @@
//! Errors emitted by ty_utils
use rustc_macros::{Diagnostic, Subdiagnostic};
-use rustc_middle::ty::Ty;
+use rustc_middle::ty::{GenericArg, Ty};
use rustc_span::Span;
#[derive(Diagnostic)]
@@ -100,3 +100,25 @@ pub struct NonPrimitiveSimdType<'tcx> {
pub ty: Ty<'tcx>,
pub e_ty: Ty<'tcx>,
}
+
+#[derive(Diagnostic)]
+#[diag(ty_utils_impl_trait_duplicate_arg)]
+pub struct DuplicateArg<'tcx> {
+ pub arg: GenericArg<'tcx>,
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ #[note]
+ pub opaque_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ty_utils_impl_trait_not_param)]
+pub struct NotParam<'tcx> {
+ pub arg: GenericArg<'tcx>,
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ #[note]
+ pub opaque_span: Span,
+}
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index 56d6cc28bc8..081be065864 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -1,8 +1,9 @@
use rustc_hir::{def::DefKind, def_id::DefId};
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
-pub fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers { assumed_wf_types, ..*providers };
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers { assumed_wf_types, ..*providers };
}
fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> {
@@ -31,6 +32,18 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> {
}
}
DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)),
+ DefKind::OpaqueTy => match tcx.def_kind(tcx.parent(def_id)) {
+ DefKind::TyAlias => ty::List::empty(),
+ DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)),
+ // Nested opaque types only occur in associated types:
+ // ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
+ // assumed_wf_types should include those of `Opaque<T>`, `Opaque<T>` itself
+ // and `&'static T`.
+ DefKind::OpaqueTy => bug!("unimplemented implied bounds for neseted opaque types"),
+ def_kind @ _ => {
+ bug!("unimplemented implied bounds for opaque types with parent {def_kind:?}")
+ }
+ },
DefKind::Mod
| DefKind::Struct
| DefKind::Union
@@ -51,7 +64,6 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> {
| DefKind::ForeignMod
| DefKind::AnonConst
| DefKind::InlineConst
- | DefKind::OpaqueTy
| DefKind::ImplTraitPlaceholder
| DefKind::Field
| DefKind::LifetimeParam
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index ec577072e19..36a20c78fcc 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -1,6 +1,7 @@
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::query::Providers;
use rustc_middle::traits::CodegenObligationError;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitableExt};
@@ -194,21 +195,18 @@ fn resolve_associated_item<'tcx>(
})
}
traits::ImplSource::Future(future_data) => {
- if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::poll {
- // For compiler developers who'd like to add new items to `Future`,
- // you either need to generate a shim body, or perhaps return
- // `InstanceDef::Item` pointing to a trait default method body if
- // it is given a default implementation by the trait.
- span_bug!(
- tcx.def_span(future_data.generator_def_id),
- "no definition for `{trait_ref}::{}` for built-in async generator type",
- tcx.item_name(trait_item_id)
- )
+ if Some(trait_item_id) == tcx.lang_items().future_poll_fn() {
+ // `Future::poll` is generated by the compiler.
+ Some(Instance {
+ def: ty::InstanceDef::Item(future_data.generator_def_id),
+ substs: future_data.substs,
+ })
+ } else {
+ // All other methods are default methods of the `Future` trait.
+ // (this assumes that `ImplSource::Future` is only used for methods on `Future`)
+ debug_assert!(tcx.impl_defaultness(trait_item_id).has_value());
+ Some(Instance::new(trait_item_id, rcvr_substs))
}
- Some(Instance {
- def: ty::InstanceDef::Item(future_data.generator_def_id),
- substs: future_data.substs,
- })
}
traits::ImplSource::Closure(closure_data) => {
if cfg!(debug_assertions)
@@ -322,6 +320,6 @@ fn resolve_associated_item<'tcx>(
})
}
-pub fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers { resolve_instance, ..*providers };
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers { resolve_instance, ..*providers };
}
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index f7c75583f60..16cd8bc8e69 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -3,6 +3,7 @@ use rustc_hir as hir;
use rustc_index::bit_set::BitSet;
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::mir::{GeneratorLayout, GeneratorSavedLocal};
+use rustc_middle::query::Providers;
use rustc_middle::ty::layout::{
IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES,
};
@@ -22,8 +23,8 @@ use crate::errors::{
};
use crate::layout_sanity_check::sanity_check_layout;
-pub fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers { layout_of, ..*providers };
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers { layout_of, ..*providers };
}
#[instrument(skip(tcx, query), level = "debug")]
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index 73a2f6af579..55b8857ed39 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -21,7 +21,7 @@ extern crate tracing;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
mod abi;
mod assoc;
@@ -33,6 +33,7 @@ pub mod instance;
mod layout;
mod layout_sanity_check;
mod needs_drop;
+mod opaque_types;
pub mod representability;
mod structural_match;
mod ty;
@@ -47,6 +48,7 @@ pub fn provide(providers: &mut Providers) {
implied_bounds::provide(providers);
layout::provide(providers);
needs_drop::provide(providers);
+ opaque_types::provide(providers);
representability::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 a04f85afb9e..1f9701b9322 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -2,6 +2,7 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def_id::DefId;
+use rustc_middle::query::Providers;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::util::{needs_drop_components, AlwaysRequiresDrop};
use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt};
@@ -323,8 +324,8 @@ fn adt_significant_drop_tys(
.map(|components| tcx.mk_type_list(&components))
}
-pub(crate) fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers {
+pub(crate) fn provide(providers: &mut Providers) {
+ *providers = Providers {
needs_drop_raw,
has_significant_drop_raw,
adt_drop_tys,
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
new file mode 100644
index 00000000000..4e91dd380e8
--- /dev/null
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -0,0 +1,198 @@
+use rustc_data_structures::fx::FxHashSet;
+use rustc_errors::ErrorGuaranteed;
+use rustc_hir::{def::DefKind, def_id::LocalDefId};
+use rustc_middle::query::Providers;
+use rustc_middle::ty::util::{CheckRegions, NotUniqueParam};
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
+use rustc_span::Span;
+use rustc_type_ir::AliasKind;
+use std::ops::ControlFlow;
+
+use crate::errors::{DuplicateArg, NotParam};
+
+struct OpaqueTypeCollector<'tcx> {
+ tcx: TyCtxt<'tcx>,
+ opaques: Vec<LocalDefId>,
+ /// The `DefId` of the item which we are collecting opaque types for.
+ item: LocalDefId,
+
+ /// Avoid infinite recursion due to recursive declarations.
+ seen: FxHashSet<LocalDefId>,
+}
+
+impl<'tcx> OpaqueTypeCollector<'tcx> {
+ fn collect(
+ tcx: TyCtxt<'tcx>,
+ item: LocalDefId,
+ val: ty::Binder<'tcx, impl TypeVisitable<TyCtxt<'tcx>>>,
+ ) -> Vec<LocalDefId> {
+ let mut collector = Self { tcx, opaques: Vec::new(), item, seen: Default::default() };
+ val.skip_binder().visit_with(&mut collector);
+ collector.opaques
+ }
+
+ fn span(&self) -> Span {
+ self.tcx.def_span(self.item)
+ }
+
+ fn parent(&self) -> Option<LocalDefId> {
+ match self.tcx.def_kind(self.item) {
+ DefKind::Fn => None,
+ DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
+ Some(self.tcx.local_parent(self.item))
+ }
+ other => span_bug!(
+ self.tcx.def_span(self.item),
+ "unhandled item with opaque types: {other:?}"
+ ),
+ }
+ }
+}
+
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
+ type BreakTy = ErrorGuaranteed;
+
+ #[instrument(skip(self), ret, level = "trace")]
+ fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<ErrorGuaranteed> {
+ match t.kind() {
+ ty::Alias(AliasKind::Opaque, alias_ty) if alias_ty.def_id.is_local() => {
+ if !self.seen.insert(alias_ty.def_id.expect_local()) {
+ return ControlFlow::Continue(());
+ }
+ match self.tcx.uses_unique_generic_params(alias_ty.substs, CheckRegions::Bound) {
+ Ok(()) => {
+ // FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not
+ // supported at all, so this is sound to do, but once we want to support them, you'll
+ // start seeing the error below.
+
+ self.opaques.push(alias_ty.def_id.expect_local());
+
+ // Collect opaque types nested within the associated type bounds of this opaque type.
+ for (pred, _span) in self
+ .tcx
+ .explicit_item_bounds(alias_ty.def_id)
+ .subst_iter_copied(self.tcx, alias_ty.substs)
+ {
+ trace!(?pred);
+ pred.visit_with(self)?;
+ }
+
+ ControlFlow::Continue(())
+ }
+ Err(NotUniqueParam::NotParam(arg)) => {
+ let err = self.tcx.sess.emit_err(NotParam {
+ arg,
+ span: self.span(),
+ opaque_span: self.tcx.def_span(alias_ty.def_id),
+ });
+ ControlFlow::Break(err)
+ }
+ Err(NotUniqueParam::DuplicateParam(arg)) => {
+ let err = self.tcx.sess.emit_err(DuplicateArg {
+ arg,
+ span: self.span(),
+ opaque_span: self.tcx.def_span(alias_ty.def_id),
+ });
+ ControlFlow::Break(err)
+ }
+ }
+ }
+ ty::Alias(AliasKind::Projection, alias_ty) => {
+ if let Some(parent) = self.parent() {
+ trace!(?alias_ty);
+ let (trait_ref, own_substs) = alias_ty.trait_ref_and_own_substs(self.tcx);
+
+ trace!(?trait_ref, ?own_substs);
+ // This avoids having to do normalization of `Self::AssocTy` by only
+ // supporting the case of a method defining opaque types from assoc types
+ // in the same impl block.
+ if trait_ref.self_ty() == self.tcx.type_of(parent).subst_identity() {
+ for assoc in self.tcx.associated_items(parent).in_definition_order() {
+ trace!(?assoc);
+ if assoc.trait_item_def_id == Some(alias_ty.def_id) {
+ // We reconstruct the generic args of the associated type within the impl
+ // from the impl's generics and the generic args passed to the type via the
+ // projection.
+ let substs = ty::InternalSubsts::identity_for_item(
+ self.tcx,
+ parent.to_def_id(),
+ );
+ trace!(?substs);
+ let substs: Vec<_> =
+ substs.iter().chain(own_substs.iter().copied()).collect();
+ trace!(?substs);
+ // Find opaque types in this associated type.
+ return self
+ .tcx
+ .type_of(assoc.def_id)
+ .subst(self.tcx, &substs)
+ .visit_with(self);
+ }
+ }
+ }
+ }
+ t.super_visit_with(self)
+ }
+ _ => t.super_visit_with(self),
+ }
+ }
+}
+
+fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [LocalDefId] {
+ let kind = tcx.def_kind(item);
+ trace!(?kind);
+ // FIXME(type_alias_impl_trait): This is definitely still wrong except for RPIT and impl trait in assoc types.
+ match kind {
+ // We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds`
+ DefKind::Fn | DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
+ let defined_opaques = match kind {
+ DefKind::Fn => {
+ OpaqueTypeCollector::collect(tcx, item, tcx.fn_sig(item).subst_identity())
+ }
+ DefKind::AssocFn => {
+ OpaqueTypeCollector::collect(tcx, item, tcx.fn_sig(item).subst_identity())
+ }
+ DefKind::AssocTy | DefKind::AssocConst => OpaqueTypeCollector::collect(
+ tcx,
+ item,
+ ty::Binder::dummy(tcx.type_of(item).subst_identity()),
+ ),
+ _ => unreachable!(),
+ };
+ tcx.arena.alloc_from_iter(defined_opaques)
+ }
+ 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::Impl { .. }
+ | DefKind::Closure
+ | DefKind::Generator => &[],
+ }
+}
+
+pub(super) fn provide(providers: &mut Providers) {
+ *providers = Providers { opaque_types_defined_by, ..*providers };
+}
diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs
index 26d6deab883..0b5e27c2c74 100644
--- a/compiler/rustc_ty_utils/src/representability.rs
+++ b/compiler/rustc_ty_utils/src/representability.rs
@@ -2,7 +2,7 @@
use rustc_hir::def::DefKind;
use rustc_index::bit_set::BitSet;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Representability, Ty, TyCtxt};
use rustc_span::def_id::LocalDefId;
diff --git a/compiler/rustc_ty_utils/src/structural_match.rs b/compiler/rustc_ty_utils/src/structural_match.rs
index 9cb0fc10594..215acbe2c8f 100644
--- a/compiler/rustc_ty_utils/src/structural_match.rs
+++ b/compiler/rustc_ty_utils/src/structural_match.rs
@@ -1,5 +1,5 @@
use rustc_hir::lang_items::LangItem;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_infer::infer::TyCtxtInferExt;
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 78efcce572d..65dc3c39c6a 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -2,6 +2,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_index::bit_set::BitSet;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{
self, Binder, EarlyBinder, ImplTraitInTraitData, Predicate, PredicateKind, ToPredicate, Ty,
TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
@@ -566,8 +567,8 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet<u32
unsizing_params
}
-pub fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers {
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers {
asyncness,
adt_sized_constraint,
param_env,
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 1e91e26e2af..f6b44bdf27e 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -229,29 +229,32 @@ bitflags! {
/// Does this have `Projection`?
const HAS_TY_PROJECTION = 1 << 10;
+ /// Does this have `Inherent`?
+ const HAS_TY_INHERENT = 1 << 11;
/// Does this have `Opaque`?
- const HAS_TY_OPAQUE = 1 << 11;
+ const HAS_TY_OPAQUE = 1 << 12;
/// Does this have `ConstKind::Unevaluated`?
- const HAS_CT_PROJECTION = 1 << 12;
+ const HAS_CT_PROJECTION = 1 << 13;
/// Could this type be normalized further?
const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits
| TypeFlags::HAS_TY_OPAQUE.bits
+ | TypeFlags::HAS_TY_INHERENT.bits
| TypeFlags::HAS_CT_PROJECTION.bits;
/// Is an error type/const reachable?
- const HAS_ERROR = 1 << 13;
+ const HAS_ERROR = 1 << 14;
/// Does this have any region that "appears free" in the type?
/// Basically anything but `ReLateBound` and `ReErased`.
- const HAS_FREE_REGIONS = 1 << 14;
+ const HAS_FREE_REGIONS = 1 << 15;
/// Does this have any `ReLateBound` regions?
- const HAS_RE_LATE_BOUND = 1 << 15;
+ const HAS_RE_LATE_BOUND = 1 << 16;
/// Does this have any `Bound` types?
- const HAS_TY_LATE_BOUND = 1 << 16;
+ const HAS_TY_LATE_BOUND = 1 << 17;
/// Does this have any `ConstKind::Bound` consts?
- const HAS_CT_LATE_BOUND = 1 << 17;
+ const HAS_CT_LATE_BOUND = 1 << 18;
/// Does this have any bound variables?
/// Used to check if a global bound is safe to evaluate.
const HAS_LATE_BOUND = TypeFlags::HAS_RE_LATE_BOUND.bits
@@ -259,20 +262,20 @@ bitflags! {
| TypeFlags::HAS_CT_LATE_BOUND.bits;
/// Does this have any `ReErased` regions?
- const HAS_RE_ERASED = 1 << 18;
+ const HAS_RE_ERASED = 1 << 19;
/// Does this value have parameters/placeholders/inference variables which could be
/// replaced later, in a way that would change the results of `impl` specialization?
- const STILL_FURTHER_SPECIALIZABLE = 1 << 19;
+ const STILL_FURTHER_SPECIALIZABLE = 1 << 20;
/// Does this value have `InferTy::FreshTy/FreshIntTy/FreshFloatTy`?
- const HAS_TY_FRESH = 1 << 20;
+ const HAS_TY_FRESH = 1 << 21;
/// Does this value have `InferConst::Fresh`?
- const HAS_CT_FRESH = 1 << 21;
+ const HAS_CT_FRESH = 1 << 22;
/// Does this have `Generator` or `GeneratorWitness`?
- const HAS_TY_GENERATOR = 1 << 22;
+ const HAS_TY_GENERATOR = 1 << 23;
}
}
@@ -640,7 +643,7 @@ impl UnifyKey for FloatVid {
}
}
-#[derive(Copy, Clone, PartialEq, Decodable, Encodable, Hash, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, 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
diff --git a/compiler/rustc_type_ir/src/structural_impls.rs b/compiler/rustc_type_ir/src/structural_impls.rs
index c9675f93f95..45a2e9023c9 100644
--- a/compiler/rustc_type_ir/src/structural_impls.rs
+++ b/compiler/rustc_type_ir/src/structural_impls.rs
@@ -21,6 +21,7 @@ TrivialTypeTraversalImpls! {
(),
bool,
usize,
+ u8,
u16,
u32,
u64,
diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs
index 4c1f2dd0e53..f7344bacc02 100644
--- a/compiler/rustc_type_ir/src/sty.rs
+++ b/compiler/rustc_type_ir/src/sty.rs
@@ -37,6 +37,7 @@ pub enum DynKind {
#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum AliasKind {
Projection,
+ Inherent,
Opaque,
}
diff --git a/config.example.toml b/config.example.toml
index 6d9c762ceca..d0eaa9fd7ff 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -750,6 +750,10 @@ changelog-seen = 2
# This option will override the same option under [build] section.
#profiler = build.profiler (bool)
+# This option supports enable `rpath` in each target independently,
+# and will override the same option under [rust] section. It only works on Unix platforms
+#rpath = rust.rpath (bool)
+
# Force static or dynamic linkage of the standard library for this target. If
# this target is a host for rustc, this will also affect the linkage of the
# compiler itself. This is useful for building rustc on targets that normally
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 2daef82d6f1..1f8a1ecba6e 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -3021,7 +3021,7 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> {
})
}
- /// Returns a mutable reference to the of the element that the cursor is
+ /// Returns a mutable reference to the key of the element that the cursor is
/// currently pointing to.
///
/// This returns `None` if the cursor is currently pointing to the
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 18f25aec5fe..59fa91c1066 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -113,7 +113,6 @@
#![feature(const_maybe_uninit_write)]
#![feature(const_maybe_uninit_zeroed)]
#![feature(const_pin)]
-#![feature(const_ptr_read)]
#![feature(const_refs_to_cell)]
#![feature(const_size_of_val)]
#![feature(const_waker)]
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 97da6f06b70..82f30a26d41 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -646,14 +646,14 @@ impl<T, A: Allocator> Vec<T, A> {
///
/// // The vector contains no items, even though it has capacity for more
/// assert_eq!(vec.len(), 0);
- /// assert_eq!(vec.capacity(), 10);
+ /// assert!(vec.capacity() >= 10);
///
/// // These are all done without reallocating...
/// for i in 0..10 {
/// vec.push(i);
/// }
/// assert_eq!(vec.len(), 10);
- /// assert_eq!(vec.capacity(), 10);
+ /// assert!(vec.capacity() >= 10);
///
/// // ...but this may make the vector reallocate
/// vec.push(11);
@@ -877,7 +877,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// ```
/// let mut vec: Vec<i32> = Vec::with_capacity(10);
/// vec.push(42);
- /// assert_eq!(vec.capacity(), 10);
+ /// assert!(vec.capacity() >= 10);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1028,7 +1028,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// ```
/// let mut vec = Vec::with_capacity(10);
/// vec.extend([1, 2, 3]);
- /// assert_eq!(vec.capacity(), 10);
+ /// assert!(vec.capacity() >= 10);
/// vec.shrink_to_fit();
/// assert!(vec.capacity() >= 3);
/// ```
@@ -1055,7 +1055,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// ```
/// let mut vec = Vec::with_capacity(10);
/// vec.extend([1, 2, 3]);
- /// assert_eq!(vec.capacity(), 10);
+ /// assert!(vec.capacity() >= 10);
/// vec.shrink_to(4);
/// assert!(vec.capacity() >= 4);
/// vec.shrink_to(0);
@@ -1090,7 +1090,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// let mut vec = Vec::with_capacity(10);
/// vec.extend([1, 2, 3]);
///
- /// assert_eq!(vec.capacity(), 10);
+ /// assert!(vec.capacity() >= 10);
/// let slice = vec.into_boxed_slice();
/// assert_eq!(slice.into_vec().capacity(), 3);
/// ```
diff --git a/library/core/benches/fmt.rs b/library/core/benches/fmt.rs
index ff726ff7559..d1cdb12e50f 100644
--- a/library/core/benches/fmt.rs
+++ b/library/core/benches/fmt.rs
@@ -1,13 +1,13 @@
use std::fmt::{self, Write as FmtWrite};
use std::io::{self, Write as IoWrite};
-use test::Bencher;
+use test::{black_box, Bencher};
#[bench]
fn write_vec_value(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = Vec::new();
for _ in 0..1000 {
- mem.write_all("abc".as_bytes()).unwrap();
+ mem.write_all(black_box("abc").as_bytes()).unwrap();
}
});
}
@@ -18,7 +18,7 @@ fn write_vec_ref(bh: &mut Bencher) {
let mut mem = Vec::new();
let wr = &mut mem as &mut dyn io::Write;
for _ in 0..1000 {
- wr.write_all("abc".as_bytes()).unwrap();
+ wr.write_all(black_box("abc").as_bytes()).unwrap();
}
});
}
@@ -29,7 +29,7 @@ fn write_vec_macro1(bh: &mut Bencher) {
let mut mem = Vec::new();
let wr = &mut mem as &mut dyn io::Write;
for _ in 0..1000 {
- write!(wr, "abc").unwrap();
+ write!(wr, "{}", black_box("abc")).unwrap();
}
});
}
@@ -40,7 +40,7 @@ fn write_vec_macro2(bh: &mut Bencher) {
let mut mem = Vec::new();
let wr = &mut mem as &mut dyn io::Write;
for _ in 0..1000 {
- write!(wr, "{}", "abc").unwrap();
+ write!(wr, "{}", black_box("abc")).unwrap();
}
});
}
@@ -51,7 +51,7 @@ fn write_vec_macro_debug(bh: &mut Bencher) {
let mut mem = Vec::new();
let wr = &mut mem as &mut dyn io::Write;
for _ in 0..1000 {
- write!(wr, "{:?}", "☃").unwrap();
+ write!(wr, "{:?}", black_box("☃")).unwrap();
}
});
}
@@ -61,7 +61,7 @@ fn write_str_value(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = String::new();
for _ in 0..1000 {
- mem.write_str("abc").unwrap();
+ mem.write_str(black_box("abc")).unwrap();
}
});
}
@@ -72,7 +72,7 @@ fn write_str_ref(bh: &mut Bencher) {
let mut mem = String::new();
let wr = &mut mem as &mut dyn fmt::Write;
for _ in 0..1000 {
- wr.write_str("abc").unwrap();
+ wr.write_str(black_box("abc")).unwrap();
}
});
}
@@ -82,7 +82,7 @@ fn write_str_macro1(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = String::new();
for _ in 0..1000 {
- write!(mem, "abc").unwrap();
+ write!(mem, "{}", black_box("abc")).unwrap();
}
});
}
@@ -93,7 +93,7 @@ fn write_str_macro2(bh: &mut Bencher) {
let mut mem = String::new();
let wr = &mut mem as &mut dyn fmt::Write;
for _ in 0..1000 {
- write!(wr, "{}", "abc").unwrap();
+ write!(wr, "{}", black_box("abc")).unwrap();
}
});
}
@@ -104,7 +104,7 @@ fn write_str_macro_debug(bh: &mut Bencher) {
let mut mem = String::new();
let wr = &mut mem as &mut dyn fmt::Write;
for _ in 0..1000 {
- write!(wr, "{:?}", "☃").unwrap();
+ write!(wr, "{:?}", black_box("☃")).unwrap();
}
});
}
@@ -115,7 +115,7 @@ fn write_str_macro_debug_ascii(bh: &mut Bencher) {
let mut mem = String::new();
let wr = &mut mem as &mut dyn fmt::Write;
for _ in 0..1000 {
- write!(wr, "{:?}", "Hello, World!").unwrap();
+ write!(wr, "{:?}", black_box("Hello, World!")).unwrap();
}
});
}
diff --git a/library/core/benches/num/dec2flt/mod.rs b/library/core/benches/num/dec2flt/mod.rs
index 305baa68729..fb4a786b27e 100644
--- a/library/core/benches/num/dec2flt/mod.rs
+++ b/library/core/benches/num/dec2flt/mod.rs
@@ -1,57 +1,57 @@
-use test::Bencher;
+use test::{black_box, Bencher};
#[bench]
fn bench_0(b: &mut Bencher) {
- b.iter(|| "0.0".parse::<f64>());
+ b.iter(|| black_box("0.0").parse::<f64>());
}
#[bench]
fn bench_42(b: &mut Bencher) {
- b.iter(|| "42".parse::<f64>());
+ b.iter(|| black_box("42").parse::<f64>());
}
#[bench]
fn bench_huge_int(b: &mut Bencher) {
// 2^128 - 1
- b.iter(|| "170141183460469231731687303715884105727".parse::<f64>());
+ b.iter(|| black_box("170141183460469231731687303715884105727").parse::<f64>());
}
#[bench]
fn bench_short_decimal(b: &mut Bencher) {
- b.iter(|| "1234.5678".parse::<f64>());
+ b.iter(|| black_box("1234.5678").parse::<f64>());
}
#[bench]
fn bench_pi_long(b: &mut Bencher) {
- b.iter(|| "3.14159265358979323846264338327950288".parse::<f64>());
+ b.iter(|| black_box("3.14159265358979323846264338327950288").parse::<f64>());
}
#[bench]
fn bench_pi_short(b: &mut Bencher) {
- b.iter(|| "3.141592653589793".parse::<f64>())
+ b.iter(|| black_box("3.141592653589793").parse::<f64>())
}
#[bench]
fn bench_1e150(b: &mut Bencher) {
- b.iter(|| "1e150".parse::<f64>());
+ b.iter(|| black_box("1e150").parse::<f64>());
}
#[bench]
fn bench_long_decimal_and_exp(b: &mut Bencher) {
- b.iter(|| "727501488517303786137132964064381141071e-123".parse::<f64>());
+ b.iter(|| black_box("727501488517303786137132964064381141071e-123").parse::<f64>());
}
#[bench]
fn bench_min_subnormal(b: &mut Bencher) {
- b.iter(|| "5e-324".parse::<f64>());
+ b.iter(|| black_box("5e-324").parse::<f64>());
}
#[bench]
fn bench_min_normal(b: &mut Bencher) {
- b.iter(|| "2.2250738585072014e-308".parse::<f64>());
+ b.iter(|| black_box("2.2250738585072014e-308").parse::<f64>());
}
#[bench]
fn bench_max(b: &mut Bencher) {
- b.iter(|| "1.7976931348623157e308".parse::<f64>());
+ b.iter(|| black_box("1.7976931348623157e308").parse::<f64>());
}
diff --git a/library/core/benches/num/flt2dec/mod.rs b/library/core/benches/num/flt2dec/mod.rs
index 32fd5e626bc..1a330ef5fe5 100644
--- a/library/core/benches/num/flt2dec/mod.rs
+++ b/library/core/benches/num/flt2dec/mod.rs
@@ -7,7 +7,7 @@ use core::num::flt2dec::MAX_SIG_DIGITS;
use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
use std::io::Write;
use std::vec::Vec;
-use test::Bencher;
+use test::{black_box, Bencher};
pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
match decode(v).1 {
@@ -22,7 +22,7 @@ fn bench_small_shortest(b: &mut Bencher) {
b.iter(|| {
buf.clear();
- write!(&mut buf, "{}", 3.1415926f64).unwrap()
+ write!(black_box(&mut buf), "{}", black_box(3.1415926f64)).unwrap()
});
}
@@ -32,6 +32,6 @@ fn bench_big_shortest(b: &mut Bencher) {
b.iter(|| {
buf.clear();
- write!(&mut buf, "{}", f64::MAX).unwrap()
+ write!(black_box(&mut buf), "{}", black_box(f64::MAX)).unwrap()
});
}
diff --git a/library/core/benches/num/mod.rs b/library/core/benches/num/mod.rs
index 2f9cad2725d..b97014d9bf9 100644
--- a/library/core/benches/num/mod.rs
+++ b/library/core/benches/num/mod.rs
@@ -3,7 +3,7 @@ mod flt2dec;
mod int_log;
use std::str::FromStr;
-use test::Bencher;
+use test::{black_box, Bencher};
const ASCII_NUMBERS: [&str; 19] = [
"0",
@@ -36,7 +36,7 @@ macro_rules! from_str_bench {
.iter()
.cycle()
.take(5_000)
- .filter_map(|s| <$t>::from_str(s).ok())
+ .filter_map(|s| <$t>::from_str(black_box(s)).ok())
.max()
})
}
@@ -52,7 +52,7 @@ macro_rules! from_str_radix_bench {
.iter()
.cycle()
.take(5_000)
- .filter_map(|s| <$t>::from_str_radix(s, $radix).ok())
+ .filter_map(|s| <$t>::from_str_radix(black_box(s), $radix).ok())
.max()
})
}
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index bb93ea509d8..d1c1ae6526b 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -866,7 +866,7 @@ where
///
/// A data provider provides values by calling this type's provide methods.
#[unstable(feature = "provide_any", issue = "96024")]
-#[repr(transparent)]
+#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
pub struct Demand<'a>(dyn Erased<'a> + 'a);
impl<'a> Demand<'a> {
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index a96dfafd9c4..744767aae44 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -2030,6 +2030,27 @@ impl<T> UnsafeCell<T> {
}
impl<T: ?Sized> UnsafeCell<T> {
+ /// Converts from `&mut T` to `&mut UnsafeCell<T>`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # #![feature(unsafe_cell_from_mut)]
+ /// use std::cell::UnsafeCell;
+ ///
+ /// let mut val = 42;
+ /// let uc = UnsafeCell::from_mut(&mut val);
+ ///
+ /// *uc.get_mut() -= 1;
+ /// assert_eq!(*uc.get_mut(), 41);
+ /// ```
+ #[inline(always)]
+ #[unstable(feature = "unsafe_cell_from_mut", issue = "111645")]
+ pub const fn from_mut(value: &mut T) -> &mut UnsafeCell<T> {
+ // SAFETY: `UnsafeCell<T>` has the same memory layout as `T` due to #[repr(transparent)].
+ unsafe { &mut *(value as *mut T as *mut UnsafeCell<T>) }
+ }
+
/// Gets a mutable pointer to the wrapped value.
///
/// This can be cast to a pointer of any kind.
@@ -2100,6 +2121,8 @@ impl<T: ?Sized> UnsafeCell<T> {
///
/// let m = MaybeUninit::<UnsafeCell<i32>>::uninit();
/// unsafe { UnsafeCell::raw_get(m.as_ptr()).write(5); }
+ /// // avoid below which references to uninitialized data
+ /// // unsafe { UnsafeCell::get(&*m.as_ptr()).write(5); }
/// let uc = unsafe { m.assume_init() };
///
/// assert_eq!(uc.into_inner(), 5);
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 48b127716f5..faf48ae570f 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -1412,6 +1412,7 @@ mod impls {
#[unstable(feature = "never_type", issue = "35121")]
impl PartialEq for ! {
+ #[inline]
fn eq(&self, _: &!) -> bool {
*self
}
@@ -1422,6 +1423,7 @@ mod impls {
#[unstable(feature = "never_type", issue = "35121")]
impl PartialOrd for ! {
+ #[inline]
fn partial_cmp(&self, _: &!) -> Option<Ordering> {
*self
}
@@ -1429,6 +1431,7 @@ mod impls {
#[unstable(feature = "never_type", issue = "35121")]
impl Ord for ! {
+ #[inline]
fn cmp(&self, _: &!) -> Ordering {
*self
}
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index 3ae787cac71..38a6d1ccdb5 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -915,6 +915,7 @@ impl Ord for Infallible {
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl From<!> for Infallible {
+ #[inline]
fn from(x: !) -> Self {
x
}
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index 07b11814f96..201bacb28c7 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -517,8 +517,6 @@ impl CStr {
/// # Examples
///
/// ```
- /// #![feature(cstr_is_empty)]
- ///
/// use std::ffi::CStr;
/// # use std::ffi::FromBytesWithNulError;
///
@@ -533,7 +531,8 @@ impl CStr {
/// # }
/// ```
#[inline]
- #[unstable(feature = "cstr_is_empty", issue = "102444")]
+ #[stable(feature = "cstr_is_empty", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "cstr_is_empty", since = "CURRENT_RUSTC_VERSION")]
pub const fn is_empty(&self) -> bool {
// SAFETY: We know there is at least one byte; for empty strings it
// is the NUL terminator.
diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs
index b85894259f1..b73abbbaca7 100644
--- a/library/core/src/ffi/mod.rs
+++ b/library/core/src/ffi/mod.rs
@@ -203,7 +203,7 @@ mod c_long_definition {
// be UB.
#[doc = include_str!("c_void.md")]
#[cfg_attr(not(bootstrap), lang = "c_void")]
-#[repr(u8)]
+#[cfg_attr(not(doc), repr(u8))] // work around https://github.com/rust-lang/rust/issues/90435
#[stable(feature = "core_c_void", since = "1.30.0")]
pub enum c_void {
#[unstable(
@@ -244,7 +244,7 @@ impl fmt::Debug for c_void {
target_os = "uefi",
windows,
))]
-#[repr(transparent)]
+#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
#[unstable(
feature = "c_variadic",
reason = "the `c_variadic` feature has not been properly tested on \
@@ -296,7 +296,7 @@ impl<'f> fmt::Debug for VaListImpl<'f> {
not(target_os = "uefi"),
not(windows),
))]
-#[repr(C)]
+#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
#[derive(Debug)]
#[unstable(
feature = "c_variadic",
@@ -316,7 +316,7 @@ pub struct VaListImpl<'f> {
/// PowerPC ABI implementation of a `va_list`.
#[cfg(all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)))]
-#[repr(C)]
+#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
#[derive(Debug)]
#[unstable(
feature = "c_variadic",
@@ -336,7 +336,7 @@ pub struct VaListImpl<'f> {
/// s390x ABI implementation of a `va_list`.
#[cfg(target_arch = "s390x")]
-#[repr(C)]
+#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
#[derive(Debug)]
#[unstable(
feature = "c_variadic",
@@ -355,7 +355,7 @@ pub struct VaListImpl<'f> {
/// x86_64 ABI implementation of a `va_list`.
#[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))]
-#[repr(C)]
+#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
#[derive(Debug)]
#[unstable(
feature = "c_variadic",
@@ -373,7 +373,7 @@ pub struct VaListImpl<'f> {
}
/// A wrapper for a `va_list`
-#[repr(transparent)]
+#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
#[derive(Debug)]
#[unstable(
feature = "c_variadic",
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index aa829edd5b0..bac2f31878b 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -2267,6 +2267,7 @@ fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperEx
#[unstable(feature = "never_type", issue = "35121")]
impl Debug for ! {
+ #[inline]
fn fmt(&self, _: &mut Formatter<'_>) -> Result {
*self
}
@@ -2274,6 +2275,7 @@ impl Debug for ! {
#[unstable(feature = "never_type", issue = "35121")]
impl Display for ! {
+ #[inline]
fn fmt(&self, _: &mut Formatter<'_>) -> Result {
*self
}
diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs
index 0596f6c30ce..d37888c27bd 100644
--- a/library/core/src/fmt/rt.rs
+++ b/library/core/src/fmt/rt.rs
@@ -152,6 +152,21 @@ impl<'a> Argument<'a> {
None
}
}
+
+ /// Used by `format_args` when all arguments are gone after inlining,
+ /// when using `&[]` would incorrectly allow for a bigger lifetime.
+ ///
+ /// This fails without format argument inlining, and that shouldn't be different
+ /// when the argument is inlined:
+ ///
+ /// ```compile_fail,E0716
+ /// let f = format_args!("{}", "a");
+ /// println!("{f}");
+ /// ```
+ #[inline(always)]
+ pub fn none() -> [Self; 0] {
+ []
+ }
}
/// This struct represents the unsafety of constructing an `Arguments`.
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 077c0fdc380..23ded42fa66 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -1187,7 +1187,7 @@ extern "rust-intrinsic" {
/// Below are common applications of `transmute` which can be replaced with safer
/// constructs.
///
- /// Turning raw bytes (`&[u8]`) into `u32`, `f64`, etc.:
+ /// Turning raw bytes (`[u8; SZ]`) into `u32`, `f64`, etc.:
///
/// ```
/// let raw_bytes = [0x78, 0x56, 0x34, 0x12];
@@ -2260,7 +2260,7 @@ extern "rust-intrinsic" {
/// This intrinsic can *only* be called where the pointer is a local without
/// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it
/// trivially obeys runtime-MIR rules about derefs in operands.
- #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
+ #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
#[rustc_nounwind]
pub fn read_via_copy<T>(ptr: *const T) -> T;
@@ -2523,6 +2523,7 @@ macro_rules! assert_unsafe_precondition {
}
}
#[allow(non_snake_case)]
+ #[inline]
const fn comptime$(<$($tt)*>)?($(_:$ty),*) {}
::core::intrinsics::const_eval_select(($($i,)*), comptime, runtime);
diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs
index b4639c07c35..5944a0de1a4 100644
--- a/library/core/src/intrinsics/mir.rs
+++ b/library/core/src/intrinsics/mir.rs
@@ -228,7 +228,7 @@
//!
//! - Operands implicitly convert to `Use` rvalues.
//! - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue.
-//! - [`Discriminant`] and [`Len`] have associated functions.
+//! - [`Discriminant`], [`Len`], and [`CopyForDeref`] have associated functions.
//! - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc.
//! - The binary operation `Offset` can be created via [`Offset`].
//! - Checked binary operations are represented by wrapping the associated binop in [`Checked`].
@@ -263,6 +263,7 @@ pub struct BasicBlock;
macro_rules! define {
($name:literal, $( #[ $meta:meta ] )* fn $($sig:tt)*) => {
#[rustc_diagnostic_item = $name]
+ #[inline]
$( #[ $meta ] )*
pub fn $($sig)* { panic!() }
}
@@ -278,6 +279,7 @@ define!("mir_storage_dead", fn StorageDead<T>(local: T));
define!("mir_deinit", fn Deinit<T>(place: T));
define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
define!("mir_len", fn Len<T>(place: T) -> usize);
+define!("mir_copy_for_deref", fn CopyForDeref<T>(place: T) -> T);
define!("mir_retag", fn Retag<T>(place: T));
define!("mir_move", fn Move<T>(place: T) -> T);
define!("mir_static", fn Static<T>(s: T) -> &'static T);
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 3abf66dbe29..0af04fac909 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -133,6 +133,7 @@
#![feature(const_maybe_uninit_assume_init)]
#![feature(const_maybe_uninit_uninit_array)]
#![feature(const_nonnull_new)]
+#![feature(const_num_midpoint)]
#![feature(const_option)]
#![feature(const_option_ext)]
#![feature(const_pin)]
@@ -140,7 +141,6 @@
#![feature(const_pointer_is_aligned)]
#![feature(const_ptr_as_ref)]
#![feature(const_ptr_is_null)]
-#![feature(const_ptr_read)]
#![feature(const_ptr_sub_ptr)]
#![feature(const_ptr_write)]
#![feature(const_raw_ptr_comparison)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 97f9d01e016..ca45683d3d6 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -695,7 +695,7 @@ impl<T: ?Sized> !Sync for *mut T {}
/// }
/// ```
///
-/// This also in turn requires the annotation `T: 'a`, indicating
+/// This also in turn infers the lifetime bound `T: 'a`, indicating
/// that any references in `T` are valid over the lifetime `'a`.
///
/// When initializing a `Slice` you simply provide the value
@@ -766,16 +766,11 @@ impl<T: ?Sized> !Sync for *mut T {}
///
/// ## Ownership and the drop check
///
-/// Adding a field of type `PhantomData<T>` indicates that your
-/// type owns data of type `T`. This in turn implies that when your
-/// type is dropped, it may drop one or more instances of the type
-/// `T`. This has bearing on the Rust compiler's [drop check]
-/// analysis.
+/// The exact interaction of `PhantomData` with drop check **may change in the future**.
///
-/// If your struct does not in fact *own* the data of type `T`, it is
-/// better to use a reference type, like `PhantomData<&'a T>`
-/// (ideally) or `PhantomData<*const T>` (if no lifetime applies), so
-/// as not to indicate ownership.
+/// Currently, adding a field of type `PhantomData<T>` indicates that your type *owns* data of type
+/// `T` in very rare circumstances. This in turn has effects on the Rust compiler's [drop check]
+/// analysis. For the exact rules, see the [drop check] documentation.
///
/// ## Layout
///
@@ -783,7 +778,7 @@ impl<T: ?Sized> !Sync for *mut T {}
/// * `size_of::<PhantomData<T>>() == 0`
/// * `align_of::<PhantomData<T>>() == 1`
///
-/// [drop check]: ../../nomicon/dropck.html
+/// [drop check]: Drop#drop-check
#[lang = "phantom_data"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct PhantomData<T: ?Sized>;
@@ -991,6 +986,14 @@ pub trait PointerLike {}
#[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")]
pub trait ConstParamTy: StructuralEq {}
+/// Derive macro generating an impl of the trait `Copy`.
+#[rustc_builtin_macro]
+#[unstable(feature = "adt_const_params", issue = "95174")]
+#[cfg(not(bootstrap))]
+pub macro ConstParamTy($item:item) {
+ /* compiler built-in */
+}
+
// FIXME(generic_const_parameter_types): handle `ty::FnDef`/`ty::Closure`
// FIXME(generic_const_parameter_types): handle `ty::Tuple`
marker_impls! {
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 7d2f2971523..289305253ec 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -968,6 +968,7 @@ pub const fn replace<T>(dest: &mut T, src: T) -> T {
/// Integers and other types implementing [`Copy`] are unaffected by `drop`.
///
/// ```
+/// # #![cfg_attr(not(bootstrap), allow(drop_copy))]
/// #[derive(Copy, Clone)]
/// struct Foo(u8);
///
@@ -1315,9 +1316,9 @@ impl<T> SizedTypeProperties for T {}
///
/// assert_eq!(mem::offset_of!(NestedA, b.0), 0);
/// ```
-#[unstable(feature = "offset_of", issue = "106655")]
-#[rustc_builtin_macro]
#[cfg(not(bootstrap))]
+#[unstable(feature = "offset_of", issue = "106655")]
+#[allow_internal_unstable(builtin_syntax)]
pub macro offset_of($Container:ty, $($fields:tt).+ $(,)?) {
- /* compiler built-in */
+ builtin # offset_of($Container, $($fields).+)
}
diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs
index 2ad0f1dc506..14e99578a7c 100644
--- a/library/core/src/num/error.rs
+++ b/library/core/src/num/error.rs
@@ -34,6 +34,7 @@ impl From<Infallible> for TryFromIntError {
#[unstable(feature = "never_type", issue = "35121")]
impl From<!> for TryFromIntError {
+ #[inline]
fn from(never: !) -> TryFromIntError {
// Match rather than coerce to make sure that code like
// `From<Infallible> for TryFromIntError` above will keep working
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 1c6819b547d..4a035ad61e1 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -940,6 +940,42 @@ impl f32 {
}
}
+ /// Calculates the middle point of `self` and `rhs`.
+ ///
+ /// This returns NaN when *either* argument is NaN or if a combination of
+ /// +inf and -inf is provided as arguments.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(num_midpoint)]
+ /// assert_eq!(1f32.midpoint(4.0), 2.5);
+ /// assert_eq!((-5.5f32).midpoint(8.0), 1.25);
+ /// ```
+ #[unstable(feature = "num_midpoint", issue = "110840")]
+ pub fn midpoint(self, other: f32) -> f32 {
+ const LO: f32 = f32::MIN_POSITIVE * 2.;
+ const HI: f32 = f32::MAX / 2.;
+
+ let (a, b) = (self, other);
+ let abs_a = a.abs_private();
+ let abs_b = b.abs_private();
+
+ if abs_a <= HI && abs_b <= HI {
+ // Overflow is impossible
+ (a + b) / 2.
+ } else if abs_a < LO {
+ // Not safe to halve a
+ a + (b / 2.)
+ } else if abs_b < LO {
+ // Not safe to halve b
+ (a / 2.) + b
+ } else {
+ // Not safe to halve a and b
+ (a / 2.) + (b / 2.)
+ }
+ }
+
/// Rounds toward zero and converts to any primitive integer type,
/// assuming that the value is finite and fits in that type.
///
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 1e7387217cb..3aafc435f1e 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -951,6 +951,42 @@ impl f64 {
}
}
+ /// Calculates the middle point of `self` and `rhs`.
+ ///
+ /// This returns NaN when *either* argument is NaN or if a combination of
+ /// +inf and -inf is provided as arguments.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(num_midpoint)]
+ /// assert_eq!(1f64.midpoint(4.0), 2.5);
+ /// assert_eq!((-5.5f64).midpoint(8.0), 1.25);
+ /// ```
+ #[unstable(feature = "num_midpoint", issue = "110840")]
+ pub fn midpoint(self, other: f64) -> f64 {
+ const LO: f64 = f64::MIN_POSITIVE * 2.;
+ const HI: f64 = f64::MAX / 2.;
+
+ let (a, b) = (self, other);
+ let abs_a = a.abs_private();
+ let abs_b = b.abs_private();
+
+ if abs_a <= HI && abs_b <= HI {
+ // Overflow is impossible
+ (a + b) / 2.
+ } else if abs_a < LO {
+ // Not safe to halve a
+ a + (b / 2.)
+ } else if abs_b < LO {
+ // Not safe to halve b
+ (a / 2.) + b
+ } else {
+ // Not safe to halve a and b
+ (a / 2.) + (b / 2.)
+ }
+ }
+
/// Rounds toward zero and converts to any primitive integer type,
/// assuming that the value is finite and fits in that type.
///
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 17715c9291f..1199d09b563 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -2332,6 +2332,44 @@ macro_rules! int_impl {
}
}
+ /// Calculates the middle point of `self` and `rhs`.
+ ///
+ /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a
+ /// sufficiently-large signed integral type. This implies that the result is
+ /// always rounded towards negative infinity and that no overflow will ever occur.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(num_midpoint)]
+ #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")]
+ #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-1), -1);")]
+ #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").midpoint(0), -1);")]
+ /// ```
+ #[unstable(feature = "num_midpoint", issue = "110840")]
+ #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")]
+ #[rustc_allow_const_fn_unstable(const_num_midpoint)]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn midpoint(self, rhs: Self) -> Self {
+ const U: $UnsignedT = <$SelfT>::MIN.unsigned_abs();
+
+ // Map an $SelfT to an $UnsignedT
+ // ex: i8 [-128; 127] to [0; 255]
+ const fn map(a: $SelfT) -> $UnsignedT {
+ (a as $UnsignedT) ^ U
+ }
+
+ // Map an $UnsignedT to an $SelfT
+ // ex: u8 [0; 255] to [-128; 127]
+ const fn demap(a: $UnsignedT) -> $SelfT {
+ (a ^ U) as $SelfT
+ }
+
+ demap(<$UnsignedT>::midpoint(map(self), map(rhs)))
+ }
+
/// Returns the logarithm of the number with respect to an arbitrary base,
/// rounded down.
///
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 08444421dca..c9baa09f407 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -95,6 +95,57 @@ depending on the target pointer size.
};
}
+macro_rules! midpoint_impl {
+ ($SelfT:ty, unsigned) => {
+ /// Calculates the middle point of `self` and `rhs`.
+ ///
+ /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a
+ /// sufficiently-large signed integral type. This implies that the result is
+ /// always rounded towards negative infinity and that no overflow will ever occur.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(num_midpoint)]
+ #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")]
+ #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".midpoint(4), 2);")]
+ /// ```
+ #[unstable(feature = "num_midpoint", issue = "110840")]
+ #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
+ // Use the well known branchless algorthim from Hacker's Delight to compute
+ // `(a + b) / 2` without overflowing: `((a ^ b) >> 1) + (a & b)`.
+ ((self ^ rhs) >> 1) + (self & rhs)
+ }
+ };
+ ($SelfT:ty, $WideT:ty, unsigned) => {
+ /// Calculates the middle point of `self` and `rhs`.
+ ///
+ /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a
+ /// sufficiently-large signed integral type. This implies that the result is
+ /// always rounded towards negative infinity and that no overflow will ever occur.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(num_midpoint)]
+ #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")]
+ #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".midpoint(4), 2);")]
+ /// ```
+ #[unstable(feature = "num_midpoint", issue = "110840")]
+ #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
+ ((self as $WideT + rhs as $WideT) / 2) as $SelfT
+ }
+ };
+}
+
macro_rules! widening_impl {
($SelfT:ty, $WideT:ty, $BITS:literal, unsigned) => {
/// Calculates the complete product `self * rhs` without the possibility to overflow.
@@ -455,6 +506,7 @@ impl u8 {
bound_condition = "",
}
widening_impl! { u8, u16, 8, unsigned }
+ midpoint_impl! { u8, u16, unsigned }
/// Checks if the value is within the ASCII range.
///
@@ -1066,6 +1118,7 @@ impl u16 {
bound_condition = "",
}
widening_impl! { u16, u32, 16, unsigned }
+ midpoint_impl! { u16, u32, unsigned }
/// Checks if the value is a Unicode surrogate code point, which are disallowed values for [`char`].
///
@@ -1114,6 +1167,7 @@ impl u32 {
bound_condition = "",
}
widening_impl! { u32, u64, 32, unsigned }
+ midpoint_impl! { u32, u64, unsigned }
}
impl u64 {
@@ -1137,6 +1191,7 @@ impl u64 {
bound_condition = "",
}
widening_impl! { u64, u128, 64, unsigned }
+ midpoint_impl! { u64, u128, unsigned }
}
impl u128 {
@@ -1161,6 +1216,7 @@ impl u128 {
from_xe_bytes_doc = "",
bound_condition = "",
}
+ midpoint_impl! { u128, unsigned }
}
#[cfg(target_pointer_width = "16")]
@@ -1185,6 +1241,7 @@ impl usize {
bound_condition = " on 16-bit targets",
}
widening_impl! { usize, u32, 16, unsigned }
+ midpoint_impl! { usize, u32, unsigned }
}
#[cfg(target_pointer_width = "32")]
@@ -1209,6 +1266,7 @@ impl usize {
bound_condition = " on 32-bit targets",
}
widening_impl! { usize, u64, 32, unsigned }
+ midpoint_impl! { usize, u64, unsigned }
}
#[cfg(target_pointer_width = "64")]
@@ -1233,6 +1291,7 @@ impl usize {
bound_condition = " on 64-bit targets",
}
widening_impl! { usize, u128, 64, unsigned }
+ midpoint_impl! { usize, u128, unsigned }
}
impl usize {
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 74a325b89d4..38a1c42d9e8 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -493,6 +493,43 @@ macro_rules! nonzero_unsigned_operations {
pub const fn ilog10(self) -> u32 {
super::int_log10::$Int(self.0)
}
+
+ /// Calculates the middle point of `self` and `rhs`.
+ ///
+ /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a
+ /// sufficiently-large signed integral type. This implies that the result is
+ /// always rounded towards negative infinity and that no overflow will ever occur.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(num_midpoint)]
+ #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+ ///
+ /// # fn main() { test().unwrap(); }
+ /// # fn test() -> Option<()> {
+ #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
+ #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+ #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
+ ///
+ /// assert_eq!(one.midpoint(four), two);
+ /// assert_eq!(four.midpoint(one), two);
+ /// # Some(())
+ /// # }
+ /// ```
+ #[unstable(feature = "num_midpoint", issue = "110840")]
+ #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")]
+ #[rustc_allow_const_fn_unstable(const_num_midpoint)]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn midpoint(self, rhs: Self) -> Self {
+ // SAFETY: The only way to get `0` with midpoint is to have two opposite or
+ // near opposite numbers: (-5, 5), (0, 1), (0, 0) which is impossible because
+ // of the unsignedness of this number and also because $Ty is guaranteed to
+ // never being 0.
+ unsafe { $Ty::new_unchecked(self.get().midpoint(rhs.get())) }
+ }
}
)+
}
@@ -719,8 +756,6 @@ macro_rules! nonzero_signed_operations {
/// # Example
///
/// ```
- /// #![feature(nonzero_negation_ops)]
- ///
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
@@ -734,7 +769,8 @@ macro_rules! nonzero_signed_operations {
/// ```
#[must_use]
#[inline]
- #[unstable(feature = "nonzero_negation_ops", issue = "102443")]
+ #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
pub const fn is_positive(self) -> bool {
self.get().is_positive()
}
@@ -745,8 +781,6 @@ macro_rules! nonzero_signed_operations {
/// # Example
///
/// ```
- /// #![feature(nonzero_negation_ops)]
- ///
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
@@ -760,7 +794,8 @@ macro_rules! nonzero_signed_operations {
/// ```
#[must_use]
#[inline]
- #[unstable(feature = "nonzero_negation_ops", issue = "102443")]
+ #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
pub const fn is_negative(self) -> bool {
self.get().is_negative()
}
@@ -770,8 +805,6 @@ macro_rules! nonzero_signed_operations {
/// # Example
///
/// ```
- /// #![feature(nonzero_negation_ops)]
- ///
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
@@ -786,7 +819,8 @@ macro_rules! nonzero_signed_operations {
/// # }
/// ```
#[inline]
- #[unstable(feature = "nonzero_negation_ops", issue = "102443")]
+ #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
pub const fn checked_neg(self) -> Option<$Ty> {
if let Some(result) = self.get().checked_neg() {
// SAFETY: negation of nonzero cannot yield zero values.
@@ -803,8 +837,6 @@ macro_rules! nonzero_signed_operations {
/// # Example
///
/// ```
- /// #![feature(nonzero_negation_ops)]
- ///
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
@@ -819,7 +851,8 @@ macro_rules! nonzero_signed_operations {
/// # }
/// ```
#[inline]
- #[unstable(feature = "nonzero_negation_ops", issue = "102443")]
+ #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
pub const fn overflowing_neg(self) -> ($Ty, bool) {
let (result, overflow) = self.get().overflowing_neg();
// SAFETY: negation of nonzero cannot yield zero values.
@@ -832,8 +865,6 @@ macro_rules! nonzero_signed_operations {
/// # Example
///
/// ```
- /// #![feature(nonzero_negation_ops)]
- ///
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
@@ -853,7 +884,8 @@ macro_rules! nonzero_signed_operations {
/// # }
/// ```
#[inline]
- #[unstable(feature = "nonzero_negation_ops", issue = "102443")]
+ #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
pub const fn saturating_neg(self) -> $Ty {
if let Some(result) = self.checked_neg() {
return result;
@@ -870,8 +902,6 @@ macro_rules! nonzero_signed_operations {
/// # Example
///
/// ```
- /// #![feature(nonzero_negation_ops)]
- ///
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
@@ -886,7 +916,8 @@ macro_rules! nonzero_signed_operations {
/// # }
/// ```
#[inline]
- #[unstable(feature = "nonzero_negation_ops", issue = "102443")]
+ #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
pub const fn wrapping_neg(self) -> $Ty {
let result = self.get().wrapping_neg();
// SAFETY: negation of nonzero cannot yield zero values.
diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs
index a2c3d978cc4..9ebf426be95 100644
--- a/library/core/src/ops/drop.rs
+++ b/library/core/src/ops/drop.rs
@@ -132,6 +132,74 @@
/// are `Copy` get implicitly duplicated by the compiler, making it very
/// hard to predict when, and how often destructors will be executed. As such,
/// these types cannot have destructors.
+///
+/// ## Drop check
+///
+/// Dropping interacts with the borrow checker in subtle ways: when a type `T` is being implicitly
+/// dropped as some variable of this type goes out of scope, the borrow checker needs to ensure that
+/// calling `T`'s destructor at this moment is safe. In particular, it also needs to be safe to
+/// recursively drop all the fields of `T`. For example, it is crucial that code like the following
+/// is being rejected:
+///
+/// ```compile_fail,E0597
+/// use std::cell::Cell;
+///
+/// struct S<'a>(Cell<Option<&'a S<'a>>>, Box<i32>);
+/// impl Drop for S<'_> {
+/// fn drop(&mut self) {
+/// if let Some(r) = self.0.get() {
+/// // Print the contents of the `Box` in `r`.
+/// println!("{}", r.1);
+/// }
+/// }
+/// }
+///
+/// fn main() {
+/// // Set up two `S` that point to each other.
+/// let s1 = S(Cell::new(None), Box::new(42));
+/// let s2 = S(Cell::new(Some(&s1)), Box::new(42));
+/// s1.0.set(Some(&s2));
+/// // Now they both get dropped. But whichever is the 2nd one
+/// // to be dropped will access the `Box` in the first one,
+/// // which is a use-after-free!
+/// }
+/// ```
+///
+/// The Nomicon discusses the need for [drop check in more detail][drop check].
+///
+/// To reject such code, the "drop check" analysis determines which types and lifetimes need to
+/// still be live when `T` gets dropped. The exact details of this analysis are not yet
+/// stably guaranteed and **subject to change**. Currently, the analysis works as follows:
+/// - If `T` has no drop glue, then trivially nothing is required to be live. This is the case if
+/// neither `T` nor any of its (recursive) fields have a destructor (`impl Drop`). [`PhantomData`]
+/// and [`ManuallyDrop`] are considered to never have a destructor, no matter their field type.
+/// - If `T` has drop glue, then, for all types `U` that are *owned* by any field of `T`,
+/// recursively add the types and lifetimes that need to be live when `U` gets dropped. The set of
+/// owned types is determined by recursively traversing `T`:
+/// - Recursively descend through `PhantomData`, `Box`, tuples, and arrays (including arrays of
+/// length 0).
+/// - Stop at reference and raw pointer types as well as function pointers and function items;
+/// they do not own anything.
+/// - Stop at non-composite types (type parameters that remain generic in the current context and
+/// base types such as integers and `bool`); these types are owned.
+/// - When hitting an ADT with `impl Drop`, stop there; this type is owned.
+/// - When hitting an ADT without `impl Drop`, recursively descend to its fields. (For an `enum`,
+/// consider all fields of all variants.)
+/// - Furthermore, if `T` implements `Drop`, then all generic (lifetime and type) parameters of `T`
+/// must be live.
+///
+/// In the above example, the last clause implies that `'a` must be live when `S<'a>` is dropped,
+/// and hence the example is rejected. If we remove the `impl Drop`, the liveness requirement
+/// disappears and the example is accepted.
+///
+/// There exists an unstable way for a type to opt-out of the last clause; this is called "drop
+/// check eyepatch" or `may_dangle`. For more details on this nightly-only feature, see the
+/// [discussion in the Nomicon][nomicon].
+///
+/// [`ManuallyDrop`]: crate::mem::ManuallyDrop
+/// [`PhantomData`]: crate::marker::PhantomData
+/// [drop check]: ../../nomicon/dropck.html
+/// [nomicon]: ../../nomicon/phantom-data.html#an-exception-the-special-case-of-the-standard-library-and-its-unstable-may_dangle
#[lang = "drop"]
#[stable(feature = "rust1", since = "1.0.0")]
#[const_trait]
diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs
index 8338a5d7e5a..ebcce79b0f8 100644
--- a/library/core/src/panic.rs
+++ b/library/core/src/panic.rs
@@ -35,9 +35,11 @@ pub macro panic_2015 {
("{}", $arg:expr $(,)?) => (
$crate::panicking::panic_display(&$arg)
),
- ($fmt:expr, $($arg:tt)+) => (
- $crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+))
- ),
+ ($fmt:expr, $($arg:tt)+) => ({
+ // Semicolon to prevent temporaries inside the formatting machinery from
+ // being considered alive in the caller after the panic_fmt call.
+ $crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+));
+ }),
}
#[doc(hidden)]
@@ -53,9 +55,11 @@ pub macro panic_2021 {
("{}", $arg:expr $(,)?) => (
$crate::panicking::panic_display(&$arg)
),
- ($($t:tt)+) => (
- $crate::panicking::panic_fmt($crate::const_format_args!($($t)+))
- ),
+ ($($t:tt)+) => ({
+ // Semicolon to prevent temporaries inside the formatting machinery from
+ // being considered alive in the caller after the panic_fmt call.
+ $crate::panicking::panic_fmt($crate::const_format_args!($($t)+));
+ }),
}
#[doc(hidden)]
diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs
index 06fbe083ca1..5576adde84b 100644
--- a/library/core/src/panic/panic_info.rs
+++ b/library/core/src/panic/panic_info.rs
@@ -134,7 +134,7 @@ impl<'a> PanicInfo<'a> {
/// whose ABI does not support unwinding.
///
/// It is safe for a panic handler to unwind even when this function returns
- /// true, however this will simply cause the panic handler to be called
+ /// false, however this will simply cause the panic handler to be called
/// again.
#[must_use]
#[unstable(feature = "panic_can_unwind", issue = "92988")]
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 585b648873a..5ee1b5e4afc 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -1195,7 +1195,7 @@ impl<T: ?Sized> *const T {
///
/// [`ptr::read`]: crate::ptr::read()
#[stable(feature = "pointer_methods", since = "1.26.0")]
- #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
+ #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn read(self) -> T
@@ -1236,7 +1236,7 @@ impl<T: ?Sized> *const T {
///
/// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
#[stable(feature = "pointer_methods", since = "1.26.0")]
- #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
+ #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn read_unaligned(self) -> T
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 4737ff5d756..ecbf4e66fa4 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -1133,7 +1133,8 @@ pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
/// [valid]: self#safety
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
+#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn read<T>(src: *const T) -> T {
// It would be semantically correct to implement this via `copy_nonoverlapping`
@@ -1249,7 +1250,8 @@ pub const unsafe fn read<T>(src: *const T) -> T {
/// ```
#[inline]
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
-#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
+#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
let mut tmp = MaybeUninit::<T>::uninit();
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index c339ccb1b4d..5edd291fb76 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1305,7 +1305,7 @@ impl<T: ?Sized> *mut T {
///
/// [`ptr::read`]: crate::ptr::read()
#[stable(feature = "pointer_methods", since = "1.26.0")]
- #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
+ #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn read(self) -> T
@@ -1346,7 +1346,7 @@ impl<T: ?Sized> *mut T {
///
/// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
#[stable(feature = "pointer_methods", since = "1.26.0")]
- #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
+ #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn read_unaligned(self) -> T
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 61fcdf58b4f..b492d2f07bc 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -449,6 +449,19 @@ impl<T: ?Sized> NonNull<T> {
// SAFETY: `self` is a `NonNull` pointer which is necessarily non-null
unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) }
}
+
+ /// See [`pointer::add`] for semantics and safety requirements.
+ #[inline]
+ pub(crate) const unsafe fn add(self, delta: usize) -> Self
+ where
+ T: Sized,
+ {
+ // SAFETY: We require that the delta stays in-bounds of the object, and
+ // thus it cannot become null, as that would require wrapping the
+ // address space, which no legal objects are allowed to do.
+ // And the caller promised the `delta` is sound to add.
+ unsafe { NonNull { pointer: self.pointer.add(delta) } }
+ }
}
impl<T> NonNull<[T]> {
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 8629aab0070..5369fe0a9a9 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -13,7 +13,7 @@ use crate::iter::{
use crate::marker::{PhantomData, Send, Sized, Sync};
use crate::mem::{self, SizedTypeProperties};
use crate::num::NonZeroUsize;
-use crate::ptr::NonNull;
+use crate::ptr::{invalid, invalid_mut, NonNull};
use super::{from_raw_parts, from_raw_parts_mut};
@@ -67,9 +67,7 @@ pub struct Iter<'a, T: 'a> {
ptr: NonNull<T>,
/// For non-ZSTs, the non-null pointer to the past-the-end element.
///
- /// For ZSTs, this is `ptr.wrapping_byte_add(len)`.
- ///
- /// For all types, `ptr == end` tests whether the iterator is empty.
+ /// For ZSTs, this is `ptr::invalid(len)`.
end: *const T,
_marker: PhantomData<&'a T>,
}
@@ -92,10 +90,7 @@ impl<'a, T> Iter<'a, T> {
let ptr = slice.as_ptr();
// SAFETY: Similar to `IterMut::new`.
unsafe {
- assume(!ptr.is_null());
-
- let end =
- if T::IS_ZST { ptr.wrapping_byte_add(slice.len()) } else { ptr.add(slice.len()) };
+ let end = if T::IS_ZST { invalid(slice.len()) } else { ptr.add(slice.len()) };
Self { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: PhantomData }
}
@@ -193,9 +188,7 @@ pub struct IterMut<'a, T: 'a> {
ptr: NonNull<T>,
/// For non-ZSTs, the non-null pointer to the past-the-end element.
///
- /// For ZSTs, this is `ptr.wrapping_byte_add(len)`.
- ///
- /// For all types, `ptr == end` tests whether the iterator is empty.
+ /// For ZSTs, this is `ptr::invalid_mut(len)`.
end: *mut T,
_marker: PhantomData<&'a mut T>,
}
@@ -233,10 +226,7 @@ impl<'a, T> IterMut<'a, T> {
// See the `next_unchecked!` and `is_empty!` macros as well as the
// `post_inc_start` method for more information.
unsafe {
- assume(!ptr.is_null());
-
- let end =
- if T::IS_ZST { ptr.wrapping_byte_add(slice.len()) } else { ptr.add(slice.len()) };
+ let end = if T::IS_ZST { invalid_mut(slice.len()) } else { ptr.add(slice.len()) };
Self { ptr: NonNull::new_unchecked(ptr), end, _marker: PhantomData }
}
diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs
index 0a30033778b..3462c0e020a 100644
--- a/library/core/src/slice/iter/macros.rs
+++ b/library/core/src/slice/iter/macros.rs
@@ -1,11 +1,30 @@
//! Macros used by iterators of slice.
+// Shrinks the iterator when T is a ZST, setting the length to `new_len`.
+// `new_len` must not exceed `self.len()`.
+macro_rules! zst_set_len {
+ ($self: ident, $new_len: expr) => {{
+ #![allow(unused_unsafe)] // we're sometimes used within an unsafe block
+
+ // SAFETY: same as `invalid(_mut)`, but the macro doesn't know
+ // which versions of that function to call, so open-code it.
+ $self.end = unsafe { mem::transmute::<usize, _>($new_len) };
+ }};
+}
+
+// Shrinks the iterator when T is a ZST, reducing the length by `n`.
+// `n` must not exceed `self.len()`.
+macro_rules! zst_shrink {
+ ($self: ident, $n: ident) => {
+ let new_len = $self.end.addr() - $n;
+ zst_set_len!($self, new_len);
+ };
+}
+
// Inlining is_empty and len makes a huge performance difference
macro_rules! is_empty {
- // The way we encode the length of a ZST iterator, this works both for ZST
- // and non-ZST.
($self: ident) => {
- $self.ptr.as_ptr() as *const T == $self.end
+ if T::IS_ZST { $self.end.addr() == 0 } else { $self.ptr.as_ptr() as *const _ == $self.end }
};
}
@@ -13,16 +32,13 @@ macro_rules! len {
($self: ident) => {{
#![allow(unused_unsafe)] // we're sometimes used within an unsafe block
- let start = $self.ptr;
if T::IS_ZST {
- // This _cannot_ use `ptr_sub` because we depend on wrapping
- // to represent the length of long ZST slice iterators.
- $self.end.addr().wrapping_sub(start.as_ptr().addr())
+ $self.end.addr()
} else {
// To get rid of some bounds checks (see `position`), we use ptr_sub instead of
// offset_from (Tested by `codegen/slice-position-bounds-check`.)
// SAFETY: by the type invariant pointers are aligned and `start <= end`
- unsafe { $self.end.sub_ptr(start.as_ptr()) }
+ unsafe { $self.end.sub_ptr($self.ptr.as_ptr()) }
}
}};
}
@@ -50,14 +66,6 @@ macro_rules! iterator {
($self: ident) => {& $( $mut_ )? *$self.pre_dec_end(1)}
}
- // Shrinks the iterator when T is a ZST, by moving the end of the iterator
- // backwards by `n`. `n` must not exceed `self.len()`.
- macro_rules! zst_shrink {
- ($self: ident, $n: ident) => {
- $self.end = $self.end.wrapping_byte_sub($n);
- }
- }
-
impl<'a, T> $name<'a, T> {
// Helper function for creating a slice from the iterator.
#[inline(always)]
@@ -73,16 +81,15 @@ macro_rules! iterator {
// Unsafe because the offset must not exceed `self.len()`.
#[inline(always)]
unsafe fn post_inc_start(&mut self, offset: usize) -> * $raw_mut T {
+ let old = self.ptr;
if T::IS_ZST {
zst_shrink!(self, offset);
- self.ptr.as_ptr()
} else {
- 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().add(offset)) };
- old
+ self.ptr = unsafe { self.ptr.add(offset) };
}
+ old.as_ptr()
}
// Helper function for moving the end of the iterator backwards by `offset` elements,
@@ -124,12 +131,10 @@ macro_rules! iterator {
fn next(&mut self) -> Option<$elem> {
// could be implemented with slices, but this avoids bounds checks
- // SAFETY: `assume` calls are safe since a slice's start pointer
- // must be non-null, and slices over non-ZSTs must also have a
- // non-null end pointer. The call to `next_unchecked!` is safe
- // since we check if the iterator is empty first.
+ // SAFETY: `assume` call is safe because slices over non-ZSTs must
+ // have a non-null end pointer. The call to `next_unchecked!` is
+ // safe since we check if the iterator is empty first.
unsafe {
- assume(!self.ptr.as_ptr().is_null());
if !<T>::IS_ZST {
assume(!self.end.is_null());
}
@@ -157,9 +162,7 @@ macro_rules! iterator {
if n >= len!(self) {
// This iterator is now empty.
if T::IS_ZST {
- // We have to do it this way as `ptr` may never be 0, but `end`
- // could be (due to wrapping).
- self.end = self.ptr.as_ptr();
+ zst_set_len!(self, 0);
} else {
// SAFETY: end can't be 0 if T isn't ZST because ptr isn't 0 and end >= ptr
unsafe {
@@ -339,12 +342,10 @@ macro_rules! iterator {
fn next_back(&mut self) -> Option<$elem> {
// could be implemented with slices, but this avoids bounds checks
- // SAFETY: `assume` calls are safe since a slice's start pointer must be non-null,
- // and slices over non-ZSTs must also have a non-null end pointer.
- // The call to `next_back_unchecked!` is safe since we check if the iterator is
- // empty first.
+ // SAFETY: `assume` call is safe because slices over non-ZSTs must
+ // have a non-null end pointer. The call to `next_back_unchecked!`
+ // is safe since we check if the iterator is empty first.
unsafe {
- assume(!self.ptr.as_ptr().is_null());
if !<T>::IS_ZST {
assume(!self.end.is_null());
}
@@ -360,7 +361,11 @@ macro_rules! iterator {
fn nth_back(&mut self, n: usize) -> Option<$elem> {
if n >= len!(self) {
// This iterator is now empty.
- self.end = self.ptr.as_ptr();
+ if T::IS_ZST {
+ zst_set_len!(self, 0);
+ } else {
+ self.end = self.ptr.as_ptr();
+ }
return None;
}
// SAFETY: We are in bounds. `pre_dec_end` does the right thing even for ZSTs.
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 4c891ba550f..6fd2b87d0e3 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -1595,7 +1595,8 @@ impl<T> [T] {
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature = "const_slice_split_at_not_mut", issue = "101158")]
+ #[rustc_const_stable(feature = "const_slice_split_at_not_mut", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_allow_const_fn_unstable(slice_split_at_unchecked)]
#[inline]
#[track_caller]
#[must_use]
@@ -3478,44 +3479,13 @@ impl<T> [T] {
// Ts = size_of::<U> / gcd(size_of::<T>, size_of::<U>)
//
// Luckily since all this is constant-evaluated... performance here matters not!
- #[inline]
- fn gcd(a: usize, b: usize) -> usize {
- use crate::intrinsics;
- // iterative stein’s algorithm
- // We should still make this `const fn` (and revert to recursive algorithm if we do)
- // because relying on llvm to consteval all this is… well, it makes me uncomfortable.
-
- // SAFETY: `a` and `b` are checked to be non-zero values.
- let (ctz_a, mut ctz_b) = unsafe {
- if a == 0 {
- return b;
- }
- if b == 0 {
- return a;
- }
- (intrinsics::cttz_nonzero(a), intrinsics::cttz_nonzero(b))
- };
- let k = ctz_a.min(ctz_b);
- let mut a = a >> ctz_a;
- let mut b = b;
- loop {
- // remove all factors of 2 from b
- b >>= ctz_b;
- if a > b {
- mem::swap(&mut a, &mut b);
- }
- b = b - a;
- // SAFETY: `b` is checked to be non-zero.
- unsafe {
- if b == 0 {
- break;
- }
- ctz_b = intrinsics::cttz_nonzero(b);
- }
- }
- a << k
+ const fn gcd(a: usize, b: usize) -> usize {
+ if b == 0 { a } else { gcd(b, a % b) }
}
- let gcd: usize = gcd(mem::size_of::<T>(), mem::size_of::<U>());
+
+ // Explicitly wrap the function call in a const block so it gets
+ // constant-evaluated even in debug mode.
+ let gcd: usize = const { gcd(mem::size_of::<T>(), mem::size_of::<U>()) };
let ts: usize = mem::size_of::<U>() / gcd;
let us: usize = mem::size_of::<T>() / gcd;
diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs
index e3a464a1c51..91ee2903aab 100644
--- a/library/core/src/str/pattern.rs
+++ b/library/core/src/str/pattern.rs
@@ -791,8 +791,8 @@ pub struct CharArrayRefSearcher<'a, 'b, const N: usize>(
/// # Examples
///
/// ```
-/// assert_eq!("Hello world".find(['l', 'l']), Some(2));
-/// assert_eq!("Hello world".find(['l', 'l']), Some(2));
+/// assert_eq!("Hello world".find(['o', 'l']), Some(2));
+/// assert_eq!("Hello world".find(['h', 'w']), Some(6));
/// ```
impl<'a, const N: usize> Pattern<'a> for [char; N] {
pattern_methods!(CharArraySearcher<'a, N>, MultiCharEqPattern, CharArraySearcher);
@@ -811,8 +811,8 @@ unsafe impl<'a, const N: usize> ReverseSearcher<'a> for CharArraySearcher<'a, N>
/// # Examples
///
/// ```
-/// assert_eq!("Hello world".find(&['l', 'l']), Some(2));
-/// assert_eq!("Hello world".find(&['l', 'l']), Some(2));
+/// assert_eq!("Hello world".find(&['o', 'l']), Some(2));
+/// assert_eq!("Hello world".find(&['h', 'w']), Some(6));
/// ```
impl<'a, 'b, const N: usize> Pattern<'a> for &'b [char; N] {
pattern_methods!(CharArrayRefSearcher<'a, 'b, N>, MultiCharEqPattern, CharArrayRefSearcher);
diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs
index 168516263f1..5283a576d1b 100644
--- a/library/core/src/task/poll.rs
+++ b/library/core/src/task/poll.rs
@@ -116,7 +116,7 @@ impl<T> Poll<T> {
/// let fut = Pin::new(&mut fut);
///
/// let num = fut.poll(cx).ready()?;
- /// # drop(num);
+ /// # let _ = num; // to silence unused warning
/// // ... use num
///
/// Poll::Ready(())
diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs
index b1daf545fbe..8d12625e88d 100644
--- a/library/core/src/task/ready.rs
+++ b/library/core/src/task/ready.rs
@@ -22,7 +22,7 @@ use core::task::Poll;
/// let fut = Pin::new(&mut fut);
///
/// let num = ready!(fut.poll(cx));
-/// # drop(num);
+/// # let _ = num;
/// // ... use num
///
/// Poll::Ready(())
@@ -44,7 +44,7 @@ use core::task::Poll;
/// Poll::Ready(t) => t,
/// Poll::Pending => return Poll::Pending,
/// };
-/// # drop(num);
+/// # let _ = num; // to silence unused warning
/// # // ... use num
/// #
/// # Poll::Ready(())
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs
index 808825326ae..7043ab5ff2b 100644
--- a/library/core/src/task/wake.rs
+++ b/library/core/src/task/wake.rs
@@ -232,7 +232,7 @@ impl fmt::Debug for Context<'_> {
///
/// [`Future::poll()`]: core::future::Future::poll
/// [`Poll::Pending`]: core::task::Poll::Pending
-#[repr(transparent)]
+#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/66401
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Waker {
waker: RawWaker,
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 84859a54c26..3933e328951 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -18,7 +18,6 @@
#![feature(const_pointer_byte_offsets)]
#![feature(const_pointer_is_aligned)]
#![feature(const_ptr_as_ref)]
-#![feature(const_ptr_read)]
#![feature(const_ptr_write)]
#![feature(const_trait_impl)]
#![feature(const_likely)]
@@ -54,6 +53,7 @@
#![feature(maybe_uninit_uninit_array_transpose)]
#![feature(min_specialization)]
#![feature(numfmt)]
+#![feature(num_midpoint)]
#![feature(step_trait)]
#![feature(str_internals)]
#![feature(std_internals)]
diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs
index 18c55e43aac..439bbe66997 100644
--- a/library/core/tests/num/int_macros.rs
+++ b/library/core/tests/num/int_macros.rs
@@ -364,6 +364,32 @@ macro_rules! int_module {
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));
}
+
+ #[test]
+ fn test_midpoint() {
+ assert_eq!(<$T>::midpoint(1, 3), 2);
+ assert_eq!(<$T>::midpoint(3, 1), 2);
+
+ assert_eq!(<$T>::midpoint(0, 0), 0);
+ assert_eq!(<$T>::midpoint(0, 2), 1);
+ assert_eq!(<$T>::midpoint(2, 0), 1);
+ assert_eq!(<$T>::midpoint(2, 2), 2);
+
+ assert_eq!(<$T>::midpoint(1, 4), 2);
+ assert_eq!(<$T>::midpoint(4, 1), 2);
+ assert_eq!(<$T>::midpoint(3, 4), 3);
+ assert_eq!(<$T>::midpoint(4, 3), 3);
+
+ assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), -1);
+ assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), -1);
+ assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
+ assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
+
+ assert_eq!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
+ assert_eq!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
+ assert_eq!(<$T>::midpoint(<$T>::MAX, 6), <$T>::MAX / 2 + 3);
+ assert_eq!(<$T>::midpoint(6, <$T>::MAX), <$T>::MAX / 2 + 3);
+ }
}
};
}
diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs
index 3e1f848ccfe..3f3659ba837 100644
--- a/library/core/tests/num/mod.rs
+++ b/library/core/tests/num/mod.rs
@@ -724,7 +724,7 @@ assume_usize_width! {
}
macro_rules! test_float {
- ($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr) => {
+ ($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr, $min: expr, $max: expr, $min_pos: expr) => {
mod $modname {
#[test]
fn min() {
@@ -845,6 +845,38 @@ macro_rules! test_float {
assert!(($nan as $fty).maximum($nan).is_nan());
}
#[test]
+ fn midpoint() {
+ assert_eq!((0.5 as $fty).midpoint(0.5), 0.5);
+ assert_eq!((0.5 as $fty).midpoint(2.5), 1.5);
+ assert_eq!((3.0 as $fty).midpoint(4.0), 3.5);
+ assert_eq!((-3.0 as $fty).midpoint(4.0), 0.5);
+ assert_eq!((3.0 as $fty).midpoint(-4.0), -0.5);
+ assert_eq!((-3.0 as $fty).midpoint(-4.0), -3.5);
+ assert_eq!((0.0 as $fty).midpoint(0.0), 0.0);
+ assert_eq!((-0.0 as $fty).midpoint(-0.0), -0.0);
+ assert_eq!((-5.0 as $fty).midpoint(5.0), 0.0);
+ assert_eq!(($max as $fty).midpoint($min), 0.0);
+ assert_eq!(($min as $fty).midpoint($max), -0.0);
+ assert_eq!(($max as $fty).midpoint($min_pos), $max / 2.);
+ assert_eq!((-$max as $fty).midpoint($min_pos), -$max / 2.);
+ assert_eq!(($max as $fty).midpoint(-$min_pos), $max / 2.);
+ assert_eq!((-$max as $fty).midpoint(-$min_pos), -$max / 2.);
+ assert_eq!(($min_pos as $fty).midpoint($max), $max / 2.);
+ assert_eq!(($min_pos as $fty).midpoint(-$max), -$max / 2.);
+ assert_eq!((-$min_pos as $fty).midpoint($max), $max / 2.);
+ assert_eq!((-$min_pos as $fty).midpoint(-$max), -$max / 2.);
+ assert_eq!(($max as $fty).midpoint($max), $max);
+ assert_eq!(($min_pos as $fty).midpoint($min_pos), $min_pos);
+ assert_eq!((-$min_pos as $fty).midpoint(-$min_pos), -$min_pos);
+ assert_eq!(($max as $fty).midpoint(5.0), $max / 2.0 + 2.5);
+ assert_eq!(($max as $fty).midpoint(-5.0), $max / 2.0 - 2.5);
+ assert_eq!(($inf as $fty).midpoint($inf), $inf);
+ assert_eq!(($neginf as $fty).midpoint($neginf), $neginf);
+ assert!(($nan as $fty).midpoint(1.0).is_nan());
+ assert!((1.0 as $fty).midpoint($nan).is_nan());
+ assert!(($nan as $fty).midpoint($nan).is_nan());
+ }
+ #[test]
fn rem_euclid() {
let a: $fty = 42.0;
assert!($inf.rem_euclid(a).is_nan());
@@ -867,5 +899,23 @@ macro_rules! test_float {
};
}
-test_float!(f32, f32, f32::INFINITY, f32::NEG_INFINITY, f32::NAN);
-test_float!(f64, f64, f64::INFINITY, f64::NEG_INFINITY, f64::NAN);
+test_float!(
+ f32,
+ f32,
+ f32::INFINITY,
+ f32::NEG_INFINITY,
+ f32::NAN,
+ f32::MIN,
+ f32::MAX,
+ f32::MIN_POSITIVE
+);
+test_float!(
+ f64,
+ f64,
+ f64::INFINITY,
+ f64::NEG_INFINITY,
+ f64::NAN,
+ f64::MIN,
+ f64::MAX,
+ f64::MIN_POSITIVE
+);
diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs
index 15ae9f2324f..7d6203db0b9 100644
--- a/library/core/tests/num/uint_macros.rs
+++ b/library/core/tests/num/uint_macros.rs
@@ -252,6 +252,32 @@ macro_rules! uint_module {
assert_eq!($T::MAX.borrowing_sub(0, true), ($T::MAX - 1, false));
assert_eq!($T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true));
}
+
+ #[test]
+ fn test_midpoint() {
+ assert_eq!(<$T>::midpoint(1, 3), 2);
+ assert_eq!(<$T>::midpoint(3, 1), 2);
+
+ assert_eq!(<$T>::midpoint(0, 0), 0);
+ assert_eq!(<$T>::midpoint(0, 2), 1);
+ assert_eq!(<$T>::midpoint(2, 0), 1);
+ assert_eq!(<$T>::midpoint(2, 2), 2);
+
+ assert_eq!(<$T>::midpoint(1, 4), 2);
+ assert_eq!(<$T>::midpoint(4, 1), 2);
+ assert_eq!(<$T>::midpoint(3, 4), 3);
+ assert_eq!(<$T>::midpoint(4, 3), 3);
+
+ assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2);
+ assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), (<$T>::MAX - <$T>::MIN) / 2);
+ assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
+ assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
+
+ assert_eq!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
+ assert_eq!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
+ assert_eq!(<$T>::midpoint(<$T>::MAX, 6), (<$T>::MAX - <$T>::MIN) / 2 + 3);
+ assert_eq!(<$T>::midpoint(6, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2 + 3);
+ }
}
};
}
diff --git a/library/portable-simd/.github/workflows/ci.yml b/library/portable-simd/.github/workflows/ci.yml
index d50dfa1be4c..acd47a3da72 100644
--- a/library/portable-simd/.github/workflows/ci.yml
+++ b/library/portable-simd/.github/workflows/ci.yml
@@ -241,6 +241,10 @@ jobs:
- "--features std"
- "--features generic_const_exprs"
- "--features std --features generic_const_exprs"
+ - "--features all_lane_counts"
+ - "--features all_lane_counts --features std"
+ - "--features all_lane_counts --features generic_const_exprs"
+ - "--features all_lane_counts --features std --features generic_const_exprs"
steps:
- uses: actions/checkout@v2
diff --git a/library/portable-simd/README.md b/library/portable-simd/README.md
index db0af2da606..e8ac600debe 100644
--- a/library/portable-simd/README.md
+++ b/library/portable-simd/README.md
@@ -24,19 +24,10 @@ or by setting up `rustup default nightly` or else with `cargo +nightly {build,te
```bash
cargo new hellosimd
```
-to create a new crate. Edit `hellosimd/Cargo.toml` to be
-```toml
-[package]
-name = "hellosimd"
-version = "0.1.0"
-edition = "2018"
-[dependencies]
-core_simd = { git = "https://github.com/rust-lang/portable-simd" }
-```
-
-and finally write this in `src/main.rs`:
+to create a new crate. Finally write this in `src/main.rs`:
```rust
-use core_simd::*;
+#![feature(portable_simd)]
+use std::simd::f32x4;
fn main() {
let a = f32x4::splat(10.0);
let b = f32x4::from_array([1.0, 2.0, 3.0, 4.0]);
@@ -44,24 +35,23 @@ fn main() {
}
```
-Explanation: We import all the bindings from the crate with the first line. Then, we construct our SIMD vectors with methods like `splat` or `from_array`. Finally, we can use operators on them like `+` and the appropriate SIMD instructions will be carried out. When we run `cargo run` you should get `[11.0, 12.0, 13.0, 14.0]`.
-
-## Code Organization
+Explanation: We construct our SIMD vectors with methods like `splat` or `from_array`. Next, we can use operators like `+` on them, and the appropriate SIMD instructions will be carried out. When we run `cargo run` you should get `[11.0, 12.0, 13.0, 14.0]`.
-Currently the crate is organized so that each element type is a file, and then the 64-bit, 128-bit, 256-bit, and 512-bit vectors using those types are contained in said file.
+## Supported vectors
-All types are then exported as a single, flat module.
+Currently, vectors may have up to 64 elements, but aliases are provided only up to 512-bit vectors.
Depending on the size of the primitive type, the number of lanes the vector will have varies. For example, 128-bit vectors have four `f32` lanes and two `f64` lanes.
The supported element types are as follows:
* **Floating Point:** `f32`, `f64`
-* **Signed Integers:** `i8`, `i16`, `i32`, `i64`, `i128`, `isize`
-* **Unsigned Integers:** `u8`, `u16`, `u32`, `u64`, `u128`, `usize`
-* **Masks:** `mask8`, `mask16`, `mask32`, `mask64`, `mask128`, `masksize`
+* **Signed Integers:** `i8`, `i16`, `i32`, `i64`, `isize` (`i128` excluded)
+* **Unsigned Integers:** `u8`, `u16`, `u32`, `u64`, `usize` (`u128` excluded)
+* **Pointers:** `*const T` and `*mut T` (zero-sized metadata only)
+* **Masks:** 8-bit, 16-bit, 32-bit, 64-bit, and `usize`-sized masks
-Floating point, signed integers, and unsigned integers are the [primitive types](https://doc.rust-lang.org/core/primitive/index.html) you're already used to.
-The `mask` types are "truthy" values, but they use the number of bits in their name instead of just 1 bit like a normal `bool` uses.
+Floating point, signed integers, unsigned integers, and pointers are the [primitive types](https://doc.rust-lang.org/core/primitive/index.html) you're already used to.
+The mask types have elements that are "truthy" values, like `bool`, but have an unspecified layout because different architectures prefer different layouts for mask types.
[simd-guide]: ./beginners-guide.md
[zulip-project-portable-simd]: https://rust-lang.zulipchat.com/#narrow/stream/257879-project-portable-simd
diff --git a/library/portable-simd/crates/core_simd/Cargo.toml b/library/portable-simd/crates/core_simd/Cargo.toml
index 8a29cf15696..d1a3a515a7e 100644
--- a/library/portable-simd/crates/core_simd/Cargo.toml
+++ b/library/portable-simd/crates/core_simd/Cargo.toml
@@ -13,12 +13,11 @@ default = ["as_crate"]
as_crate = []
std = []
generic_const_exprs = []
+all_lane_counts = []
-[target.'cfg(target_arch = "wasm32")'.dev-dependencies.wasm-bindgen]
-version = "0.2"
-
-[dev-dependencies.wasm-bindgen-test]
-version = "0.3"
+[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
+wasm-bindgen = "0.2"
+wasm-bindgen-test = "0.3"
[dev-dependencies.proptest]
version = "0.10"
diff --git a/library/portable-simd/crates/core_simd/examples/README.md b/library/portable-simd/crates/core_simd/examples/README.md
new file mode 100644
index 00000000000..82747f1b5a6
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/examples/README.md
@@ -0,0 +1,13 @@
+### `stdsimd` examples
+
+This crate is a port of example uses of `stdsimd`, mostly taken from the `packed_simd` crate.
+
+The examples contain, as in the case of `dot_product.rs`, multiple ways of solving the problem, in order to show idiomatic uses of SIMD and iteration of performance designs.
+
+Run the tests with the command
+
+```
+cargo run --example dot_product
+```
+
+and verify the code for `dot_product.rs` on your machine.
diff --git a/library/portable-simd/crates/core_simd/examples/dot_product.rs b/library/portable-simd/crates/core_simd/examples/dot_product.rs
new file mode 100644
index 00000000000..391f08f55a0
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/examples/dot_product.rs
@@ -0,0 +1,169 @@
+// Code taken from the `packed_simd` crate
+// Run this code with `cargo test --example dot_product`
+//use std::iter::zip;
+
+#![feature(array_chunks)]
+#![feature(slice_as_chunks)]
+// Add these imports to use the stdsimd library
+#![feature(portable_simd)]
+use core_simd::simd::*;
+
+// This is your barebones dot product implementation:
+// Take 2 vectors, multiply them element wise and *then*
+// go along the resulting array and add up the result.
+// In the next example we will see if there
+// is any difference to adding and multiplying in tandem.
+pub fn dot_prod_scalar_0(a: &[f32], b: &[f32]) -> f32 {
+ assert_eq!(a.len(), b.len());
+
+ a.iter().zip(b.iter()).map(|(a, b)| a * b).sum()
+}
+
+// When dealing with SIMD, it is very important to think about the amount
+// of data movement and when it happens. We're going over simple computation examples here, and yet
+// it is not trivial to understand what may or may not contribute to performance
+// changes. Eventually, you will need tools to inspect the generated assembly and confirm your
+// hypothesis and benchmarks - we will mention them later on.
+// With the use of `fold`, we're doing a multiplication,
+// and then adding it to the sum, one element from both vectors at a time.
+pub fn dot_prod_scalar_1(a: &[f32], b: &[f32]) -> f32 {
+ assert_eq!(a.len(), b.len());
+ a.iter()
+ .zip(b.iter())
+ .fold(0.0, |a, zipped| a + zipped.0 * zipped.1)
+}
+
+// We now move on to the SIMD implementations: notice the following constructs:
+// `array_chunks::<4>`: mapping this over the vector will let use construct SIMD vectors
+// `f32x4::from_array`: construct the SIMD vector from a slice
+// `(a * b).reduce_sum()`: Multiply both f32x4 vectors together, and then reduce them.
+// This approach essentially uses SIMD to produce a vector of length N/4 of all the products,
+// and then add those with `sum()`. This is suboptimal.
+// TODO: ASCII diagrams
+pub fn dot_prod_simd_0(a: &[f32], b: &[f32]) -> f32 {
+ assert_eq!(a.len(), b.len());
+ // TODO handle remainder when a.len() % 4 != 0
+ a.array_chunks::<4>()
+ .map(|&a| f32x4::from_array(a))
+ .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b)))
+ .map(|(a, b)| (a * b).reduce_sum())
+ .sum()
+}
+
+// There's some simple ways to improve the previous code:
+// 1. Make a `zero` `f32x4` SIMD vector that we will be accumulating into
+// So that there is only one `sum()` reduction when the last `f32x4` has been processed
+// 2. Exploit Fused Multiply Add so that the multiplication, addition and sinking into the reduciton
+// happen in the same step.
+// If the arrays are large, minimizing the data shuffling will lead to great perf.
+// If the arrays are small, handling the remainder elements when the length isn't a multiple of 4
+// Can become a problem.
+pub fn dot_prod_simd_1(a: &[f32], b: &[f32]) -> f32 {
+ assert_eq!(a.len(), b.len());
+ // TODO handle remainder when a.len() % 4 != 0
+ a.array_chunks::<4>()
+ .map(|&a| f32x4::from_array(a))
+ .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b)))
+ .fold(f32x4::splat(0.0), |acc, zipped| acc + zipped.0 * zipped.1)
+ .reduce_sum()
+}
+
+// A lot of knowledgeable use of SIMD comes from knowing specific instructions that are
+// available - let's try to use the `mul_add` instruction, which is the fused-multiply-add we were looking for.
+use std_float::StdFloat;
+pub fn dot_prod_simd_2(a: &[f32], b: &[f32]) -> f32 {
+ assert_eq!(a.len(), b.len());
+ // TODO handle remainder when a.len() % 4 != 0
+ let mut res = f32x4::splat(0.0);
+ a.array_chunks::<4>()
+ .map(|&a| f32x4::from_array(a))
+ .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b)))
+ .for_each(|(a, b)| {
+ res = a.mul_add(b, res);
+ });
+ res.reduce_sum()
+}
+
+// Finally, we will write the same operation but handling the loop remainder.
+const LANES: usize = 4;
+pub fn dot_prod_simd_3(a: &[f32], b: &[f32]) -> f32 {
+ assert_eq!(a.len(), b.len());
+
+ let (a_extra, a_chunks) = a.as_rchunks();
+ let (b_extra, b_chunks) = b.as_rchunks();
+
+ // These are always true, but for emphasis:
+ assert_eq!(a_chunks.len(), b_chunks.len());
+ assert_eq!(a_extra.len(), b_extra.len());
+
+ let mut sums = [0.0; LANES];
+ for ((x, y), d) in std::iter::zip(a_extra, b_extra).zip(&mut sums) {
+ *d = x * y;
+ }
+
+ let mut sums = f32x4::from_array(sums);
+ std::iter::zip(a_chunks, b_chunks).for_each(|(x, y)| {
+ sums += f32x4::from_array(*x) * f32x4::from_array(*y);
+ });
+
+ sums.reduce_sum()
+}
+
+// Finally, we present an iterator version for handling remainders in a scalar fashion at the end of the loop.
+// Unfortunately, this is allocating 1 `XMM` register on the order of `~len(a)` - we'll see how we can get around it in the
+// next example.
+pub fn dot_prod_simd_4(a: &[f32], b: &[f32]) -> f32 {
+ let mut sum = a
+ .array_chunks::<4>()
+ .map(|&a| f32x4::from_array(a))
+ .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b)))
+ .map(|(a, b)| a * b)
+ .fold(f32x4::splat(0.0), std::ops::Add::add)
+ .reduce_sum();
+ let remain = a.len() - (a.len() % 4);
+ sum += a[remain..]
+ .iter()
+ .zip(&b[remain..])
+ .map(|(a, b)| a * b)
+ .sum::<f32>();
+ sum
+}
+
+// This version allocates a single `XMM` register for accumulation, and the folds don't allocate on top of that.
+// Notice the the use of `mul_add`, which can do a multiply and an add operation ber iteration.
+pub fn dot_prod_simd_5(a: &[f32], b: &[f32]) -> f32 {
+ a.array_chunks::<4>()
+ .map(|&a| f32x4::from_array(a))
+ .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b)))
+ .fold(f32x4::splat(0.), |acc, (a, b)| a.mul_add(b, acc))
+ .reduce_sum()
+}
+
+fn main() {
+ // Empty main to make cargo happy
+}
+
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn smoke_test() {
+ use super::*;
+ let a: Vec<f32> = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
+ let b: Vec<f32> = vec![-8.0, -7.0, -6.0, -5.0, 4.0, 3.0, 2.0, 1.0];
+ let x: Vec<f32> = [0.5; 1003].to_vec();
+ let y: Vec<f32> = [2.0; 1003].to_vec();
+
+ // Basic check
+ assert_eq!(0.0, dot_prod_scalar_0(&a, &b));
+ assert_eq!(0.0, dot_prod_scalar_1(&a, &b));
+ assert_eq!(0.0, dot_prod_simd_0(&a, &b));
+ assert_eq!(0.0, dot_prod_simd_1(&a, &b));
+ assert_eq!(0.0, dot_prod_simd_2(&a, &b));
+ assert_eq!(0.0, dot_prod_simd_3(&a, &b));
+ assert_eq!(0.0, dot_prod_simd_4(&a, &b));
+ assert_eq!(0.0, dot_prod_simd_5(&a, &b));
+
+ // We can handle vectors that are non-multiples of 4
+ assert_eq!(1003.0, dot_prod_simd_3(&x, &y));
+ }
+}
diff --git a/library/portable-simd/crates/core_simd/src/alias.rs b/library/portable-simd/crates/core_simd/src/alias.rs
new file mode 100644
index 00000000000..23f121c4619
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/src/alias.rs
@@ -0,0 +1,227 @@
+macro_rules! number {
+ { 1 } => { "one" };
+ { 2 } => { "two" };
+ { 4 } => { "four" };
+ { 8 } => { "eight" };
+ { $x:literal } => { stringify!($x) };
+}
+
+macro_rules! plural {
+ { 1 } => { "" };
+ { $x:literal } => { "s" };
+}
+
+macro_rules! alias {
+ {
+ $(
+ $element_ty:ty = {
+ $($alias:ident $num_elements:tt)*
+ }
+ )*
+ } => {
+ $(
+ $(
+ #[doc = concat!("A SIMD vector with ", number!($num_elements), " element", plural!($num_elements), " of type [`", stringify!($element_ty), "`].")]
+ #[allow(non_camel_case_types)]
+ pub type $alias = $crate::simd::Simd<$element_ty, $num_elements>;
+ )*
+ )*
+ }
+}
+
+macro_rules! mask_alias {
+ {
+ $(
+ $element_ty:ty : $size:literal = {
+ $($alias:ident $num_elements:tt)*
+ }
+ )*
+ } => {
+ $(
+ $(
+ #[doc = concat!("A SIMD mask with ", number!($num_elements), " element", plural!($num_elements), " for vectors with ", $size, " element types.")]
+ ///
+ #[doc = concat!(
+ "The layout of this type is unspecified, and may change between platforms and/or Rust versions, and code should not assume that it is equivalent to `[",
+ stringify!($element_ty), "; ", $num_elements, "]`."
+ )]
+ #[allow(non_camel_case_types)]
+ pub type $alias = $crate::simd::Mask<$element_ty, $num_elements>;
+ )*
+ )*
+ }
+}
+
+alias! {
+ i8 = {
+ i8x1 1
+ i8x2 2
+ i8x4 4
+ i8x8 8
+ i8x16 16
+ i8x32 32
+ i8x64 64
+ }
+
+ i16 = {
+ i16x1 1
+ i16x2 2
+ i16x4 4
+ i16x8 8
+ i16x16 16
+ i16x32 32
+ i16x64 64
+ }
+
+ i32 = {
+ i32x1 1
+ i32x2 2
+ i32x4 4
+ i32x8 8
+ i32x16 16
+ i32x32 32
+ i32x64 64
+ }
+
+ i64 = {
+ i64x1 1
+ i64x2 2
+ i64x4 4
+ i64x8 8
+ i64x16 16
+ i64x32 32
+ i64x64 64
+ }
+
+ isize = {
+ isizex1 1
+ isizex2 2
+ isizex4 4
+ isizex8 8
+ isizex16 16
+ isizex32 32
+ isizex64 64
+ }
+
+ u8 = {
+ u8x1 1
+ u8x2 2
+ u8x4 4
+ u8x8 8
+ u8x16 16
+ u8x32 32
+ u8x64 64
+ }
+
+ u16 = {
+ u16x1 1
+ u16x2 2
+ u16x4 4
+ u16x8 8
+ u16x16 16
+ u16x32 32
+ u16x64 64
+ }
+
+ u32 = {
+ u32x1 1
+ u32x2 2
+ u32x4 4
+ u32x8 8
+ u32x16 16
+ u32x32 32
+ u32x64 64
+ }
+
+ u64 = {
+ u64x1 1
+ u64x2 2
+ u64x4 4
+ u64x8 8
+ u64x16 16
+ u64x32 32
+ u64x64 64
+ }
+
+ usize = {
+ usizex1 1
+ usizex2 2
+ usizex4 4
+ usizex8 8
+ usizex16 16
+ usizex32 32
+ usizex64 64
+ }
+
+ f32 = {
+ f32x1 1
+ f32x2 2
+ f32x4 4
+ f32x8 8
+ f32x16 16
+ f32x32 32
+ f32x64 64
+ }
+
+ f64 = {
+ f64x1 1
+ f64x2 2
+ f64x4 4
+ f64x8 8
+ f64x16 16
+ f64x32 32
+ f64x64 64
+ }
+}
+
+mask_alias! {
+ i8 : "8-bit" = {
+ mask8x1 1
+ mask8x2 2
+ mask8x4 4
+ mask8x8 8
+ mask8x16 16
+ mask8x32 32
+ mask8x64 64
+ }
+
+ i16 : "16-bit" = {
+ mask16x1 1
+ mask16x2 2
+ mask16x4 4
+ mask16x8 8
+ mask16x16 16
+ mask16x32 32
+ mask16x64 64
+ }
+
+ i32 : "32-bit" = {
+ mask32x1 1
+ mask32x2 2
+ mask32x4 4
+ mask32x8 8
+ mask32x16 16
+ mask32x32 32
+ mask32x64 64
+ }
+
+ i64 : "64-bit" = {
+ mask64x1 1
+ mask64x2 2
+ mask64x4 4
+ mask64x8 8
+ mask64x16 16
+ mask64x32 32
+ mask64x64 64
+ }
+
+ isize : "pointer-sized" = {
+ masksizex1 1
+ masksizex2 2
+ masksizex4 4
+ masksizex8 8
+ masksizex16 16
+ masksizex32 32
+ masksizex64 64
+ }
+}
diff --git a/library/portable-simd/crates/core_simd/src/cast.rs b/library/portable-simd/crates/core_simd/src/cast.rs
new file mode 100644
index 00000000000..65a3f845ffc
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/src/cast.rs
@@ -0,0 +1,55 @@
+use crate::simd::SimdElement;
+
+/// Supporting trait for `Simd::cast`. Typically doesn't need to be used directly.
+///
+/// # Safety
+/// Implementing this trait asserts that the type is a valid vector element for the `simd_cast` or
+/// `simd_as` intrinsics.
+pub unsafe trait SimdCast: SimdElement {}
+
+// Safety: primitive number types can be cast to other primitive number types
+unsafe impl SimdCast for i8 {}
+// Safety: primitive number types can be cast to other primitive number types
+unsafe impl SimdCast for i16 {}
+// Safety: primitive number types can be cast to other primitive number types
+unsafe impl SimdCast for i32 {}
+// Safety: primitive number types can be cast to other primitive number types
+unsafe impl SimdCast for i64 {}
+// Safety: primitive number types can be cast to other primitive number types
+unsafe impl SimdCast for isize {}
+// Safety: primitive number types can be cast to other primitive number types
+unsafe impl SimdCast for u8 {}
+// Safety: primitive number types can be cast to other primitive number types
+unsafe impl SimdCast for u16 {}
+// Safety: primitive number types can be cast to other primitive number types
+unsafe impl SimdCast for u32 {}
+// Safety: primitive number types can be cast to other primitive number types
+unsafe impl SimdCast for u64 {}
+// Safety: primitive number types can be cast to other primitive number types
+unsafe impl SimdCast for usize {}
+// Safety: primitive number types can be cast to other primitive number types
+unsafe impl SimdCast for f32 {}
+// Safety: primitive number types can be cast to other primitive number types
+unsafe impl SimdCast for f64 {}
+
+/// Supporting trait for `Simd::cast_ptr`. Typically doesn't need to be used directly.
+///
+/// # Safety
+/// Implementing this trait asserts that the type is a valid vector element for the `simd_cast_ptr`
+/// intrinsic.
+pub unsafe trait SimdCastPtr<T> {}
+
+// Safety: pointers can be cast to other pointer types
+unsafe impl<T, U> SimdCastPtr<T> for *const U
+where
+ U: core::ptr::Pointee,
+ T: core::ptr::Pointee<Metadata = U::Metadata>,
+{
+}
+// Safety: pointers can be cast to other pointer types
+unsafe impl<T, U> SimdCastPtr<T> for *mut U
+where
+ U: core::ptr::Pointee,
+ T: core::ptr::Pointee<Metadata = U::Metadata>,
+{
+}
diff --git a/library/portable-simd/crates/core_simd/src/elements.rs b/library/portable-simd/crates/core_simd/src/elements.rs
index 701eb66b248..dc7f52a4d57 100644
--- a/library/portable-simd/crates/core_simd/src/elements.rs
+++ b/library/portable-simd/crates/core_simd/src/elements.rs
@@ -1,11 +1,15 @@
+mod const_ptr;
mod float;
mod int;
+mod mut_ptr;
mod uint;
mod sealed {
pub trait Sealed {}
}
+pub use const_ptr::*;
pub use float::*;
pub use int::*;
+pub use mut_ptr::*;
pub use uint::*;
diff --git a/library/portable-simd/crates/core_simd/src/elements/const_ptr.rs b/library/portable-simd/crates/core_simd/src/elements/const_ptr.rs
new file mode 100644
index 00000000000..0ef9802b5e2
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/src/elements/const_ptr.rs
@@ -0,0 +1,141 @@
+use super::sealed::Sealed;
+use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdPartialEq, SupportedLaneCount};
+
+/// Operations on SIMD vectors of constant pointers.
+pub trait SimdConstPtr: Copy + Sealed {
+ /// Vector of `usize` with the same number of lanes.
+ type Usize;
+
+ /// Vector of `isize` with the same number of lanes.
+ type Isize;
+
+ /// Vector of mutable pointers to the same type.
+ type MutPtr;
+
+ /// Mask type used for manipulating this SIMD vector type.
+ type Mask;
+
+ /// Returns `true` for each lane that is null.
+ fn is_null(self) -> Self::Mask;
+
+ /// Changes constness without changing the type.
+ ///
+ /// Equivalent to calling [`pointer::cast_mut`] on each lane.
+ fn cast_mut(self) -> Self::MutPtr;
+
+ /// Gets the "address" portion of the pointer.
+ ///
+ /// This method discards pointer semantic metadata, so the result cannot be
+ /// directly cast into a valid pointer.
+ ///
+ /// This method semantically discards *provenance* and
+ /// *address-space* information. To properly restore that information, use [`Self::with_addr`].
+ ///
+ /// Equivalent to calling [`pointer::addr`] on each lane.
+ fn addr(self) -> Self::Usize;
+
+ /// Creates a new pointer with the given address.
+ ///
+ /// This performs the same operation as a cast, but copies the *address-space* and
+ /// *provenance* of `self` to the new pointer.
+ ///
+ /// Equivalent to calling [`pointer::with_addr`] on each lane.
+ fn with_addr(self, addr: Self::Usize) -> Self;
+
+ /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use
+ /// in [`Self::from_exposed_addr`].
+ fn expose_addr(self) -> Self::Usize;
+
+ /// Convert an address back to a pointer, picking up a previously "exposed" provenance.
+ ///
+ /// Equivalent to calling [`core::ptr::from_exposed_addr`] on each lane.
+ fn from_exposed_addr(addr: Self::Usize) -> Self;
+
+ /// Calculates the offset from a pointer using wrapping arithmetic.
+ ///
+ /// Equivalent to calling [`pointer::wrapping_offset`] on each lane.
+ fn wrapping_offset(self, offset: Self::Isize) -> Self;
+
+ /// Calculates the offset from a pointer using wrapping arithmetic.
+ ///
+ /// Equivalent to calling [`pointer::wrapping_add`] on each lane.
+ fn wrapping_add(self, count: Self::Usize) -> Self;
+
+ /// Calculates the offset from a pointer using wrapping arithmetic.
+ ///
+ /// Equivalent to calling [`pointer::wrapping_sub`] on each lane.
+ fn wrapping_sub(self, count: Self::Usize) -> Self;
+}
+
+impl<T, const LANES: usize> Sealed for Simd<*const T, LANES> where
+ LaneCount<LANES>: SupportedLaneCount
+{
+}
+
+impl<T, const LANES: usize> SimdConstPtr for Simd<*const T, LANES>
+where
+ LaneCount<LANES>: SupportedLaneCount,
+{
+ type Usize = Simd<usize, LANES>;
+ type Isize = Simd<isize, LANES>;
+ type MutPtr = Simd<*mut T, LANES>;
+ type Mask = Mask<isize, LANES>;
+
+ #[inline]
+ fn is_null(self) -> Self::Mask {
+ Simd::splat(core::ptr::null()).simd_eq(self)
+ }
+
+ #[inline]
+ fn cast_mut(self) -> Self::MutPtr {
+ self.cast_ptr()
+ }
+
+ #[inline]
+ fn addr(self) -> Self::Usize {
+ // 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_copy(&self) }
+ }
+
+ #[inline]
+ fn with_addr(self, addr: Self::Usize) -> Self {
+ // 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.
+ self.cast_ptr::<*const u8>()
+ .wrapping_offset(addr.cast::<isize>() - self.addr().cast::<isize>())
+ .cast_ptr()
+ }
+
+ #[inline]
+ fn expose_addr(self) -> Self::Usize {
+ // Safety: `self` is a pointer vector
+ unsafe { intrinsics::simd_expose_addr(self) }
+ }
+
+ #[inline]
+ fn from_exposed_addr(addr: Self::Usize) -> Self {
+ // Safety: `self` is a pointer vector
+ unsafe { intrinsics::simd_from_exposed_addr(addr) }
+ }
+
+ #[inline]
+ fn wrapping_offset(self, count: Self::Isize) -> Self {
+ // Safety: simd_arith_offset takes a vector of pointers and a vector of offsets
+ unsafe { intrinsics::simd_arith_offset(self, count) }
+ }
+
+ #[inline]
+ fn wrapping_add(self, count: Self::Usize) -> Self {
+ self.wrapping_offset(count.cast())
+ }
+
+ #[inline]
+ fn wrapping_sub(self, count: Self::Usize) -> Self {
+ self.wrapping_offset(-count.cast::<isize>())
+ }
+}
diff --git a/library/portable-simd/crates/core_simd/src/elements/mut_ptr.rs b/library/portable-simd/crates/core_simd/src/elements/mut_ptr.rs
new file mode 100644
index 00000000000..d87986b4a09
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/src/elements/mut_ptr.rs
@@ -0,0 +1,136 @@
+use super::sealed::Sealed;
+use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdPartialEq, SupportedLaneCount};
+
+/// Operations on SIMD vectors of mutable pointers.
+pub trait SimdMutPtr: Copy + Sealed {
+ /// Vector of `usize` with the same number of lanes.
+ type Usize;
+
+ /// Vector of `isize` with the same number of lanes.
+ type Isize;
+
+ /// Vector of constant pointers to the same type.
+ type ConstPtr;
+
+ /// Mask type used for manipulating this SIMD vector type.
+ type Mask;
+
+ /// Returns `true` for each lane that is null.
+ fn is_null(self) -> Self::Mask;
+
+ /// Changes constness without changing the type.
+ ///
+ /// Equivalent to calling [`pointer::cast_const`] on each lane.
+ fn cast_const(self) -> Self::ConstPtr;
+
+ /// Gets the "address" portion of the pointer.
+ ///
+ /// This method discards pointer semantic metadata, so the result cannot be
+ /// directly cast into a valid pointer.
+ ///
+ /// Equivalent to calling [`pointer::addr`] on each lane.
+ fn addr(self) -> Self::Usize;
+
+ /// Creates a new pointer with the given address.
+ ///
+ /// This performs the same operation as a cast, but copies the *address-space* and
+ /// *provenance* of `self` to the new pointer.
+ ///
+ /// Equivalent to calling [`pointer::with_addr`] on each lane.
+ fn with_addr(self, addr: Self::Usize) -> Self;
+
+ /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use
+ /// in [`Self::from_exposed_addr`].
+ fn expose_addr(self) -> Self::Usize;
+
+ /// Convert an address back to a pointer, picking up a previously "exposed" provenance.
+ ///
+ /// Equivalent to calling [`core::ptr::from_exposed_addr_mut`] on each lane.
+ fn from_exposed_addr(addr: Self::Usize) -> Self;
+
+ /// Calculates the offset from a pointer using wrapping arithmetic.
+ ///
+ /// Equivalent to calling [`pointer::wrapping_offset`] on each lane.
+ fn wrapping_offset(self, offset: Self::Isize) -> Self;
+
+ /// Calculates the offset from a pointer using wrapping arithmetic.
+ ///
+ /// Equivalent to calling [`pointer::wrapping_add`] on each lane.
+ fn wrapping_add(self, count: Self::Usize) -> Self;
+
+ /// Calculates the offset from a pointer using wrapping arithmetic.
+ ///
+ /// Equivalent to calling [`pointer::wrapping_sub`] on each lane.
+ fn wrapping_sub(self, count: Self::Usize) -> Self;
+}
+
+impl<T, const LANES: usize> Sealed for Simd<*mut T, LANES> where LaneCount<LANES>: SupportedLaneCount
+{}
+
+impl<T, const LANES: usize> SimdMutPtr for Simd<*mut T, LANES>
+where
+ LaneCount<LANES>: SupportedLaneCount,
+{
+ type Usize = Simd<usize, LANES>;
+ type Isize = Simd<isize, LANES>;
+ type ConstPtr = Simd<*const T, LANES>;
+ type Mask = Mask<isize, LANES>;
+
+ #[inline]
+ fn is_null(self) -> Self::Mask {
+ Simd::splat(core::ptr::null_mut()).simd_eq(self)
+ }
+
+ #[inline]
+ fn cast_const(self) -> Self::ConstPtr {
+ self.cast_ptr()
+ }
+
+ #[inline]
+ fn addr(self) -> Self::Usize {
+ // 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_copy(&self) }
+ }
+
+ #[inline]
+ fn with_addr(self, addr: Self::Usize) -> Self {
+ // 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.
+ self.cast_ptr::<*mut u8>()
+ .wrapping_offset(addr.cast::<isize>() - self.addr().cast::<isize>())
+ .cast_ptr()
+ }
+
+ #[inline]
+ fn expose_addr(self) -> Self::Usize {
+ // Safety: `self` is a pointer vector
+ unsafe { intrinsics::simd_expose_addr(self) }
+ }
+
+ #[inline]
+ fn from_exposed_addr(addr: Self::Usize) -> Self {
+ // Safety: `self` is a pointer vector
+ unsafe { intrinsics::simd_from_exposed_addr(addr) }
+ }
+
+ #[inline]
+ fn wrapping_offset(self, count: Self::Isize) -> Self {
+ // Safety: simd_arith_offset takes a vector of pointers and a vector of offsets
+ unsafe { intrinsics::simd_arith_offset(self, count) }
+ }
+
+ #[inline]
+ fn wrapping_add(self, count: Self::Usize) -> Self {
+ self.wrapping_offset(count.cast())
+ }
+
+ #[inline]
+ fn wrapping_sub(self, count: Self::Usize) -> Self {
+ self.wrapping_offset(-count.cast::<isize>())
+ }
+}
diff --git a/library/portable-simd/crates/core_simd/src/eq.rs b/library/portable-simd/crates/core_simd/src/eq.rs
index c7111f720a8..80763c07272 100644
--- a/library/portable-simd/crates/core_simd/src/eq.rs
+++ b/library/portable-simd/crates/core_simd/src/eq.rs
@@ -1,4 +1,6 @@
-use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdElement, SupportedLaneCount};
+use crate::simd::{
+ intrinsics, LaneCount, Mask, Simd, SimdConstPtr, SimdElement, SimdMutPtr, SupportedLaneCount,
+};
/// Parallel `PartialEq`.
pub trait SimdPartialEq {
@@ -71,3 +73,37 @@ macro_rules! impl_mask {
}
impl_mask! { i8, i16, i32, i64, isize }
+
+impl<T, const LANES: usize> SimdPartialEq for Simd<*const T, LANES>
+where
+ LaneCount<LANES>: SupportedLaneCount,
+{
+ type Mask = Mask<isize, LANES>;
+
+ #[inline]
+ fn simd_eq(self, other: Self) -> Self::Mask {
+ self.addr().simd_eq(other.addr())
+ }
+
+ #[inline]
+ fn simd_ne(self, other: Self) -> Self::Mask {
+ self.addr().simd_ne(other.addr())
+ }
+}
+
+impl<T, const LANES: usize> SimdPartialEq for Simd<*mut T, LANES>
+where
+ LaneCount<LANES>: SupportedLaneCount,
+{
+ type Mask = Mask<isize, LANES>;
+
+ #[inline]
+ fn simd_eq(self, other: Self) -> Self::Mask {
+ self.addr().simd_eq(other.addr())
+ }
+
+ #[inline]
+ fn simd_ne(self, other: Self) -> Self::Mask {
+ self.addr().simd_ne(other.addr())
+ }
+}
diff --git a/library/portable-simd/crates/core_simd/src/fmt.rs b/library/portable-simd/crates/core_simd/src/fmt.rs
index dbd9839c4bf..b7317969cbb 100644
--- a/library/portable-simd/crates/core_simd/src/fmt.rs
+++ b/library/portable-simd/crates/core_simd/src/fmt.rs
@@ -1,39 +1,21 @@
use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount};
use core::fmt;
-macro_rules! impl_fmt_trait {
- { $($trait:ident,)* } => {
- $(
- impl<T, const LANES: usize> fmt::$trait for Simd<T, LANES>
- where
- LaneCount<LANES>: SupportedLaneCount,
- T: SimdElement + fmt::$trait,
- {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- #[repr(transparent)]
- struct Wrapper<'a, T: fmt::$trait>(&'a T);
-
- impl<T: fmt::$trait> fmt::Debug for Wrapper<'_, T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0.fmt(f)
- }
- }
-
- f.debug_list()
- .entries(self.as_array().iter().map(|x| Wrapper(x)))
- .finish()
- }
- }
- )*
+impl<T, const LANES: usize> fmt::Debug for Simd<T, LANES>
+where
+ LaneCount<LANES>: SupportedLaneCount,
+ T: SimdElement + fmt::Debug,
+{
+ /// A `Simd<T, N>` has a debug format like the one for `[T]`:
+ /// ```
+ /// # #![feature(portable_simd)]
+ /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd;
+ /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd;
+ /// let floats = Simd::<f32, 4>::splat(-1.0);
+ /// assert_eq!(format!("{:?}", [-1.0; 4]), format!("{:?}", floats));
+ /// ```
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ <[T] as fmt::Debug>::fmt(self.as_array(), f)
}
}
-
-impl_fmt_trait! {
- Debug,
- Binary,
- LowerExp,
- UpperExp,
- Octal,
- LowerHex,
- UpperHex,
-}
diff --git a/library/portable-simd/crates/core_simd/src/intrinsics.rs b/library/portable-simd/crates/core_simd/src/intrinsics.rs
index 704e6ed0159..dd6698e2ba5 100644
--- a/library/portable-simd/crates/core_simd/src/intrinsics.rs
+++ b/library/portable-simd/crates/core_simd/src/intrinsics.rs
@@ -61,9 +61,6 @@ extern "platform-intrinsic" {
/// xor
pub(crate) fn simd_xor<T>(x: T, y: T) -> T;
- /// getelementptr (without inbounds)
- pub(crate) fn simd_arith_offset<T, U>(ptrs: T, offsets: U) -> T;
-
/// fptoui/fptosi/uitofp/sitofp
/// casting floats to integers is truncating, so it is safe to convert values like e.g. 1.5
/// but the truncated value must fit in the target type or the result is poison.
@@ -150,4 +147,17 @@ extern "platform-intrinsic" {
pub(crate) fn simd_select<M, T>(m: M, yes: T, no: T) -> T;
#[allow(unused)]
pub(crate) fn simd_select_bitmask<M, T>(m: M, yes: T, no: T) -> T;
+
+ /// getelementptr (without inbounds)
+ /// equivalent to wrapping_offset
+ pub(crate) fn simd_arith_offset<T, U>(ptr: T, offset: U) -> T;
+
+ /// equivalent to `T as U` semantics, specifically for pointers
+ pub(crate) fn simd_cast_ptr<T, U>(ptr: T) -> U;
+
+ /// expose a pointer as an address
+ pub(crate) fn simd_expose_addr<T, U>(ptr: T) -> U;
+
+ /// convert an exposed address back to a pointer
+ pub(crate) fn simd_from_exposed_addr<T, U>(addr: T) -> U;
}
diff --git a/library/portable-simd/crates/core_simd/src/lane_count.rs b/library/portable-simd/crates/core_simd/src/lane_count.rs
index 63723e2ec13..2b91eb9e800 100644
--- a/library/portable-simd/crates/core_simd/src/lane_count.rs
+++ b/library/portable-simd/crates/core_simd/src/lane_count.rs
@@ -23,24 +23,20 @@ pub trait SupportedLaneCount: Sealed {
impl<const LANES: usize> Sealed for LaneCount<LANES> {}
-impl SupportedLaneCount for LaneCount<1> {
- type BitMask = [u8; 1];
-}
-impl SupportedLaneCount for LaneCount<2> {
- type BitMask = [u8; 1];
-}
-impl SupportedLaneCount for LaneCount<4> {
- type BitMask = [u8; 1];
-}
-impl SupportedLaneCount for LaneCount<8> {
- type BitMask = [u8; 1];
-}
-impl SupportedLaneCount for LaneCount<16> {
- type BitMask = [u8; 2];
-}
-impl SupportedLaneCount for LaneCount<32> {
- type BitMask = [u8; 4];
-}
-impl SupportedLaneCount for LaneCount<64> {
- type BitMask = [u8; 8];
+macro_rules! supported_lane_count {
+ ($($lanes:literal),+) => {
+ $(
+ impl SupportedLaneCount for LaneCount<$lanes> {
+ type BitMask = [u8; ($lanes + 7) / 8];
+ }
+ )+
+ };
}
+
+supported_lane_count!(1, 2, 4, 8, 16, 32, 64);
+#[cfg(feature = "all_lane_counts")]
+supported_lane_count!(
+ 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63
+);
diff --git a/library/portable-simd/crates/core_simd/src/lib.rs b/library/portable-simd/crates/core_simd/src/lib.rs
index 715f258f617..e5307de2155 100644
--- a/library/portable-simd/crates/core_simd/src/lib.rs
+++ b/library/portable-simd/crates/core_simd/src/lib.rs
@@ -1,5 +1,8 @@
#![no_std]
#![feature(
+ const_refs_to_cell,
+ const_maybe_uninit_as_mut_ptr,
+ const_mut_refs,
convert_float_to_int,
decl_macro,
intra_doc_pointers,
@@ -7,7 +10,9 @@
repr_simd,
simd_ffi,
staged_api,
- stdsimd
+ stdsimd,
+ strict_provenance,
+ ptr_metadata
)]
#![cfg_attr(feature = "generic_const_exprs", feature(generic_const_exprs))]
#![cfg_attr(feature = "generic_const_exprs", allow(incomplete_features))]
@@ -19,4 +24,3 @@
#[path = "mod.rs"]
mod core_simd;
pub use self::core_simd::simd;
-pub use simd::*;
diff --git a/library/portable-simd/crates/core_simd/src/masks.rs b/library/portable-simd/crates/core_simd/src/masks.rs
index c36c336d8a2..e0f3c7beef6 100644
--- a/library/portable-simd/crates/core_simd/src/masks.rs
+++ b/library/portable-simd/crates/core_simd/src/masks.rs
@@ -55,6 +55,7 @@ pub unsafe trait MaskElement: SimdElement + Sealed {}
macro_rules! impl_element {
{ $ty:ty } => {
impl Sealed for $ty {
+ #[inline]
fn valid<const LANES: usize>(value: Simd<Self, LANES>) -> bool
where
LaneCount<LANES>: SupportedLaneCount,
@@ -62,6 +63,7 @@ macro_rules! impl_element {
(value.simd_eq(Simd::splat(0 as _)) | value.simd_eq(Simd::splat(-1 as _))).all()
}
+ #[inline]
fn eq(self, other: Self) -> bool { self == other }
const TRUE: Self = -1;
@@ -83,8 +85,10 @@ impl_element! { isize }
///
/// Masks represent boolean inclusion/exclusion on a per-lane basis.
///
-/// The layout of this type is unspecified.
-#[repr(transparent)]
+/// The layout of this type is unspecified, and may change between platforms
+/// and/or Rust versions, and code should not assume that it is equivalent to
+/// `[T; LANES]`.
+#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
pub struct Mask<T, const LANES: usize>(mask_impl::Mask<T, LANES>)
where
T: MaskElement,
@@ -102,6 +106,7 @@ where
T: MaskElement,
LaneCount<LANES>: SupportedLaneCount,
{
+ #[inline]
fn clone(&self) -> Self {
*self
}
@@ -113,11 +118,13 @@ where
LaneCount<LANES>: SupportedLaneCount,
{
/// Construct a mask by setting all lanes to the given value.
+ #[inline]
pub fn splat(value: bool) -> Self {
Self(mask_impl::Mask::splat(value))
}
/// Converts an array of bools to a SIMD mask.
+ #[inline]
pub fn from_array(array: [bool; LANES]) -> Self {
// SAFETY: Rust's bool has a layout of 1 byte (u8) with a value of
// true: 0b_0000_0001
@@ -134,6 +141,7 @@ where
}
/// Converts a SIMD mask to an array of bools.
+ #[inline]
pub fn to_array(self) -> [bool; LANES] {
// This follows mostly the same logic as from_array.
// SAFETY: Rust's bool has a layout of 1 byte (u8) with a value of
@@ -261,6 +269,7 @@ where
T: MaskElement,
LaneCount<LANES>: SupportedLaneCount,
{
+ #[inline]
fn from(array: [bool; LANES]) -> Self {
Self::from_array(array)
}
@@ -271,6 +280,7 @@ where
T: MaskElement,
LaneCount<LANES>: SupportedLaneCount,
{
+ #[inline]
fn from(vector: Mask<T, LANES>) -> Self {
vector.to_array()
}
@@ -520,60 +530,6 @@ where
}
}
-/// A mask for SIMD vectors with eight elements of 8 bits.
-pub type mask8x8 = Mask<i8, 8>;
-
-/// A mask for SIMD vectors with 16 elements of 8 bits.
-pub type mask8x16 = Mask<i8, 16>;
-
-/// A mask for SIMD vectors with 32 elements of 8 bits.
-pub type mask8x32 = Mask<i8, 32>;
-
-/// A mask for SIMD vectors with 64 elements of 8 bits.
-pub type mask8x64 = Mask<i8, 64>;
-
-/// A mask for SIMD vectors with four elements of 16 bits.
-pub type mask16x4 = Mask<i16, 4>;
-
-/// A mask for SIMD vectors with eight elements of 16 bits.
-pub type mask16x8 = Mask<i16, 8>;
-
-/// A mask for SIMD vectors with 16 elements of 16 bits.
-pub type mask16x16 = Mask<i16, 16>;
-
-/// A mask for SIMD vectors with 32 elements of 16 bits.
-pub type mask16x32 = Mask<i16, 32>;
-
-/// A mask for SIMD vectors with two elements of 32 bits.
-pub type mask32x2 = Mask<i32, 2>;
-
-/// A mask for SIMD vectors with four elements of 32 bits.
-pub type mask32x4 = Mask<i32, 4>;
-
-/// A mask for SIMD vectors with eight elements of 32 bits.
-pub type mask32x8 = Mask<i32, 8>;
-
-/// A mask for SIMD vectors with 16 elements of 32 bits.
-pub type mask32x16 = Mask<i32, 16>;
-
-/// A mask for SIMD vectors with two elements of 64 bits.
-pub type mask64x2 = Mask<i64, 2>;
-
-/// A mask for SIMD vectors with four elements of 64 bits.
-pub type mask64x4 = Mask<i64, 4>;
-
-/// A mask for SIMD vectors with eight elements of 64 bits.
-pub type mask64x8 = Mask<i64, 8>;
-
-/// A mask for SIMD vectors with two elements of pointer width.
-pub type masksizex2 = Mask<isize, 2>;
-
-/// A mask for SIMD vectors with four elements of pointer width.
-pub type masksizex4 = Mask<isize, 4>;
-
-/// A mask for SIMD vectors with eight elements of pointer width.
-pub type masksizex8 = Mask<isize, 8>;
-
macro_rules! impl_from {
{ $from:ty => $($to:ty),* } => {
$(
@@ -581,6 +537,7 @@ macro_rules! impl_from {
where
LaneCount<LANES>: SupportedLaneCount,
{
+ #[inline]
fn from(value: Mask<$from, LANES>) -> Self {
value.cast()
}
diff --git a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs
index 365ecc0a325..20465ba9b07 100644
--- a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs
+++ b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs
@@ -26,6 +26,7 @@ where
T: MaskElement,
LaneCount<LANES>: SupportedLaneCount,
{
+ #[inline]
fn clone(&self) -> Self {
*self
}
@@ -36,6 +37,7 @@ where
T: MaskElement,
LaneCount<LANES>: SupportedLaneCount,
{
+ #[inline]
fn eq(&self, other: &Self) -> bool {
self.0.as_ref() == other.0.as_ref()
}
@@ -46,6 +48,7 @@ where
T: MaskElement,
LaneCount<LANES>: SupportedLaneCount,
{
+ #[inline]
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
self.0.as_ref().partial_cmp(other.0.as_ref())
}
@@ -63,6 +66,7 @@ where
T: MaskElement,
LaneCount<LANES>: SupportedLaneCount,
{
+ #[inline]
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.0.as_ref().cmp(other.0.as_ref())
}
diff --git a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs
index b5ba198e504..1d13c45b8e7 100644
--- a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs
+++ b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs
@@ -37,6 +37,7 @@ where
T: MaskElement + PartialEq,
LaneCount<LANES>: SupportedLaneCount,
{
+ #[inline]
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
@@ -47,6 +48,7 @@ where
T: MaskElement + PartialOrd,
LaneCount<LANES>: SupportedLaneCount,
{
+ #[inline]
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
@@ -64,6 +66,7 @@ where
T: MaskElement + Ord,
LaneCount<LANES>: SupportedLaneCount,
{
+ #[inline]
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.0.cmp(&other.0)
}
@@ -262,6 +265,7 @@ where
T: MaskElement,
LaneCount<LANES>: SupportedLaneCount,
{
+ #[inline]
fn from(value: Mask<T, LANES>) -> Self {
value.0
}
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 2235f016c71..fc7d6b781f2 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
@@ -48,10 +48,12 @@ macro_rules! impl_integer_intrinsic {
impl<T: MaskElement> ToBitMask for Mask<T, $lanes> {
type BitMask = $int;
+ #[inline]
fn to_bitmask(self) -> $int {
self.0.to_bitmask_integer()
}
+ #[inline]
fn from_bitmask(bitmask: $int) -> Self {
Self(mask_impl::Mask::from_bitmask_integer(bitmask))
}
@@ -83,10 +85,12 @@ where
{
const BYTES: usize = bitmask_len(LANES);
+ #[inline]
fn to_bitmask_array(self) -> [u8; Self::BYTES] {
self.0.to_bitmask_array()
}
+ #[inline]
fn from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self {
Mask(mask_impl::Mask::from_bitmask_array(bitmask))
}
diff --git a/library/portable-simd/crates/core_simd/src/mod.rs b/library/portable-simd/crates/core_simd/src/mod.rs
index b472aa3abe2..35c659b7a42 100644
--- a/library/portable-simd/crates/core_simd/src/mod.rs
+++ b/library/portable-simd/crates/core_simd/src/mod.rs
@@ -6,6 +6,8 @@ pub(crate) mod intrinsics;
#[cfg(feature = "generic_const_exprs")]
mod to_bytes;
+mod alias;
+mod cast;
mod elements;
mod eq;
mod fmt;
@@ -15,6 +17,7 @@ mod masks;
mod ops;
mod ord;
mod select;
+mod swizzle_dyn;
mod vector;
mod vendor;
@@ -22,11 +25,14 @@ mod vendor;
pub mod simd {
pub(crate) use crate::core_simd::intrinsics;
+ pub use crate::core_simd::alias::*;
+ pub use crate::core_simd::cast::*;
pub use crate::core_simd::elements::*;
pub use crate::core_simd::eq::*;
pub use crate::core_simd::lane_count::{LaneCount, SupportedLaneCount};
pub use crate::core_simd::masks::*;
pub use crate::core_simd::ord::*;
pub use crate::core_simd::swizzle::*;
+ pub use crate::core_simd::swizzle_dyn::*;
pub use crate::core_simd::vector::*;
}
diff --git a/library/portable-simd/crates/core_simd/src/ord.rs b/library/portable-simd/crates/core_simd/src/ord.rs
index 9a87bc2e344..1ae9cd061fb 100644
--- a/library/portable-simd/crates/core_simd/src/ord.rs
+++ b/library/portable-simd/crates/core_simd/src/ord.rs
@@ -1,4 +1,6 @@
-use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdPartialEq, SupportedLaneCount};
+use crate::simd::{
+ intrinsics, LaneCount, Mask, Simd, SimdConstPtr, SimdMutPtr, SimdPartialEq, SupportedLaneCount,
+};
/// Parallel `PartialOrd`.
pub trait SimdPartialOrd: SimdPartialEq {
@@ -211,3 +213,101 @@ macro_rules! impl_mask {
}
impl_mask! { i8, i16, i32, i64, isize }
+
+impl<T, const LANES: usize> SimdPartialOrd for Simd<*const T, LANES>
+where
+ LaneCount<LANES>: SupportedLaneCount,
+{
+ #[inline]
+ fn simd_lt(self, other: Self) -> Self::Mask {
+ self.addr().simd_lt(other.addr())
+ }
+
+ #[inline]
+ fn simd_le(self, other: Self) -> Self::Mask {
+ self.addr().simd_le(other.addr())
+ }
+
+ #[inline]
+ fn simd_gt(self, other: Self) -> Self::Mask {
+ self.addr().simd_gt(other.addr())
+ }
+
+ #[inline]
+ fn simd_ge(self, other: Self) -> Self::Mask {
+ self.addr().simd_ge(other.addr())
+ }
+}
+
+impl<T, const LANES: usize> SimdOrd for Simd<*const T, LANES>
+where
+ LaneCount<LANES>: SupportedLaneCount,
+{
+ #[inline]
+ fn simd_max(self, other: Self) -> Self {
+ self.simd_lt(other).select(other, self)
+ }
+
+ #[inline]
+ fn simd_min(self, other: Self) -> Self {
+ self.simd_gt(other).select(other, self)
+ }
+
+ #[inline]
+ fn simd_clamp(self, min: Self, max: Self) -> Self {
+ assert!(
+ min.simd_le(max).all(),
+ "each lane in `min` must be less than or equal to the corresponding lane in `max`",
+ );
+ self.simd_max(min).simd_min(max)
+ }
+}
+
+impl<T, const LANES: usize> SimdPartialOrd for Simd<*mut T, LANES>
+where
+ LaneCount<LANES>: SupportedLaneCount,
+{
+ #[inline]
+ fn simd_lt(self, other: Self) -> Self::Mask {
+ self.addr().simd_lt(other.addr())
+ }
+
+ #[inline]
+ fn simd_le(self, other: Self) -> Self::Mask {
+ self.addr().simd_le(other.addr())
+ }
+
+ #[inline]
+ fn simd_gt(self, other: Self) -> Self::Mask {
+ self.addr().simd_gt(other.addr())
+ }
+
+ #[inline]
+ fn simd_ge(self, other: Self) -> Self::Mask {
+ self.addr().simd_ge(other.addr())
+ }
+}
+
+impl<T, const LANES: usize> SimdOrd for Simd<*mut T, LANES>
+where
+ LaneCount<LANES>: SupportedLaneCount,
+{
+ #[inline]
+ fn simd_max(self, other: Self) -> Self {
+ self.simd_lt(other).select(other, self)
+ }
+
+ #[inline]
+ fn simd_min(self, other: Self) -> Self {
+ self.simd_gt(other).select(other, self)
+ }
+
+ #[inline]
+ fn simd_clamp(self, min: Self, max: Self) -> Self {
+ assert!(
+ min.simd_le(max).all(),
+ "each lane in `min` must be less than or equal to the corresponding lane in `max`",
+ );
+ self.simd_max(min).simd_min(max)
+ }
+}
diff --git a/library/portable-simd/crates/core_simd/src/swizzle.rs b/library/portable-simd/crates/core_simd/src/swizzle.rs
index 22999d24950..68f20516cf5 100644
--- a/library/portable-simd/crates/core_simd/src/swizzle.rs
+++ b/library/portable-simd/crates/core_simd/src/swizzle.rs
@@ -265,16 +265,13 @@ where
/// Interleave two vectors.
///
- /// Produces two vectors with lanes taken alternately from `self` and `other`.
+ /// The resulting vectors contain lanes taken alternatively from `self` and `other`, first
+ /// filling the first result, and then the second.
///
- /// The first result contains the first `LANES / 2` lanes from `self` and `other`,
- /// alternating, starting with the first lane of `self`.
- ///
- /// The second result contains the last `LANES / 2` lanes from `self` and `other`,
- /// alternating, starting with the lane `LANES / 2` from the start of `self`.
+ /// The reverse of this operation is [`Simd::deinterleave`].
///
/// ```
- /// #![feature(portable_simd)]
+ /// # #![feature(portable_simd)]
/// # use core::simd::Simd;
/// let a = Simd::from_array([0, 1, 2, 3]);
/// let b = Simd::from_array([4, 5, 6, 7]);
@@ -285,29 +282,17 @@ where
#[inline]
#[must_use = "method returns a new vector and does not mutate the original inputs"]
pub fn interleave(self, other: Self) -> (Self, Self) {
- const fn lo<const LANES: usize>() -> [Which; LANES] {
- let mut idx = [Which::First(0); LANES];
- let mut i = 0;
- while i < LANES {
- let offset = i / 2;
- idx[i] = if i % 2 == 0 {
- Which::First(offset)
- } else {
- Which::Second(offset)
- };
- i += 1;
- }
- idx
- }
- const fn hi<const LANES: usize>() -> [Which; LANES] {
+ const fn interleave<const LANES: usize>(high: bool) -> [Which; LANES] {
let mut idx = [Which::First(0); LANES];
let mut i = 0;
while i < LANES {
- let offset = (LANES + i) / 2;
- idx[i] = if i % 2 == 0 {
- Which::First(offset)
+ // Treat the source as a concatenated vector
+ let dst_index = if high { i + LANES } else { i };
+ let src_index = dst_index / 2 + (dst_index % 2) * LANES;
+ idx[i] = if src_index < LANES {
+ Which::First(src_index)
} else {
- Which::Second(offset)
+ Which::Second(src_index % LANES)
};
i += 1;
}
@@ -318,11 +303,11 @@ where
struct Hi;
impl<const LANES: usize> Swizzle2<LANES, LANES> for Lo {
- const INDEX: [Which; LANES] = lo::<LANES>();
+ const INDEX: [Which; LANES] = interleave::<LANES>(false);
}
impl<const LANES: usize> Swizzle2<LANES, LANES> for Hi {
- const INDEX: [Which; LANES] = hi::<LANES>();
+ const INDEX: [Which; LANES] = interleave::<LANES>(true);
}
(Lo::swizzle2(self, other), Hi::swizzle2(self, other))
@@ -336,8 +321,10 @@ where
/// The second result takes every other lane of `self` and then `other`, starting with
/// the second lane.
///
+ /// The reverse of this operation is [`Simd::interleave`].
+ ///
/// ```
- /// #![feature(portable_simd)]
+ /// # #![feature(portable_simd)]
/// # use core::simd::Simd;
/// let a = Simd::from_array([0, 4, 1, 5]);
/// let b = Simd::from_array([2, 6, 3, 7]);
@@ -348,22 +335,17 @@ where
#[inline]
#[must_use = "method returns a new vector and does not mutate the original inputs"]
pub fn deinterleave(self, other: Self) -> (Self, Self) {
- const fn even<const LANES: usize>() -> [Which; LANES] {
- let mut idx = [Which::First(0); LANES];
- let mut i = 0;
- while i < LANES / 2 {
- idx[i] = Which::First(2 * i);
- idx[i + LANES / 2] = Which::Second(2 * i);
- i += 1;
- }
- idx
- }
- const fn odd<const LANES: usize>() -> [Which; LANES] {
+ const fn deinterleave<const LANES: usize>(second: bool) -> [Which; LANES] {
let mut idx = [Which::First(0); LANES];
let mut i = 0;
- while i < LANES / 2 {
- idx[i] = Which::First(2 * i + 1);
- idx[i + LANES / 2] = Which::Second(2 * i + 1);
+ while i < LANES {
+ // Treat the source as a concatenated vector
+ let src_index = i * 2 + second as usize;
+ idx[i] = if src_index < LANES {
+ Which::First(src_index)
+ } else {
+ Which::Second(src_index % LANES)
+ };
i += 1;
}
idx
@@ -373,11 +355,11 @@ where
struct Odd;
impl<const LANES: usize> Swizzle2<LANES, LANES> for Even {
- const INDEX: [Which; LANES] = even::<LANES>();
+ const INDEX: [Which; LANES] = deinterleave::<LANES>(false);
}
impl<const LANES: usize> Swizzle2<LANES, LANES> for Odd {
- const INDEX: [Which; LANES] = odd::<LANES>();
+ const INDEX: [Which; LANES] = deinterleave::<LANES>(true);
}
(Even::swizzle2(self, other), Odd::swizzle2(self, other))
diff --git a/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs b/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs
new file mode 100644
index 00000000000..6065d645937
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs
@@ -0,0 +1,157 @@
+use crate::simd::{LaneCount, Simd, SupportedLaneCount};
+use core::mem;
+
+impl<const N: usize> Simd<u8, N>
+where
+ LaneCount<N>: SupportedLaneCount,
+{
+ /// Swizzle a vector of bytes according to the index vector.
+ /// Indices within range select the appropriate byte.
+ /// Indices "out of bounds" instead select 0.
+ ///
+ /// Note that the current implementation is selected during build-time
+ /// of the standard library, so `cargo build -Zbuild-std` may be necessary
+ /// to unlock better performance, especially for larger vectors.
+ /// A planned compiler improvement will enable using `#[target_feature]` instead.
+ #[inline]
+ pub fn swizzle_dyn(self, idxs: Simd<u8, N>) -> Self {
+ #![allow(unused_imports, unused_unsafe)]
+ #[cfg(target_arch = "aarch64")]
+ use core::arch::aarch64::{uint8x8_t, vqtbl1q_u8, vtbl1_u8};
+ #[cfg(all(target_arch = "arm", target_feature = "v7", target_feature = "neon"))]
+ use core::arch::arm::{uint8x8_t, vtbl1_u8};
+ #[cfg(target_arch = "wasm32")]
+ use core::arch::wasm32 as wasm;
+ #[cfg(target_arch = "x86")]
+ use core::arch::x86;
+ #[cfg(target_arch = "x86_64")]
+ use core::arch::x86_64 as x86;
+ // SAFETY: Intrinsics covered by cfg
+ unsafe {
+ match N {
+ #[cfg(target_feature = "neon")]
+ 8 => transize(vtbl1_u8, self, idxs),
+ #[cfg(target_feature = "ssse3")]
+ 16 => transize(x86::_mm_shuffle_epi8, self, idxs),
+ #[cfg(target_feature = "simd128")]
+ 16 => transize(wasm::i8x16_swizzle, self, idxs),
+ #[cfg(all(target_arch = "aarch64", target_feature = "neon"))]
+ 16 => transize(vqtbl1q_u8, self, idxs),
+ #[cfg(all(target_feature = "avx2", not(target_feature = "avx512vbmi")))]
+ 32 => transize_raw(avx2_pshufb, self, idxs),
+ #[cfg(target_feature = "avx512vl,avx512vbmi")]
+ 32 => transize(x86::_mm256_permutexvar_epi8, self, idxs),
+ // Notable absence: avx512bw shuffle
+ // If avx512bw is available, odds of avx512vbmi are good
+ // FIXME: initial AVX512VBMI variant didn't actually pass muster
+ // #[cfg(target_feature = "avx512vbmi")]
+ // 64 => transize(x86::_mm512_permutexvar_epi8, self, idxs),
+ _ => {
+ let mut array = [0; N];
+ for (i, k) in idxs.to_array().into_iter().enumerate() {
+ if (k as usize) < N {
+ array[i] = self[k as usize];
+ };
+ }
+ array.into()
+ }
+ }
+ }
+ }
+}
+
+/// "vpshufb like it was meant to be" on AVX2
+///
+/// # Safety
+/// This requires AVX2 to work
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+#[target_feature(enable = "avx2")]
+#[allow(unused)]
+#[inline]
+#[allow(clippy::let_and_return)]
+unsafe fn avx2_pshufb(bytes: Simd<u8, 32>, idxs: Simd<u8, 32>) -> Simd<u8, 32> {
+ use crate::simd::SimdPartialOrd;
+ #[cfg(target_arch = "x86")]
+ use core::arch::x86;
+ #[cfg(target_arch = "x86_64")]
+ use core::arch::x86_64 as x86;
+ use x86::_mm256_permute2x128_si256 as avx2_cross_shuffle;
+ use x86::_mm256_shuffle_epi8 as avx2_half_pshufb;
+ let mid = Simd::splat(16u8);
+ let high = mid + mid;
+ // SAFETY: Caller promised AVX2
+ unsafe {
+ // This is ordering sensitive, and LLVM will order these how you put them.
+ // Most AVX2 impls use ~5 "ports", and only 1 or 2 are capable of permutes.
+ // But the "compose" step will lower to ops that can also use at least 1 other port.
+ // So this tries to break up permutes so composition flows through "open" ports.
+ // Comparative benches should be done on multiple AVX2 CPUs before reordering this
+
+ let hihi = avx2_cross_shuffle::<0x11>(bytes.into(), bytes.into());
+ let hi_shuf = Simd::from(avx2_half_pshufb(
+ hihi, // duplicate the vector's top half
+ idxs.into(), // so that using only 4 bits of an index still picks bytes 16-31
+ ));
+ // A zero-fill during the compose step gives the "all-Neon-like" OOB-is-0 semantics
+ let compose = idxs.simd_lt(high).select(hi_shuf, Simd::splat(0));
+ let lolo = avx2_cross_shuffle::<0x00>(bytes.into(), bytes.into());
+ let lo_shuf = Simd::from(avx2_half_pshufb(lolo, idxs.into()));
+ // Repeat, then pick indices < 16, overwriting indices 0-15 from previous compose step
+ let compose = idxs.simd_lt(mid).select(lo_shuf, compose);
+ compose
+ }
+}
+
+/// This sets up a call to an architecture-specific function, and in doing so
+/// it persuades rustc that everything is the correct size. Which it is.
+/// This would not be needed if one could convince Rust that, by matching on N,
+/// N is that value, and thus it would be valid to substitute e.g. 16.
+///
+/// # Safety
+/// The correctness of this function hinges on the sizes agreeing in actuality.
+#[allow(dead_code)]
+#[inline(always)]
+unsafe fn transize<T, const N: usize>(
+ f: unsafe fn(T, T) -> T,
+ bytes: Simd<u8, N>,
+ idxs: Simd<u8, N>,
+) -> Simd<u8, N>
+where
+ LaneCount<N>: SupportedLaneCount,
+{
+ let idxs = zeroing_idxs(idxs);
+ // SAFETY: Same obligation to use this function as to use mem::transmute_copy.
+ unsafe { mem::transmute_copy(&f(mem::transmute_copy(&bytes), mem::transmute_copy(&idxs))) }
+}
+
+/// Make indices that yield 0 for this architecture
+#[inline(always)]
+fn zeroing_idxs<const N: usize>(idxs: Simd<u8, N>) -> Simd<u8, N>
+where
+ LaneCount<N>: SupportedLaneCount,
+{
+ // On x86, make sure the top bit is set.
+ #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+ let idxs = {
+ use crate::simd::SimdPartialOrd;
+ idxs.simd_lt(Simd::splat(N as u8))
+ .select(idxs, Simd::splat(u8::MAX))
+ };
+ // Simply do nothing on most architectures.
+ idxs
+}
+
+/// As transize but no implicit call to `zeroing_idxs`.
+#[allow(dead_code)]
+#[inline(always)]
+unsafe fn transize_raw<T, const N: usize>(
+ f: unsafe fn(T, T) -> T,
+ bytes: Simd<u8, N>,
+ idxs: Simd<u8, N>,
+) -> Simd<u8, N>
+where
+ LaneCount<N>: SupportedLaneCount,
+{
+ // SAFETY: Same obligation to use this function as to use mem::transmute_copy.
+ unsafe { mem::transmute_copy(&f(mem::transmute_copy(&bytes), mem::transmute_copy(&idxs))) }
+}
diff --git a/library/portable-simd/crates/core_simd/src/vector.rs b/library/portable-simd/crates/core_simd/src/vector.rs
index d52d1ac4d3a..3809cc96151 100644
--- a/library/portable-simd/crates/core_simd/src/vector.rs
+++ b/library/portable-simd/crates/core_simd/src/vector.rs
@@ -1,60 +1,63 @@
-mod float;
-mod int;
-mod uint;
-
-pub use float::*;
-pub use int::*;
-pub use uint::*;
-
-// Vectors of pointers are not for public use at the current time.
-pub(crate) mod ptr;
-
use crate::simd::{
- intrinsics, LaneCount, Mask, MaskElement, SimdPartialOrd, SupportedLaneCount, Swizzle,
+ intrinsics, LaneCount, Mask, MaskElement, SimdCast, SimdCastPtr, SimdConstPtr, SimdMutPtr,
+ SimdPartialOrd, SupportedLaneCount, Swizzle,
};
+use core::convert::{TryFrom, TryInto};
-/// A SIMD vector of `LANES` elements of type `T`. `Simd<T, N>` has the same shape as [`[T; N]`](array), but operates like `T`.
+/// A SIMD vector with the shape of `[T; N]` but the operations of `T`.
///
-/// Two vectors of the same type and length will, by convention, support the operators (+, *, etc.) that `T` does.
-/// These take the lanes at each index on the left-hand side and right-hand side, perform the operation,
-/// and return the result in the same lane in a vector of equal size. For a given operator, this is equivalent to zipping
-/// the two arrays together and mapping the operator over each lane.
+/// `Simd<T, N>` supports the operators (+, *, etc.) that `T` does in "elementwise" fashion.
+/// These take the element at each index from the left-hand side and right-hand side,
+/// perform the operation, then return the result in the same index in a vector of equal size.
+/// However, `Simd` differs from normal iteration and normal arrays:
+/// - `Simd<T, N>` executes `N` operations in a single step with no `break`s
+/// - `Simd<T, N>` can have an alignment greater than `T`, for better mechanical sympathy
+///
+/// By always imposing these constraints on `Simd`, it is easier to compile elementwise operations
+/// into machine instructions that can themselves be executed in parallel.
///
/// ```rust
-/// # #![feature(array_zip, portable_simd)]
+/// # #![feature(portable_simd)]
/// # use core::simd::{Simd};
-/// let a0: [i32; 4] = [-2, 0, 2, 4];
-/// let a1 = [10, 9, 8, 7];
-/// let zm_add = a0.zip(a1).map(|(lhs, rhs)| lhs + rhs);
-/// let zm_mul = a0.zip(a1).map(|(lhs, rhs)| lhs * rhs);
+/// # use core::array;
+/// let a: [i32; 4] = [-2, 0, 2, 4];
+/// let b = [10, 9, 8, 7];
+/// let sum = array::from_fn(|i| a[i] + b[i]);
+/// let prod = array::from_fn(|i| a[i] * b[i]);
///
/// // `Simd<T, N>` implements `From<[T; N]>`
-/// let (v0, v1) = (Simd::from(a0), Simd::from(a1));
+/// let (v, w) = (Simd::from(a), Simd::from(b));
/// // Which means arrays implement `Into<Simd<T, N>>`.
-/// assert_eq!(v0 + v1, zm_add.into());
-/// assert_eq!(v0 * v1, zm_mul.into());
+/// assert_eq!(v + w, sum.into());
+/// assert_eq!(v * w, prod.into());
/// ```
///
-/// `Simd` with integers has the quirk that these operations are also inherently wrapping, as if `T` was [`Wrapping<T>`].
+///
+/// `Simd` with integer elements treats operators as wrapping, as if `T` was [`Wrapping<T>`].
/// Thus, `Simd` does not implement `wrapping_add`, because that is the default behavior.
/// This means there is no warning on overflows, even in "debug" builds.
/// For most applications where `Simd` is appropriate, it is "not a bug" to wrap,
/// and even "debug builds" are unlikely to tolerate the loss of performance.
/// You may want to consider using explicitly checked arithmetic if such is required.
-/// Division by zero still causes a panic, so you may want to consider using floating point numbers if that is unacceptable.
+/// Division by zero on integers still causes a panic, so
+/// you may want to consider using `f32` or `f64` if that is unacceptable.
///
/// [`Wrapping<T>`]: core::num::Wrapping
///
/// # Layout
-/// `Simd<T, N>` has a layout similar to `[T; N]` (identical "shapes"), but with a greater alignment.
+/// `Simd<T, N>` has a layout similar to `[T; N]` (identical "shapes"), with a greater alignment.
/// `[T; N]` is aligned to `T`, but `Simd<T, N>` will have an alignment based on both `T` and `N`.
-/// It is thus sound to [`transmute`] `Simd<T, N>` to `[T; N]`, and will typically optimize to zero cost,
-/// but the reverse transmutation is more likely to require a copy the compiler cannot simply elide.
+/// Thus it is sound to [`transmute`] `Simd<T, N>` to `[T; N]` and should optimize to "zero cost",
+/// but the reverse transmutation may require a copy the compiler cannot simply elide.
///
/// # ABI "Features"
-/// Due to Rust's safety guarantees, `Simd<T, N>` is currently passed to and from functions via memory, not SIMD registers,
-/// except as an optimization. `#[inline]` hints are recommended on functions that accept `Simd<T, N>` or return it.
-/// The need for this may be corrected in the future.
+/// Due to Rust's safety guarantees, `Simd<T, N>` is currently passed and returned via memory,
+/// not SIMD registers, except as an optimization. Using `#[inline]` on functions that accept
+/// `Simd<T, N>` or return it is recommended, at the cost of code generation time, as
+/// inlining SIMD-using functions can omit a large function prolog or epilog and thus
+/// improve both speed and code size. The need for this may be corrected in the future.
+///
+/// Using `#[inline(always)]` still requires additional care.
///
/// # Safe SIMD with Unsafe Rust
///
@@ -65,18 +68,22 @@ use crate::simd::{
/// Thus, when using `unsafe` Rust to read and write `Simd<T, N>` through [raw pointers], it is a good idea to first try with
/// [`read_unaligned`] and [`write_unaligned`]. This is because:
/// - [`read`] and [`write`] require full alignment (in this case, `Simd<T, N>`'s alignment)
-/// - the likely source for reading or destination for writing `Simd<T, N>` is [`[T]`](slice) and similar types, aligned to `T`
-/// - combining these actions would violate the `unsafe` contract and explode the program into a puff of **undefined behavior**
-/// - the compiler can implicitly adjust layouts to make unaligned reads or writes fully aligned if it sees the optimization
-/// - most contemporary processors suffer no performance penalty for "unaligned" reads and writes that are aligned at runtime
+/// - `Simd<T, N>` is often read from or written to [`[T]`](slice) and other types aligned to `T`
+/// - combining these actions violates the `unsafe` contract and explodes the program into
+/// a puff of **undefined behavior**
+/// - the compiler can implicitly adjust layouts to make unaligned reads or writes fully aligned
+/// if it sees the optimization
+/// - most contemporary processors with "aligned" and "unaligned" read and write instructions
+/// exhibit no performance difference if the "unaligned" variant is aligned at runtime
///
-/// By imposing less obligations, unaligned functions are less likely to make the program unsound,
+/// Less obligations mean unaligned reads and writes are less likely to make the program unsound,
/// and may be just as fast as stricter alternatives.
-/// When trying to guarantee alignment, [`[T]::as_simd`][as_simd] is an option for converting `[T]` to `[Simd<T, N>]`,
-/// and allows soundly operating on an aligned SIMD body, but it may cost more time when handling the scalar head and tail.
-/// If these are not sufficient, then it is most ideal to design data structures to be already aligned
-/// to the `Simd<T, N>` you wish to use before using `unsafe` Rust to read or write.
-/// More conventional ways to compensate for these facts, like materializing `Simd` to or from an array first,
+/// When trying to guarantee alignment, [`[T]::as_simd`][as_simd] is an option for
+/// converting `[T]` to `[Simd<T, N>]`, and allows soundly operating on an aligned SIMD body,
+/// but it may cost more time when handling the scalar head and tail.
+/// If these are not enough, it is most ideal to design data structures to be already aligned
+/// to `mem::align_of::<Simd<T, N>>()` before using `unsafe` Rust to read or write.
+/// Other ways to compensate for these facts, like materializing `Simd` to or from an array first,
/// are handled by safe methods like [`Simd::from_array`] and [`Simd::from_slice`].
///
/// [`transmute`]: core::mem::transmute
@@ -86,21 +93,26 @@ use crate::simd::{
/// [`read`]: pointer::read
/// [`write`]: pointer::write
/// [as_simd]: slice::as_simd
+//
+// NOTE: Accessing the inner array directly in any way (e.g. by using the `.0` field syntax) or
+// directly constructing an instance of the type (i.e. `let vector = Simd(array)`) should be
+// avoided, as it will likely become illegal on `#[repr(simd)]` structs in the future. It also
+// causes rustc to emit illegal LLVM IR in some cases.
#[repr(simd)]
-pub struct Simd<T, const LANES: usize>([T; LANES])
+pub struct Simd<T, const N: usize>([T; N])
where
- T: SimdElement,
- LaneCount<LANES>: SupportedLaneCount;
+ LaneCount<N>: SupportedLaneCount,
+ T: SimdElement;
-impl<T, const LANES: usize> Simd<T, LANES>
+impl<T, const N: usize> Simd<T, N>
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement,
{
- /// Number of lanes in this vector.
- pub const LANES: usize = LANES;
+ /// Number of elements in this vector.
+ pub const LANES: usize = N;
- /// Returns the number of lanes in this SIMD vector.
+ /// Returns the number of elements in this SIMD vector.
///
/// # Examples
///
@@ -111,10 +123,10 @@ where
/// assert_eq!(v.lanes(), 4);
/// ```
pub const fn lanes(&self) -> usize {
- LANES
+ Self::LANES
}
- /// Constructs a new SIMD vector with all lanes set to the given value.
+ /// Constructs a new SIMD vector with all elements set to the given value.
///
/// # Examples
///
@@ -125,11 +137,11 @@ where
/// assert_eq!(v.as_array(), &[8, 8, 8, 8]);
/// ```
pub fn splat(value: T) -> Self {
- // This is preferred over `[value; LANES]`, since it's explicitly a splat:
+ // This is preferred over `[value; N]`, since it's explicitly a splat:
// https://github.com/rust-lang/rust/issues/97804
struct Splat;
- impl<const LANES: usize> Swizzle<1, LANES> for Splat {
- const INDEX: [usize; LANES] = [0; LANES];
+ impl<const N: usize> Swizzle<1, N> for Splat {
+ const INDEX: [usize; N] = [0; N];
}
Splat::swizzle(Simd::<T, 1>::from([value]))
}
@@ -144,32 +156,100 @@ where
/// let v: u64x4 = Simd::from_array([0, 1, 2, 3]);
/// assert_eq!(v.as_array(), &[0, 1, 2, 3]);
/// ```
- pub const fn as_array(&self) -> &[T; LANES] {
- &self.0
+ pub const fn as_array(&self) -> &[T; N] {
+ // SAFETY: `Simd<T, N>` is just an overaligned `[T; N]` with
+ // potential padding at the end, so pointer casting to a
+ // `&[T; N]` is safe.
+ //
+ // NOTE: This deliberately doesn't just use `&self.0`, see the comment
+ // on the struct definition for details.
+ unsafe { &*(self as *const Self as *const [T; N]) }
}
/// Returns a mutable array reference containing the entire SIMD vector.
- pub fn as_mut_array(&mut self) -> &mut [T; LANES] {
- &mut self.0
+ pub fn as_mut_array(&mut self) -> &mut [T; N] {
+ // SAFETY: `Simd<T, N>` is just an overaligned `[T; N]` with
+ // potential padding at the end, so pointer casting to a
+ // `&mut [T; N]` is safe.
+ //
+ // NOTE: This deliberately doesn't just use `&mut self.0`, see the comment
+ // on the struct definition for details.
+ unsafe { &mut *(self as *mut Self as *mut [T; N]) }
+ }
+
+ /// Load a vector from an array of `T`.
+ ///
+ /// This function is necessary since `repr(simd)` has padding for non-power-of-2 vectors (at the time of writing).
+ /// With padding, `read_unaligned` will read past the end of an array of N elements.
+ ///
+ /// # Safety
+ /// Reading `ptr` must be safe, as if by `<*const [T; N]>::read_unaligned`.
+ const unsafe fn load(ptr: *const [T; N]) -> Self {
+ // There are potentially simpler ways to write this function, but this should result in
+ // LLVM `load <N x T>`
+
+ let mut tmp = core::mem::MaybeUninit::<Self>::uninit();
+ // SAFETY: `Simd<T, N>` always contains `N` elements of type `T`. It may have padding
+ // which does not need to be initialized. The safety of reading `ptr` is ensured by the
+ // caller.
+ unsafe {
+ core::ptr::copy_nonoverlapping(ptr, tmp.as_mut_ptr().cast(), 1);
+ tmp.assume_init()
+ }
+ }
+
+ /// Store a vector to an array of `T`.
+ ///
+ /// See `load` as to why this function is necessary.
+ ///
+ /// # Safety
+ /// Writing to `ptr` must be safe, as if by `<*mut [T; N]>::write_unaligned`.
+ const unsafe fn store(self, ptr: *mut [T; N]) {
+ // There are potentially simpler ways to write this function, but this should result in
+ // LLVM `store <N x T>`
+
+ // Creating a temporary helps LLVM turn the memcpy into a store.
+ let tmp = self;
+ // SAFETY: `Simd<T, N>` always contains `N` elements of type `T`. The safety of writing
+ // `ptr` is ensured by the caller.
+ unsafe { core::ptr::copy_nonoverlapping(tmp.as_array(), ptr, 1) }
}
/// Converts an array to a SIMD vector.
- pub const fn from_array(array: [T; LANES]) -> Self {
- Self(array)
+ pub const fn from_array(array: [T; N]) -> Self {
+ // SAFETY: `&array` is safe to read.
+ //
+ // FIXME: We currently use a pointer load instead of `transmute_copy` because `repr(simd)`
+ // results in padding for non-power-of-2 vectors (so vectors are larger than arrays).
+ //
+ // NOTE: This deliberately doesn't just use `Self(array)`, see the comment
+ // on the struct definition for details.
+ unsafe { Self::load(&array) }
}
/// Converts a SIMD vector to an array.
- pub const fn to_array(self) -> [T; LANES] {
- self.0
+ pub const fn to_array(self) -> [T; N] {
+ let mut tmp = core::mem::MaybeUninit::uninit();
+ // SAFETY: writing to `tmp` is safe and initializes it.
+ //
+ // FIXME: We currently use a pointer store instead of `transmute_copy` because `repr(simd)`
+ // results in padding for non-power-of-2 vectors (so vectors are larger than arrays).
+ //
+ // NOTE: This deliberately doesn't just use `self.0`, see the comment
+ // on the struct definition for details.
+ unsafe {
+ self.store(tmp.as_mut_ptr());
+ tmp.assume_init()
+ }
}
- /// Converts a slice to a SIMD vector containing `slice[..LANES]`.
+ /// Converts a slice to a SIMD vector containing `slice[..N]`.
///
/// # Panics
///
- /// Panics if the slice's length is less than the vector's `Simd::LANES`.
+ /// Panics if the slice's length is less than the vector's `Simd::N`.
///
- /// # Examples
+ /// # Example
///
/// ```
/// # #![feature(portable_simd)]
@@ -180,22 +260,49 @@ where
/// ```
#[must_use]
pub const fn from_slice(slice: &[T]) -> Self {
- assert!(slice.len() >= LANES, "slice length must be at least the number of lanes");
- let mut array = [slice[0]; LANES];
- let mut i = 0;
- while i < LANES {
- array[i] = slice[i];
- i += 1;
- }
- Self(array)
+ assert!(
+ slice.len() >= Self::LANES,
+ "slice length must be at least the number of elements"
+ );
+ // SAFETY: We just checked that the slice contains
+ // at least `N` elements.
+ unsafe { Self::load(slice.as_ptr().cast()) }
+ }
+
+ /// Writes a SIMD vector to the first `N` elements of a slice.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the slice's length is less than the vector's `Simd::N`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # #![feature(portable_simd)]
+ /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+ /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+ /// # use simd::u32x4;
+ /// let mut dest = vec![0; 6];
+ /// let v = u32x4::from_array([1, 2, 3, 4]);
+ /// v.copy_to_slice(&mut dest);
+ /// assert_eq!(&dest, &[1, 2, 3, 4, 0, 0]);
+ /// ```
+ pub fn copy_to_slice(self, slice: &mut [T]) {
+ assert!(
+ slice.len() >= Self::LANES,
+ "slice length must be at least the number of elements"
+ );
+ // SAFETY: We just checked that the slice contains
+ // at least `N` elements.
+ unsafe { self.store(slice.as_mut_ptr().cast()) }
}
- /// Performs lanewise conversion of a SIMD vector's elements to another SIMD-valid type.
+ /// Performs elementwise conversion of a SIMD vector's elements to another SIMD-valid type.
///
- /// This follows the semantics of Rust's `as` conversion for casting
- /// integers to unsigned integers (interpreting as the other type, so `-1` to `MAX`),
- /// and from floats to integers (truncating, or saturating at the limits) for each lane,
- /// or vice versa.
+ /// This follows the semantics of Rust's `as` conversion for casting integers between
+ /// signed and unsigned (interpreting integers as 2s complement, so `-1` to `U::MAX` and
+ /// `1 << (U::BITS -1)` becoming `I::MIN` ), and from floats to integers (truncating,
+ /// or saturating at the limits) for each element.
///
/// # Examples
/// ```
@@ -215,11 +322,26 @@ where
/// ```
#[must_use]
#[inline]
- pub fn cast<U: SimdElement>(self) -> Simd<U, LANES> {
- // Safety: The input argument is a vector of a valid SIMD element type.
+ pub fn cast<U: SimdCast>(self) -> Simd<U, N>
+ where
+ T: SimdCast,
+ {
+ // Safety: supported types are guaranteed by SimdCast
unsafe { intrinsics::simd_as(self) }
}
+ /// Casts a vector of pointers to another pointer type.
+ #[must_use]
+ #[inline]
+ pub fn cast_ptr<U>(self) -> Simd<U, N>
+ where
+ T: SimdCastPtr<U>,
+ U: SimdElement,
+ {
+ // Safety: supported types are guaranteed by SimdCastPtr
+ unsafe { intrinsics::simd_cast_ptr(self) }
+ }
+
/// Rounds toward zero and converts to the same-width integer type, assuming that
/// the value is finite and fits in that type.
///
@@ -235,90 +357,90 @@ where
///
/// [cast]: Simd::cast
#[inline]
- pub unsafe fn to_int_unchecked<I>(self) -> Simd<I, LANES>
+ #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+ pub unsafe fn to_int_unchecked<I>(self) -> Simd<I, N>
where
- T: core::convert::FloatToInt<I>,
- I: SimdElement,
+ T: core::convert::FloatToInt<I> + SimdCast,
+ I: SimdCast,
{
- // Safety: `self` is a vector, and `FloatToInt` ensures the type can be casted to
- // an integer.
+ // Safety: supported types are guaranteed by SimdCast, the caller is responsible for the extra invariants
unsafe { intrinsics::simd_cast(self) }
}
/// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector.
- /// If an index is out-of-bounds, the lane is instead selected from the `or` vector.
+ /// If an index is out-of-bounds, the element is instead selected from the `or` vector.
///
/// # Examples
/// ```
/// # #![feature(portable_simd)]
/// # use core::simd::Simd;
/// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
- /// let idxs = Simd::from_array([9, 3, 0, 5]);
+ /// let idxs = Simd::from_array([9, 3, 0, 5]); // Note the index that is out-of-bounds
/// let alt = Simd::from_array([-5, -4, -3, -2]);
///
- /// let result = Simd::gather_or(&vec, idxs, alt); // Note the lane that is out-of-bounds.
+ /// let result = Simd::gather_or(&vec, idxs, alt);
/// assert_eq!(result, Simd::from_array([-5, 13, 10, 15]));
/// ```
#[must_use]
#[inline]
- pub fn gather_or(slice: &[T], idxs: Simd<usize, LANES>, or: Self) -> Self {
+ pub fn gather_or(slice: &[T], idxs: Simd<usize, N>, or: Self) -> Self {
Self::gather_select(slice, Mask::splat(true), idxs, or)
}
- /// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector.
- /// If an index is out-of-bounds, the lane is set to the default value for the type.
+ /// Reads from indices in `slice` to construct a SIMD vector.
+ /// If an index is out-of-bounds, the element is set to the default given by `T: Default`.
///
/// # Examples
/// ```
/// # #![feature(portable_simd)]
/// # use core::simd::Simd;
/// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
- /// let idxs = Simd::from_array([9, 3, 0, 5]);
+ /// let idxs = Simd::from_array([9, 3, 0, 5]); // Note the index that is out-of-bounds
///
- /// let result = Simd::gather_or_default(&vec, idxs); // Note the lane that is out-of-bounds.
+ /// let result = Simd::gather_or_default(&vec, idxs);
/// assert_eq!(result, Simd::from_array([0, 13, 10, 15]));
/// ```
#[must_use]
#[inline]
- pub fn gather_or_default(slice: &[T], idxs: Simd<usize, LANES>) -> Self
+ pub fn gather_or_default(slice: &[T], idxs: Simd<usize, N>) -> Self
where
T: Default,
{
Self::gather_or(slice, idxs, Self::splat(T::default()))
}
- /// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector.
- /// The mask `enable`s all `true` lanes and disables all `false` lanes.
- /// If an index is disabled or is out-of-bounds, the lane is selected from the `or` vector.
+ /// Reads from indices in `slice` to construct a SIMD vector.
+ /// The mask `enable`s all `true` indices and disables all `false` indices.
+ /// If an index is disabled or is out-of-bounds, the element is selected from the `or` vector.
///
/// # Examples
/// ```
/// # #![feature(portable_simd)]
/// # use core::simd::{Simd, Mask};
/// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
- /// let idxs = Simd::from_array([9, 3, 0, 5]);
+ /// let idxs = Simd::from_array([9, 3, 0, 5]); // Includes an out-of-bounds index
/// let alt = Simd::from_array([-5, -4, -3, -2]);
- /// let enable = Mask::from_array([true, true, true, false]); // Note the mask of the last lane.
+ /// let enable = Mask::from_array([true, true, true, false]); // Includes a masked element
///
- /// let result = Simd::gather_select(&vec, enable, idxs, alt); // Note the lane that is out-of-bounds.
+ /// let result = Simd::gather_select(&vec, enable, idxs, alt);
/// assert_eq!(result, Simd::from_array([-5, 13, 10, -2]));
/// ```
#[must_use]
#[inline]
pub fn gather_select(
slice: &[T],
- enable: Mask<isize, LANES>,
- idxs: Simd<usize, LANES>,
+ enable: Mask<isize, N>,
+ idxs: Simd<usize, N>,
or: Self,
) -> Self {
- let enable: Mask<isize, LANES> = enable & idxs.simd_lt(Simd::splat(slice.len()));
- // Safety: We have masked-off out-of-bounds lanes.
+ let enable: Mask<isize, N> = enable & idxs.simd_lt(Simd::splat(slice.len()));
+ // Safety: We have masked-off out-of-bounds indices.
unsafe { Self::gather_select_unchecked(slice, enable, idxs, or) }
}
- /// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector.
- /// The mask `enable`s all `true` lanes and disables all `false` lanes.
- /// If an index is disabled, the lane is selected from the `or` vector.
+ /// Reads from indices in `slice` to construct a SIMD vector.
+ /// The mask `enable`s all `true` indices and disables all `false` indices.
+ /// If an index is disabled, the element is selected from the `or` vector.
///
/// # Safety
///
@@ -332,57 +454,123 @@ where
/// # #[cfg(not(feature = "as_crate"))] use core::simd;
/// # use simd::{Simd, SimdPartialOrd, Mask};
/// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
- /// let idxs = Simd::from_array([9, 3, 0, 5]);
+ /// let idxs = Simd::from_array([9, 3, 0, 5]); // Includes an out-of-bounds index
/// let alt = Simd::from_array([-5, -4, -3, -2]);
- /// let enable = Mask::from_array([true, true, true, false]); // Note the final mask lane.
+ /// let enable = Mask::from_array([true, true, true, false]); // Includes a masked element
/// // If this mask was used to gather, it would be unsound. Let's fix that.
/// let enable = enable & idxs.simd_lt(Simd::splat(vec.len()));
///
- /// // We have masked the OOB lane, so it's safe to gather now.
+ /// // The out-of-bounds index has been masked, so it's safe to gather now.
/// let result = unsafe { Simd::gather_select_unchecked(&vec, enable, idxs, alt) };
/// assert_eq!(result, Simd::from_array([-5, 13, 10, -2]));
/// ```
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
#[must_use]
#[inline]
+ #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub unsafe fn gather_select_unchecked(
slice: &[T],
- enable: Mask<isize, LANES>,
- idxs: Simd<usize, LANES>,
+ enable: Mask<isize, N>,
+ idxs: Simd<usize, N>,
or: Self,
) -> Self {
- let base_ptr = crate::simd::ptr::SimdConstPtr::splat(slice.as_ptr());
+ let base_ptr = Simd::<*const T, N>::splat(slice.as_ptr());
// Ferris forgive me, I have done pointer arithmetic here.
let ptrs = base_ptr.wrapping_add(idxs);
- // Safety: The ptrs have been bounds-masked to prevent memory-unsafe reads insha'allah
- unsafe { intrinsics::simd_gather(or, ptrs, enable.to_int()) }
+ // Safety: The caller is responsible for determining the indices are okay to read
+ unsafe { Self::gather_select_ptr(ptrs, enable, or) }
+ }
+
+ /// Read elementwise from pointers into a SIMD vector.
+ ///
+ /// # Safety
+ ///
+ /// Each read must satisfy the same conditions as [`core::ptr::read`].
+ ///
+ /// # Example
+ /// ```
+ /// # #![feature(portable_simd)]
+ /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+ /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+ /// # use simd::{Simd, SimdConstPtr};
+ /// let values = [6, 2, 4, 9];
+ /// let offsets = Simd::from_array([1, 0, 0, 3]);
+ /// let source = Simd::splat(values.as_ptr()).wrapping_add(offsets);
+ /// let gathered = unsafe { Simd::gather_ptr(source) };
+ /// assert_eq!(gathered, Simd::from_array([2, 6, 6, 9]));
+ /// ```
+ #[must_use]
+ #[inline]
+ #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+ pub unsafe fn gather_ptr(source: Simd<*const T, N>) -> Self
+ where
+ T: Default,
+ {
+ // TODO: add an intrinsic that doesn't use a passthru vector, and remove the T: Default bound
+ // Safety: The caller is responsible for upholding all invariants
+ unsafe { Self::gather_select_ptr(source, Mask::splat(true), Self::default()) }
+ }
+
+ /// Conditionally read elementwise from pointers into a SIMD vector.
+ /// The mask `enable`s all `true` pointers and disables all `false` pointers.
+ /// If a pointer is disabled, the element is selected from the `or` vector,
+ /// and no read is performed.
+ ///
+ /// # Safety
+ ///
+ /// Enabled elements must satisfy the same conditions as [`core::ptr::read`].
+ ///
+ /// # Example
+ /// ```
+ /// # #![feature(portable_simd)]
+ /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+ /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+ /// # use simd::{Mask, Simd, SimdConstPtr};
+ /// let values = [6, 2, 4, 9];
+ /// let enable = Mask::from_array([true, true, false, true]);
+ /// let offsets = Simd::from_array([1, 0, 0, 3]);
+ /// let source = Simd::splat(values.as_ptr()).wrapping_add(offsets);
+ /// let gathered = unsafe { Simd::gather_select_ptr(source, enable, Simd::splat(0)) };
+ /// assert_eq!(gathered, Simd::from_array([2, 6, 0, 9]));
+ /// ```
+ #[must_use]
+ #[inline]
+ #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+ pub unsafe fn gather_select_ptr(
+ source: Simd<*const T, N>,
+ enable: Mask<isize, N>,
+ or: Self,
+ ) -> Self {
+ // Safety: The caller is responsible for upholding all invariants
+ unsafe { intrinsics::simd_gather(or, source, enable.to_int()) }
}
/// Writes the values in a SIMD vector to potentially discontiguous indices in `slice`.
- /// If two lanes in the scattered vector would write to the same index
- /// only the last lane is guaranteed to actually be written.
+ /// If an index is out-of-bounds, the write is suppressed without panicking.
+ /// If two elements in the scattered vector would write to the same index
+ /// only the last element is guaranteed to actually be written.
///
/// # Examples
/// ```
/// # #![feature(portable_simd)]
/// # use core::simd::Simd;
/// let mut vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
- /// let idxs = Simd::from_array([9, 3, 0, 0]);
+ /// let idxs = Simd::from_array([9, 3, 0, 0]); // Note the duplicate index.
/// let vals = Simd::from_array([-27, 82, -41, 124]);
///
- /// vals.scatter(&mut vec, idxs); // index 0 receives two writes.
+ /// vals.scatter(&mut vec, idxs); // two logical writes means the last wins.
/// assert_eq!(vec, vec![124, 11, 12, 82, 14, 15, 16, 17, 18]);
/// ```
#[inline]
- pub fn scatter(self, slice: &mut [T], idxs: Simd<usize, LANES>) {
+ pub fn scatter(self, slice: &mut [T], idxs: Simd<usize, N>) {
self.scatter_select(slice, Mask::splat(true), idxs)
}
- /// Writes the values in a SIMD vector to multiple potentially discontiguous indices in `slice`.
- /// The mask `enable`s all `true` lanes and disables all `false` lanes.
- /// If an enabled index is out-of-bounds, the lane is not written.
- /// If two enabled lanes in the scattered vector would write to the same index,
- /// only the last lane is guaranteed to actually be written.
+ /// Writes values from a SIMD vector to multiple potentially discontiguous indices in `slice`.
+ /// The mask `enable`s all `true` indices and disables all `false` indices.
+ /// If an enabled index is out-of-bounds, the write is suppressed without panicking.
+ /// If two enabled elements in the scattered vector would write to the same index,
+ /// only the last element is guaranteed to actually be written.
///
/// # Examples
/// ```
@@ -391,29 +579,24 @@ where
/// # #[cfg(not(feature = "as_crate"))] use core::simd;
/// # use simd::{Simd, Mask};
/// let mut vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
- /// let idxs = Simd::from_array([9, 3, 0, 0]);
+ /// let idxs = Simd::from_array([9, 3, 0, 0]); // Includes an out-of-bounds index
/// let vals = Simd::from_array([-27, 82, -41, 124]);
- /// let enable = Mask::from_array([true, true, true, false]); // Note the mask of the last lane.
+ /// let enable = Mask::from_array([true, true, true, false]); // Includes a masked element
///
- /// vals.scatter_select(&mut vec, enable, idxs); // index 0's second write is masked, thus omitted.
+ /// vals.scatter_select(&mut vec, enable, idxs); // The last write is masked, thus omitted.
/// assert_eq!(vec, vec![-41, 11, 12, 82, 14, 15, 16, 17, 18]);
/// ```
#[inline]
- pub fn scatter_select(
- self,
- slice: &mut [T],
- enable: Mask<isize, LANES>,
- idxs: Simd<usize, LANES>,
- ) {
- let enable: Mask<isize, LANES> = enable & idxs.simd_lt(Simd::splat(slice.len()));
- // Safety: We have masked-off out-of-bounds lanes.
+ pub fn scatter_select(self, slice: &mut [T], enable: Mask<isize, N>, idxs: Simd<usize, N>) {
+ let enable: Mask<isize, N> = enable & idxs.simd_lt(Simd::splat(slice.len()));
+ // Safety: We have masked-off out-of-bounds indices.
unsafe { self.scatter_select_unchecked(slice, enable, idxs) }
}
- /// Writes the values in a SIMD vector to multiple potentially discontiguous indices in `slice`.
- /// The mask `enable`s all `true` lanes and disables all `false` lanes.
- /// If two enabled lanes in the scattered vector would write to the same index,
- /// only the last lane is guaranteed to actually be written.
+ /// Writes values from a SIMD vector to multiple potentially discontiguous indices in `slice`.
+ /// The mask `enable`s all `true` indices and disables all `false` indices.
+ /// If two enabled elements in the scattered vector would write to the same index,
+ /// only the last element is guaranteed to actually be written.
///
/// # Safety
///
@@ -429,22 +612,23 @@ where
/// let mut vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
/// let idxs = Simd::from_array([9, 3, 0, 0]);
/// let vals = Simd::from_array([-27, 82, -41, 124]);
- /// let enable = Mask::from_array([true, true, true, false]); // Note the mask of the last lane.
+ /// let enable = Mask::from_array([true, true, true, false]); // Masks the final index
/// // If this mask was used to scatter, it would be unsound. Let's fix that.
/// let enable = enable & idxs.simd_lt(Simd::splat(vec.len()));
///
- /// // We have masked the OOB lane, so it's safe to scatter now.
+ /// // We have masked the OOB index, so it's safe to scatter now.
/// unsafe { vals.scatter_select_unchecked(&mut vec, enable, idxs); }
- /// // index 0's second write is masked, thus was omitted.
+ /// // The second write to index 0 was masked, thus omitted.
/// assert_eq!(vec, vec![-41, 11, 12, 82, 14, 15, 16, 17, 18]);
/// ```
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
#[inline]
+ #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub unsafe fn scatter_select_unchecked(
self,
slice: &mut [T],
- enable: Mask<isize, LANES>,
- idxs: Simd<usize, LANES>,
+ enable: Mask<isize, N>,
+ idxs: Simd<usize, N>,
) {
// Safety: This block works with *mut T derived from &mut 'a [T],
// which means it is delicate in Rust's borrowing model, circa 2021:
@@ -458,36 +642,89 @@ where
// 3. &mut [T] which will become our base ptr.
unsafe {
// Now Entering â˜¢ï¸ *mut T Zone
- let base_ptr = crate::simd::ptr::SimdMutPtr::splat(slice.as_mut_ptr());
+ let base_ptr = Simd::<*mut T, N>::splat(slice.as_mut_ptr());
// Ferris forgive me, I have done pointer arithmetic here.
let ptrs = base_ptr.wrapping_add(idxs);
// The ptrs have been bounds-masked to prevent memory-unsafe writes insha'allah
- intrinsics::simd_scatter(self, ptrs, enable.to_int())
+ self.scatter_select_ptr(ptrs, enable);
// Cleared â˜¢ï¸ *mut T Zone
}
}
+
+ /// Write pointers elementwise into a SIMD vector.
+ ///
+ /// # Safety
+ ///
+ /// Each write must satisfy the same conditions as [`core::ptr::write`].
+ ///
+ /// # Example
+ /// ```
+ /// # #![feature(portable_simd)]
+ /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+ /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+ /// # use simd::{Simd, SimdMutPtr};
+ /// let mut values = [0; 4];
+ /// let offset = Simd::from_array([3, 2, 1, 0]);
+ /// let ptrs = Simd::splat(values.as_mut_ptr()).wrapping_add(offset);
+ /// unsafe { Simd::from_array([6, 3, 5, 7]).scatter_ptr(ptrs); }
+ /// assert_eq!(values, [7, 5, 3, 6]);
+ /// ```
+ #[inline]
+ #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+ pub unsafe fn scatter_ptr(self, dest: Simd<*mut T, N>) {
+ // Safety: The caller is responsible for upholding all invariants
+ unsafe { self.scatter_select_ptr(dest, Mask::splat(true)) }
+ }
+
+ /// Conditionally write pointers elementwise into a SIMD vector.
+ /// The mask `enable`s all `true` pointers and disables all `false` pointers.
+ /// If a pointer is disabled, the write to its pointee is skipped.
+ ///
+ /// # Safety
+ ///
+ /// Enabled pointers must satisfy the same conditions as [`core::ptr::write`].
+ ///
+ /// # Example
+ /// ```
+ /// # #![feature(portable_simd)]
+ /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+ /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+ /// # use simd::{Mask, Simd, SimdMutPtr};
+ /// let mut values = [0; 4];
+ /// let offset = Simd::from_array([3, 2, 1, 0]);
+ /// let ptrs = Simd::splat(values.as_mut_ptr()).wrapping_add(offset);
+ /// let enable = Mask::from_array([true, true, false, false]);
+ /// unsafe { Simd::from_array([6, 3, 5, 7]).scatter_select_ptr(ptrs, enable); }
+ /// assert_eq!(values, [0, 0, 3, 6]);
+ /// ```
+ #[inline]
+ #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+ pub unsafe fn scatter_select_ptr(self, dest: Simd<*mut T, N>, enable: Mask<isize, N>) {
+ // Safety: The caller is responsible for upholding all invariants
+ unsafe { intrinsics::simd_scatter(self, dest, enable.to_int()) }
+ }
}
-impl<T, const LANES: usize> Copy for Simd<T, LANES>
+impl<T, const N: usize> Copy for Simd<T, N>
where
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement,
- LaneCount<LANES>: SupportedLaneCount,
{
}
-impl<T, const LANES: usize> Clone for Simd<T, LANES>
+impl<T, const N: usize> Clone for Simd<T, N>
where
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement,
- LaneCount<LANES>: SupportedLaneCount,
{
fn clone(&self) -> Self {
*self
}
}
-impl<T, const LANES: usize> Default for Simd<T, LANES>
+impl<T, const N: usize> Default for Simd<T, N>
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement + Default,
{
#[inline]
@@ -496,20 +733,20 @@ where
}
}
-impl<T, const LANES: usize> PartialEq for Simd<T, LANES>
+impl<T, const N: usize> PartialEq for Simd<T, N>
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement + PartialEq,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
// Safety: All SIMD vectors are SimdPartialEq, and the comparison produces a valid mask.
let mask = unsafe {
- let tfvec: Simd<<T as SimdElement>::Mask, LANES> = intrinsics::simd_eq(*self, *other);
+ let tfvec: Simd<<T as SimdElement>::Mask, N> = intrinsics::simd_eq(*self, *other);
Mask::from_int_unchecked(tfvec)
};
- // Two vectors are equal if all lanes tested true for vertical equality.
+ // Two vectors are equal if all elements are equal when compared elementwise
mask.all()
}
@@ -518,18 +755,18 @@ where
fn ne(&self, other: &Self) -> bool {
// Safety: All SIMD vectors are SimdPartialEq, and the comparison produces a valid mask.
let mask = unsafe {
- let tfvec: Simd<<T as SimdElement>::Mask, LANES> = intrinsics::simd_ne(*self, *other);
+ let tfvec: Simd<<T as SimdElement>::Mask, N> = intrinsics::simd_ne(*self, *other);
Mask::from_int_unchecked(tfvec)
};
- // Two vectors are non-equal if any lane tested true for vertical non-equality.
+ // Two vectors are non-equal if any elements are non-equal when compared elementwise
mask.any()
}
}
-impl<T, const LANES: usize> PartialOrd for Simd<T, LANES>
+impl<T, const N: usize> PartialOrd for Simd<T, N>
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement + PartialOrd,
{
#[inline]
@@ -539,16 +776,16 @@ where
}
}
-impl<T, const LANES: usize> Eq for Simd<T, LANES>
+impl<T, const N: usize> Eq for Simd<T, N>
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement + Eq,
{
}
-impl<T, const LANES: usize> Ord for Simd<T, LANES>
+impl<T, const N: usize> Ord for Simd<T, N>
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement + Ord,
{
#[inline]
@@ -558,9 +795,9 @@ where
}
}
-impl<T, const LANES: usize> core::hash::Hash for Simd<T, LANES>
+impl<T, const N: usize> core::hash::Hash for Simd<T, N>
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement + core::hash::Hash,
{
#[inline]
@@ -573,72 +810,96 @@ where
}
// array references
-impl<T, const LANES: usize> AsRef<[T; LANES]> for Simd<T, LANES>
+impl<T, const N: usize> AsRef<[T; N]> for Simd<T, N>
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement,
{
#[inline]
- fn as_ref(&self) -> &[T; LANES] {
- &self.0
+ fn as_ref(&self) -> &[T; N] {
+ self.as_array()
}
}
-impl<T, const LANES: usize> AsMut<[T; LANES]> for Simd<T, LANES>
+impl<T, const N: usize> AsMut<[T; N]> for Simd<T, N>
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement,
{
#[inline]
- fn as_mut(&mut self) -> &mut [T; LANES] {
- &mut self.0
+ fn as_mut(&mut self) -> &mut [T; N] {
+ self.as_mut_array()
}
}
// slice references
-impl<T, const LANES: usize> AsRef<[T]> for Simd<T, LANES>
+impl<T, const N: usize> AsRef<[T]> for Simd<T, N>
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement,
{
#[inline]
fn as_ref(&self) -> &[T] {
- &self.0
+ self.as_array()
}
}
-impl<T, const LANES: usize> AsMut<[T]> for Simd<T, LANES>
+impl<T, const N: usize> AsMut<[T]> for Simd<T, N>
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement,
{
#[inline]
fn as_mut(&mut self) -> &mut [T] {
- &mut self.0
+ self.as_mut_array()
}
}
// vector/array conversion
-impl<T, const LANES: usize> From<[T; LANES]> for Simd<T, LANES>
+impl<T, const N: usize> From<[T; N]> for Simd<T, N>
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement,
{
- fn from(array: [T; LANES]) -> Self {
- Self(array)
+ fn from(array: [T; N]) -> Self {
+ Self::from_array(array)
}
}
-impl<T, const LANES: usize> From<Simd<T, LANES>> for [T; LANES]
+impl<T, const N: usize> From<Simd<T, N>> for [T; N]
where
- LaneCount<LANES>: SupportedLaneCount,
+ LaneCount<N>: SupportedLaneCount,
T: SimdElement,
{
- fn from(vector: Simd<T, LANES>) -> Self {
+ fn from(vector: Simd<T, N>) -> Self {
vector.to_array()
}
}
+impl<T, const N: usize> TryFrom<&[T]> for Simd<T, N>
+where
+ LaneCount<N>: SupportedLaneCount,
+ T: SimdElement,
+{
+ type Error = core::array::TryFromSliceError;
+
+ fn try_from(slice: &[T]) -> Result<Self, core::array::TryFromSliceError> {
+ Ok(Self::from_array(slice.try_into()?))
+ }
+}
+
+impl<T, const N: usize> TryFrom<&mut [T]> for Simd<T, N>
+where
+ LaneCount<N>: SupportedLaneCount,
+ T: SimdElement,
+{
+ type Error = core::array::TryFromSliceError;
+
+ fn try_from(slice: &mut [T]) -> Result<Self, core::array::TryFromSliceError> {
+ Ok(Self::from_array(slice.try_into()?))
+ }
+}
+
mod sealed {
pub trait Sealed {}
}
@@ -740,3 +1001,27 @@ impl Sealed for f64 {}
unsafe impl SimdElement for f64 {
type Mask = i64;
}
+
+impl<T> Sealed for *const T {}
+
+// Safety: (thin) const pointers are valid SIMD element types, and are supported by this API
+//
+// Fat pointers may be supported in the future.
+unsafe impl<T> SimdElement for *const T
+where
+ T: core::ptr::Pointee<Metadata = ()>,
+{
+ type Mask = isize;
+}
+
+impl<T> Sealed for *mut T {}
+
+// Safety: (thin) mut pointers are valid SIMD element types, and are supported by this API
+//
+// Fat pointers may be supported in the future.
+unsafe impl<T> SimdElement for *mut T
+where
+ T: core::ptr::Pointee<Metadata = ()>,
+{
+ type Mask = isize;
+}
diff --git a/library/portable-simd/crates/core_simd/src/vector/float.rs b/library/portable-simd/crates/core_simd/src/vector/float.rs
deleted file mode 100644
index f836c99b1e2..00000000000
--- a/library/portable-simd/crates/core_simd/src/vector/float.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-#![allow(non_camel_case_types)]
-
-use crate::simd::Simd;
-
-/// A 64-bit SIMD vector with two elements of type `f32`.
-pub type f32x2 = Simd<f32, 2>;
-
-/// A 128-bit SIMD vector with four elements of type `f32`.
-pub type f32x4 = Simd<f32, 4>;
-
-/// A 256-bit SIMD vector with eight elements of type `f32`.
-pub type f32x8 = Simd<f32, 8>;
-
-/// A 512-bit SIMD vector with 16 elements of type `f32`.
-pub type f32x16 = Simd<f32, 16>;
-
-/// A 128-bit SIMD vector with two elements of type `f64`.
-pub type f64x2 = Simd<f64, 2>;
-
-/// A 256-bit SIMD vector with four elements of type `f64`.
-pub type f64x4 = Simd<f64, 4>;
-
-/// A 512-bit SIMD vector with eight elements of type `f64`.
-pub type f64x8 = Simd<f64, 8>;
diff --git a/library/portable-simd/crates/core_simd/src/vector/int.rs b/library/portable-simd/crates/core_simd/src/vector/int.rs
deleted file mode 100644
index 20e56c7dc64..00000000000
--- a/library/portable-simd/crates/core_simd/src/vector/int.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-#![allow(non_camel_case_types)]
-
-use crate::simd::Simd;
-
-/// A SIMD vector with two elements of type `isize`.
-pub type isizex2 = Simd<isize, 2>;
-
-/// A SIMD vector with four elements of type `isize`.
-pub type isizex4 = Simd<isize, 4>;
-
-/// A SIMD vector with eight elements of type `isize`.
-pub type isizex8 = Simd<isize, 8>;
-
-/// A 32-bit SIMD vector with two elements of type `i16`.
-pub type i16x2 = Simd<i16, 2>;
-
-/// A 64-bit SIMD vector with four elements of type `i16`.
-pub type i16x4 = Simd<i16, 4>;
-
-/// A 128-bit SIMD vector with eight elements of type `i16`.
-pub type i16x8 = Simd<i16, 8>;
-
-/// A 256-bit SIMD vector with 16 elements of type `i16`.
-pub type i16x16 = Simd<i16, 16>;
-
-/// A 512-bit SIMD vector with 32 elements of type `i16`.
-pub type i16x32 = Simd<i16, 32>;
-
-/// A 64-bit SIMD vector with two elements of type `i32`.
-pub type i32x2 = Simd<i32, 2>;
-
-/// A 128-bit SIMD vector with four elements of type `i32`.
-pub type i32x4 = Simd<i32, 4>;
-
-/// A 256-bit SIMD vector with eight elements of type `i32`.
-pub type i32x8 = Simd<i32, 8>;
-
-/// A 512-bit SIMD vector with 16 elements of type `i32`.
-pub type i32x16 = Simd<i32, 16>;
-
-/// A 128-bit SIMD vector with two elements of type `i64`.
-pub type i64x2 = Simd<i64, 2>;
-
-/// A 256-bit SIMD vector with four elements of type `i64`.
-pub type i64x4 = Simd<i64, 4>;
-
-/// A 512-bit SIMD vector with eight elements of type `i64`.
-pub type i64x8 = Simd<i64, 8>;
-
-/// A 32-bit SIMD vector with four elements of type `i8`.
-pub type i8x4 = Simd<i8, 4>;
-
-/// A 64-bit SIMD vector with eight elements of type `i8`.
-pub type i8x8 = Simd<i8, 8>;
-
-/// A 128-bit SIMD vector with 16 elements of type `i8`.
-pub type i8x16 = Simd<i8, 16>;
-
-/// A 256-bit SIMD vector with 32 elements of type `i8`.
-pub type i8x32 = Simd<i8, 32>;
-
-/// A 512-bit SIMD vector with 64 elements of type `i8`.
-pub type i8x64 = Simd<i8, 64>;
diff --git a/library/portable-simd/crates/core_simd/src/vector/ptr.rs b/library/portable-simd/crates/core_simd/src/vector/ptr.rs
deleted file mode 100644
index fa756344db9..00000000000
--- a/library/portable-simd/crates/core_simd/src/vector/ptr.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-//! Private implementation details of public gather/scatter APIs.
-use crate::simd::intrinsics;
-use crate::simd::{LaneCount, Simd, SupportedLaneCount};
-
-/// A vector of *const T.
-#[derive(Debug, Copy, Clone)]
-#[repr(simd)]
-pub(crate) struct SimdConstPtr<T, const LANES: usize>([*const T; LANES]);
-
-impl<T, const LANES: usize> SimdConstPtr<T, LANES>
-where
- LaneCount<LANES>: SupportedLaneCount,
- T: Sized,
-{
- #[inline]
- #[must_use]
- pub fn splat(ptr: *const T) -> Self {
- Self([ptr; LANES])
- }
-
- #[inline]
- #[must_use]
- pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
- // Safety: this intrinsic doesn't have a precondition
- unsafe { intrinsics::simd_arith_offset(self, addend) }
- }
-}
-
-/// A vector of *mut T. Be very careful around potential aliasing.
-#[derive(Debug, Copy, Clone)]
-#[repr(simd)]
-pub(crate) struct SimdMutPtr<T, const LANES: usize>([*mut T; LANES]);
-
-impl<T, const LANES: usize> SimdMutPtr<T, LANES>
-where
- LaneCount<LANES>: SupportedLaneCount,
- T: Sized,
-{
- #[inline]
- #[must_use]
- pub fn splat(ptr: *mut T) -> Self {
- Self([ptr; LANES])
- }
-
- #[inline]
- #[must_use]
- pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
- // Safety: this intrinsic doesn't have a precondition
- unsafe { intrinsics::simd_arith_offset(self, addend) }
- }
-}
diff --git a/library/portable-simd/crates/core_simd/src/vector/uint.rs b/library/portable-simd/crates/core_simd/src/vector/uint.rs
deleted file mode 100644
index b4a69c44363..00000000000
--- a/library/portable-simd/crates/core_simd/src/vector/uint.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-#![allow(non_camel_case_types)]
-
-use crate::simd::Simd;
-
-/// A SIMD vector with two elements of type `usize`.
-pub type usizex2 = Simd<usize, 2>;
-
-/// A SIMD vector with four elements of type `usize`.
-pub type usizex4 = Simd<usize, 4>;
-
-/// A SIMD vector with eight elements of type `usize`.
-pub type usizex8 = Simd<usize, 8>;
-
-/// A 32-bit SIMD vector with two elements of type `u16`.
-pub type u16x2 = Simd<u16, 2>;
-
-/// A 64-bit SIMD vector with four elements of type `u16`.
-pub type u16x4 = Simd<u16, 4>;
-
-/// A 128-bit SIMD vector with eight elements of type `u16`.
-pub type u16x8 = Simd<u16, 8>;
-
-/// A 256-bit SIMD vector with 16 elements of type `u16`.
-pub type u16x16 = Simd<u16, 16>;
-
-/// A 512-bit SIMD vector with 32 elements of type `u16`.
-pub type u16x32 = Simd<u16, 32>;
-
-/// A 64-bit SIMD vector with two elements of type `u32`.
-pub type u32x2 = Simd<u32, 2>;
-
-/// A 128-bit SIMD vector with four elements of type `u32`.
-pub type u32x4 = Simd<u32, 4>;
-
-/// A 256-bit SIMD vector with eight elements of type `u32`.
-pub type u32x8 = Simd<u32, 8>;
-
-/// A 512-bit SIMD vector with 16 elements of type `u32`.
-pub type u32x16 = Simd<u32, 16>;
-
-/// A 128-bit SIMD vector with two elements of type `u64`.
-pub type u64x2 = Simd<u64, 2>;
-
-/// A 256-bit SIMD vector with four elements of type `u64`.
-pub type u64x4 = Simd<u64, 4>;
-
-/// A 512-bit SIMD vector with eight elements of type `u64`.
-pub type u64x8 = Simd<u64, 8>;
-
-/// A 32-bit SIMD vector with four elements of type `u8`.
-pub type u8x4 = Simd<u8, 4>;
-
-/// A 64-bit SIMD vector with eight elements of type `u8`.
-pub type u8x8 = Simd<u8, 8>;
-
-/// A 128-bit SIMD vector with 16 elements of type `u8`.
-pub type u8x16 = Simd<u8, 16>;
-
-/// A 256-bit SIMD vector with 32 elements of type `u8`.
-pub type u8x32 = Simd<u8, 32>;
-
-/// A 512-bit SIMD vector with 64 elements of type `u8`.
-pub type u8x64 = Simd<u8, 64>;
diff --git a/library/portable-simd/crates/core_simd/tests/autoderef.rs b/library/portable-simd/crates/core_simd/tests/autoderef.rs
index 9359da16ee5..3181826ef59 100644
--- a/library/portable-simd/crates/core_simd/tests/autoderef.rs
+++ b/library/portable-simd/crates/core_simd/tests/autoderef.rs
@@ -1,6 +1,6 @@
// Test that we handle all our "auto-deref" cases correctly.
#![feature(portable_simd)]
-use core_simd::f32x4;
+use core_simd::simd::f32x4;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
diff --git a/library/portable-simd/crates/core_simd/tests/mask_ops_impl/mask_macros.rs b/library/portable-simd/crates/core_simd/tests/mask_ops_impl/mask_macros.rs
index 795f9e27c44..faafa5fa51f 100644
--- a/library/portable-simd/crates/core_simd/tests/mask_ops_impl/mask_macros.rs
+++ b/library/portable-simd/crates/core_simd/tests/mask_ops_impl/mask_macros.rs
@@ -2,7 +2,7 @@ macro_rules! mask_tests {
{ $vector:ident, $lanes:literal } => {
#[cfg(test)]
mod $vector {
- use core_simd::$vector as Vector;
+ use core_simd::simd::$vector as Vector;
const LANES: usize = $lanes;
#[cfg(target_arch = "wasm32")]
diff --git a/library/portable-simd/crates/core_simd/tests/masks.rs b/library/portable-simd/crates/core_simd/tests/masks.rs
index 673d0db93fe..9f8bad1c36c 100644
--- a/library/portable-simd/crates/core_simd/tests/masks.rs
+++ b/library/portable-simd/crates/core_simd/tests/masks.rs
@@ -13,11 +13,13 @@ macro_rules! test_mask_api {
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
+ use core_simd::simd::Mask;
+
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn set_and_test() {
let values = [true, false, false, true, false, false, true, false];
- let mut mask = core_simd::Mask::<$type, 8>::splat(false);
+ let mut mask = Mask::<$type, 8>::splat(false);
for (lane, value) in values.iter().copied().enumerate() {
mask.set(lane, value);
}
@@ -29,7 +31,7 @@ macro_rules! test_mask_api {
#[test]
#[should_panic]
fn set_invalid_lane() {
- let mut mask = core_simd::Mask::<$type, 8>::splat(false);
+ let mut mask = Mask::<$type, 8>::splat(false);
mask.set(8, true);
let _ = mask;
}
@@ -37,24 +39,24 @@ macro_rules! test_mask_api {
#[test]
#[should_panic]
fn test_invalid_lane() {
- let mask = core_simd::Mask::<$type, 8>::splat(false);
+ let mask = Mask::<$type, 8>::splat(false);
let _ = mask.test(8);
}
#[test]
fn any() {
- assert!(!core_simd::Mask::<$type, 8>::splat(false).any());
- assert!(core_simd::Mask::<$type, 8>::splat(true).any());
- let mut v = core_simd::Mask::<$type, 8>::splat(false);
+ assert!(!Mask::<$type, 8>::splat(false).any());
+ assert!(Mask::<$type, 8>::splat(true).any());
+ let mut v = Mask::<$type, 8>::splat(false);
v.set(2, true);
assert!(v.any());
}
#[test]
fn all() {
- assert!(!core_simd::Mask::<$type, 8>::splat(false).all());
- assert!(core_simd::Mask::<$type, 8>::splat(true).all());
- let mut v = core_simd::Mask::<$type, 8>::splat(false);
+ assert!(!Mask::<$type, 8>::splat(false).all());
+ assert!(Mask::<$type, 8>::splat(true).all());
+ let mut v = Mask::<$type, 8>::splat(false);
v.set(2, true);
assert!(!v.all());
}
@@ -62,57 +64,57 @@ macro_rules! test_mask_api {
#[test]
fn roundtrip_int_conversion() {
let values = [true, false, false, true, false, false, true, false];
- let mask = core_simd::Mask::<$type, 8>::from_array(values);
+ let mask = Mask::<$type, 8>::from_array(values);
let int = mask.to_int();
assert_eq!(int.to_array(), [-1, 0, 0, -1, 0, 0, -1, 0]);
- assert_eq!(core_simd::Mask::<$type, 8>::from_int(int), mask);
+ assert_eq!(Mask::<$type, 8>::from_int(int), mask);
}
#[test]
fn roundtrip_bitmask_conversion() {
- use core_simd::ToBitMask;
+ use core_simd::simd::ToBitMask;
let values = [
true, false, false, true, false, false, true, false,
true, true, false, false, false, false, false, true,
];
- let mask = core_simd::Mask::<$type, 16>::from_array(values);
+ let mask = Mask::<$type, 16>::from_array(values);
let bitmask = mask.to_bitmask();
assert_eq!(bitmask, 0b1000001101001001);
- assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask(bitmask), mask);
+ assert_eq!(Mask::<$type, 16>::from_bitmask(bitmask), mask);
}
#[test]
fn roundtrip_bitmask_conversion_short() {
- use core_simd::ToBitMask;
+ use core_simd::simd::ToBitMask;
let values = [
false, false, false, true,
];
- let mask = core_simd::Mask::<$type, 4>::from_array(values);
+ let mask = Mask::<$type, 4>::from_array(values);
let bitmask = mask.to_bitmask();
assert_eq!(bitmask, 0b1000);
- assert_eq!(core_simd::Mask::<$type, 4>::from_bitmask(bitmask), mask);
+ assert_eq!(Mask::<$type, 4>::from_bitmask(bitmask), mask);
let values = [true, false];
- let mask = core_simd::Mask::<$type, 2>::from_array(values);
+ let mask = Mask::<$type, 2>::from_array(values);
let bitmask = mask.to_bitmask();
assert_eq!(bitmask, 0b01);
- assert_eq!(core_simd::Mask::<$type, 2>::from_bitmask(bitmask), mask);
+ assert_eq!(Mask::<$type, 2>::from_bitmask(bitmask), mask);
}
#[test]
fn cast() {
- fn cast_impl<T: core_simd::MaskElement>()
+ fn cast_impl<T: core_simd::simd::MaskElement>()
where
- core_simd::Mask<$type, 8>: Into<core_simd::Mask<T, 8>>,
+ Mask<$type, 8>: Into<Mask<T, 8>>,
{
let values = [true, false, false, true, false, false, true, false];
- let mask = core_simd::Mask::<$type, 8>::from_array(values);
+ let mask = Mask::<$type, 8>::from_array(values);
let cast_mask = mask.cast::<T>();
assert_eq!(values, cast_mask.to_array());
- let into_mask: core_simd::Mask<T, 8> = mask.into();
+ let into_mask: Mask<T, 8> = mask.into();
assert_eq!(values, into_mask.to_array());
}
@@ -126,15 +128,15 @@ macro_rules! test_mask_api {
#[cfg(feature = "generic_const_exprs")]
#[test]
fn roundtrip_bitmask_array_conversion() {
- use core_simd::ToBitMaskArray;
+ use core_simd::simd::ToBitMaskArray;
let values = [
true, false, false, true, false, false, true, false,
true, true, false, false, false, false, false, true,
];
- let mask = core_simd::Mask::<$type, 16>::from_array(values);
+ let mask = Mask::<$type, 16>::from_array(values);
let bitmask = mask.to_bitmask_array();
assert_eq!(bitmask, [0b01001001, 0b10000011]);
- assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask_array(bitmask), mask);
+ assert_eq!(Mask::<$type, 16>::from_bitmask_array(bitmask), mask);
}
}
}
@@ -150,9 +152,10 @@ mod mask_api {
#[test]
fn convert() {
+ use core_simd::simd::Mask;
let values = [true, false, false, true, false, false, true, false];
assert_eq!(
- core_simd::Mask::<i8, 8>::from_array(values),
- core_simd::Mask::<i32, 8>::from_array(values).into()
+ Mask::<i8, 8>::from_array(values),
+ Mask::<i32, 8>::from_array(values).into()
);
}
diff --git a/library/portable-simd/crates/core_simd/tests/ops_macros.rs b/library/portable-simd/crates/core_simd/tests/ops_macros.rs
index f759394d075..3a02f3f01e1 100644
--- a/library/portable-simd/crates/core_simd/tests/ops_macros.rs
+++ b/library/portable-simd/crates/core_simd/tests/ops_macros.rs
@@ -7,7 +7,7 @@ macro_rules! impl_unary_op_test {
test_helpers::test_lanes! {
fn $fn<const LANES: usize>() {
test_helpers::test_unary_elementwise(
- &<core_simd::Simd<$scalar, LANES> as core::ops::$trait>::$fn,
+ &<core_simd::simd::Simd<$scalar, LANES> as core::ops::$trait>::$fn,
&$scalar_fn,
&|_| true,
);
@@ -27,7 +27,7 @@ macro_rules! impl_binary_op_test {
{ $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr } => {
mod $fn {
use super::*;
- use core_simd::Simd;
+ use core_simd::simd::Simd;
test_helpers::test_lanes! {
fn normal<const LANES: usize>() {
@@ -64,7 +64,7 @@ macro_rules! impl_binary_checked_op_test {
{ $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr, $check_fn:expr } => {
mod $fn {
use super::*;
- use core_simd::Simd;
+ use core_simd::simd::Simd;
test_helpers::test_lanes! {
fn normal<const LANES: usize>() {
@@ -173,7 +173,7 @@ macro_rules! impl_signed_tests {
{ $scalar:tt } => {
mod $scalar {
use core_simd::simd::SimdInt;
- type Vector<const LANES: usize> = core_simd::Simd<Scalar, LANES>;
+ type Vector<const LANES: usize> = core_simd::simd::Simd<Scalar, LANES>;
type Scalar = $scalar;
impl_common_integer_tests! { Vector, Scalar }
@@ -314,7 +314,7 @@ macro_rules! impl_unsigned_tests {
{ $scalar:tt } => {
mod $scalar {
use core_simd::simd::SimdUint;
- type Vector<const LANES: usize> = core_simd::Simd<Scalar, LANES>;
+ type Vector<const LANES: usize> = core_simd::simd::Simd<Scalar, LANES>;
type Scalar = $scalar;
impl_common_integer_tests! { Vector, Scalar }
@@ -348,8 +348,8 @@ macro_rules! impl_unsigned_tests {
macro_rules! impl_float_tests {
{ $scalar:tt, $int_scalar:tt } => {
mod $scalar {
- use core_simd::SimdFloat;
- type Vector<const LANES: usize> = core_simd::Simd<Scalar, LANES>;
+ use core_simd::simd::SimdFloat;
+ type Vector<const LANES: usize> = core_simd::simd::Simd<Scalar, LANES>;
type Scalar = $scalar;
impl_unary_op_test!(Scalar, Neg::neg);
diff --git a/library/portable-simd/crates/core_simd/tests/pointers.rs b/library/portable-simd/crates/core_simd/tests/pointers.rs
new file mode 100644
index 00000000000..0ae8f83b8b9
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/tests/pointers.rs
@@ -0,0 +1,111 @@
+#![feature(portable_simd, strict_provenance)]
+
+use core_simd::simd::{Simd, SimdConstPtr, SimdMutPtr};
+
+macro_rules! common_tests {
+ { $constness:ident } => {
+ test_helpers::test_lanes! {
+ fn is_null<const LANES: usize>() {
+ test_helpers::test_unary_mask_elementwise(
+ &Simd::<*$constness u32, LANES>::is_null,
+ &<*$constness u32>::is_null,
+ &|_| true,
+ );
+ }
+
+ fn addr<const LANES: usize>() {
+ test_helpers::test_unary_elementwise(
+ &Simd::<*$constness u32, LANES>::addr,
+ &<*$constness u32>::addr,
+ &|_| true,
+ );
+ }
+
+ fn with_addr<const LANES: usize>() {
+ test_helpers::test_binary_elementwise(
+ &Simd::<*$constness u32, LANES>::with_addr,
+ &<*$constness u32>::with_addr,
+ &|_, _| true,
+ );
+ }
+
+ fn expose_addr<const LANES: usize>() {
+ test_helpers::test_unary_elementwise(
+ &Simd::<*$constness u32, LANES>::expose_addr,
+ &<*$constness u32>::expose_addr,
+ &|_| true,
+ );
+ }
+
+ fn wrapping_offset<const LANES: usize>() {
+ test_helpers::test_binary_elementwise(
+ &Simd::<*$constness u32, LANES>::wrapping_offset,
+ &<*$constness u32>::wrapping_offset,
+ &|_, _| true,
+ );
+ }
+
+ fn wrapping_add<const LANES: usize>() {
+ test_helpers::test_binary_elementwise(
+ &Simd::<*$constness u32, LANES>::wrapping_add,
+ &<*$constness u32>::wrapping_add,
+ &|_, _| true,
+ );
+ }
+
+ fn wrapping_sub<const LANES: usize>() {
+ test_helpers::test_binary_elementwise(
+ &Simd::<*$constness u32, LANES>::wrapping_sub,
+ &<*$constness u32>::wrapping_sub,
+ &|_, _| true,
+ );
+ }
+ }
+ }
+}
+
+mod const_ptr {
+ use super::*;
+ common_tests! { const }
+
+ test_helpers::test_lanes! {
+ fn cast_mut<const LANES: usize>() {
+ test_helpers::test_unary_elementwise(
+ &Simd::<*const u32, LANES>::cast_mut,
+ &<*const u32>::cast_mut,
+ &|_| true,
+ );
+ }
+
+ fn from_exposed_addr<const LANES: usize>() {
+ test_helpers::test_unary_elementwise(
+ &Simd::<*const u32, LANES>::from_exposed_addr,
+ &core::ptr::from_exposed_addr::<u32>,
+ &|_| true,
+ );
+ }
+ }
+}
+
+mod mut_ptr {
+ use super::*;
+ common_tests! { mut }
+
+ test_helpers::test_lanes! {
+ fn cast_const<const LANES: usize>() {
+ test_helpers::test_unary_elementwise(
+ &Simd::<*mut u32, LANES>::cast_const,
+ &<*mut u32>::cast_const,
+ &|_| true,
+ );
+ }
+
+ fn from_exposed_addr<const LANES: usize>() {
+ test_helpers::test_unary_elementwise(
+ &Simd::<*mut u32, LANES>::from_exposed_addr,
+ &core::ptr::from_exposed_addr_mut::<u32>,
+ &|_| true,
+ );
+ }
+ }
+}
diff --git a/library/portable-simd/crates/core_simd/tests/round.rs b/library/portable-simd/crates/core_simd/tests/round.rs
index 484fd5bf47d..8b9638ad466 100644
--- a/library/portable-simd/crates/core_simd/tests/round.rs
+++ b/library/portable-simd/crates/core_simd/tests/round.rs
@@ -5,7 +5,7 @@ macro_rules! float_rounding_test {
mod $scalar {
use std_float::StdFloat;
- type Vector<const LANES: usize> = core_simd::Simd<$scalar, LANES>;
+ type Vector<const LANES: usize> = core_simd::simd::Simd<$scalar, LANES>;
type Scalar = $scalar;
type IntScalar = $int_scalar;
diff --git a/library/portable-simd/crates/core_simd/tests/swizzle.rs b/library/portable-simd/crates/core_simd/tests/swizzle.rs
index 51c63611aba..8cd7c33e823 100644
--- a/library/portable-simd/crates/core_simd/tests/swizzle.rs
+++ b/library/portable-simd/crates/core_simd/tests/swizzle.rs
@@ -1,5 +1,5 @@
#![feature(portable_simd)]
-use core_simd::{Simd, Swizzle};
+use core_simd::simd::{Simd, Swizzle};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
@@ -60,3 +60,17 @@ fn interleave() {
assert_eq!(even, a);
assert_eq!(odd, b);
}
+
+// portable-simd#298
+#[test]
+#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+fn interleave_one() {
+ let a = Simd::from_array([0]);
+ let b = Simd::from_array([1]);
+ let (lo, hi) = a.interleave(b);
+ assert_eq!(lo.to_array(), [0]);
+ assert_eq!(hi.to_array(), [1]);
+ let (even, odd) = lo.deinterleave(hi);
+ assert_eq!(even, a);
+ assert_eq!(odd, b);
+}
diff --git a/library/portable-simd/crates/core_simd/tests/swizzle_dyn.rs b/library/portable-simd/crates/core_simd/tests/swizzle_dyn.rs
new file mode 100644
index 00000000000..646cd5f3383
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/tests/swizzle_dyn.rs
@@ -0,0 +1,74 @@
+#![feature(portable_simd)]
+use core::{fmt, ops::RangeInclusive};
+use proptest;
+use test_helpers::{self, biteq, make_runner, prop_assert_biteq};
+
+fn swizzle_dyn_scalar_ver<const N: usize>(values: [u8; N], idxs: [u8; N]) -> [u8; N] {
+ let mut array = [0; N];
+ for (i, k) in idxs.into_iter().enumerate() {
+ if (k as usize) < N {
+ array[i] = values[k as usize];
+ };
+ }
+ array
+}
+
+test_helpers::test_lanes! {
+ fn swizzle_dyn<const N: usize>() {
+ match_simd_with_fallback(
+ &core_simd::simd::Simd::<u8, N>::swizzle_dyn,
+ &swizzle_dyn_scalar_ver,
+ &|_, _| true,
+ );
+ }
+}
+
+fn match_simd_with_fallback<Scalar, ScalarResult, Vector, VectorResult, const N: usize>(
+ fv: &dyn Fn(Vector, Vector) -> VectorResult,
+ fs: &dyn Fn([Scalar; N], [Scalar; N]) -> [ScalarResult; N],
+ check: &dyn Fn([Scalar; N], [Scalar; N]) -> bool,
+) where
+ Scalar: Copy + fmt::Debug + SwizzleStrategy,
+ ScalarResult: Copy + biteq::BitEq + fmt::Debug + SwizzleStrategy,
+ Vector: Into<[Scalar; N]> + From<[Scalar; N]> + Copy,
+ VectorResult: Into<[ScalarResult; N]> + From<[ScalarResult; N]> + Copy,
+{
+ test_swizzles_2(&|x: [Scalar; N], y: [Scalar; N]| {
+ proptest::prop_assume!(check(x, y));
+ let result_v: [ScalarResult; N] = fv(x.into(), y.into()).into();
+ let result_s: [ScalarResult; N] = fs(x, y);
+ crate::prop_assert_biteq!(result_v, result_s);
+ Ok(())
+ });
+}
+
+fn test_swizzles_2<A: fmt::Debug + SwizzleStrategy, B: fmt::Debug + SwizzleStrategy>(
+ f: &dyn Fn(A, B) -> proptest::test_runner::TestCaseResult,
+) {
+ let mut runner = make_runner();
+ runner
+ .run(
+ &(A::swizzled_strategy(), B::swizzled_strategy()),
+ |(a, b)| f(a, b),
+ )
+ .unwrap();
+}
+
+pub trait SwizzleStrategy {
+ type Strategy: proptest::strategy::Strategy<Value = Self>;
+ fn swizzled_strategy() -> Self::Strategy;
+}
+
+impl SwizzleStrategy for u8 {
+ type Strategy = RangeInclusive<u8>;
+ fn swizzled_strategy() -> Self::Strategy {
+ 0..=64
+ }
+}
+
+impl<T: fmt::Debug + SwizzleStrategy, const N: usize> SwizzleStrategy for [T; N] {
+ type Strategy = test_helpers::array::UniformArrayStrategy<T::Strategy, Self>;
+ fn swizzled_strategy() -> Self::Strategy {
+ Self::Strategy::new(T::swizzled_strategy())
+ }
+}
diff --git a/library/portable-simd/crates/core_simd/tests/to_bytes.rs b/library/portable-simd/crates/core_simd/tests/to_bytes.rs
index debb4335e2c..be0ee4349c5 100644
--- a/library/portable-simd/crates/core_simd/tests/to_bytes.rs
+++ b/library/portable-simd/crates/core_simd/tests/to_bytes.rs
@@ -2,7 +2,7 @@
#![allow(incomplete_features)]
#![cfg(feature = "generic_const_exprs")]
-use core_simd::Simd;
+use core_simd::simd::Simd;
#[test]
fn byte_convert() {
diff --git a/library/portable-simd/crates/core_simd/tests/try_from_slice.rs b/library/portable-simd/crates/core_simd/tests/try_from_slice.rs
new file mode 100644
index 00000000000..859e3b94f2c
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/tests/try_from_slice.rs
@@ -0,0 +1,25 @@
+#![feature(portable_simd)]
+
+#[cfg(target_arch = "wasm32")]
+use wasm_bindgen_test::*;
+
+#[cfg(target_arch = "wasm32")]
+wasm_bindgen_test_configure!(run_in_browser);
+
+use core_simd::simd::i32x4;
+
+#[test]
+#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+fn try_from_slice() {
+ // Equal length
+ assert_eq!(
+ i32x4::try_from([1, 2, 3, 4].as_slice()).unwrap(),
+ i32x4::from_array([1, 2, 3, 4])
+ );
+
+ // Slice length > vector length
+ assert!(i32x4::try_from([1, 2, 3, 4, 5].as_slice()).is_err());
+
+ // Slice length < vector length
+ assert!(i32x4::try_from([1, 2, 3].as_slice()).is_err());
+}
diff --git a/library/portable-simd/crates/test_helpers/Cargo.toml b/library/portable-simd/crates/test_helpers/Cargo.toml
index a04b0961d7f..1d2bc8b519a 100644
--- a/library/portable-simd/crates/test_helpers/Cargo.toml
+++ b/library/portable-simd/crates/test_helpers/Cargo.toml
@@ -8,3 +8,6 @@ publish = false
version = "0.10"
default-features = false
features = ["alloc"]
+
+[features]
+all_lane_counts = []
diff --git a/library/portable-simd/crates/test_helpers/src/array.rs b/library/portable-simd/crates/test_helpers/src/array.rs
index 5ffc9226976..984a427320d 100644
--- a/library/portable-simd/crates/test_helpers/src/array.rs
+++ b/library/portable-simd/crates/test_helpers/src/array.rs
@@ -41,6 +41,7 @@ where
fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
let tree: [S::Tree; LANES] = unsafe {
+ #[allow(clippy::uninit_assumed_init)]
let mut tree: [MaybeUninit<S::Tree>; LANES] = MaybeUninit::uninit().assume_init();
for t in tree.iter_mut() {
*t = MaybeUninit::new(self.strategy.new_tree(runner)?)
@@ -60,6 +61,7 @@ impl<T: ValueTree, const LANES: usize> ValueTree for ArrayValueTree<[T; LANES]>
fn current(&self) -> Self::Value {
unsafe {
+ #[allow(clippy::uninit_assumed_init)]
let mut value: [MaybeUninit<T::Value>; LANES] = MaybeUninit::uninit().assume_init();
for (tree_elem, value_elem) in self.tree.iter().zip(value.iter_mut()) {
*value_elem = MaybeUninit::new(tree_elem.current());
diff --git a/library/portable-simd/crates/test_helpers/src/biteq.rs b/library/portable-simd/crates/test_helpers/src/biteq.rs
index 00350e22418..7d91260d838 100644
--- a/library/portable-simd/crates/test_helpers/src/biteq.rs
+++ b/library/portable-simd/crates/test_helpers/src/biteq.rs
@@ -55,6 +55,26 @@ macro_rules! impl_float_biteq {
impl_float_biteq! { f32, f64 }
+impl<T> BitEq for *const T {
+ fn biteq(&self, other: &Self) -> bool {
+ self == other
+ }
+
+ fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+ write!(f, "{:?}", self)
+ }
+}
+
+impl<T> BitEq for *mut T {
+ fn biteq(&self, other: &Self) -> bool {
+ self == other
+ }
+
+ fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+ write!(f, "{:?}", self)
+ }
+}
+
impl<T: BitEq, const N: usize> BitEq for [T; N] {
fn biteq(&self, other: &Self) -> bool {
self.iter()
diff --git a/library/portable-simd/crates/test_helpers/src/lib.rs b/library/portable-simd/crates/test_helpers/src/lib.rs
index 141bee18a9a..b26cdc311a2 100644
--- a/library/portable-simd/crates/test_helpers/src/lib.rs
+++ b/library/portable-simd/crates/test_helpers/src/lib.rs
@@ -38,6 +38,28 @@ impl_num! { usize }
impl_num! { f32 }
impl_num! { f64 }
+impl<T> DefaultStrategy for *const T {
+ type Strategy = proptest::strategy::Map<proptest::num::isize::Any, fn(isize) -> *const T>;
+ fn default_strategy() -> Self::Strategy {
+ fn map<T>(x: isize) -> *const T {
+ x as _
+ }
+ use proptest::strategy::Strategy;
+ proptest::num::isize::ANY.prop_map(map)
+ }
+}
+
+impl<T> DefaultStrategy for *mut T {
+ type Strategy = proptest::strategy::Map<proptest::num::isize::Any, fn(isize) -> *mut T>;
+ fn default_strategy() -> Self::Strategy {
+ fn map<T>(x: isize) -> *mut T {
+ x as _
+ }
+ use proptest::strategy::Strategy;
+ proptest::num::isize::ANY.prop_map(map)
+ }
+}
+
#[cfg(not(target_arch = "wasm32"))]
impl DefaultStrategy for u128 {
type Strategy = proptest::num::u128::Any;
@@ -135,21 +157,21 @@ pub fn test_unary_elementwise<Scalar, ScalarResult, Vector, VectorResult, const
fs: &dyn Fn(Scalar) -> ScalarResult,
check: &dyn Fn([Scalar; LANES]) -> bool,
) where
- Scalar: Copy + Default + core::fmt::Debug + DefaultStrategy,
- ScalarResult: Copy + Default + biteq::BitEq + core::fmt::Debug + DefaultStrategy,
+ Scalar: Copy + core::fmt::Debug + DefaultStrategy,
+ ScalarResult: Copy + biteq::BitEq + core::fmt::Debug + DefaultStrategy,
Vector: Into<[Scalar; LANES]> + From<[Scalar; LANES]> + Copy,
VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy,
{
test_1(&|x: [Scalar; LANES]| {
proptest::prop_assume!(check(x));
let result_1: [ScalarResult; LANES] = fv(x.into()).into();
- let result_2: [ScalarResult; LANES] = {
- let mut result = [ScalarResult::default(); LANES];
- for (i, o) in x.iter().zip(result.iter_mut()) {
- *o = fs(*i);
- }
- result
- };
+ let result_2: [ScalarResult; LANES] = x
+ .iter()
+ .copied()
+ .map(fs)
+ .collect::<Vec<_>>()
+ .try_into()
+ .unwrap();
crate::prop_assert_biteq!(result_1, result_2);
Ok(())
});
@@ -162,7 +184,7 @@ pub fn test_unary_mask_elementwise<Scalar, Vector, Mask, const LANES: usize>(
fs: &dyn Fn(Scalar) -> bool,
check: &dyn Fn([Scalar; LANES]) -> bool,
) where
- Scalar: Copy + Default + core::fmt::Debug + DefaultStrategy,
+ Scalar: Copy + core::fmt::Debug + DefaultStrategy,
Vector: Into<[Scalar; LANES]> + From<[Scalar; LANES]> + Copy,
Mask: Into<[bool; LANES]> + From<[bool; LANES]> + Copy,
{
@@ -196,9 +218,9 @@ pub fn test_binary_elementwise<
fs: &dyn Fn(Scalar1, Scalar2) -> ScalarResult,
check: &dyn Fn([Scalar1; LANES], [Scalar2; LANES]) -> bool,
) where
- Scalar1: Copy + Default + core::fmt::Debug + DefaultStrategy,
- Scalar2: Copy + Default + core::fmt::Debug + DefaultStrategy,
- ScalarResult: Copy + Default + biteq::BitEq + core::fmt::Debug + DefaultStrategy,
+ Scalar1: Copy + core::fmt::Debug + DefaultStrategy,
+ Scalar2: Copy + core::fmt::Debug + DefaultStrategy,
+ ScalarResult: Copy + biteq::BitEq + core::fmt::Debug + DefaultStrategy,
Vector1: Into<[Scalar1; LANES]> + From<[Scalar1; LANES]> + Copy,
Vector2: Into<[Scalar2; LANES]> + From<[Scalar2; LANES]> + Copy,
VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy,
@@ -206,13 +228,14 @@ pub fn test_binary_elementwise<
test_2(&|x: [Scalar1; LANES], y: [Scalar2; LANES]| {
proptest::prop_assume!(check(x, y));
let result_1: [ScalarResult; LANES] = fv(x.into(), y.into()).into();
- let result_2: [ScalarResult; LANES] = {
- let mut result = [ScalarResult::default(); LANES];
- for ((i1, i2), o) in x.iter().zip(y.iter()).zip(result.iter_mut()) {
- *o = fs(*i1, *i2);
- }
- result
- };
+ let result_2: [ScalarResult; LANES] = x
+ .iter()
+ .copied()
+ .zip(y.iter().copied())
+ .map(|(x, y)| fs(x, y))
+ .collect::<Vec<_>>()
+ .try_into()
+ .unwrap();
crate::prop_assert_biteq!(result_1, result_2);
Ok(())
});
@@ -333,6 +356,39 @@ pub fn test_ternary_elementwise<
);
}
+#[doc(hidden)]
+#[macro_export]
+macro_rules! test_lanes_helper {
+ ($($(#[$meta:meta])* $fn_name:ident $lanes:literal;)+) => {
+ $(
+ #[test]
+ $(#[$meta])*
+ fn $fn_name() {
+ implementation::<$lanes>();
+ }
+ )+
+ };
+ (
+ $(#[$meta:meta])+;
+ $($(#[$meta_before:meta])+ $fn_name_before:ident $lanes_before:literal;)*
+ $fn_name:ident $lanes:literal;
+ $($fn_name_rest:ident $lanes_rest:literal;)*
+ ) => {
+ $crate::test_lanes_helper!(
+ $(#[$meta])+;
+ $($(#[$meta_before])+ $fn_name_before $lanes_before;)*
+ $(#[$meta])+ $fn_name $lanes;
+ $($fn_name_rest $lanes_rest;)*
+ );
+ };
+ (
+ $(#[$meta_ignored:meta])+;
+ $($(#[$meta:meta])+ $fn_name:ident $lanes:literal;)+
+ ) => {
+ $crate::test_lanes_helper!($($(#[$meta])+ $fn_name $lanes;)+);
+ };
+}
+
/// Expand a const-generic test into separate tests for each possible lane count.
#[macro_export]
macro_rules! test_lanes {
@@ -345,57 +401,96 @@ macro_rules! test_lanes {
fn implementation<const $lanes: usize>()
where
- core_simd::LaneCount<$lanes>: core_simd::SupportedLaneCount,
+ core_simd::simd::LaneCount<$lanes>: core_simd::simd::SupportedLaneCount,
$body
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
- #[test]
- #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
- fn lanes_1() {
- implementation::<1>();
- }
-
- #[test]
- #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
- fn lanes_2() {
- implementation::<2>();
- }
-
- #[test]
- #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
- fn lanes_4() {
- implementation::<4>();
- }
+ $crate::test_lanes_helper!(
+ #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)];
+ lanes_1 1;
+ lanes_2 2;
+ lanes_4 4;
+ );
- #[test]
- #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
- fn lanes_8() {
- implementation::<8>();
- }
-
- #[test]
- #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
+ $crate::test_lanes_helper!(
+ #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)];
+ lanes_8 8;
+ lanes_16 16;
+ lanes_32 32;
+ lanes_64 64;
+ );
+
+ #[cfg(feature = "all_lane_counts")]
+ $crate::test_lanes_helper!(
+ // test some odd and even non-power-of-2 lengths on miri
+ #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)];
+ lanes_3 3;
+ lanes_5 5;
+ lanes_6 6;
+ );
+
+ #[cfg(feature = "all_lane_counts")]
#[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
- fn lanes_16() {
- implementation::<16>();
- }
-
- #[test]
- #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
- #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
- fn lanes_32() {
- implementation::<32>();
- }
-
- #[test]
- #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
- #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
- fn lanes_64() {
- implementation::<64>();
- }
+ $crate::test_lanes_helper!(
+ #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)];
+ lanes_7 7;
+ lanes_9 9;
+ lanes_10 10;
+ lanes_11 11;
+ lanes_12 12;
+ lanes_13 13;
+ lanes_14 14;
+ lanes_15 15;
+ lanes_17 17;
+ lanes_18 18;
+ lanes_19 19;
+ lanes_20 20;
+ lanes_21 21;
+ lanes_22 22;
+ lanes_23 23;
+ lanes_24 24;
+ lanes_25 25;
+ lanes_26 26;
+ lanes_27 27;
+ lanes_28 28;
+ lanes_29 29;
+ lanes_30 30;
+ lanes_31 31;
+ lanes_33 33;
+ lanes_34 34;
+ lanes_35 35;
+ lanes_36 36;
+ lanes_37 37;
+ lanes_38 38;
+ lanes_39 39;
+ lanes_40 40;
+ lanes_41 41;
+ lanes_42 42;
+ lanes_43 43;
+ lanes_44 44;
+ lanes_45 45;
+ lanes_46 46;
+ lanes_47 47;
+ lanes_48 48;
+ lanes_49 49;
+ lanes_50 50;
+ lanes_51 51;
+ lanes_52 52;
+ lanes_53 53;
+ lanes_54 54;
+ lanes_55 55;
+ lanes_56 56;
+ lanes_57 57;
+ lanes_58 58;
+ lanes_59 59;
+ lanes_60 60;
+ lanes_61 61;
+ lanes_62 62;
+ lanes_63 63;
+ );
}
)*
}
@@ -413,50 +508,93 @@ macro_rules! test_lanes_panic {
fn implementation<const $lanes: usize>()
where
- core_simd::LaneCount<$lanes>: core_simd::SupportedLaneCount,
+ core_simd::simd::LaneCount<$lanes>: core_simd::simd::SupportedLaneCount,
$body
- #[test]
- #[should_panic]
- fn lanes_1() {
- implementation::<1>();
- }
-
- #[test]
- #[should_panic]
- fn lanes_2() {
- implementation::<2>();
- }
-
- #[test]
- #[should_panic]
- fn lanes_4() {
- implementation::<4>();
- }
-
- #[test]
- #[should_panic]
- fn lanes_8() {
- implementation::<8>();
- }
+ $crate::test_lanes_helper!(
+ #[should_panic];
+ lanes_1 1;
+ lanes_2 2;
+ lanes_4 4;
+ );
- #[test]
- #[should_panic]
- fn lanes_16() {
- implementation::<16>();
- }
-
- #[test]
- #[should_panic]
- fn lanes_32() {
- implementation::<32>();
- }
-
- #[test]
- #[should_panic]
- fn lanes_64() {
- implementation::<64>();
- }
+ #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
+ $crate::test_lanes_helper!(
+ #[should_panic];
+ lanes_8 8;
+ lanes_16 16;
+ lanes_32 32;
+ lanes_64 64;
+ );
+
+ #[cfg(feature = "all_lane_counts")]
+ $crate::test_lanes_helper!(
+ // test some odd and even non-power-of-2 lengths on miri
+ #[should_panic];
+ lanes_3 3;
+ lanes_5 5;
+ lanes_6 6;
+ );
+
+ #[cfg(feature = "all_lane_counts")]
+ #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
+ $crate::test_lanes_helper!(
+ #[should_panic];
+ lanes_7 7;
+ lanes_9 9;
+ lanes_10 10;
+ lanes_11 11;
+ lanes_12 12;
+ lanes_13 13;
+ lanes_14 14;
+ lanes_15 15;
+ lanes_17 17;
+ lanes_18 18;
+ lanes_19 19;
+ lanes_20 20;
+ lanes_21 21;
+ lanes_22 22;
+ lanes_23 23;
+ lanes_24 24;
+ lanes_25 25;
+ lanes_26 26;
+ lanes_27 27;
+ lanes_28 28;
+ lanes_29 29;
+ lanes_30 30;
+ lanes_31 31;
+ lanes_33 33;
+ lanes_34 34;
+ lanes_35 35;
+ lanes_36 36;
+ lanes_37 37;
+ lanes_38 38;
+ lanes_39 39;
+ lanes_40 40;
+ lanes_41 41;
+ lanes_42 42;
+ lanes_43 43;
+ lanes_44 44;
+ lanes_45 45;
+ lanes_46 46;
+ lanes_47 47;
+ lanes_48 48;
+ lanes_49 49;
+ lanes_50 50;
+ lanes_51 51;
+ lanes_52 52;
+ lanes_53 53;
+ lanes_54 54;
+ lanes_55 55;
+ lanes_56 56;
+ lanes_57 57;
+ lanes_58 58;
+ lanes_59 59;
+ lanes_60 60;
+ lanes_61 61;
+ lanes_62 62;
+ lanes_63 63;
+ );
}
)*
}
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 6640c7fb162..2a6b1a5ec73 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -1946,7 +1946,7 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
/// On success, the total number of bytes copied is returned and it is equal to
/// the length of the `to` file as reported by `metadata`.
///
-/// If you’re wanting to copy the contents of one file to another and you’re
+/// If you want to copy the contents of one file to another and you’re
/// working with [`File`]s, see the [`io::copy()`] function.
///
/// # Platform-specific behavior
diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs
index 38b98afffa1..1d9d93f5b64 100644
--- a/library/std/src/io/copy.rs
+++ b/library/std/src/io/copy.rs
@@ -10,7 +10,7 @@ use crate::mem::MaybeUninit;
/// On success, the total number of bytes that were copied from
/// `reader` to `writer` is returned.
///
-/// If you’re wanting to copy the contents of one file to another and you’re
+/// If you want to copy the contents of one file to another and you’re
/// working with filesystem paths, see the [`fs::copy`] function.
///
/// [`fs::copy`]: crate::fs::copy
diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index 9b77cd8321b..cbf8209a5ad 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -9,7 +9,7 @@ use crate::io;
use crate::marker::PhantomData;
use crate::mem::forget;
use crate::ptr;
-use crate::sys::c;
+use crate::sys;
use crate::sys::cvt;
use crate::sys_common::{AsInner, FromInner, IntoInner};
@@ -190,14 +190,14 @@ impl BorrowedHandle<'_> {
/// object as the existing `BorrowedHandle` instance.
#[stable(feature = "io_safety", since = "1.63.0")]
pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedHandle> {
- self.duplicate(0, false, c::DUPLICATE_SAME_ACCESS)
+ self.duplicate(0, false, sys::c::DUPLICATE_SAME_ACCESS)
}
pub(crate) fn duplicate(
&self,
- access: c::DWORD,
+ access: u32,
inherit: bool,
- options: c::DWORD,
+ options: u32,
) -> io::Result<OwnedHandle> {
let handle = self.as_raw_handle();
@@ -211,14 +211,14 @@ impl BorrowedHandle<'_> {
let mut ret = ptr::null_mut();
cvt(unsafe {
- let cur_proc = c::GetCurrentProcess();
- c::DuplicateHandle(
+ let cur_proc = sys::c::GetCurrentProcess();
+ sys::c::DuplicateHandle(
cur_proc,
handle,
cur_proc,
&mut ret,
access,
- inherit as c::BOOL,
+ inherit as sys::c::BOOL,
options,
)
})?;
@@ -233,7 +233,7 @@ impl TryFrom<HandleOrInvalid> for OwnedHandle {
#[inline]
fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, InvalidHandleError> {
let owned_handle = handle_or_invalid.0;
- if owned_handle.handle == c::INVALID_HANDLE_VALUE {
+ if owned_handle.handle == sys::c::INVALID_HANDLE_VALUE {
// Don't call `CloseHandle`; it'd be harmless, except that it could
// overwrite the `GetLastError` error.
forget(owned_handle);
@@ -365,7 +365,7 @@ impl Drop for OwnedHandle {
#[inline]
fn drop(&mut self) {
unsafe {
- let _ = c::CloseHandle(self.handle);
+ let _ = sys::c::CloseHandle(self.handle);
}
}
}
@@ -437,6 +437,42 @@ impl<T: AsHandle> AsHandle for &mut T {
}
}
+#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")]
+/// This impl allows implementing traits that require `AsHandle` on Arc.
+/// ```
+/// # #[cfg(windows)] mod group_cfg {
+/// # use std::os::windows::io::AsHandle;
+/// use std::fs::File;
+/// use std::sync::Arc;
+///
+/// trait MyTrait: AsHandle {}
+/// impl MyTrait for Arc<File> {}
+/// impl MyTrait for Box<File> {}
+/// # }
+/// ```
+impl<T: AsHandle> AsHandle for crate::sync::Arc<T> {
+ #[inline]
+ fn as_handle(&self) -> BorrowedHandle<'_> {
+ (**self).as_handle()
+ }
+}
+
+#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")]
+impl<T: AsHandle> AsHandle for crate::rc::Rc<T> {
+ #[inline]
+ fn as_handle(&self) -> BorrowedHandle<'_> {
+ (**self).as_handle()
+ }
+}
+
+#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")]
+impl<T: AsHandle> AsHandle for Box<T> {
+ #[inline]
+ fn as_handle(&self) -> BorrowedHandle<'_> {
+ (**self).as_handle()
+ }
+}
+
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for BorrowedHandle<'_> {
#[inline]
diff --git a/library/std/src/os/windows/io/raw.rs b/library/std/src/os/windows/io/raw.rs
index 49e4f304f5d..1759e2e7f3f 100644
--- a/library/std/src/os/windows/io/raw.rs
+++ b/library/std/src/os/windows/io/raw.rs
@@ -11,7 +11,6 @@ use crate::os::windows::io::{OwnedHandle, OwnedSocket};
use crate::os::windows::raw;
use crate::ptr;
use crate::sys;
-use crate::sys::c;
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
/// Raw HANDLEs.
@@ -104,42 +103,42 @@ impl AsRawHandle for fs::File {
#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawHandle for io::Stdin {
fn as_raw_handle(&self) -> RawHandle {
- stdio_handle(unsafe { c::GetStdHandle(c::STD_INPUT_HANDLE) as RawHandle })
+ stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_INPUT_HANDLE) as RawHandle })
}
}
#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawHandle for io::Stdout {
fn as_raw_handle(&self) -> RawHandle {
- stdio_handle(unsafe { c::GetStdHandle(c::STD_OUTPUT_HANDLE) as RawHandle })
+ stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_OUTPUT_HANDLE) as RawHandle })
}
}
#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawHandle for io::Stderr {
fn as_raw_handle(&self) -> RawHandle {
- stdio_handle(unsafe { c::GetStdHandle(c::STD_ERROR_HANDLE) as RawHandle })
+ stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_ERROR_HANDLE) as RawHandle })
}
}
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawHandle for io::StdinLock<'a> {
fn as_raw_handle(&self) -> RawHandle {
- stdio_handle(unsafe { c::GetStdHandle(c::STD_INPUT_HANDLE) as RawHandle })
+ stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_INPUT_HANDLE) as RawHandle })
}
}
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawHandle for io::StdoutLock<'a> {
fn as_raw_handle(&self) -> RawHandle {
- stdio_handle(unsafe { c::GetStdHandle(c::STD_OUTPUT_HANDLE) as RawHandle })
+ stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_OUTPUT_HANDLE) as RawHandle })
}
}
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawHandle for io::StderrLock<'a> {
fn as_raw_handle(&self) -> RawHandle {
- stdio_handle(unsafe { c::GetStdHandle(c::STD_ERROR_HANDLE) as RawHandle })
+ stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_ERROR_HANDLE) as RawHandle })
}
}
@@ -152,14 +151,14 @@ fn stdio_handle(raw: RawHandle) -> RawHandle {
// console. In that case, return null to the user, which is consistent
// with what they'd get in the parent, and which avoids the problem that
// `INVALID_HANDLE_VALUE` aliases the current process handle.
- if raw == c::INVALID_HANDLE_VALUE { ptr::null_mut() } else { raw }
+ if raw == sys::c::INVALID_HANDLE_VALUE { ptr::null_mut() } else { raw }
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawHandle for fs::File {
#[inline]
unsafe fn from_raw_handle(handle: RawHandle) -> fs::File {
- let handle = handle as c::HANDLE;
+ let handle = handle as sys::c::HANDLE;
fs::File::from_inner(sys::fs::File::from_inner(FromInner::from_inner(
OwnedHandle::from_raw_handle(handle),
)))
diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs
index b6bd0f9e12b..0c90d55c024 100644
--- a/library/std/src/os/windows/io/socket.rs
+++ b/library/std/src/os/windows/io/socket.rs
@@ -9,7 +9,6 @@ use crate::marker::PhantomData;
use crate::mem;
use crate::mem::forget;
use crate::sys;
-use crate::sys::c;
#[cfg(not(target_vendor = "uwp"))]
use crate::sys::cvt;
@@ -76,7 +75,7 @@ impl BorrowedSocket<'_> {
#[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub const unsafe fn borrow_raw(socket: RawSocket) -> Self {
- assert!(socket != c::INVALID_SOCKET as RawSocket);
+ assert!(socket != sys::c::INVALID_SOCKET as RawSocket);
Self { socket, _phantom: PhantomData }
}
}
@@ -94,7 +93,11 @@ impl OwnedSocket {
#[cfg(not(target_vendor = "uwp"))]
pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
cvt(unsafe {
- c::SetHandleInformation(self.as_raw_socket() as c::HANDLE, c::HANDLE_FLAG_INHERIT, 0)
+ sys::c::SetHandleInformation(
+ self.as_raw_socket() as sys::c::HANDLE,
+ sys::c::HANDLE_FLAG_INHERIT,
+ 0,
+ )
})
.map(drop)
}
@@ -110,43 +113,47 @@ impl BorrowedSocket<'_> {
/// object as the existing `BorrowedSocket` instance.
#[stable(feature = "io_safety", since = "1.63.0")]
pub fn try_clone_to_owned(&self) -> io::Result<OwnedSocket> {
- let mut info = unsafe { mem::zeroed::<c::WSAPROTOCOL_INFO>() };
+ let mut info = unsafe { mem::zeroed::<sys::c::WSAPROTOCOL_INFOW>() };
let result = unsafe {
- c::WSADuplicateSocketW(self.as_raw_socket(), c::GetCurrentProcessId(), &mut info)
+ sys::c::WSADuplicateSocketW(
+ self.as_raw_socket(),
+ sys::c::GetCurrentProcessId(),
+ &mut info,
+ )
};
sys::net::cvt(result)?;
let socket = unsafe {
- c::WSASocketW(
+ sys::c::WSASocketW(
info.iAddressFamily,
info.iSocketType,
info.iProtocol,
&mut info,
0,
- c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT,
+ sys::c::WSA_FLAG_OVERLAPPED | sys::c::WSA_FLAG_NO_HANDLE_INHERIT,
)
};
- if socket != c::INVALID_SOCKET {
+ if socket != sys::c::INVALID_SOCKET {
unsafe { Ok(OwnedSocket::from_raw_socket(socket)) }
} else {
- let error = unsafe { c::WSAGetLastError() };
+ let error = unsafe { sys::c::WSAGetLastError() };
- if error != c::WSAEPROTOTYPE && error != c::WSAEINVAL {
+ if error != sys::c::WSAEPROTOTYPE && error != sys::c::WSAEINVAL {
return Err(io::Error::from_raw_os_error(error));
}
let socket = unsafe {
- c::WSASocketW(
+ sys::c::WSASocketW(
info.iAddressFamily,
info.iSocketType,
info.iProtocol,
&mut info,
0,
- c::WSA_FLAG_OVERLAPPED,
+ sys::c::WSA_FLAG_OVERLAPPED,
)
};
- if socket == c::INVALID_SOCKET {
+ if socket == sys::c::INVALID_SOCKET {
return Err(last_error());
}
@@ -161,7 +168,7 @@ impl BorrowedSocket<'_> {
/// Returns the last error from the Windows socket interface.
fn last_error() -> io::Error {
- io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
+ io::Error::from_raw_os_error(unsafe { sys::c::WSAGetLastError() })
}
#[stable(feature = "io_safety", since = "1.63.0")]
@@ -194,7 +201,7 @@ impl IntoRawSocket for OwnedSocket {
impl FromRawSocket for OwnedSocket {
#[inline]
unsafe fn from_raw_socket(socket: RawSocket) -> Self {
- debug_assert_ne!(socket, c::INVALID_SOCKET as RawSocket);
+ debug_assert_ne!(socket, sys::c::INVALID_SOCKET as RawSocket);
Self { socket }
}
}
@@ -204,7 +211,7 @@ impl Drop for OwnedSocket {
#[inline]
fn drop(&mut self) {
unsafe {
- let _ = c::closesocket(self.socket);
+ let _ = sys::c::closesocket(self.socket);
}
}
}
@@ -247,6 +254,42 @@ impl<T: AsSocket> AsSocket for &mut T {
}
}
+#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")]
+/// This impl allows implementing traits that require `AsSocket` on Arc.
+/// ```
+/// # #[cfg(windows)] mod group_cfg {
+/// # use std::os::windows::io::AsSocket;
+/// use std::net::UdpSocket;
+/// use std::sync::Arc;
+///
+/// trait MyTrait: AsSocket {}
+/// impl MyTrait for Arc<UdpSocket> {}
+/// impl MyTrait for Box<UdpSocket> {}
+/// # }
+/// ```
+impl<T: AsSocket> AsSocket for crate::sync::Arc<T> {
+ #[inline]
+ fn as_socket(&self) -> BorrowedSocket<'_> {
+ (**self).as_socket()
+ }
+}
+
+#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")]
+impl<T: AsSocket> AsSocket for crate::rc::Rc<T> {
+ #[inline]
+ fn as_socket(&self) -> BorrowedSocket<'_> {
+ (**self).as_socket()
+ }
+}
+
+#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")]
+impl<T: AsSocket> AsSocket for Box<T> {
+ #[inline]
+ fn as_socket(&self) -> BorrowedSocket<'_> {
+ (**self).as_socket()
+ }
+}
+
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsSocket for BorrowedSocket<'_> {
#[inline]
diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs
index 345d72ef867..a2ffd8b1e7e 100644
--- a/library/std/src/panic.rs
+++ b/library/std/src/panic.rs
@@ -26,7 +26,9 @@ pub macro panic_2015 {
$crate::rt::panic_display(&$arg)
}),
($fmt:expr, $($arg:tt)+) => ({
- $crate::rt::panic_fmt($crate::const_format_args!($fmt, $($arg)+))
+ // Semicolon to prevent temporaries inside the formatting machinery from
+ // being considered alive in the caller after the panic_fmt call.
+ $crate::rt::panic_fmt($crate::const_format_args!($fmt, $($arg)+));
}),
}
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index a46a29cbad6..6d59266b6f8 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -541,7 +541,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
// Lazily, the first time this gets called, run the actual string formatting.
self.string.get_or_insert_with(|| {
let mut s = String::new();
- drop(s.write_fmt(*inner));
+ let _err = s.write_fmt(*inner);
s
})
}
diff --git a/library/std/src/personality/dwarf/eh.rs b/library/std/src/personality/dwarf/eh.rs
index 87585a8fcd0..79624703a4c 100644
--- a/library/std/src/personality/dwarf/eh.rs
+++ b/library/std/src/personality/dwarf/eh.rs
@@ -47,6 +47,7 @@ pub enum EHAction {
None,
Cleanup(usize),
Catch(usize),
+ Filter(usize),
Terminate,
}
@@ -142,9 +143,11 @@ unsafe fn interpret_cs_action(
let ttype_index = action_reader.read_sleb128();
if ttype_index == 0 {
EHAction::Cleanup(lpad)
- } else {
+ } else if ttype_index > 0 {
// Stop unwinding Rust panics at catch_unwind.
EHAction::Catch(lpad)
+ } else {
+ EHAction::Filter(lpad)
}
}
}
diff --git a/library/std/src/personality/gcc.rs b/library/std/src/personality/gcc.rs
index 0421b47be02..82edb11cbd1 100644
--- a/library/std/src/personality/gcc.rs
+++ b/library/std/src/personality/gcc.rs
@@ -135,7 +135,7 @@ cfg_if::cfg_if! {
EHAction::None | EHAction::Cleanup(_) => {
return continue_unwind(exception_object, context);
}
- EHAction::Catch(_) => {
+ EHAction::Catch(_) | EHAction::Filter(_) => {
// EHABI requires the personality routine to update the
// SP value in the barrier cache of the exception object.
(*exception_object).private[5] =
@@ -147,7 +147,8 @@ cfg_if::cfg_if! {
} else {
match eh_action {
EHAction::None => return continue_unwind(exception_object, context),
- EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => {
+ EHAction::Filter(_) if state & uw::_US_FORCE_UNWIND as c_int != 0 => return continue_unwind(exception_object, context),
+ EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
uw::_Unwind_SetGR(
context,
UNWIND_DATA_REG.0,
@@ -201,13 +202,15 @@ cfg_if::cfg_if! {
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::Catch(_) | EHAction::Filter(_) => 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) => {
+ // Forced unwinding hits a terminate action.
+ EHAction::Filter(_) if actions as i32 & uw::_UA_FORCE_UNWIND as i32 != 0 => uw::_URC_CONTINUE_UNWIND,
+ EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
uw::_Unwind_SetGR(
context,
UNWIND_DATA_REG.0,
diff --git a/library/std/src/sync/mpmc/error.rs b/library/std/src/sync/mpmc/error.rs
index 1b8a1f38797..33b2bff8534 100644
--- a/library/std/src/sync/mpmc/error.rs
+++ b/library/std/src/sync/mpmc/error.rs
@@ -35,7 +35,7 @@ impl<T> fmt::Display for SendTimeoutError<T> {
}
}
-impl<T: Send> error::Error for SendTimeoutError<T> {}
+impl<T> error::Error for SendTimeoutError<T> {}
impl<T> From<SendError<T>> for SendTimeoutError<T> {
fn from(err: SendError<T>) -> SendTimeoutError<T> {
diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs
index 6e3c28f10bb..0e0c87d1c74 100644
--- a/library/std/src/sync/mpsc/mod.rs
+++ b/library/std/src/sync/mpsc/mod.rs
@@ -1124,7 +1124,7 @@ impl<T> fmt::Display for SendError<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> error::Error for SendError<T> {
+impl<T> error::Error for SendError<T> {
#[allow(deprecated)]
fn description(&self) -> &str {
"sending on a closed channel"
@@ -1152,7 +1152,7 @@ impl<T> fmt::Display for TrySendError<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> error::Error for TrySendError<T> {
+impl<T> error::Error for TrySendError<T> {
#[allow(deprecated)]
fn description(&self) -> &str {
match *self {
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index e767b2866cb..c72be13804d 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -52,31 +52,6 @@ cfg_if::cfg_if! {
}
}
-// Import essential modules from platforms used in `std::os` when documenting.
-//
-// Note that on some platforms those modules don't compile
-// (missing things in `libc` which is empty), so they are not included in `std::os` and can be
-// omitted here as well.
-
-#[cfg(doc)]
-#[cfg(not(any(
- all(target_arch = "wasm32", not(target_os = "wasi")),
- all(target_vendor = "fortanix", target_env = "sgx")
-)))]
-cfg_if::cfg_if! {
- if #[cfg(not(windows))] {
- // On non-Windows platforms (aka linux/osx/etc) pull in a "minimal"
- // amount of windows goop which ends up compiling
-
- #[macro_use]
- #[path = "windows/compat.rs"]
- pub mod compat;
-
- #[path = "windows/c.rs"]
- pub mod c;
- }
-}
-
cfg_if::cfg_if! {
// Fuchsia components default to full backtrace.
if #[cfg(target_os = "fuchsia")] {
diff --git a/library/std/src/sys/sgx/waitqueue/mod.rs b/library/std/src/sys/sgx/waitqueue/mod.rs
index 61bb11d9a6f..5e1d859ee99 100644
--- a/library/std/src/sys/sgx/waitqueue/mod.rs
+++ b/library/std/src/sys/sgx/waitqueue/mod.rs
@@ -202,12 +202,18 @@ impl WaitQueue {
pub fn notify_one<T>(
mut guard: SpinMutexGuard<'_, WaitVariable<T>>,
) -> Result<WaitGuard<'_, T>, SpinMutexGuard<'_, WaitVariable<T>>> {
+ // SAFETY: lifetime of the pop() return value is limited to the map
+ // closure (The closure return value is 'static). The underlying
+ // stack frame won't be freed until after the WaitGuard created below
+ // is dropped.
unsafe {
- if let Some(entry) = guard.queue.inner.pop() {
+ let tcs = guard.queue.inner.pop().map(|entry| -> Tcs {
let mut entry_guard = entry.lock();
- let tcs = entry_guard.tcs;
entry_guard.wake = true;
- drop(entry);
+ entry_guard.tcs
+ });
+
+ if let Some(tcs) = tcs {
Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::Single(tcs) })
} else {
Err(guard)
@@ -223,6 +229,9 @@ impl WaitQueue {
pub fn notify_all<T>(
mut guard: SpinMutexGuard<'_, WaitVariable<T>>,
) -> Result<WaitGuard<'_, T>, SpinMutexGuard<'_, WaitVariable<T>>> {
+ // SAFETY: lifetime of the pop() return values are limited to the
+ // while loop body. The underlying stack frames won't be freed until
+ // after the WaitGuard created below is dropped.
unsafe {
let mut count = 0;
while let Some(entry) = guard.queue.inner.pop() {
@@ -230,6 +239,7 @@ impl WaitQueue {
let mut entry_guard = entry.lock();
entry_guard.wake = true;
}
+
if let Some(count) = NonZeroUsize::new(count) {
Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::All { count } })
} else {
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index 22d2ae39713..09db5b11dbf 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -1210,7 +1210,7 @@ impl File {
// Redox doesn't appear to support `UTIME_OMIT`.
// 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);
+ let _ = times;
Err(io::const_io_error!(
io::ErrorKind::Unsupported,
"setting file times not supported",
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index 1f4092ad738..2bc40c4748a 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -6,33 +6,18 @@
use crate::ffi::CStr;
use crate::mem;
-use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort};
-use crate::os::windows::io::{BorrowedHandle, HandleOrInvalid, HandleOrNull};
+pub use crate::os::raw::c_int;
+use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_void};
+use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
use crate::ptr;
use core::ffi::NonZero_c_ulong;
-use libc::{c_void, size_t, wchar_t};
-
-pub use crate::os::raw::c_int;
-
-#[path = "c/errors.rs"] // c.rs is included from two places so we need to specify this
-mod errors;
-pub use errors::*;
+#[path = "c/windows_sys.rs"] // c.rs is included from two places so we need to specify this
+mod windows_sys;
+pub use windows_sys::*;
-pub use self::EXCEPTION_DISPOSITION::*;
-pub use self::FILE_INFO_BY_HANDLE_CLASS::*;
-
-pub type DWORD_PTR = ULONG_PTR;
pub type DWORD = c_ulong;
pub type NonZeroDWORD = NonZero_c_ulong;
-pub type HANDLE = LPVOID;
-pub type HINSTANCE = HANDLE;
-pub type HMODULE = HINSTANCE;
-pub type HRESULT = LONG;
-pub type BOOL = c_int;
-pub type BYTE = u8;
-pub type BOOLEAN = BYTE;
-pub type GROUP = c_uint;
pub type LARGE_INTEGER = c_longlong;
pub type LONG = c_long;
pub type UINT = c_uint;
@@ -41,218 +26,40 @@ pub type USHORT = c_ushort;
pub type SIZE_T = usize;
pub type WORD = u16;
pub type CHAR = c_char;
-pub type CCHAR = c_char;
-pub type ULONG_PTR = usize;
pub type ULONG = c_ulong;
-pub type NTSTATUS = LONG;
pub type ACCESS_MASK = DWORD;
-pub type LPBOOL = *mut BOOL;
-pub type LPBYTE = *mut BYTE;
-pub type LPCCH = *const CHAR;
-pub type LPCSTR = *const CHAR;
-pub type LPCWCH = *const WCHAR;
-pub type LPCWSTR = *const WCHAR;
pub type LPCVOID = *const c_void;
-pub type LPDWORD = *mut DWORD;
pub type LPHANDLE = *mut HANDLE;
pub type LPOVERLAPPED = *mut OVERLAPPED;
-pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION;
pub type LPSECURITY_ATTRIBUTES = *mut SECURITY_ATTRIBUTES;
-pub type LPSTARTUPINFO = *mut STARTUPINFO;
-pub type LPSTR = *mut CHAR;
pub type LPVOID = *mut c_void;
pub type LPWCH = *mut WCHAR;
-pub type LPWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW;
-pub type LPWSADATA = *mut WSADATA;
-pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO;
pub type LPWSTR = *mut WCHAR;
-pub type LPFILETIME = *mut FILETIME;
-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;
pub type PSRWLOCK = *mut SRWLOCK;
-pub type LPINIT_ONCE = *mut INIT_ONCE;
-pub type SOCKET = crate::os::windows::raw::SOCKET;
pub type socklen_t = c_int;
pub type ADDRESS_FAMILY = USHORT;
+pub use FD_SET as fd_set;
+pub use LINGER as linger;
+pub use TIMEVAL as timeval;
-pub const TRUE: BOOL = 1;
-pub const FALSE: BOOL = 0;
-
-pub const CSTR_LESS_THAN: c_int = 1;
-pub const CSTR_EQUAL: c_int = 2;
-pub const CSTR_GREATER_THAN: c_int = 3;
-
-pub const FILE_ATTRIBUTE_READONLY: DWORD = 0x1;
-pub const FILE_ATTRIBUTE_DIRECTORY: DWORD = 0x10;
-pub const FILE_ATTRIBUTE_REPARSE_POINT: DWORD = 0x400;
-pub const INVALID_FILE_ATTRIBUTES: DWORD = DWORD::MAX;
-
-pub const FILE_SHARE_DELETE: DWORD = 0x4;
-pub const FILE_SHARE_READ: DWORD = 0x1;
-pub const FILE_SHARE_WRITE: DWORD = 0x2;
+pub type CONDITION_VARIABLE = RTL_CONDITION_VARIABLE;
+pub type SRWLOCK = RTL_SRWLOCK;
+pub type INIT_ONCE = RTL_RUN_ONCE;
-pub const FILE_OPEN: ULONG = 0x00000001;
-pub const FILE_OPEN_REPARSE_POINT: ULONG = 0x200000;
-pub const OBJ_DONT_REPARSE: ULONG = 0x1000;
+pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { Ptr: ptr::null_mut() };
+pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { Ptr: ptr::null_mut() };
+pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: ptr::null_mut() };
-pub const CREATE_ALWAYS: DWORD = 2;
-pub const CREATE_NEW: DWORD = 1;
-pub const OPEN_ALWAYS: DWORD = 4;
-pub const OPEN_EXISTING: DWORD = 3;
-pub const TRUNCATE_EXISTING: DWORD = 5;
-
-pub const FILE_LIST_DIRECTORY: DWORD = 0x1;
-pub const FILE_WRITE_DATA: DWORD = 0x00000002;
-pub const FILE_APPEND_DATA: DWORD = 0x00000004;
-pub const FILE_WRITE_EA: DWORD = 0x00000010;
-pub const FILE_WRITE_ATTRIBUTES: DWORD = 0x00000100;
-pub const DELETE: DWORD = 0x10000;
-pub const READ_CONTROL: DWORD = 0x00020000;
-pub const SYNCHRONIZE: DWORD = 0x00100000;
-pub const GENERIC_READ: DWORD = 0x80000000;
-pub const GENERIC_WRITE: DWORD = 0x40000000;
-pub const STANDARD_RIGHTS_WRITE: DWORD = READ_CONTROL;
-pub const FILE_GENERIC_WRITE: DWORD = STANDARD_RIGHTS_WRITE
- | FILE_WRITE_DATA
- | FILE_WRITE_ATTRIBUTES
- | FILE_WRITE_EA
- | FILE_APPEND_DATA
- | SYNCHRONIZE;
-
-pub const FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000;
-pub const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000;
-pub const SECURITY_SQOS_PRESENT: DWORD = 0x00100000;
-
-pub const FIONBIO: c_ulong = 0x8004667e;
-
-pub const MAX_PATH: usize = 260;
-
-pub const FILE_TYPE_PIPE: u32 = 3;
-
-pub const CP_UTF8: DWORD = 65001;
-pub const MB_ERR_INVALID_CHARS: DWORD = 0x08;
-pub const WC_ERR_INVALID_CHARS: DWORD = 0x80;
-
-#[repr(C)]
-#[derive(Copy)]
-pub struct WIN32_FIND_DATAW {
- pub dwFileAttributes: DWORD,
- pub ftCreationTime: FILETIME,
- pub ftLastAccessTime: FILETIME,
- pub ftLastWriteTime: FILETIME,
- pub nFileSizeHigh: DWORD,
- pub nFileSizeLow: DWORD,
- pub dwReserved0: DWORD,
- pub dwReserved1: DWORD,
- pub cFileName: [wchar_t; 260], // #define MAX_PATH 260
- pub cAlternateFileName: [wchar_t; 14],
-}
-impl Clone for WIN32_FIND_DATAW {
- fn clone(&self) -> Self {
- *self
- }
-}
-
-pub const WSA_FLAG_OVERLAPPED: DWORD = 0x01;
-pub const WSA_FLAG_NO_HANDLE_INHERIT: DWORD = 0x80;
-
-pub const WSADESCRIPTION_LEN: usize = 256;
-pub const WSASYS_STATUS_LEN: usize = 128;
-pub const WSAPROTOCOL_LEN: DWORD = 255;
-pub const INVALID_SOCKET: SOCKET = !0;
-
-pub const MAX_PROTOCOL_CHAIN: DWORD = 7;
-
-pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
-pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
-pub const IO_REPARSE_TAG_SYMLINK: DWORD = 0xa000000c;
-pub const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003;
-pub const SYMLINK_FLAG_RELATIVE: DWORD = 0x00000001;
-pub const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
-
-pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;
-pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;
-
-// Note that these are not actually HANDLEs, just values to pass to GetStdHandle
-pub const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD;
-pub const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
-pub const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
-
-pub const PROGRESS_CONTINUE: DWORD = 0;
-
-pub const E_NOTIMPL: HRESULT = 0x80004001u32 as HRESULT;
-
-pub const INVALID_HANDLE_VALUE: HANDLE = ptr::invalid_mut(!0);
-
-pub const FACILITY_NT_BIT: DWORD = 0x1000_0000;
-
-pub const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
-pub const FORMAT_MESSAGE_FROM_HMODULE: DWORD = 0x00000800;
-pub const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
-
-pub const TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF;
-
-pub const DLL_THREAD_DETACH: DWORD = 3;
-pub const DLL_PROCESS_DETACH: DWORD = 0;
-
-pub const INFINITE: DWORD = !0;
-
-pub const DUPLICATE_SAME_ACCESS: DWORD = 0x00000002;
-
-pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { ptr: ptr::null_mut() };
-pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { ptr: ptr::null_mut() };
-pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { ptr: ptr::null_mut() };
-
-pub const INIT_ONCE_INIT_FAILED: DWORD = 0x00000004;
-
-pub const DETACHED_PROCESS: DWORD = 0x00000008;
-pub const CREATE_NEW_PROCESS_GROUP: DWORD = 0x00000200;
-pub const CREATE_UNICODE_ENVIRONMENT: DWORD = 0x00000400;
-pub const STARTF_USESTDHANDLES: DWORD = 0x00000100;
-
-pub const AF_INET: c_int = 2;
-pub const AF_INET6: c_int = 23;
-pub const SD_BOTH: c_int = 2;
-pub const SD_RECEIVE: c_int = 0;
-pub const SD_SEND: c_int = 1;
-pub const SOCK_DGRAM: c_int = 2;
-pub const SOCK_STREAM: c_int = 1;
-pub const SOCKET_ERROR: c_int = -1;
-pub const SOL_SOCKET: c_int = 0xffff;
-pub const SO_LINGER: c_int = 0x0080;
-pub const SO_RCVTIMEO: c_int = 0x1006;
-pub const SO_SNDTIMEO: c_int = 0x1005;
-pub const IPPROTO_IP: c_int = 0;
-pub const IPPROTO_TCP: c_int = 6;
-pub const IPPROTO_IPV6: c_int = 41;
-pub const TCP_NODELAY: c_int = 0x0001;
-pub const IP_TTL: c_int = 4;
-pub const IPV6_V6ONLY: c_int = 27;
-pub const SO_ERROR: c_int = 0x1007;
-pub const SO_BROADCAST: c_int = 0x0020;
-pub const IP_MULTICAST_LOOP: c_int = 11;
-pub const IPV6_MULTICAST_LOOP: c_int = 11;
-pub const IP_MULTICAST_TTL: c_int = 10;
-pub const IP_ADD_MEMBERSHIP: c_int = 12;
-pub const IP_DROP_MEMBERSHIP: c_int = 13;
-pub const IPV6_ADD_MEMBERSHIP: c_int = 12;
-pub const IPV6_DROP_MEMBERSHIP: c_int = 13;
-pub const MSG_PEEK: c_int = 0x2;
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct linger {
- pub l_onoff: c_ushort,
- pub l_linger: c_ushort,
-}
+// Some windows_sys types have different signs than the types we use.
+pub const OBJ_DONT_REPARSE: u32 = windows_sys::OBJ_DONT_REPARSE as u32;
+pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: u32 =
+ windows_sys::FRS_ERR_SYSVOL_POPULATE_TIMEOUT as u32;
+pub const AF_INET: c_int = windows_sys::AF_INET as c_int;
+pub const AF_INET6: c_int = windows_sys::AF_INET6 as c_int;
#[repr(C)]
pub struct ip_mreq {
@@ -266,66 +73,19 @@ pub struct ipv6_mreq {
pub ipv6mr_interface: c_uint,
}
-pub const VOLUME_NAME_DOS: DWORD = 0x0;
-pub const MOVEFILE_REPLACE_EXISTING: DWORD = 1;
-
-pub const FILE_BEGIN: DWORD = 0;
-pub const FILE_CURRENT: DWORD = 1;
-pub const FILE_END: DWORD = 2;
-
-pub const WAIT_OBJECT_0: DWORD = 0x00000000;
-pub const WAIT_TIMEOUT: DWORD = 258;
-pub const WAIT_FAILED: DWORD = 0xFFFFFFFF;
-
-pub const PIPE_ACCESS_INBOUND: DWORD = 0x00000001;
-pub const PIPE_ACCESS_OUTBOUND: DWORD = 0x00000002;
-pub const FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD = 0x00080000;
-pub const FILE_FLAG_OVERLAPPED: DWORD = 0x40000000;
-pub const PIPE_WAIT: DWORD = 0x00000000;
-pub const PIPE_TYPE_BYTE: DWORD = 0x00000000;
-pub const PIPE_REJECT_REMOTE_CLIENTS: DWORD = 0x00000008;
-pub const PIPE_READMODE_BYTE: DWORD = 0x00000000;
-
-pub const FD_SETSIZE: usize = 64;
-
-pub const STACK_SIZE_PARAM_IS_A_RESERVATION: DWORD = 0x00010000;
-
-pub const STATUS_SUCCESS: NTSTATUS = 0x00000000;
-pub const STATUS_DELETE_PENDING: NTSTATUS = 0xc0000056_u32 as _;
-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 _;
-
// Equivalent to the `NT_SUCCESS` C preprocessor macro.
// See: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values
pub fn nt_success(status: NTSTATUS) -> bool {
status >= 0
}
-pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;
-
-#[repr(C)]
-pub struct UNICODE_STRING {
- pub Length: u16,
- pub MaximumLength: u16,
- pub Buffer: *mut u16,
-}
impl UNICODE_STRING {
pub fn from_ref(slice: &[u16]) -> Self {
let len = slice.len() * mem::size_of::<u16>();
Self { Length: len as _, MaximumLength: len as _, Buffer: slice.as_ptr() as _ }
}
}
-#[repr(C)]
-pub struct OBJECT_ATTRIBUTES {
- pub Length: ULONG,
- pub RootDirectory: HANDLE,
- pub ObjectName: *const UNICODE_STRING,
- pub Attributes: ULONG,
- pub SecurityDescriptor: *mut c_void,
- pub SecurityQualityOfService: *mut c_void,
-}
+
impl Default for OBJECT_ATTRIBUTES {
fn default() -> Self {
Self {
@@ -338,193 +98,20 @@ impl Default for OBJECT_ATTRIBUTES {
}
}
}
-#[repr(C)]
-union IO_STATUS_BLOCK_union {
- Status: NTSTATUS,
- Pointer: *mut c_void,
-}
-impl Default for IO_STATUS_BLOCK_union {
- fn default() -> Self {
- let mut this = Self { Pointer: ptr::null_mut() };
- this.Status = STATUS_PENDING;
- this
- }
-}
-#[repr(C)]
-#[derive(Default)]
-pub struct IO_STATUS_BLOCK {
- u: IO_STATUS_BLOCK_union,
- pub Information: usize,
-}
+
impl IO_STATUS_BLOCK {
+ pub const PENDING: Self =
+ IO_STATUS_BLOCK { Anonymous: IO_STATUS_BLOCK_0 { Status: STATUS_PENDING }, Information: 0 };
pub fn status(&self) -> NTSTATUS {
- // SAFETY: If `self.u.Status` was set then this is obviously safe.
- // If `self.u.Pointer` was set then this is the equivalent to converting
+ // SAFETY: If `self.Anonymous.Status` was set then this is obviously safe.
+ // If `self.Anonymous.Pointer` was set then this is the equivalent to converting
// the pointer to an integer, which is also safe.
// Currently the only safe way to construct `IO_STATUS_BLOCK` outside of
// this module is to call the `default` method, which sets the `Status`.
- unsafe { self.u.Status }
+ unsafe { self.Anonymous.Status }
}
}
-pub type LPOVERLAPPED_COMPLETION_ROUTINE = unsafe extern "system" fn(
- dwErrorCode: DWORD,
- dwNumberOfBytesTransferred: DWORD,
- lpOverlapped: *mut OVERLAPPED,
-);
-
-type IO_APC_ROUTINE = unsafe extern "system" fn(
- ApcContext: *mut c_void,
- IoStatusBlock: *mut IO_STATUS_BLOCK,
- Reserved: ULONG,
-);
-
-#[repr(C)]
-#[cfg(not(target_pointer_width = "64"))]
-pub struct WSADATA {
- pub wVersion: WORD,
- pub wHighVersion: WORD,
- pub szDescription: [u8; WSADESCRIPTION_LEN + 1],
- pub szSystemStatus: [u8; WSASYS_STATUS_LEN + 1],
- pub iMaxSockets: u16,
- pub iMaxUdpDg: u16,
- pub lpVendorInfo: *mut u8,
-}
-#[repr(C)]
-#[cfg(target_pointer_width = "64")]
-pub struct WSADATA {
- pub wVersion: WORD,
- pub wHighVersion: WORD,
- pub iMaxSockets: u16,
- pub iMaxUdpDg: u16,
- pub lpVendorInfo: *mut u8,
- pub szDescription: [u8; WSADESCRIPTION_LEN + 1],
- pub szSystemStatus: [u8; WSASYS_STATUS_LEN + 1],
-}
-
-#[derive(Copy, Clone)]
-#[repr(C)]
-pub struct WSABUF {
- pub len: ULONG,
- pub buf: *mut CHAR,
-}
-
-#[repr(C)]
-pub struct WSAPROTOCOL_INFO {
- pub dwServiceFlags1: DWORD,
- pub dwServiceFlags2: DWORD,
- pub dwServiceFlags3: DWORD,
- pub dwServiceFlags4: DWORD,
- pub dwProviderFlags: DWORD,
- pub ProviderId: GUID,
- pub dwCatalogEntryId: DWORD,
- pub ProtocolChain: WSAPROTOCOLCHAIN,
- pub iVersion: c_int,
- pub iAddressFamily: c_int,
- pub iMaxSockAddr: c_int,
- pub iMinSockAddr: c_int,
- pub iSocketType: c_int,
- pub iProtocol: c_int,
- pub iProtocolMaxOffset: c_int,
- pub iNetworkByteOrder: c_int,
- pub iSecurityScheme: c_int,
- pub dwMessageSize: DWORD,
- pub dwProviderReserved: DWORD,
- pub szProtocol: [u16; (WSAPROTOCOL_LEN as usize) + 1],
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct WIN32_FILE_ATTRIBUTE_DATA {
- pub dwFileAttributes: DWORD,
- pub ftCreationTime: FILETIME,
- pub ftLastAccessTime: FILETIME,
- pub ftLastWriteTime: FILETIME,
- pub nFileSizeHigh: DWORD,
- pub nFileSizeLow: DWORD,
-}
-
-#[repr(C)]
-#[allow(dead_code)] // we only use some variants
-pub enum FILE_INFO_BY_HANDLE_CLASS {
- FileBasicInfo = 0,
- FileStandardInfo = 1,
- FileNameInfo = 2,
- FileRenameInfo = 3,
- FileDispositionInfo = 4,
- FileAllocationInfo = 5,
- FileEndOfFileInfo = 6,
- FileStreamInfo = 7,
- FileCompressionInfo = 8,
- FileAttributeTagInfo = 9,
- FileIdBothDirectoryInfo = 10, // 0xA
- FileIdBothDirectoryRestartInfo = 11, // 0xB
- FileIoPriorityHintInfo = 12, // 0xC
- FileRemoteProtocolInfo = 13, // 0xD
- FileFullDirectoryInfo = 14, // 0xE
- FileFullDirectoryRestartInfo = 15, // 0xF
- FileStorageInfo = 16, // 0x10
- FileAlignmentInfo = 17, // 0x11
- FileIdInfo = 18, // 0x12
- FileIdExtdDirectoryInfo = 19, // 0x13
- FileIdExtdDirectoryRestartInfo = 20, // 0x14
- FileDispositionInfoEx = 21, // 0x15, Windows 10 version 1607
- MaximumFileInfoByHandlesClass,
-}
-
-#[repr(C)]
-pub struct FILE_ATTRIBUTE_TAG_INFO {
- pub FileAttributes: DWORD,
- pub ReparseTag: DWORD,
-}
-
-#[repr(C)]
-pub struct FILE_DISPOSITION_INFO {
- pub DeleteFile: BOOLEAN,
-}
-
-pub const FILE_DISPOSITION_DELETE: DWORD = 0x1;
-pub const FILE_DISPOSITION_POSIX_SEMANTICS: DWORD = 0x2;
-pub const FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE: DWORD = 0x10;
-
-#[repr(C)]
-pub struct FILE_DISPOSITION_INFO_EX {
- pub Flags: DWORD,
-}
-
-#[repr(C)]
-#[derive(Default)]
-pub struct FILE_ID_BOTH_DIR_INFO {
- pub NextEntryOffset: DWORD,
- pub FileIndex: DWORD,
- pub CreationTime: LARGE_INTEGER,
- pub LastAccessTime: LARGE_INTEGER,
- pub LastWriteTime: LARGE_INTEGER,
- pub ChangeTime: LARGE_INTEGER,
- pub EndOfFile: LARGE_INTEGER,
- pub AllocationSize: LARGE_INTEGER,
- pub FileAttributes: DWORD,
- pub FileNameLength: DWORD,
- pub EaSize: DWORD,
- pub ShortNameLength: CCHAR,
- pub ShortName: [WCHAR; 12],
- pub FileId: LARGE_INTEGER,
- pub FileName: [WCHAR; 1],
-}
-#[repr(C)]
-pub struct FILE_BASIC_INFO {
- pub CreationTime: LARGE_INTEGER,
- pub LastAccessTime: LARGE_INTEGER,
- pub LastWriteTime: LARGE_INTEGER,
- pub ChangeTime: LARGE_INTEGER,
- pub FileAttributes: DWORD,
-}
-
-#[repr(C)]
-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)]
@@ -555,34 +142,6 @@ pub struct MOUNT_POINT_REPARSE_BUFFER {
pub PrintNameLength: c_ushort,
pub PathBuffer: WCHAR,
}
-
-pub type LPPROGRESS_ROUTINE = crate::option::Option<
- unsafe extern "system" fn(
- TotalFileSize: LARGE_INTEGER,
- TotalBytesTransferred: LARGE_INTEGER,
- StreamSize: LARGE_INTEGER,
- StreamBytesTransferred: LARGE_INTEGER,
- dwStreamNumber: DWORD,
- dwCallbackReason: DWORD,
- hSourceFile: HANDLE,
- hDestinationFile: HANDLE,
- lpData: LPVOID,
- ) -> DWORD,
->;
-
-#[repr(C)]
-pub struct CONDITION_VARIABLE {
- pub ptr: LPVOID,
-}
-#[repr(C)]
-pub struct SRWLOCK {
- pub ptr: LPVOID,
-}
-#[repr(C)]
-pub struct INIT_ONCE {
- pub ptr: LPVOID,
-}
-
#[repr(C)]
pub struct REPARSE_MOUNTPOINT_DATA_BUFFER {
pub ReparseTag: DWORD,
@@ -595,103 +154,6 @@ pub struct REPARSE_MOUNTPOINT_DATA_BUFFER {
}
#[repr(C)]
-pub struct GUID {
- pub Data1: DWORD,
- pub Data2: WORD,
- pub Data3: WORD,
- pub Data4: [BYTE; 8],
-}
-
-#[repr(C)]
-pub struct WSAPROTOCOLCHAIN {
- pub ChainLen: c_int,
- pub ChainEntries: [DWORD; MAX_PROTOCOL_CHAIN as usize],
-}
-
-#[repr(C)]
-pub struct SECURITY_ATTRIBUTES {
- pub nLength: DWORD,
- pub lpSecurityDescriptor: LPVOID,
- pub bInheritHandle: BOOL,
-}
-
-#[repr(C)]
-pub struct PROCESS_INFORMATION {
- pub hProcess: HANDLE,
- pub hThread: HANDLE,
- pub dwProcessId: DWORD,
- pub dwThreadId: DWORD,
-}
-
-#[repr(C)]
-pub struct STARTUPINFO {
- pub cb: DWORD,
- pub lpReserved: LPWSTR,
- pub lpDesktop: LPWSTR,
- pub lpTitle: LPWSTR,
- pub dwX: DWORD,
- pub dwY: DWORD,
- pub dwXSize: DWORD,
- pub dwYSize: DWORD,
- pub dwXCountChars: DWORD,
- pub dwYCountCharts: DWORD,
- pub dwFillAttribute: DWORD,
- pub dwFlags: DWORD,
- pub wShowWindow: WORD,
- pub cbReserved2: WORD,
- pub lpReserved2: LPBYTE,
- pub hStdInput: HANDLE,
- pub hStdOutput: HANDLE,
- pub hStdError: HANDLE,
-}
-
-#[repr(C)]
-pub struct SOCKADDR {
- pub sa_family: ADDRESS_FAMILY,
- pub sa_data: [CHAR; 14],
-}
-
-#[repr(C)]
-#[derive(Copy, Clone, Debug, Default)]
-pub struct FILETIME {
- pub dwLowDateTime: DWORD,
- pub dwHighDateTime: DWORD,
-}
-
-#[repr(C)]
-pub struct SYSTEM_INFO {
- pub wProcessorArchitecture: WORD,
- pub wReserved: WORD,
- pub dwPageSize: DWORD,
- pub lpMinimumApplicationAddress: LPVOID,
- pub lpMaximumApplicationAddress: LPVOID,
- pub dwActiveProcessorMask: DWORD_PTR,
- pub dwNumberOfProcessors: DWORD,
- pub dwProcessorType: DWORD,
- pub dwAllocationGranularity: DWORD,
- pub wProcessorLevel: WORD,
- pub wProcessorRevision: WORD,
-}
-
-#[repr(C)]
-pub struct OVERLAPPED {
- pub Internal: *mut c_ulong,
- pub InternalHigh: *mut c_ulong,
- pub Offset: DWORD,
- pub OffsetHigh: DWORD,
- pub hEvent: HANDLE,
-}
-
-#[repr(C)]
-#[allow(dead_code)] // we only use some variants
-pub enum ADDRESS_MODE {
- AddrMode1616,
- AddrMode1632,
- AddrModeReal,
- AddrModeFlat,
-}
-
-#[repr(C)]
pub struct SOCKADDR_STORAGE_LH {
pub ss_family: ADDRESS_FAMILY,
pub __ss_pad1: [CHAR; 6],
@@ -700,18 +162,6 @@ pub struct SOCKADDR_STORAGE_LH {
}
#[repr(C)]
-pub struct ADDRINFOA {
- pub ai_flags: c_int,
- pub ai_family: c_int,
- pub ai_socktype: c_int,
- pub ai_protocol: c_int,
- pub ai_addrlen: size_t,
- pub ai_canonname: *mut c_char,
- pub ai_addr: *mut SOCKADDR,
- pub ai_next: *mut ADDRINFOA,
-}
-
-#[repr(C)]
#[derive(Copy, Clone)]
pub struct sockaddr_in {
pub sin_family: ADDRESS_FAMILY,
@@ -742,583 +192,126 @@ pub struct in6_addr {
pub s6_addr: [u8; 16],
}
-#[repr(C)]
-#[derive(Copy, Clone)]
-#[allow(dead_code)] // we only use some variants
-pub enum EXCEPTION_DISPOSITION {
- ExceptionContinueExecution,
- ExceptionContinueSearch,
- ExceptionNestedException,
- ExceptionCollidedUnwind,
-}
-
-#[repr(C)]
-#[derive(Copy)]
-pub struct fd_set {
- pub fd_count: c_uint,
- pub fd_array: [SOCKET; FD_SETSIZE],
-}
-
-impl Clone for fd_set {
- fn clone(&self) -> fd_set {
- *self
- }
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct timeval {
- pub tv_sec: c_long,
- pub tv_usec: c_long,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct CONSOLE_READCONSOLE_CONTROL {
- pub nLength: ULONG,
- pub nInitialChars: ULONG,
- pub dwCtrlWakeupMask: ULONG,
- pub dwControlKeyState: ULONG,
-}
-pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL;
-
// Desktop specific functions & types
cfg_if::cfg_if! {
if #[cfg(not(target_vendor = "uwp"))] {
- pub const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
- pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
- pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;
-
- #[repr(C)]
- pub struct EXCEPTION_RECORD {
- pub ExceptionCode: DWORD,
- pub ExceptionFlags: DWORD,
- pub ExceptionRecord: *mut EXCEPTION_RECORD,
- pub ExceptionAddress: LPVOID,
- pub NumberParameters: DWORD,
- pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS],
- }
-
- pub enum CONTEXT {}
-
- #[repr(C)]
- pub struct EXCEPTION_POINTERS {
- pub ExceptionRecord: *mut EXCEPTION_RECORD,
- pub ContextRecord: *mut CONTEXT,
- }
-
- pub type PVECTORED_EXCEPTION_HANDLER =
- extern "system" fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG;
-
- #[repr(C)]
- pub struct BY_HANDLE_FILE_INFORMATION {
- pub dwFileAttributes: DWORD,
- pub ftCreationTime: FILETIME,
- pub ftLastAccessTime: FILETIME,
- pub ftLastWriteTime: FILETIME,
- pub dwVolumeSerialNumber: DWORD,
- pub nFileSizeHigh: DWORD,
- pub nFileSizeLow: DWORD,
- pub nNumberOfLinks: DWORD,
- pub nFileIndexHigh: DWORD,
- pub nFileIndexLow: DWORD,
- }
-
- pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
-
- pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
-
- pub const TOKEN_READ: DWORD = 0x20008;
-
- #[link(name = "advapi32")]
- extern "system" {
- // Forbidden when targeting UWP
- #[link_name = "SystemFunction036"]
- pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN;
-
- // Allowed but unused by UWP
- pub fn OpenProcessToken(
- ProcessHandle: HANDLE,
- DesiredAccess: DWORD,
- TokenHandle: *mut HANDLE,
- ) -> BOOL;
- }
-
- #[link(name = "userenv")]
- extern "system" {
- // Allowed but unused by UWP
- pub fn GetUserProfileDirectoryW(
- hToken: HANDLE,
- lpProfileDir: LPWSTR,
- lpcchSize: *mut DWORD,
- ) -> BOOL;
- }
-
- #[link(name = "kernel32")]
- extern "system" {
- // Allowed but unused by UWP
- pub fn GetFileInformationByHandle(
- hFile: HANDLE,
- lpFileInformation: LPBY_HANDLE_FILE_INFORMATION,
- ) -> BOOL;
- pub fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) -> BOOL;
- pub fn AddVectoredExceptionHandler(
- FirstHandler: ULONG,
- VectoredHandler: PVECTORED_EXCEPTION_HANDLER,
- ) -> LPVOID;
- pub fn CreateHardLinkW(
- lpSymlinkFileName: LPCWSTR,
- lpTargetFileName: LPCWSTR,
- lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
- ) -> BOOL;
- pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL;
- pub fn GetWindowsDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT;
- }
-}
-}
-
-// UWP specific functions & types
-cfg_if::cfg_if! {
-if #[cfg(target_vendor = "uwp")] {
- #[repr(C)]
- pub struct FILE_STANDARD_INFO {
- pub AllocationSize: LARGE_INTEGER,
- pub EndOfFile: LARGE_INTEGER,
- pub NumberOfLinks: DWORD,
- pub DeletePending: BOOLEAN,
- pub Directory: BOOLEAN,
- }
-}
-}
-
-// Shared between Desktop & UWP
-
-#[link(name = "kernel32")]
-extern "system" {
- pub fn GetCurrentProcessId() -> DWORD;
-
- pub fn ReadConsoleW(
- hConsoleInput: HANDLE,
- lpBuffer: LPVOID,
- nNumberOfCharsToRead: DWORD,
- lpNumberOfCharsRead: LPDWORD,
- pInputControl: PCONSOLE_READCONSOLE_CONTROL,
- ) -> BOOL;
- pub fn WriteConsoleW(
- hConsoleOutput: HANDLE,
- lpBuffer: LPCVOID,
- nNumberOfCharsToWrite: DWORD,
- lpNumberOfCharsWritten: LPDWORD,
- lpReserved: LPVOID,
- ) -> BOOL;
- pub fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL;
-
- pub fn GetSystemDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT;
- pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
- pub fn SetFileAttributesW(lpFileName: LPCWSTR, dwFileAttributes: DWORD) -> BOOL;
- pub fn SetFileTime(
- hFile: BorrowedHandle<'_>,
- lpCreationTime: Option<&FILETIME>,
- lpLastAccessTime: Option<&FILETIME>,
- lpLastWriteTime: Option<&FILETIME>,
- ) -> BOOL;
- pub fn SetLastError(dwErrCode: DWORD);
- pub fn GetCommandLineW() -> LPWSTR;
- pub fn GetTempPathW(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD;
- pub fn GetCurrentProcess() -> HANDLE;
- pub fn GetCurrentThread() -> HANDLE;
- pub fn GetStdHandle(which: DWORD) -> HANDLE;
- pub fn ExitProcess(uExitCode: c_uint) -> !;
- pub fn DeviceIoControl(
- hDevice: HANDLE,
- dwIoControlCode: DWORD,
- lpInBuffer: LPVOID,
- nInBufferSize: DWORD,
- lpOutBuffer: LPVOID,
- nOutBufferSize: DWORD,
- lpBytesReturned: LPDWORD,
- lpOverlapped: LPOVERLAPPED,
- ) -> BOOL;
- pub fn CreateThread(
- lpThreadAttributes: LPSECURITY_ATTRIBUTES,
- dwStackSize: SIZE_T,
- lpStartAddress: extern "system" fn(*mut c_void) -> DWORD,
- lpParameter: LPVOID,
- dwCreationFlags: DWORD,
- lpThreadId: LPDWORD,
- ) -> HandleOrNull;
- pub fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
- pub fn SwitchToThread() -> BOOL;
- pub fn Sleep(dwMilliseconds: DWORD);
- pub fn SleepEx(dwMilliseconds: DWORD, bAlertable: BOOL) -> DWORD;
- pub fn GetProcessId(handle: HANDLE) -> DWORD;
- pub fn CopyFileExW(
- lpExistingFileName: LPCWSTR,
- lpNewFileName: LPCWSTR,
- lpProgressRoutine: LPPROGRESS_ROUTINE,
- lpData: LPVOID,
- pbCancel: LPBOOL,
- dwCopyFlags: DWORD,
- ) -> BOOL;
- pub fn FormatMessageW(
- flags: DWORD,
- lpSrc: LPVOID,
- msgId: DWORD,
- langId: DWORD,
- buf: LPWSTR,
- nsize: DWORD,
- args: *const c_void,
- ) -> DWORD;
- pub fn TlsAlloc() -> DWORD;
- pub fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
- pub fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
- pub fn TlsFree(dwTlsIndex: DWORD) -> BOOL;
- pub fn GetLastError() -> DWORD;
- pub fn QueryPerformanceFrequency(lpFrequency: *mut LARGE_INTEGER) -> BOOL;
- pub fn QueryPerformanceCounter(lpPerformanceCount: *mut LARGE_INTEGER) -> BOOL;
- pub fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: LPDWORD) -> BOOL;
- pub fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) -> BOOL;
- pub fn CreateProcessW(
- lpApplicationName: LPCWSTR,
- lpCommandLine: LPWSTR,
- lpProcessAttributes: LPSECURITY_ATTRIBUTES,
- lpThreadAttributes: LPSECURITY_ATTRIBUTES,
- bInheritHandles: BOOL,
- dwCreationFlags: DWORD,
- lpEnvironment: LPVOID,
- lpCurrentDirectory: LPCWSTR,
- lpStartupInfo: LPSTARTUPINFO,
- lpProcessInformation: LPPROCESS_INFORMATION,
- ) -> BOOL;
- pub fn GetEnvironmentVariableW(n: LPCWSTR, v: LPWSTR, nsize: DWORD) -> DWORD;
- pub fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR) -> BOOL;
- pub fn GetEnvironmentStringsW() -> LPWCH;
- pub fn FreeEnvironmentStringsW(env_ptr: LPWCH) -> BOOL;
- pub fn GetModuleFileNameW(hModule: HMODULE, lpFilename: LPWSTR, nSize: DWORD) -> DWORD;
- pub fn CreateDirectoryW(
- lpPathName: LPCWSTR,
- lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
- ) -> BOOL;
- pub fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL;
- pub fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD;
- pub fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL;
- pub fn DuplicateHandle(
- hSourceProcessHandle: HANDLE,
- hSourceHandle: HANDLE,
- hTargetProcessHandle: HANDLE,
- lpTargetHandle: LPHANDLE,
- dwDesiredAccess: DWORD,
- bInheritHandle: BOOL,
- dwOptions: DWORD,
- ) -> BOOL;
- pub fn ReadFile(
- hFile: BorrowedHandle<'_>,
- lpBuffer: LPVOID,
- nNumberOfBytesToRead: DWORD,
- lpNumberOfBytesRead: LPDWORD,
- lpOverlapped: LPOVERLAPPED,
- ) -> BOOL;
- pub fn ReadFileEx(
- hFile: BorrowedHandle<'_>,
- lpBuffer: LPVOID,
- nNumberOfBytesToRead: DWORD,
- lpOverlapped: LPOVERLAPPED,
- lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,
- ) -> BOOL;
- pub fn WriteFileEx(
- hFile: BorrowedHandle<'_>,
- lpBuffer: LPVOID,
- nNumberOfBytesToWrite: DWORD,
- lpOverlapped: LPOVERLAPPED,
- lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,
- ) -> BOOL;
- pub fn CloseHandle(hObject: HANDLE) -> BOOL;
- pub fn MoveFileExW(lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, dwFlags: DWORD)
- -> BOOL;
- pub fn SetFilePointerEx(
- hFile: HANDLE,
- liDistanceToMove: LARGE_INTEGER,
- lpNewFilePointer: PLARGE_INTEGER,
- dwMoveMethod: DWORD,
- ) -> BOOL;
- pub fn FlushFileBuffers(hFile: HANDLE) -> BOOL;
- pub fn CreateFileW(
- lpFileName: LPCWSTR,
- dwDesiredAccess: DWORD,
- dwShareMode: DWORD,
- lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
- dwCreationDisposition: DWORD,
- dwFlagsAndAttributes: DWORD,
- hTemplateFile: HANDLE,
- ) -> HandleOrInvalid;
-
- pub fn FindFirstFileW(fileName: LPCWSTR, findFileData: LPWIN32_FIND_DATAW) -> HANDLE;
- pub fn FindNextFileW(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW) -> BOOL;
- pub fn FindClose(findFile: HANDLE) -> BOOL;
-
- pub fn GetProcAddress(handle: HMODULE, name: LPCSTR) -> *mut c_void;
- pub fn GetModuleHandleA(lpModuleName: LPCSTR) -> HMODULE;
- pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
-
- pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME);
- pub fn GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO);
-
- pub fn CreateEventW(
- lpEventAttributes: LPSECURITY_ATTRIBUTES,
- bManualReset: BOOL,
- bInitialState: BOOL,
- lpName: LPCWSTR,
- ) -> HANDLE;
- pub fn WaitForMultipleObjects(
- nCount: DWORD,
- lpHandles: *const HANDLE,
- bWaitAll: BOOL,
- dwMilliseconds: DWORD,
- ) -> DWORD;
- pub fn CreateNamedPipeW(
- lpName: LPCWSTR,
- dwOpenMode: DWORD,
- dwPipeMode: DWORD,
- nMaxInstances: DWORD,
- nOutBufferSize: DWORD,
- nInBufferSize: DWORD,
- nDefaultTimeOut: DWORD,
- lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
- ) -> HANDLE;
- pub fn CancelIo(handle: HANDLE) -> BOOL;
- pub fn GetOverlappedResult(
- hFile: HANDLE,
- lpOverlapped: LPOVERLAPPED,
- lpNumberOfBytesTransferred: LPDWORD,
- bWait: BOOL,
- ) -> BOOL;
- pub fn CreateSymbolicLinkW(
- lpSymlinkFileName: LPCWSTR,
- lpTargetFileName: LPCWSTR,
- dwFlags: DWORD,
- ) -> BOOLEAN;
- pub fn GetFinalPathNameByHandleW(
- hFile: HANDLE,
- lpszFilePath: LPCWSTR,
- cchFilePath: DWORD,
- dwFlags: DWORD,
- ) -> DWORD;
- pub fn GetFileInformationByHandleEx(
- hFile: HANDLE,
- fileInfoClass: FILE_INFO_BY_HANDLE_CLASS,
- lpFileInformation: LPVOID,
- dwBufferSize: DWORD,
- ) -> BOOL;
- pub fn SetFileInformationByHandle(
- hFile: HANDLE,
- FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
- lpFileInformation: LPVOID,
- dwBufferSize: DWORD,
- ) -> BOOL;
- pub fn GetFileType(hfile: HANDLE) -> DWORD;
- pub fn SleepConditionVariableSRW(
- ConditionVariable: PCONDITION_VARIABLE,
- SRWLock: PSRWLOCK,
- dwMilliseconds: DWORD,
- Flags: ULONG,
- ) -> BOOL;
-
- pub fn WakeConditionVariable(ConditionVariable: PCONDITION_VARIABLE);
- pub fn WakeAllConditionVariable(ConditionVariable: PCONDITION_VARIABLE);
-
- pub fn AcquireSRWLockExclusive(SRWLock: PSRWLOCK);
- pub fn AcquireSRWLockShared(SRWLock: PSRWLOCK);
- pub fn ReleaseSRWLockExclusive(SRWLock: PSRWLOCK);
- pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK);
- pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN;
- pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN;
-
- pub fn InitOnceBeginInitialize(
- lpInitOnce: LPINIT_ONCE,
- dwFlags: DWORD,
- fPending: LPBOOL,
- lpContext: *mut LPVOID,
- ) -> BOOL;
- pub fn InitOnceComplete(lpInitOnce: LPINIT_ONCE, dwFlags: DWORD, lpContext: LPVOID) -> BOOL;
-
- pub fn CompareStringOrdinal(
- lpString1: LPCWSTR,
- cchCount1: c_int,
- lpString2: LPCWSTR,
- cchCount2: c_int,
- bIgnoreCase: BOOL,
- ) -> c_int;
- pub fn GetFullPathNameW(
- lpFileName: LPCWSTR,
- nBufferLength: DWORD,
- lpBuffer: LPWSTR,
- lpFilePart: *mut LPWSTR,
- ) -> DWORD;
- pub fn GetFileAttributesW(lpFileName: LPCWSTR) -> DWORD;
-
- pub fn MultiByteToWideChar(
- CodePage: UINT,
- dwFlags: DWORD,
- lpMultiByteStr: LPCCH,
- cbMultiByte: c_int,
- lpWideCharStr: LPWSTR,
- cchWideChar: c_int,
- ) -> c_int;
- pub fn WideCharToMultiByte(
- CodePage: UINT,
- dwFlags: DWORD,
- lpWideCharStr: LPCWCH,
- cchWideChar: c_int,
- lpMultiByteStr: LPSTR,
- cbMultiByte: c_int,
- lpDefaultChar: LPCCH,
- lpUsedDefaultChar: LPBOOL,
- ) -> c_int;
+ pub const EXCEPTION_CONTINUE_SEARCH: i32 = 0;
}
-
-#[link(name = "ws2_32")]
-extern "system" {
- pub fn WSAStartup(wVersionRequested: WORD, lpWSAData: LPWSADATA) -> c_int;
- pub fn WSACleanup() -> c_int;
- pub fn WSAGetLastError() -> c_int;
- pub fn WSADuplicateSocketW(
- s: SOCKET,
- dwProcessId: DWORD,
- lpProtocolInfo: LPWSAPROTOCOL_INFO,
- ) -> c_int;
- pub fn WSASend(
- s: SOCKET,
- lpBuffers: LPWSABUF,
- dwBufferCount: DWORD,
- lpNumberOfBytesSent: LPDWORD,
- dwFlags: DWORD,
- lpOverlapped: LPWSAOVERLAPPED,
- lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
- ) -> c_int;
- pub fn WSARecv(
- s: SOCKET,
- lpBuffers: LPWSABUF,
- dwBufferCount: DWORD,
- lpNumberOfBytesRecvd: LPDWORD,
- lpFlags: LPDWORD,
- lpOverlapped: LPWSAOVERLAPPED,
- lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
- ) -> c_int;
- pub fn WSASocketW(
- af: c_int,
- kind: c_int,
- protocol: c_int,
- lpProtocolInfo: LPWSAPROTOCOL_INFO,
- g: GROUP,
- dwFlags: DWORD,
- ) -> SOCKET;
- pub fn ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut c_ulong) -> c_int;
- pub fn closesocket(socket: SOCKET) -> c_int;
- pub fn recv(socket: SOCKET, buf: *mut c_void, len: c_int, flags: c_int) -> c_int;
- pub fn send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int;
- pub fn recvfrom(
- socket: SOCKET,
- buf: *mut c_void,
- len: c_int,
- flags: c_int,
- addr: *mut SOCKADDR,
- addrlen: *mut c_int,
- ) -> c_int;
- pub fn sendto(
- socket: SOCKET,
- buf: *const c_void,
- len: c_int,
- flags: c_int,
- addr: *const SOCKADDR,
- addrlen: c_int,
- ) -> c_int;
- pub fn shutdown(socket: SOCKET, how: c_int) -> c_int;
- pub fn accept(socket: SOCKET, address: *mut SOCKADDR, address_len: *mut c_int) -> SOCKET;
- pub fn getsockopt(
- s: SOCKET,
- level: c_int,
- optname: c_int,
- optval: *mut c_char,
- optlen: *mut c_int,
- ) -> c_int;
- pub fn setsockopt(
- s: SOCKET,
- level: c_int,
- optname: c_int,
- optval: *const c_void,
- optlen: c_int,
- ) -> c_int;
- pub fn getsockname(socket: SOCKET, address: *mut SOCKADDR, address_len: *mut c_int) -> c_int;
- pub fn getpeername(socket: SOCKET, address: *mut SOCKADDR, address_len: *mut c_int) -> c_int;
- pub fn bind(socket: SOCKET, address: *const SOCKADDR, address_len: socklen_t) -> c_int;
- pub fn listen(socket: SOCKET, backlog: c_int) -> c_int;
- pub fn connect(socket: SOCKET, address: *const SOCKADDR, len: c_int) -> c_int;
- pub fn getaddrinfo(
- node: *const c_char,
- service: *const c_char,
- hints: *const ADDRINFOA,
- res: *mut *mut ADDRINFOA,
- ) -> c_int;
- pub fn freeaddrinfo(res: *mut ADDRINFOA);
- pub fn select(
- nfds: c_int,
- readfds: *mut fd_set,
- writefds: *mut fd_set,
- exceptfds: *mut fd_set,
- timeout: *const timeval,
- ) -> c_int;
-}
-
-#[link(name = "bcrypt")]
-extern "system" {
- // >= Vista / Server 2008
- // https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
- pub fn BCryptGenRandom(
- hAlgorithm: BCRYPT_ALG_HANDLE,
- pBuffer: *mut u8,
- cbBuffer: ULONG,
- dwFlags: ULONG,
- ) -> NTSTATUS;
}
-#[link(name = "ntdll")]
-extern "system" {
- pub fn NtCreateFile(
- FileHandle: *mut HANDLE,
- DesiredAccess: ACCESS_MASK,
- ObjectAttributes: *const OBJECT_ATTRIBUTES,
- IoStatusBlock: *mut IO_STATUS_BLOCK,
- AllocationSize: *mut i64,
- FileAttributes: ULONG,
- ShareAccess: ULONG,
- CreateDisposition: ULONG,
- CreateOptions: ULONG,
- EaBuffer: *mut c_void,
- EaLength: ULONG,
- ) -> NTSTATUS;
- pub fn NtReadFile(
- FileHandle: BorrowedHandle<'_>,
- Event: HANDLE,
- ApcRoutine: Option<IO_APC_ROUTINE>,
- ApcContext: *mut c_void,
- IoStatusBlock: &mut IO_STATUS_BLOCK,
- Buffer: *mut crate::mem::MaybeUninit<u8>,
- Length: ULONG,
- ByteOffset: Option<&LARGE_INTEGER>,
- Key: Option<&ULONG>,
- ) -> NTSTATUS;
- pub fn NtWriteFile(
- FileHandle: BorrowedHandle<'_>,
- Event: HANDLE,
- ApcRoutine: Option<IO_APC_ROUTINE>,
- ApcContext: *mut c_void,
- IoStatusBlock: &mut IO_STATUS_BLOCK,
- Buffer: *const u8,
- Length: ULONG,
- ByteOffset: Option<&LARGE_INTEGER>,
- Key: Option<&ULONG>,
- ) -> NTSTATUS;
- pub fn RtlNtStatusToDosError(Status: NTSTATUS) -> ULONG;
+pub unsafe extern "system" fn WriteFileEx(
+ hFile: BorrowedHandle<'_>,
+ lpBuffer: *mut ::core::ffi::c_void,
+ nNumberOfBytesToWrite: u32,
+ lpOverlapped: *mut OVERLAPPED,
+ lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,
+) -> BOOL {
+ windows_sys::WriteFileEx(
+ hFile.as_raw_handle(),
+ lpBuffer.cast::<u8>(),
+ nNumberOfBytesToWrite,
+ lpOverlapped,
+ lpCompletionRoutine,
+ )
+}
+
+pub unsafe extern "system" fn ReadFileEx(
+ hFile: BorrowedHandle<'_>,
+ lpBuffer: *mut ::core::ffi::c_void,
+ nNumberOfBytesToRead: u32,
+ lpOverlapped: *mut OVERLAPPED,
+ lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,
+) -> BOOL {
+ windows_sys::ReadFileEx(
+ hFile.as_raw_handle(),
+ lpBuffer,
+ nNumberOfBytesToRead,
+ lpOverlapped,
+ lpCompletionRoutine,
+ )
+}
+
+// POSIX compatibility shims.
+pub unsafe fn recv(socket: SOCKET, buf: *mut c_void, len: c_int, flags: c_int) -> c_int {
+ windows_sys::recv(socket, buf.cast::<u8>(), len, flags)
+}
+pub unsafe fn send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int {
+ windows_sys::send(socket, buf.cast::<u8>(), len, flags)
+}
+pub unsafe fn recvfrom(
+ socket: SOCKET,
+ buf: *mut c_void,
+ len: c_int,
+ flags: c_int,
+ addr: *mut SOCKADDR,
+ addrlen: *mut c_int,
+) -> c_int {
+ windows_sys::recvfrom(socket, buf.cast::<u8>(), len, flags, addr, addrlen)
+}
+pub unsafe fn sendto(
+ socket: SOCKET,
+ buf: *const c_void,
+ len: c_int,
+ flags: c_int,
+ addr: *const SOCKADDR,
+ addrlen: c_int,
+) -> c_int {
+ windows_sys::sendto(socket, buf.cast::<u8>(), len, flags, addr, addrlen)
+}
+pub unsafe fn getaddrinfo(
+ node: *const c_char,
+ service: *const c_char,
+ hints: *const ADDRINFOA,
+ res: *mut *mut ADDRINFOA,
+) -> c_int {
+ windows_sys::getaddrinfo(node.cast::<u8>(), service.cast::<u8>(), hints, res)
+}
+
+pub unsafe fn NtReadFile(
+ filehandle: BorrowedHandle<'_>,
+ event: HANDLE,
+ apcroutine: PIO_APC_ROUTINE,
+ apccontext: *mut c_void,
+ iostatusblock: &mut IO_STATUS_BLOCK,
+ buffer: *mut crate::mem::MaybeUninit<u8>,
+ length: ULONG,
+ byteoffset: Option<&LARGE_INTEGER>,
+ key: Option<&ULONG>,
+) -> NTSTATUS {
+ windows_sys::NtReadFile(
+ filehandle.as_raw_handle(),
+ event,
+ apcroutine,
+ apccontext,
+ iostatusblock,
+ buffer.cast::<c_void>(),
+ length,
+ byteoffset.map(|o| o as *const i64).unwrap_or(ptr::null()),
+ key.map(|k| k as *const u32).unwrap_or(ptr::null()),
+ )
+}
+pub unsafe fn NtWriteFile(
+ filehandle: BorrowedHandle<'_>,
+ event: HANDLE,
+ apcroutine: PIO_APC_ROUTINE,
+ apccontext: *mut c_void,
+ iostatusblock: &mut IO_STATUS_BLOCK,
+ buffer: *const u8,
+ length: ULONG,
+ byteoffset: Option<&LARGE_INTEGER>,
+ key: Option<&ULONG>,
+) -> NTSTATUS {
+ windows_sys::NtWriteFile(
+ filehandle.as_raw_handle(),
+ event,
+ apcroutine,
+ apccontext,
+ iostatusblock,
+ buffer.cast::<c_void>(),
+ length,
+ byteoffset.map(|o| o as *const i64).unwrap_or(ptr::null()),
+ key.map(|k| k as *const u32).unwrap_or(ptr::null()),
+ )
}
// Functions that aren't available on every version of Windows that we support,
@@ -1328,34 +321,32 @@ compat_fn_with_fallback! {
// >= Win10 1607
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
- pub fn SetThreadDescription(hThread: HANDLE,
- lpThreadDescription: LPCWSTR) -> HRESULT {
+ pub fn SetThreadDescription(hthread: HANDLE, lpthreaddescription: PCWSTR) -> HRESULT {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL
}
// >= Win8 / Server 2012
// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime
- pub fn GetSystemTimePreciseAsFileTime(lpSystemTimeAsFileTime: LPFILETIME)
- -> () {
- GetSystemTimeAsFileTime(lpSystemTimeAsFileTime)
+ pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () {
+ GetSystemTimeAsFileTime(lpsystemtimeasfiletime)
}
// >= Win11 / Server 2022
// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a
- pub fn GetTempPath2W(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD {
- GetTempPathW(nBufferLength, lpBuffer)
+ pub fn GetTempPath2W(bufferlength: u32, buffer: PWSTR) -> u32 {
+ GetTempPathW(bufferlength, buffer)
}
}
compat_fn_optional! {
crate::sys::compat::load_synch_functions();
pub fn WaitOnAddress(
- Address: LPVOID,
- CompareAddress: LPVOID,
- AddressSize: SIZE_T,
- dwMilliseconds: DWORD
- );
- pub fn WakeByAddressSingle(Address: LPVOID);
+ address: *const ::core::ffi::c_void,
+ compareaddress: *const ::core::ffi::c_void,
+ addresssize: usize,
+ dwmilliseconds: u32
+ ) -> BOOL;
+ pub fn WakeByAddressSingle(address: *const ::core::ffi::c_void);
}
compat_fn_with_fallback! {
diff --git a/library/std/src/sys/windows/c/errors.rs b/library/std/src/sys/windows/c/errors.rs
deleted file mode 100644
index ad8da19b6da..00000000000
--- a/library/std/src/sys/windows/c/errors.rs
+++ /dev/null
@@ -1,1883 +0,0 @@
-// List of Windows system error codes with descriptions:
-// https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes#system-error-codes
-
-#![allow(dead_code)]
-
-use super::{c_int, DWORD};
-
-pub const ERROR_DIRECTORY_NOT_SUPPORTED: DWORD = 336;
-pub const ERROR_DRIVER_CANCEL_TIMEOUT: DWORD = 594;
-pub const ERROR_DISK_QUOTA_EXCEEDED: DWORD = 1295;
-pub const ERROR_RESOURCE_CALL_TIMED_OUT: DWORD = 5910;
-pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: DWORD = 8014;
-pub const DNS_ERROR_RECORD_TIMED_OUT: DWORD = 9705;
-
-// The following list was obtained from
-// `/usr/x86_64-w64-mingw32/include/winerror.h`
-// in the Debian package
-// mingw-w64_6.0.0-3_all.deb
-//
-// The header of that file says:
-// * This file has no copyright assigned and is placed in the Public Domain.
-// * This file is part of the mingw-w64 runtime package.
-// * No warranty is given; refer to the file DISCLAIMER.PD within this package.
-//
-// The text here is the result of the following rune:
-// grep -P '#define ERROR' /usr/x86_64-w64-mingw32/include/winerror.h >>library/std/src/sys/windows/c/errors.rs
-// grep -P '#define WSA' /usr/x86_64-w64-mingw32/include/winerror.h >>library/std/src/sys/windows/c/errors.rs
-// and then using some manually-invented but rather obvious editor search-and-replace
-// invocations, plus some straightforward manual fixups, to turn it into Rust syntax
-// and remove all the duplicates from the manual table above.
-
-pub const ERROR_SUCCESS: DWORD = 0;
-pub const ERROR_INVALID_FUNCTION: DWORD = 1;
-pub const ERROR_FILE_NOT_FOUND: DWORD = 2;
-pub const ERROR_PATH_NOT_FOUND: DWORD = 3;
-pub const ERROR_TOO_MANY_OPEN_FILES: DWORD = 4;
-pub const ERROR_ACCESS_DENIED: DWORD = 5;
-pub const ERROR_INVALID_HANDLE: DWORD = 6;
-pub const ERROR_ARENA_TRASHED: DWORD = 7;
-pub const ERROR_NOT_ENOUGH_MEMORY: DWORD = 8;
-pub const ERROR_INVALID_BLOCK: DWORD = 9;
-pub const ERROR_BAD_ENVIRONMENT: DWORD = 10;
-pub const ERROR_BAD_FORMAT: DWORD = 11;
-pub const ERROR_INVALID_ACCESS: DWORD = 12;
-pub const ERROR_INVALID_DATA: DWORD = 13;
-pub const ERROR_OUTOFMEMORY: DWORD = 14;
-pub const ERROR_INVALID_DRIVE: DWORD = 15;
-pub const ERROR_CURRENT_DIRECTORY: DWORD = 16;
-pub const ERROR_NOT_SAME_DEVICE: DWORD = 17;
-pub const ERROR_NO_MORE_FILES: DWORD = 18;
-pub const ERROR_WRITE_PROTECT: DWORD = 19;
-pub const ERROR_BAD_UNIT: DWORD = 20;
-pub const ERROR_NOT_READY: DWORD = 21;
-pub const ERROR_BAD_COMMAND: DWORD = 22;
-pub const ERROR_CRC: DWORD = 23;
-pub const ERROR_BAD_LENGTH: DWORD = 24;
-pub const ERROR_SEEK: DWORD = 25;
-pub const ERROR_NOT_DOS_DISK: DWORD = 26;
-pub const ERROR_SECTOR_NOT_FOUND: DWORD = 27;
-pub const ERROR_OUT_OF_PAPER: DWORD = 28;
-pub const ERROR_WRITE_FAULT: DWORD = 29;
-pub const ERROR_READ_FAULT: DWORD = 30;
-pub const ERROR_GEN_FAILURE: DWORD = 31;
-pub const ERROR_SHARING_VIOLATION: DWORD = 32;
-pub const ERROR_LOCK_VIOLATION: DWORD = 33;
-pub const ERROR_WRONG_DISK: DWORD = 34;
-pub const ERROR_SHARING_BUFFER_EXCEEDED: DWORD = 36;
-pub const ERROR_HANDLE_EOF: DWORD = 38;
-pub const ERROR_HANDLE_DISK_FULL: DWORD = 39;
-pub const ERROR_NOT_SUPPORTED: DWORD = 50;
-pub const ERROR_REM_NOT_LIST: DWORD = 51;
-pub const ERROR_DUP_NAME: DWORD = 52;
-pub const ERROR_BAD_NETPATH: DWORD = 53;
-pub const ERROR_NETWORK_BUSY: DWORD = 54;
-pub const ERROR_DEV_NOT_EXIST: DWORD = 55;
-pub const ERROR_TOO_MANY_CMDS: DWORD = 56;
-pub const ERROR_ADAP_HDW_ERR: DWORD = 57;
-pub const ERROR_BAD_NET_RESP: DWORD = 58;
-pub const ERROR_UNEXP_NET_ERR: DWORD = 59;
-pub const ERROR_BAD_REM_ADAP: DWORD = 60;
-pub const ERROR_PRINTQ_FULL: DWORD = 61;
-pub const ERROR_NO_SPOOL_SPACE: DWORD = 62;
-pub const ERROR_PRINT_CANCELLED: DWORD = 63;
-pub const ERROR_NETNAME_DELETED: DWORD = 64;
-pub const ERROR_NETWORK_ACCESS_DENIED: DWORD = 65;
-pub const ERROR_BAD_DEV_TYPE: DWORD = 66;
-pub const ERROR_BAD_NET_NAME: DWORD = 67;
-pub const ERROR_TOO_MANY_NAMES: DWORD = 68;
-pub const ERROR_TOO_MANY_SESS: DWORD = 69;
-pub const ERROR_SHARING_PAUSED: DWORD = 70;
-pub const ERROR_REQ_NOT_ACCEP: DWORD = 71;
-pub const ERROR_REDIR_PAUSED: DWORD = 72;
-pub const ERROR_FILE_EXISTS: DWORD = 80;
-pub const ERROR_CANNOT_MAKE: DWORD = 82;
-pub const ERROR_FAIL_I24: DWORD = 83;
-pub const ERROR_OUT_OF_STRUCTURES: DWORD = 84;
-pub const ERROR_ALREADY_ASSIGNED: DWORD = 85;
-pub const ERROR_INVALID_PASSWORD: DWORD = 86;
-pub const ERROR_INVALID_PARAMETER: DWORD = 87;
-pub const ERROR_NET_WRITE_FAULT: DWORD = 88;
-pub const ERROR_NO_PROC_SLOTS: DWORD = 89;
-pub const ERROR_TOO_MANY_SEMAPHORES: DWORD = 100;
-pub const ERROR_EXCL_SEM_ALREADY_OWNED: DWORD = 101;
-pub const ERROR_SEM_IS_SET: DWORD = 102;
-pub const ERROR_TOO_MANY_SEM_REQUESTS: DWORD = 103;
-pub const ERROR_INVALID_AT_INTERRUPT_TIME: DWORD = 104;
-pub const ERROR_SEM_OWNER_DIED: DWORD = 105;
-pub const ERROR_SEM_USER_LIMIT: DWORD = 106;
-pub const ERROR_DISK_CHANGE: DWORD = 107;
-pub const ERROR_DRIVE_LOCKED: DWORD = 108;
-pub const ERROR_BROKEN_PIPE: DWORD = 109;
-pub const ERROR_OPEN_FAILED: DWORD = 110;
-pub const ERROR_BUFFER_OVERFLOW: DWORD = 111;
-pub const ERROR_DISK_FULL: DWORD = 112;
-pub const ERROR_NO_MORE_SEARCH_HANDLES: DWORD = 113;
-pub const ERROR_INVALID_TARGET_HANDLE: DWORD = 114;
-pub const ERROR_INVALID_CATEGORY: DWORD = 117;
-pub const ERROR_INVALID_VERIFY_SWITCH: DWORD = 118;
-pub const ERROR_BAD_DRIVER_LEVEL: DWORD = 119;
-pub const ERROR_CALL_NOT_IMPLEMENTED: DWORD = 120;
-pub const ERROR_SEM_TIMEOUT: DWORD = 121;
-pub const ERROR_INSUFFICIENT_BUFFER: DWORD = 122;
-pub const ERROR_INVALID_NAME: DWORD = 123;
-pub const ERROR_INVALID_LEVEL: DWORD = 124;
-pub const ERROR_NO_VOLUME_LABEL: DWORD = 125;
-pub const ERROR_MOD_NOT_FOUND: DWORD = 126;
-pub const ERROR_PROC_NOT_FOUND: DWORD = 127;
-pub const ERROR_WAIT_NO_CHILDREN: DWORD = 128;
-pub const ERROR_CHILD_NOT_COMPLETE: DWORD = 129;
-pub const ERROR_DIRECT_ACCESS_HANDLE: DWORD = 130;
-pub const ERROR_NEGATIVE_SEEK: DWORD = 131;
-pub const ERROR_SEEK_ON_DEVICE: DWORD = 132;
-pub const ERROR_IS_JOIN_TARGET: DWORD = 133;
-pub const ERROR_IS_JOINED: DWORD = 134;
-pub const ERROR_IS_SUBSTED: DWORD = 135;
-pub const ERROR_NOT_JOINED: DWORD = 136;
-pub const ERROR_NOT_SUBSTED: DWORD = 137;
-pub const ERROR_JOIN_TO_JOIN: DWORD = 138;
-pub const ERROR_SUBST_TO_SUBST: DWORD = 139;
-pub const ERROR_JOIN_TO_SUBST: DWORD = 140;
-pub const ERROR_SUBST_TO_JOIN: DWORD = 141;
-pub const ERROR_BUSY_DRIVE: DWORD = 142;
-pub const ERROR_SAME_DRIVE: DWORD = 143;
-pub const ERROR_DIR_NOT_ROOT: DWORD = 144;
-pub const ERROR_DIR_NOT_EMPTY: DWORD = 145;
-pub const ERROR_IS_SUBST_PATH: DWORD = 146;
-pub const ERROR_IS_JOIN_PATH: DWORD = 147;
-pub const ERROR_PATH_BUSY: DWORD = 148;
-pub const ERROR_IS_SUBST_TARGET: DWORD = 149;
-pub const ERROR_SYSTEM_TRACE: DWORD = 150;
-pub const ERROR_INVALID_EVENT_COUNT: DWORD = 151;
-pub const ERROR_TOO_MANY_MUXWAITERS: DWORD = 152;
-pub const ERROR_INVALID_LIST_FORMAT: DWORD = 153;
-pub const ERROR_LABEL_TOO_LONG: DWORD = 154;
-pub const ERROR_TOO_MANY_TCBS: DWORD = 155;
-pub const ERROR_SIGNAL_REFUSED: DWORD = 156;
-pub const ERROR_DISCARDED: DWORD = 157;
-pub const ERROR_NOT_LOCKED: DWORD = 158;
-pub const ERROR_BAD_THREADID_ADDR: DWORD = 159;
-pub const ERROR_BAD_ARGUMENTS: DWORD = 160;
-pub const ERROR_BAD_PATHNAME: DWORD = 161;
-pub const ERROR_SIGNAL_PENDING: DWORD = 162;
-pub const ERROR_MAX_THRDS_REACHED: DWORD = 164;
-pub const ERROR_LOCK_FAILED: DWORD = 167;
-pub const ERROR_BUSY: DWORD = 170;
-pub const ERROR_CANCEL_VIOLATION: DWORD = 173;
-pub const ERROR_ATOMIC_LOCKS_NOT_SUPPORTED: DWORD = 174;
-pub const ERROR_INVALID_SEGMENT_NUMBER: DWORD = 180;
-pub const ERROR_INVALID_ORDINAL: DWORD = 182;
-pub const ERROR_ALREADY_EXISTS: DWORD = 183;
-pub const ERROR_INVALID_FLAG_NUMBER: DWORD = 186;
-pub const ERROR_SEM_NOT_FOUND: DWORD = 187;
-pub const ERROR_INVALID_STARTING_CODESEG: DWORD = 188;
-pub const ERROR_INVALID_STACKSEG: DWORD = 189;
-pub const ERROR_INVALID_MODULETYPE: DWORD = 190;
-pub const ERROR_INVALID_EXE_SIGNATURE: DWORD = 191;
-pub const ERROR_EXE_MARKED_INVALID: DWORD = 192;
-pub const ERROR_BAD_EXE_FORMAT: DWORD = 193;
-pub const ERROR_ITERATED_DATA_EXCEEDS_64k: DWORD = 194;
-pub const ERROR_INVALID_MINALLOCSIZE: DWORD = 195;
-pub const ERROR_DYNLINK_FROM_INVALID_RING: DWORD = 196;
-pub const ERROR_IOPL_NOT_ENABLED: DWORD = 197;
-pub const ERROR_INVALID_SEGDPL: DWORD = 198;
-pub const ERROR_AUTODATASEG_EXCEEDS_64k: DWORD = 199;
-pub const ERROR_RING2SEG_MUST_BE_MOVABLE: DWORD = 200;
-pub const ERROR_RELOC_CHAIN_XEEDS_SEGLIM: DWORD = 201;
-pub const ERROR_INFLOOP_IN_RELOC_CHAIN: DWORD = 202;
-pub const ERROR_ENVVAR_NOT_FOUND: DWORD = 203;
-pub const ERROR_NO_SIGNAL_SENT: DWORD = 205;
-pub const ERROR_FILENAME_EXCED_RANGE: DWORD = 206;
-pub const ERROR_RING2_STACK_IN_USE: DWORD = 207;
-pub const ERROR_META_EXPANSION_TOO_LONG: DWORD = 208;
-pub const ERROR_INVALID_SIGNAL_NUMBER: DWORD = 209;
-pub const ERROR_THREAD_1_INACTIVE: DWORD = 210;
-pub const ERROR_LOCKED: DWORD = 212;
-pub const ERROR_TOO_MANY_MODULES: DWORD = 214;
-pub const ERROR_NESTING_NOT_ALLOWED: DWORD = 215;
-pub const ERROR_EXE_MACHINE_TYPE_MISMATCH: DWORD = 216;
-pub const ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY: DWORD = 217;
-pub const ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY: DWORD = 218;
-pub const ERROR_FILE_CHECKED_OUT: DWORD = 220;
-pub const ERROR_CHECKOUT_REQUIRED: DWORD = 221;
-pub const ERROR_BAD_FILE_TYPE: DWORD = 222;
-pub const ERROR_FILE_TOO_LARGE: DWORD = 223;
-pub const ERROR_FORMS_AUTH_REQUIRED: DWORD = 224;
-pub const ERROR_PIPE_LOCAL: DWORD = 229;
-pub const ERROR_BAD_PIPE: DWORD = 230;
-pub const ERROR_PIPE_BUSY: DWORD = 231;
-pub const ERROR_NO_DATA: DWORD = 232;
-pub const ERROR_PIPE_NOT_CONNECTED: DWORD = 233;
-pub const ERROR_MORE_DATA: DWORD = 234;
-pub const ERROR_VC_DISCONNECTED: DWORD = 240;
-pub const ERROR_INVALID_EA_NAME: DWORD = 254;
-pub const ERROR_EA_LIST_INCONSISTENT: DWORD = 255;
-pub const ERROR_NO_MORE_ITEMS: DWORD = 259;
-pub const ERROR_CANNOT_COPY: DWORD = 266;
-pub const ERROR_DIRECTORY: DWORD = 267;
-pub const ERROR_EAS_DIDNT_FIT: DWORD = 275;
-pub const ERROR_EA_FILE_CORRUPT: DWORD = 276;
-pub const ERROR_EA_TABLE_FULL: DWORD = 277;
-pub const ERROR_INVALID_EA_HANDLE: DWORD = 278;
-pub const ERROR_EAS_NOT_SUPPORTED: DWORD = 282;
-pub const ERROR_NOT_OWNER: DWORD = 288;
-pub const ERROR_TOO_MANY_POSTS: DWORD = 298;
-pub const ERROR_PARTIAL_COPY: DWORD = 299;
-pub const ERROR_OPLOCK_NOT_GRANTED: DWORD = 300;
-pub const ERROR_INVALID_OPLOCK_PROTOCOL: DWORD = 301;
-pub const ERROR_DISK_TOO_FRAGMENTED: DWORD = 302;
-pub const ERROR_DELETE_PENDING: DWORD = 303;
-pub const ERROR_INVALID_TOKEN: DWORD = 315;
-pub const ERROR_MR_MID_NOT_FOUND: DWORD = 317;
-pub const ERROR_SCOPE_NOT_FOUND: DWORD = 318;
-pub const ERROR_INVALID_ADDRESS: DWORD = 487;
-pub const ERROR_ARITHMETIC_OVERFLOW: DWORD = 534;
-pub const ERROR_PIPE_CONNECTED: DWORD = 535;
-pub const ERROR_PIPE_LISTENING: DWORD = 536;
-pub const ERROR_WAKE_SYSTEM: DWORD = 730;
-pub const ERROR_WAIT_1: DWORD = 731;
-pub const ERROR_WAIT_2: DWORD = 732;
-pub const ERROR_WAIT_3: DWORD = 733;
-pub const ERROR_WAIT_63: DWORD = 734;
-pub const ERROR_ABANDONED_WAIT_0: DWORD = 735;
-pub const ERROR_ABANDONED_WAIT_63: DWORD = 736;
-pub const ERROR_USER_APC: DWORD = 737;
-pub const ERROR_KERNEL_APC: DWORD = 738;
-pub const ERROR_ALERTED: DWORD = 739;
-pub const ERROR_EA_ACCESS_DENIED: DWORD = 994;
-pub const ERROR_OPERATION_ABORTED: DWORD = 995;
-pub const ERROR_IO_INCOMPLETE: DWORD = 996;
-pub const ERROR_IO_PENDING: DWORD = 997;
-pub const ERROR_NOACCESS: DWORD = 998;
-pub const ERROR_SWAPERROR: DWORD = 999;
-pub const ERROR_STACK_OVERFLOW: DWORD = 1001;
-pub const ERROR_INVALID_MESSAGE: DWORD = 1002;
-pub const ERROR_CAN_NOT_COMPLETE: DWORD = 1003;
-pub const ERROR_INVALID_FLAGS: DWORD = 1004;
-pub const ERROR_UNRECOGNIZED_VOLUME: DWORD = 1005;
-pub const ERROR_FILE_INVALID: DWORD = 1006;
-pub const ERROR_FULLSCREEN_MODE: DWORD = 1007;
-pub const ERROR_NO_TOKEN: DWORD = 1008;
-pub const ERROR_BADDB: DWORD = 1009;
-pub const ERROR_BADKEY: DWORD = 1010;
-pub const ERROR_CANTOPEN: DWORD = 1011;
-pub const ERROR_CANTREAD: DWORD = 1012;
-pub const ERROR_CANTWRITE: DWORD = 1013;
-pub const ERROR_REGISTRY_RECOVERED: DWORD = 1014;
-pub const ERROR_REGISTRY_CORRUPT: DWORD = 1015;
-pub const ERROR_REGISTRY_IO_FAILED: DWORD = 1016;
-pub const ERROR_NOT_REGISTRY_FILE: DWORD = 1017;
-pub const ERROR_KEY_DELETED: DWORD = 1018;
-pub const ERROR_NO_LOG_SPACE: DWORD = 1019;
-pub const ERROR_KEY_HAS_CHILDREN: DWORD = 1020;
-pub const ERROR_CHILD_MUST_BE_VOLATILE: DWORD = 1021;
-pub const ERROR_NOTIFY_ENUM_DIR: DWORD = 1022;
-pub const ERROR_DEPENDENT_SERVICES_RUNNING: DWORD = 1051;
-pub const ERROR_INVALID_SERVICE_CONTROL: DWORD = 1052;
-pub const ERROR_SERVICE_REQUEST_TIMEOUT: DWORD = 1053;
-pub const ERROR_SERVICE_NO_THREAD: DWORD = 1054;
-pub const ERROR_SERVICE_DATABASE_LOCKED: DWORD = 1055;
-pub const ERROR_SERVICE_ALREADY_RUNNING: DWORD = 1056;
-pub const ERROR_INVALID_SERVICE_ACCOUNT: DWORD = 1057;
-pub const ERROR_SERVICE_DISABLED: DWORD = 1058;
-pub const ERROR_CIRCULAR_DEPENDENCY: DWORD = 1059;
-pub const ERROR_SERVICE_DOES_NOT_EXIST: DWORD = 1060;
-pub const ERROR_SERVICE_CANNOT_ACCEPT_CTRL: DWORD = 1061;
-pub const ERROR_SERVICE_NOT_ACTIVE: DWORD = 1062;
-pub const ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: DWORD = 1063;
-pub const ERROR_EXCEPTION_IN_SERVICE: DWORD = 1064;
-pub const ERROR_DATABASE_DOES_NOT_EXIST: DWORD = 1065;
-pub const ERROR_SERVICE_SPECIFIC_ERROR: DWORD = 1066;
-pub const ERROR_PROCESS_ABORTED: DWORD = 1067;
-pub const ERROR_SERVICE_DEPENDENCY_FAIL: DWORD = 1068;
-pub const ERROR_SERVICE_LOGON_FAILED: DWORD = 1069;
-pub const ERROR_SERVICE_START_HANG: DWORD = 1070;
-pub const ERROR_INVALID_SERVICE_LOCK: DWORD = 1071;
-pub const ERROR_SERVICE_MARKED_FOR_DELETE: DWORD = 1072;
-pub const ERROR_SERVICE_EXISTS: DWORD = 1073;
-pub const ERROR_ALREADY_RUNNING_LKG: DWORD = 1074;
-pub const ERROR_SERVICE_DEPENDENCY_DELETED: DWORD = 1075;
-pub const ERROR_BOOT_ALREADY_ACCEPTED: DWORD = 1076;
-pub const ERROR_SERVICE_NEVER_STARTED: DWORD = 1077;
-pub const ERROR_DUPLICATE_SERVICE_NAME: DWORD = 1078;
-pub const ERROR_DIFFERENT_SERVICE_ACCOUNT: DWORD = 1079;
-pub const ERROR_CANNOT_DETECT_DRIVER_FAILURE: DWORD = 1080;
-pub const ERROR_CANNOT_DETECT_PROCESS_ABORT: DWORD = 1081;
-pub const ERROR_NO_RECOVERY_PROGRAM: DWORD = 1082;
-pub const ERROR_SERVICE_NOT_IN_EXE: DWORD = 1083;
-pub const ERROR_NOT_SAFEBOOT_SERVICE: DWORD = 1084;
-pub const ERROR_END_OF_MEDIA: DWORD = 1100;
-pub const ERROR_FILEMARK_DETECTED: DWORD = 1101;
-pub const ERROR_BEGINNING_OF_MEDIA: DWORD = 1102;
-pub const ERROR_SETMARK_DETECTED: DWORD = 1103;
-pub const ERROR_NO_DATA_DETECTED: DWORD = 1104;
-pub const ERROR_PARTITION_FAILURE: DWORD = 1105;
-pub const ERROR_INVALID_BLOCK_LENGTH: DWORD = 1106;
-pub const ERROR_DEVICE_NOT_PARTITIONED: DWORD = 1107;
-pub const ERROR_UNABLE_TO_LOCK_MEDIA: DWORD = 1108;
-pub const ERROR_UNABLE_TO_UNLOAD_MEDIA: DWORD = 1109;
-pub const ERROR_MEDIA_CHANGED: DWORD = 1110;
-pub const ERROR_BUS_RESET: DWORD = 1111;
-pub const ERROR_NO_MEDIA_IN_DRIVE: DWORD = 1112;
-pub const ERROR_NO_UNICODE_TRANSLATION: DWORD = 1113;
-pub const ERROR_DLL_INIT_FAILED: DWORD = 1114;
-pub const ERROR_SHUTDOWN_IN_PROGRESS: DWORD = 1115;
-pub const ERROR_NO_SHUTDOWN_IN_PROGRESS: DWORD = 1116;
-pub const ERROR_IO_DEVICE: DWORD = 1117;
-pub const ERROR_SERIAL_NO_DEVICE: DWORD = 1118;
-pub const ERROR_IRQ_BUSY: DWORD = 1119;
-pub const ERROR_MORE_WRITES: DWORD = 1120;
-pub const ERROR_COUNTER_TIMEOUT: DWORD = 1121;
-pub const ERROR_FLOPPY_ID_MARK_NOT_FOUND: DWORD = 1122;
-pub const ERROR_FLOPPY_WRONG_CYLINDER: DWORD = 1123;
-pub const ERROR_FLOPPY_UNKNOWN_ERROR: DWORD = 1124;
-pub const ERROR_FLOPPY_BAD_REGISTERS: DWORD = 1125;
-pub const ERROR_DISK_RECALIBRATE_FAILED: DWORD = 1126;
-pub const ERROR_DISK_OPERATION_FAILED: DWORD = 1127;
-pub const ERROR_DISK_RESET_FAILED: DWORD = 1128;
-pub const ERROR_EOM_OVERFLOW: DWORD = 1129;
-pub const ERROR_NOT_ENOUGH_SERVER_MEMORY: DWORD = 1130;
-pub const ERROR_POSSIBLE_DEADLOCK: DWORD = 1131;
-pub const ERROR_MAPPED_ALIGNMENT: DWORD = 1132;
-pub const ERROR_SET_POWER_STATE_VETOED: DWORD = 1140;
-pub const ERROR_SET_POWER_STATE_FAILED: DWORD = 1141;
-pub const ERROR_TOO_MANY_LINKS: DWORD = 1142;
-pub const ERROR_OLD_WIN_VERSION: DWORD = 1150;
-pub const ERROR_APP_WRONG_OS: DWORD = 1151;
-pub const ERROR_SINGLE_INSTANCE_APP: DWORD = 1152;
-pub const ERROR_RMODE_APP: DWORD = 1153;
-pub const ERROR_INVALID_DLL: DWORD = 1154;
-pub const ERROR_NO_ASSOCIATION: DWORD = 1155;
-pub const ERROR_DDE_FAIL: DWORD = 1156;
-pub const ERROR_DLL_NOT_FOUND: DWORD = 1157;
-pub const ERROR_NO_MORE_USER_HANDLES: DWORD = 1158;
-pub const ERROR_MESSAGE_SYNC_ONLY: DWORD = 1159;
-pub const ERROR_SOURCE_ELEMENT_EMPTY: DWORD = 1160;
-pub const ERROR_DESTINATION_ELEMENT_FULL: DWORD = 1161;
-pub const ERROR_ILLEGAL_ELEMENT_ADDRESS: DWORD = 1162;
-pub const ERROR_MAGAZINE_NOT_PRESENT: DWORD = 1163;
-pub const ERROR_DEVICE_REINITIALIZATION_NEEDED: DWORD = 1164;
-pub const ERROR_DEVICE_REQUIRES_CLEANING: DWORD = 1165;
-pub const ERROR_DEVICE_DOOR_OPEN: DWORD = 1166;
-pub const ERROR_DEVICE_NOT_CONNECTED: DWORD = 1167;
-pub const ERROR_NOT_FOUND: DWORD = 1168;
-pub const ERROR_NO_MATCH: DWORD = 1169;
-pub const ERROR_SET_NOT_FOUND: DWORD = 1170;
-pub const ERROR_POINT_NOT_FOUND: DWORD = 1171;
-pub const ERROR_NO_TRACKING_SERVICE: DWORD = 1172;
-pub const ERROR_NO_VOLUME_ID: DWORD = 1173;
-pub const ERROR_UNABLE_TO_REMOVE_REPLACED: DWORD = 1175;
-pub const ERROR_UNABLE_TO_MOVE_REPLACEMENT: DWORD = 1176;
-pub const ERROR_UNABLE_TO_MOVE_REPLACEMENT_2: DWORD = 1177;
-pub const ERROR_JOURNAL_DELETE_IN_PROGRESS: DWORD = 1178;
-pub const ERROR_JOURNAL_NOT_ACTIVE: DWORD = 1179;
-pub const ERROR_POTENTIAL_FILE_FOUND: DWORD = 1180;
-pub const ERROR_JOURNAL_ENTRY_DELETED: DWORD = 1181;
-pub const ERROR_BAD_DEVICE: DWORD = 1200;
-pub const ERROR_CONNECTION_UNAVAIL: DWORD = 1201;
-pub const ERROR_DEVICE_ALREADY_REMEMBERED: DWORD = 1202;
-pub const ERROR_NO_NET_OR_BAD_PATH: DWORD = 1203;
-pub const ERROR_BAD_PROVIDER: DWORD = 1204;
-pub const ERROR_CANNOT_OPEN_PROFILE: DWORD = 1205;
-pub const ERROR_BAD_PROFILE: DWORD = 1206;
-pub const ERROR_NOT_CONTAINER: DWORD = 1207;
-pub const ERROR_EXTENDED_ERROR: DWORD = 1208;
-pub const ERROR_INVALID_GROUPNAME: DWORD = 1209;
-pub const ERROR_INVALID_COMPUTERNAME: DWORD = 1210;
-pub const ERROR_INVALID_EVENTNAME: DWORD = 1211;
-pub const ERROR_INVALID_DOMAINNAME: DWORD = 1212;
-pub const ERROR_INVALID_SERVICENAME: DWORD = 1213;
-pub const ERROR_INVALID_NETNAME: DWORD = 1214;
-pub const ERROR_INVALID_SHARENAME: DWORD = 1215;
-pub const ERROR_INVALID_PASSWORDNAME: DWORD = 1216;
-pub const ERROR_INVALID_MESSAGENAME: DWORD = 1217;
-pub const ERROR_INVALID_MESSAGEDEST: DWORD = 1218;
-pub const ERROR_SESSION_CREDENTIAL_CONFLICT: DWORD = 1219;
-pub const ERROR_REMOTE_SESSION_LIMIT_EXCEEDED: DWORD = 1220;
-pub const ERROR_DUP_DOMAINNAME: DWORD = 1221;
-pub const ERROR_NO_NETWORK: DWORD = 1222;
-pub const ERROR_CANCELLED: DWORD = 1223;
-pub const ERROR_USER_MAPPED_FILE: DWORD = 1224;
-pub const ERROR_CONNECTION_REFUSED: DWORD = 1225;
-pub const ERROR_GRACEFUL_DISCONNECT: DWORD = 1226;
-pub const ERROR_ADDRESS_ALREADY_ASSOCIATED: DWORD = 1227;
-pub const ERROR_ADDRESS_NOT_ASSOCIATED: DWORD = 1228;
-pub const ERROR_CONNECTION_INVALID: DWORD = 1229;
-pub const ERROR_CONNECTION_ACTIVE: DWORD = 1230;
-pub const ERROR_NETWORK_UNREACHABLE: DWORD = 1231;
-pub const ERROR_HOST_UNREACHABLE: DWORD = 1232;
-pub const ERROR_PROTOCOL_UNREACHABLE: DWORD = 1233;
-pub const ERROR_PORT_UNREACHABLE: DWORD = 1234;
-pub const ERROR_REQUEST_ABORTED: DWORD = 1235;
-pub const ERROR_CONNECTION_ABORTED: DWORD = 1236;
-pub const ERROR_RETRY: DWORD = 1237;
-pub const ERROR_CONNECTION_COUNT_LIMIT: DWORD = 1238;
-pub const ERROR_LOGIN_TIME_RESTRICTION: DWORD = 1239;
-pub const ERROR_LOGIN_WKSTA_RESTRICTION: DWORD = 1240;
-pub const ERROR_INCORRECT_ADDRESS: DWORD = 1241;
-pub const ERROR_ALREADY_REGISTERED: DWORD = 1242;
-pub const ERROR_SERVICE_NOT_FOUND: DWORD = 1243;
-pub const ERROR_NOT_AUTHENTICATED: DWORD = 1244;
-pub const ERROR_NOT_LOGGED_ON: DWORD = 1245;
-pub const ERROR_CONTINUE: DWORD = 1246;
-pub const ERROR_ALREADY_INITIALIZED: DWORD = 1247;
-pub const ERROR_NO_MORE_DEVICES: DWORD = 1248;
-pub const ERROR_NO_SUCH_SITE: DWORD = 1249;
-pub const ERROR_DOMAIN_CONTROLLER_EXISTS: DWORD = 1250;
-pub const ERROR_ONLY_IF_CONNECTED: DWORD = 1251;
-pub const ERROR_OVERRIDE_NOCHANGES: DWORD = 1252;
-pub const ERROR_BAD_USER_PROFILE: DWORD = 1253;
-pub const ERROR_NOT_SUPPORTED_ON_SBS: DWORD = 1254;
-pub const ERROR_SERVER_SHUTDOWN_IN_PROGRESS: DWORD = 1255;
-pub const ERROR_HOST_DOWN: DWORD = 1256;
-pub const ERROR_NON_ACCOUNT_SID: DWORD = 1257;
-pub const ERROR_NON_DOMAIN_SID: DWORD = 1258;
-pub const ERROR_APPHELP_BLOCK: DWORD = 1259;
-pub const ERROR_ACCESS_DISABLED_BY_POLICY: DWORD = 1260;
-pub const ERROR_REG_NAT_CONSUMPTION: DWORD = 1261;
-pub const ERROR_CSCSHARE_OFFLINE: DWORD = 1262;
-pub const ERROR_PKINIT_FAILURE: DWORD = 1263;
-pub const ERROR_SMARTCARD_SUBSYSTEM_FAILURE: DWORD = 1264;
-pub const ERROR_DOWNGRADE_DETECTED: DWORD = 1265;
-pub const ERROR_MACHINE_LOCKED: DWORD = 1271;
-pub const ERROR_CALLBACK_SUPPLIED_INVALID_DATA: DWORD = 1273;
-pub const ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED: DWORD = 1274;
-pub const ERROR_DRIVER_BLOCKED: DWORD = 1275;
-pub const ERROR_INVALID_IMPORT_OF_NON_DLL: DWORD = 1276;
-pub const ERROR_ACCESS_DISABLED_WEBBLADE: DWORD = 1277;
-pub const ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER: DWORD = 1278;
-pub const ERROR_RECOVERY_FAILURE: DWORD = 1279;
-pub const ERROR_ALREADY_FIBER: DWORD = 1280;
-pub const ERROR_ALREADY_THREAD: DWORD = 1281;
-pub const ERROR_STACK_BUFFER_OVERRUN: DWORD = 1282;
-pub const ERROR_PARAMETER_QUOTA_EXCEEDED: DWORD = 1283;
-pub const ERROR_DEBUGGER_INACTIVE: DWORD = 1284;
-pub const ERROR_DELAY_LOAD_FAILED: DWORD = 1285;
-pub const ERROR_VDM_DISALLOWED: DWORD = 1286;
-pub const ERROR_UNIDENTIFIED_ERROR: DWORD = 1287;
-pub const ERROR_NOT_ALL_ASSIGNED: DWORD = 1300;
-pub const ERROR_SOME_NOT_MAPPED: DWORD = 1301;
-pub const ERROR_NO_QUOTAS_FOR_ACCOUNT: DWORD = 1302;
-pub const ERROR_LOCAL_USER_SESSION_KEY: DWORD = 1303;
-pub const ERROR_NULL_LM_PASSWORD: DWORD = 1304;
-pub const ERROR_UNKNOWN_REVISION: DWORD = 1305;
-pub const ERROR_REVISION_MISMATCH: DWORD = 1306;
-pub const ERROR_INVALID_OWNER: DWORD = 1307;
-pub const ERROR_INVALID_PRIMARY_GROUP: DWORD = 1308;
-pub const ERROR_NO_IMPERSONATION_TOKEN: DWORD = 1309;
-pub const ERROR_CANT_DISABLE_MANDATORY: DWORD = 1310;
-pub const ERROR_NO_LOGON_SERVERS: DWORD = 1311;
-pub const ERROR_NO_SUCH_LOGON_SESSION: DWORD = 1312;
-pub const ERROR_NO_SUCH_PRIVILEGE: DWORD = 1313;
-pub const ERROR_PRIVILEGE_NOT_HELD: DWORD = 1314;
-pub const ERROR_INVALID_ACCOUNT_NAME: DWORD = 1315;
-pub const ERROR_USER_EXISTS: DWORD = 1316;
-pub const ERROR_NO_SUCH_USER: DWORD = 1317;
-pub const ERROR_GROUP_EXISTS: DWORD = 1318;
-pub const ERROR_NO_SUCH_GROUP: DWORD = 1319;
-pub const ERROR_MEMBER_IN_GROUP: DWORD = 1320;
-pub const ERROR_MEMBER_NOT_IN_GROUP: DWORD = 1321;
-pub const ERROR_LAST_ADMIN: DWORD = 1322;
-pub const ERROR_WRONG_PASSWORD: DWORD = 1323;
-pub const ERROR_ILL_FORMED_PASSWORD: DWORD = 1324;
-pub const ERROR_PASSWORD_RESTRICTION: DWORD = 1325;
-pub const ERROR_LOGON_FAILURE: DWORD = 1326;
-pub const ERROR_ACCOUNT_RESTRICTION: DWORD = 1327;
-pub const ERROR_INVALID_LOGON_HOURS: DWORD = 1328;
-pub const ERROR_INVALID_WORKSTATION: DWORD = 1329;
-pub const ERROR_PASSWORD_EXPIRED: DWORD = 1330;
-pub const ERROR_ACCOUNT_DISABLED: DWORD = 1331;
-pub const ERROR_NONE_MAPPED: DWORD = 1332;
-pub const ERROR_TOO_MANY_LUIDS_REQUESTED: DWORD = 1333;
-pub const ERROR_LUIDS_EXHAUSTED: DWORD = 1334;
-pub const ERROR_INVALID_SUB_AUTHORITY: DWORD = 1335;
-pub const ERROR_INVALID_ACL: DWORD = 1336;
-pub const ERROR_INVALID_SID: DWORD = 1337;
-pub const ERROR_INVALID_SECURITY_DESCR: DWORD = 1338;
-pub const ERROR_BAD_INHERITANCE_ACL: DWORD = 1340;
-pub const ERROR_SERVER_DISABLED: DWORD = 1341;
-pub const ERROR_SERVER_NOT_DISABLED: DWORD = 1342;
-pub const ERROR_INVALID_ID_AUTHORITY: DWORD = 1343;
-pub const ERROR_ALLOTTED_SPACE_EXCEEDED: DWORD = 1344;
-pub const ERROR_INVALID_GROUP_ATTRIBUTES: DWORD = 1345;
-pub const ERROR_BAD_IMPERSONATION_LEVEL: DWORD = 1346;
-pub const ERROR_CANT_OPEN_ANONYMOUS: DWORD = 1347;
-pub const ERROR_BAD_VALIDATION_CLASS: DWORD = 1348;
-pub const ERROR_BAD_TOKEN_TYPE: DWORD = 1349;
-pub const ERROR_NO_SECURITY_ON_OBJECT: DWORD = 1350;
-pub const ERROR_CANT_ACCESS_DOMAIN_INFO: DWORD = 1351;
-pub const ERROR_INVALID_SERVER_STATE: DWORD = 1352;
-pub const ERROR_INVALID_DOMAIN_STATE: DWORD = 1353;
-pub const ERROR_INVALID_DOMAIN_ROLE: DWORD = 1354;
-pub const ERROR_NO_SUCH_DOMAIN: DWORD = 1355;
-pub const ERROR_DOMAIN_EXISTS: DWORD = 1356;
-pub const ERROR_DOMAIN_LIMIT_EXCEEDED: DWORD = 1357;
-pub const ERROR_INTERNAL_DB_CORRUPTION: DWORD = 1358;
-pub const ERROR_INTERNAL_ERROR: DWORD = 1359;
-pub const ERROR_GENERIC_NOT_MAPPED: DWORD = 1360;
-pub const ERROR_BAD_DESCRIPTOR_FORMAT: DWORD = 1361;
-pub const ERROR_NOT_LOGON_PROCESS: DWORD = 1362;
-pub const ERROR_LOGON_SESSION_EXISTS: DWORD = 1363;
-pub const ERROR_NO_SUCH_PACKAGE: DWORD = 1364;
-pub const ERROR_BAD_LOGON_SESSION_STATE: DWORD = 1365;
-pub const ERROR_LOGON_SESSION_COLLISION: DWORD = 1366;
-pub const ERROR_INVALID_LOGON_TYPE: DWORD = 1367;
-pub const ERROR_CANNOT_IMPERSONATE: DWORD = 1368;
-pub const ERROR_RXACT_INVALID_STATE: DWORD = 1369;
-pub const ERROR_RXACT_COMMIT_FAILURE: DWORD = 1370;
-pub const ERROR_SPECIAL_ACCOUNT: DWORD = 1371;
-pub const ERROR_SPECIAL_GROUP: DWORD = 1372;
-pub const ERROR_SPECIAL_USER: DWORD = 1373;
-pub const ERROR_MEMBERS_PRIMARY_GROUP: DWORD = 1374;
-pub const ERROR_TOKEN_ALREADY_IN_USE: DWORD = 1375;
-pub const ERROR_NO_SUCH_ALIAS: DWORD = 1376;
-pub const ERROR_MEMBER_NOT_IN_ALIAS: DWORD = 1377;
-pub const ERROR_MEMBER_IN_ALIAS: DWORD = 1378;
-pub const ERROR_ALIAS_EXISTS: DWORD = 1379;
-pub const ERROR_LOGON_NOT_GRANTED: DWORD = 1380;
-pub const ERROR_TOO_MANY_SECRETS: DWORD = 1381;
-pub const ERROR_SECRET_TOO_LONG: DWORD = 1382;
-pub const ERROR_INTERNAL_DB_ERROR: DWORD = 1383;
-pub const ERROR_TOO_MANY_CONTEXT_IDS: DWORD = 1384;
-pub const ERROR_LOGON_TYPE_NOT_GRANTED: DWORD = 1385;
-pub const ERROR_NT_CROSS_ENCRYPTION_REQUIRED: DWORD = 1386;
-pub const ERROR_NO_SUCH_MEMBER: DWORD = 1387;
-pub const ERROR_INVALID_MEMBER: DWORD = 1388;
-pub const ERROR_TOO_MANY_SIDS: DWORD = 1389;
-pub const ERROR_LM_CROSS_ENCRYPTION_REQUIRED: DWORD = 1390;
-pub const ERROR_NO_INHERITANCE: DWORD = 1391;
-pub const ERROR_FILE_CORRUPT: DWORD = 1392;
-pub const ERROR_DISK_CORRUPT: DWORD = 1393;
-pub const ERROR_NO_USER_SESSION_KEY: DWORD = 1394;
-pub const ERROR_LICENSE_QUOTA_EXCEEDED: DWORD = 1395;
-pub const ERROR_WRONG_TARGET_NAME: DWORD = 1396;
-pub const ERROR_MUTUAL_AUTH_FAILED: DWORD = 1397;
-pub const ERROR_TIME_SKEW: DWORD = 1398;
-pub const ERROR_CURRENT_DOMAIN_NOT_ALLOWED: DWORD = 1399;
-pub const ERROR_INVALID_WINDOW_HANDLE: DWORD = 1400;
-pub const ERROR_INVALID_MENU_HANDLE: DWORD = 1401;
-pub const ERROR_INVALID_CURSOR_HANDLE: DWORD = 1402;
-pub const ERROR_INVALID_ACCEL_HANDLE: DWORD = 1403;
-pub const ERROR_INVALID_HOOK_HANDLE: DWORD = 1404;
-pub const ERROR_INVALID_DWP_HANDLE: DWORD = 1405;
-pub const ERROR_TLW_WITH_WSCHILD: DWORD = 1406;
-pub const ERROR_CANNOT_FIND_WND_CLASS: DWORD = 1407;
-pub const ERROR_WINDOW_OF_OTHER_THREAD: DWORD = 1408;
-pub const ERROR_HOTKEY_ALREADY_REGISTERED: DWORD = 1409;
-pub const ERROR_CLASS_ALREADY_EXISTS: DWORD = 1410;
-pub const ERROR_CLASS_DOES_NOT_EXIST: DWORD = 1411;
-pub const ERROR_CLASS_HAS_WINDOWS: DWORD = 1412;
-pub const ERROR_INVALID_INDEX: DWORD = 1413;
-pub const ERROR_INVALID_ICON_HANDLE: DWORD = 1414;
-pub const ERROR_PRIVATE_DIALOG_INDEX: DWORD = 1415;
-pub const ERROR_LISTBOX_ID_NOT_FOUND: DWORD = 1416;
-pub const ERROR_NO_WILDCARD_CHARACTERS: DWORD = 1417;
-pub const ERROR_CLIPBOARD_NOT_OPEN: DWORD = 1418;
-pub const ERROR_HOTKEY_NOT_REGISTERED: DWORD = 1419;
-pub const ERROR_WINDOW_NOT_DIALOG: DWORD = 1420;
-pub const ERROR_CONTROL_ID_NOT_FOUND: DWORD = 1421;
-pub const ERROR_INVALID_COMBOBOX_MESSAGE: DWORD = 1422;
-pub const ERROR_WINDOW_NOT_COMBOBOX: DWORD = 1423;
-pub const ERROR_INVALID_EDIT_HEIGHT: DWORD = 1424;
-pub const ERROR_DC_NOT_FOUND: DWORD = 1425;
-pub const ERROR_INVALID_HOOK_FILTER: DWORD = 1426;
-pub const ERROR_INVALID_FILTER_PROC: DWORD = 1427;
-pub const ERROR_HOOK_NEEDS_HMOD: DWORD = 1428;
-pub const ERROR_GLOBAL_ONLY_HOOK: DWORD = 1429;
-pub const ERROR_JOURNAL_HOOK_SET: DWORD = 1430;
-pub const ERROR_HOOK_NOT_INSTALLED: DWORD = 1431;
-pub const ERROR_INVALID_LB_MESSAGE: DWORD = 1432;
-pub const ERROR_SETCOUNT_ON_BAD_LB: DWORD = 1433;
-pub const ERROR_LB_WITHOUT_TABSTOPS: DWORD = 1434;
-pub const ERROR_DESTROY_OBJECT_OF_OTHER_THREAD: DWORD = 1435;
-pub const ERROR_CHILD_WINDOW_MENU: DWORD = 1436;
-pub const ERROR_NO_SYSTEM_MENU: DWORD = 1437;
-pub const ERROR_INVALID_MSGBOX_STYLE: DWORD = 1438;
-pub const ERROR_INVALID_SPI_VALUE: DWORD = 1439;
-pub const ERROR_SCREEN_ALREADY_LOCKED: DWORD = 1440;
-pub const ERROR_HWNDS_HAVE_DIFF_PARENT: DWORD = 1441;
-pub const ERROR_NOT_CHILD_WINDOW: DWORD = 1442;
-pub const ERROR_INVALID_GW_COMMAND: DWORD = 1443;
-pub const ERROR_INVALID_THREAD_ID: DWORD = 1444;
-pub const ERROR_NON_MDICHILD_WINDOW: DWORD = 1445;
-pub const ERROR_POPUP_ALREADY_ACTIVE: DWORD = 1446;
-pub const ERROR_NO_SCROLLBARS: DWORD = 1447;
-pub const ERROR_INVALID_SCROLLBAR_RANGE: DWORD = 1448;
-pub const ERROR_INVALID_SHOWWIN_COMMAND: DWORD = 1449;
-pub const ERROR_NO_SYSTEM_RESOURCES: DWORD = 1450;
-pub const ERROR_NONPAGED_SYSTEM_RESOURCES: DWORD = 1451;
-pub const ERROR_PAGED_SYSTEM_RESOURCES: DWORD = 1452;
-pub const ERROR_WORKING_SET_QUOTA: DWORD = 1453;
-pub const ERROR_PAGEFILE_QUOTA: DWORD = 1454;
-pub const ERROR_COMMITMENT_LIMIT: DWORD = 1455;
-pub const ERROR_MENU_ITEM_NOT_FOUND: DWORD = 1456;
-pub const ERROR_INVALID_KEYBOARD_HANDLE: DWORD = 1457;
-pub const ERROR_HOOK_TYPE_NOT_ALLOWED: DWORD = 1458;
-pub const ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION: DWORD = 1459;
-pub const ERROR_TIMEOUT: DWORD = 1460;
-pub const ERROR_INVALID_MONITOR_HANDLE: DWORD = 1461;
-pub const ERROR_INCORRECT_SIZE: DWORD = 1462;
-pub const ERROR_SYMLINK_CLASS_DISABLED: DWORD = 1463;
-pub const ERROR_SYMLINK_NOT_SUPPORTED: DWORD = 1464;
-pub const ERROR_XML_PARSE_ERROR: DWORD = 1465;
-pub const ERROR_XMLDSIG_ERROR: DWORD = 1466;
-pub const ERROR_RESTART_APPLICATION: DWORD = 1467;
-pub const ERROR_WRONG_COMPARTMENT: DWORD = 1468;
-pub const ERROR_AUTHIP_FAILURE: DWORD = 1469;
-pub const ERROR_NO_NVRAM_RESOURCES: DWORD = 1470;
-pub const ERROR_NOT_GUI_PROCESS: DWORD = 1471;
-pub const ERROR_EVENTLOG_FILE_CORRUPT: DWORD = 1500;
-pub const ERROR_EVENTLOG_CANT_START: DWORD = 1501;
-pub const ERROR_LOG_FILE_FULL: DWORD = 1502;
-pub const ERROR_EVENTLOG_FILE_CHANGED: DWORD = 1503;
-pub const ERROR_INSTALL_SERVICE_FAILURE: DWORD = 1601;
-pub const ERROR_INSTALL_USEREXIT: DWORD = 1602;
-pub const ERROR_INSTALL_FAILURE: DWORD = 1603;
-pub const ERROR_INSTALL_SUSPEND: DWORD = 1604;
-pub const ERROR_UNKNOWN_PRODUCT: DWORD = 1605;
-pub const ERROR_UNKNOWN_FEATURE: DWORD = 1606;
-pub const ERROR_UNKNOWN_COMPONENT: DWORD = 1607;
-pub const ERROR_UNKNOWN_PROPERTY: DWORD = 1608;
-pub const ERROR_INVALID_HANDLE_STATE: DWORD = 1609;
-pub const ERROR_BAD_CONFIGURATION: DWORD = 1610;
-pub const ERROR_INDEX_ABSENT: DWORD = 1611;
-pub const ERROR_INSTALL_SOURCE_ABSENT: DWORD = 1612;
-pub const ERROR_INSTALL_PACKAGE_VERSION: DWORD = 1613;
-pub const ERROR_PRODUCT_UNINSTALLED: DWORD = 1614;
-pub const ERROR_BAD_QUERY_SYNTAX: DWORD = 1615;
-pub const ERROR_INVALID_FIELD: DWORD = 1616;
-pub const ERROR_DEVICE_REMOVED: DWORD = 1617;
-pub const ERROR_INSTALL_ALREADY_RUNNING: DWORD = 1618;
-pub const ERROR_INSTALL_PACKAGE_OPEN_FAILED: DWORD = 1619;
-pub const ERROR_INSTALL_PACKAGE_INVALID: DWORD = 1620;
-pub const ERROR_INSTALL_UI_FAILURE: DWORD = 1621;
-pub const ERROR_INSTALL_LOG_FAILURE: DWORD = 1622;
-pub const ERROR_INSTALL_LANGUAGE_UNSUPPORTED: DWORD = 1623;
-pub const ERROR_INSTALL_TRANSFORM_FAILURE: DWORD = 1624;
-pub const ERROR_INSTALL_PACKAGE_REJECTED: DWORD = 1625;
-pub const ERROR_FUNCTION_NOT_CALLED: DWORD = 1626;
-pub const ERROR_FUNCTION_FAILED: DWORD = 1627;
-pub const ERROR_INVALID_TABLE: DWORD = 1628;
-pub const ERROR_DATATYPE_MISMATCH: DWORD = 1629;
-pub const ERROR_UNSUPPORTED_TYPE: DWORD = 1630;
-pub const ERROR_CREATE_FAILED: DWORD = 1631;
-pub const ERROR_INSTALL_TEMP_UNWRITABLE: DWORD = 1632;
-pub const ERROR_INSTALL_PLATFORM_UNSUPPORTED: DWORD = 1633;
-pub const ERROR_INSTALL_NOTUSED: DWORD = 1634;
-pub const ERROR_PATCH_PACKAGE_OPEN_FAILED: DWORD = 1635;
-pub const ERROR_PATCH_PACKAGE_INVALID: DWORD = 1636;
-pub const ERROR_PATCH_PACKAGE_UNSUPPORTED: DWORD = 1637;
-pub const ERROR_PRODUCT_VERSION: DWORD = 1638;
-pub const ERROR_INVALID_COMMAND_LINE: DWORD = 1639;
-pub const ERROR_INSTALL_REMOTE_DISALLOWED: DWORD = 1640;
-pub const ERROR_SUCCESS_REBOOT_INITIATED: DWORD = 1641;
-pub const ERROR_PATCH_TARGET_NOT_FOUND: DWORD = 1642;
-pub const ERROR_PATCH_PACKAGE_REJECTED: DWORD = 1643;
-pub const ERROR_INSTALL_TRANSFORM_REJECTED: DWORD = 1644;
-pub const ERROR_INSTALL_REMOTE_PROHIBITED: DWORD = 1645;
-pub const ERROR_INVALID_USER_BUFFER: DWORD = 1784;
-pub const ERROR_UNRECOGNIZED_MEDIA: DWORD = 1785;
-pub const ERROR_NO_TRUST_LSA_SECRET: DWORD = 1786;
-pub const ERROR_NO_TRUST_SAM_ACCOUNT: DWORD = 1787;
-pub const ERROR_TRUSTED_DOMAIN_FAILURE: DWORD = 1788;
-pub const ERROR_TRUSTED_RELATIONSHIP_FAILURE: DWORD = 1789;
-pub const ERROR_TRUST_FAILURE: DWORD = 1790;
-pub const ERROR_NETLOGON_NOT_STARTED: DWORD = 1792;
-pub const ERROR_ACCOUNT_EXPIRED: DWORD = 1793;
-pub const ERROR_REDIRECTOR_HAS_OPEN_HANDLES: DWORD = 1794;
-pub const ERROR_PRINTER_DRIVER_ALREADY_INSTALLED: DWORD = 1795;
-pub const ERROR_UNKNOWN_PORT: DWORD = 1796;
-pub const ERROR_UNKNOWN_PRINTER_DRIVER: DWORD = 1797;
-pub const ERROR_UNKNOWN_PRINTPROCESSOR: DWORD = 1798;
-pub const ERROR_INVALID_SEPARATOR_FILE: DWORD = 1799;
-pub const ERROR_INVALID_PRIORITY: DWORD = 1800;
-pub const ERROR_INVALID_PRINTER_NAME: DWORD = 1801;
-pub const ERROR_PRINTER_ALREADY_EXISTS: DWORD = 1802;
-pub const ERROR_INVALID_PRINTER_COMMAND: DWORD = 1803;
-pub const ERROR_INVALID_DATATYPE: DWORD = 1804;
-pub const ERROR_INVALID_ENVIRONMENT: DWORD = 1805;
-pub const ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT: DWORD = 1807;
-pub const ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT: DWORD = 1808;
-pub const ERROR_NOLOGON_SERVER_TRUST_ACCOUNT: DWORD = 1809;
-pub const ERROR_DOMAIN_TRUST_INCONSISTENT: DWORD = 1810;
-pub const ERROR_SERVER_HAS_OPEN_HANDLES: DWORD = 1811;
-pub const ERROR_RESOURCE_DATA_NOT_FOUND: DWORD = 1812;
-pub const ERROR_RESOURCE_TYPE_NOT_FOUND: DWORD = 1813;
-pub const ERROR_RESOURCE_NAME_NOT_FOUND: DWORD = 1814;
-pub const ERROR_RESOURCE_LANG_NOT_FOUND: DWORD = 1815;
-pub const ERROR_NOT_ENOUGH_QUOTA: DWORD = 1816;
-pub const ERROR_INVALID_TIME: DWORD = 1901;
-pub const ERROR_INVALID_FORM_NAME: DWORD = 1902;
-pub const ERROR_INVALID_FORM_SIZE: DWORD = 1903;
-pub const ERROR_ALREADY_WAITING: DWORD = 1904;
-pub const ERROR_PRINTER_DELETED: DWORD = 1905;
-pub const ERROR_INVALID_PRINTER_STATE: DWORD = 1906;
-pub const ERROR_PASSWORD_MUST_CHANGE: DWORD = 1907;
-pub const ERROR_DOMAIN_CONTROLLER_NOT_FOUND: DWORD = 1908;
-pub const ERROR_ACCOUNT_LOCKED_OUT: DWORD = 1909;
-pub const ERROR_NO_SITENAME: DWORD = 1919;
-pub const ERROR_CANT_ACCESS_FILE: DWORD = 1920;
-pub const ERROR_CANT_RESOLVE_FILENAME: DWORD = 1921;
-pub const ERROR_KM_DRIVER_BLOCKED: DWORD = 1930;
-pub const ERROR_CONTEXT_EXPIRED: DWORD = 1931;
-pub const ERROR_PER_USER_TRUST_QUOTA_EXCEEDED: DWORD = 1932;
-pub const ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED: DWORD = 1933;
-pub const ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED: DWORD = 1934;
-pub const ERROR_AUTHENTICATION_FIREWALL_FAILED: DWORD = 1935;
-pub const ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED: DWORD = 1936;
-pub const ERROR_INVALID_PIXEL_FORMAT: DWORD = 2000;
-pub const ERROR_BAD_DRIVER: DWORD = 2001;
-pub const ERROR_INVALID_WINDOW_STYLE: DWORD = 2002;
-pub const ERROR_METAFILE_NOT_SUPPORTED: DWORD = 2003;
-pub const ERROR_TRANSFORM_NOT_SUPPORTED: DWORD = 2004;
-pub const ERROR_CLIPPING_NOT_SUPPORTED: DWORD = 2005;
-pub const ERROR_INVALID_CMM: DWORD = 2010;
-pub const ERROR_INVALID_PROFILE: DWORD = 2011;
-pub const ERROR_TAG_NOT_FOUND: DWORD = 2012;
-pub const ERROR_TAG_NOT_PRESENT: DWORD = 2013;
-pub const ERROR_DUPLICATE_TAG: DWORD = 2014;
-pub const ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE: DWORD = 2015;
-pub const ERROR_PROFILE_NOT_FOUND: DWORD = 2016;
-pub const ERROR_INVALID_COLORSPACE: DWORD = 2017;
-pub const ERROR_ICM_NOT_ENABLED: DWORD = 2018;
-pub const ERROR_DELETING_ICM_XFORM: DWORD = 2019;
-pub const ERROR_INVALID_TRANSFORM: DWORD = 2020;
-pub const ERROR_COLORSPACE_MISMATCH: DWORD = 2021;
-pub const ERROR_INVALID_COLORINDEX: DWORD = 2022;
-pub const ERROR_CONNECTED_OTHER_PASSWORD: DWORD = 2108;
-pub const ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT: DWORD = 2109;
-pub const ERROR_BAD_USERNAME: DWORD = 2202;
-pub const ERROR_NOT_CONNECTED: DWORD = 2250;
-pub const ERROR_OPEN_FILES: DWORD = 2401;
-pub const ERROR_ACTIVE_CONNECTIONS: DWORD = 2402;
-pub const ERROR_DEVICE_IN_USE: DWORD = 2404;
-pub const ERROR_UNKNOWN_PRINT_MONITOR: DWORD = 3000;
-pub const ERROR_PRINTER_DRIVER_IN_USE: DWORD = 3001;
-pub const ERROR_SPOOL_FILE_NOT_FOUND: DWORD = 3002;
-pub const ERROR_SPL_NO_STARTDOC: DWORD = 3003;
-pub const ERROR_SPL_NO_ADDJOB: DWORD = 3004;
-pub const ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED: DWORD = 3005;
-pub const ERROR_PRINT_MONITOR_ALREADY_INSTALLED: DWORD = 3006;
-pub const ERROR_INVALID_PRINT_MONITOR: DWORD = 3007;
-pub const ERROR_PRINT_MONITOR_IN_USE: DWORD = 3008;
-pub const ERROR_PRINTER_HAS_JOBS_QUEUED: DWORD = 3009;
-pub const ERROR_SUCCESS_REBOOT_REQUIRED: DWORD = 3010;
-pub const ERROR_SUCCESS_RESTART_REQUIRED: DWORD = 3011;
-pub const ERROR_PRINTER_NOT_FOUND: DWORD = 3012;
-pub const ERROR_PRINTER_DRIVER_WARNED: DWORD = 3013;
-pub const ERROR_PRINTER_DRIVER_BLOCKED: DWORD = 3014;
-pub const ERROR_WINS_INTERNAL: DWORD = 4000;
-pub const ERROR_CAN_NOT_DEL_LOCAL_WINS: DWORD = 4001;
-pub const ERROR_STATIC_INIT: DWORD = 4002;
-pub const ERROR_INC_BACKUP: DWORD = 4003;
-pub const ERROR_FULL_BACKUP: DWORD = 4004;
-pub const ERROR_REC_NON_EXISTENT: DWORD = 4005;
-pub const ERROR_RPL_NOT_ALLOWED: DWORD = 4006;
-pub const ERROR_DHCP_ADDRESS_CONFLICT: DWORD = 4100;
-pub const ERROR_WMI_GUID_NOT_FOUND: DWORD = 4200;
-pub const ERROR_WMI_INSTANCE_NOT_FOUND: DWORD = 4201;
-pub const ERROR_WMI_ITEMID_NOT_FOUND: DWORD = 4202;
-pub const ERROR_WMI_TRY_AGAIN: DWORD = 4203;
-pub const ERROR_WMI_DP_NOT_FOUND: DWORD = 4204;
-pub const ERROR_WMI_UNRESOLVED_INSTANCE_REF: DWORD = 4205;
-pub const ERROR_WMI_ALREADY_ENABLED: DWORD = 4206;
-pub const ERROR_WMI_GUID_DISCONNECTED: DWORD = 4207;
-pub const ERROR_WMI_SERVER_UNAVAILABLE: DWORD = 4208;
-pub const ERROR_WMI_DP_FAILED: DWORD = 4209;
-pub const ERROR_WMI_INVALID_MOF: DWORD = 4210;
-pub const ERROR_WMI_INVALID_REGINFO: DWORD = 4211;
-pub const ERROR_WMI_ALREADY_DISABLED: DWORD = 4212;
-pub const ERROR_WMI_READ_ONLY: DWORD = 4213;
-pub const ERROR_WMI_SET_FAILURE: DWORD = 4214;
-pub const ERROR_INVALID_MEDIA: DWORD = 4300;
-pub const ERROR_INVALID_LIBRARY: DWORD = 4301;
-pub const ERROR_INVALID_MEDIA_POOL: DWORD = 4302;
-pub const ERROR_DRIVE_MEDIA_MISMATCH: DWORD = 4303;
-pub const ERROR_MEDIA_OFFLINE: DWORD = 4304;
-pub const ERROR_LIBRARY_OFFLINE: DWORD = 4305;
-pub const ERROR_EMPTY: DWORD = 4306;
-pub const ERROR_NOT_EMPTY: DWORD = 4307;
-pub const ERROR_MEDIA_UNAVAILABLE: DWORD = 4308;
-pub const ERROR_RESOURCE_DISABLED: DWORD = 4309;
-pub const ERROR_INVALID_CLEANER: DWORD = 4310;
-pub const ERROR_UNABLE_TO_CLEAN: DWORD = 4311;
-pub const ERROR_OBJECT_NOT_FOUND: DWORD = 4312;
-pub const ERROR_DATABASE_FAILURE: DWORD = 4313;
-pub const ERROR_DATABASE_FULL: DWORD = 4314;
-pub const ERROR_MEDIA_INCOMPATIBLE: DWORD = 4315;
-pub const ERROR_RESOURCE_NOT_PRESENT: DWORD = 4316;
-pub const ERROR_INVALID_OPERATION: DWORD = 4317;
-pub const ERROR_MEDIA_NOT_AVAILABLE: DWORD = 4318;
-pub const ERROR_DEVICE_NOT_AVAILABLE: DWORD = 4319;
-pub const ERROR_REQUEST_REFUSED: DWORD = 4320;
-pub const ERROR_INVALID_DRIVE_OBJECT: DWORD = 4321;
-pub const ERROR_LIBRARY_FULL: DWORD = 4322;
-pub const ERROR_MEDIUM_NOT_ACCESSIBLE: DWORD = 4323;
-pub const ERROR_UNABLE_TO_LOAD_MEDIUM: DWORD = 4324;
-pub const ERROR_UNABLE_TO_INVENTORY_DRIVE: DWORD = 4325;
-pub const ERROR_UNABLE_TO_INVENTORY_SLOT: DWORD = 4326;
-pub const ERROR_UNABLE_TO_INVENTORY_TRANSPORT: DWORD = 4327;
-pub const ERROR_TRANSPORT_FULL: DWORD = 4328;
-pub const ERROR_CONTROLLING_IEPORT: DWORD = 4329;
-pub const ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA: DWORD = 4330;
-pub const ERROR_CLEANER_SLOT_SET: DWORD = 4331;
-pub const ERROR_CLEANER_SLOT_NOT_SET: DWORD = 4332;
-pub const ERROR_CLEANER_CARTRIDGE_SPENT: DWORD = 4333;
-pub const ERROR_UNEXPECTED_OMID: DWORD = 4334;
-pub const ERROR_CANT_DELETE_LAST_ITEM: DWORD = 4335;
-pub const ERROR_MESSAGE_EXCEEDS_MAX_SIZE: DWORD = 4336;
-pub const ERROR_VOLUME_CONTAINS_SYS_FILES: DWORD = 4337;
-pub const ERROR_INDIGENOUS_TYPE: DWORD = 4338;
-pub const ERROR_NO_SUPPORTING_DRIVES: DWORD = 4339;
-pub const ERROR_CLEANER_CARTRIDGE_INSTALLED: DWORD = 4340;
-pub const ERROR_IEPORT_FULL: DWORD = 4341;
-pub const ERROR_FILE_OFFLINE: DWORD = 4350;
-pub const ERROR_REMOTE_STORAGE_NOT_ACTIVE: DWORD = 4351;
-pub const ERROR_REMOTE_STORAGE_MEDIA_ERROR: DWORD = 4352;
-pub const ERROR_NOT_A_REPARSE_POINT: DWORD = 4390;
-pub const ERROR_REPARSE_ATTRIBUTE_CONFLICT: DWORD = 4391;
-pub const ERROR_INVALID_REPARSE_DATA: DWORD = 4392;
-pub const ERROR_REPARSE_TAG_INVALID: DWORD = 4393;
-pub const ERROR_REPARSE_TAG_MISMATCH: DWORD = 4394;
-pub const ERROR_VOLUME_NOT_SIS_ENABLED: DWORD = 4500;
-pub const ERROR_DEPENDENT_RESOURCE_EXISTS: DWORD = 5001;
-pub const ERROR_DEPENDENCY_NOT_FOUND: DWORD = 5002;
-pub const ERROR_DEPENDENCY_ALREADY_EXISTS: DWORD = 5003;
-pub const ERROR_RESOURCE_NOT_ONLINE: DWORD = 5004;
-pub const ERROR_HOST_NODE_NOT_AVAILABLE: DWORD = 5005;
-pub const ERROR_RESOURCE_NOT_AVAILABLE: DWORD = 5006;
-pub const ERROR_RESOURCE_NOT_FOUND: DWORD = 5007;
-pub const ERROR_SHUTDOWN_CLUSTER: DWORD = 5008;
-pub const ERROR_CANT_EVICT_ACTIVE_NODE: DWORD = 5009;
-pub const ERROR_OBJECT_ALREADY_EXISTS: DWORD = 5010;
-pub const ERROR_OBJECT_IN_LIST: DWORD = 5011;
-pub const ERROR_GROUP_NOT_AVAILABLE: DWORD = 5012;
-pub const ERROR_GROUP_NOT_FOUND: DWORD = 5013;
-pub const ERROR_GROUP_NOT_ONLINE: DWORD = 5014;
-pub const ERROR_HOST_NODE_NOT_RESOURCE_OWNER: DWORD = 5015;
-pub const ERROR_HOST_NODE_NOT_GROUP_OWNER: DWORD = 5016;
-pub const ERROR_RESMON_CREATE_FAILED: DWORD = 5017;
-pub const ERROR_RESMON_ONLINE_FAILED: DWORD = 5018;
-pub const ERROR_RESOURCE_ONLINE: DWORD = 5019;
-pub const ERROR_QUORUM_RESOURCE: DWORD = 5020;
-pub const ERROR_NOT_QUORUM_CAPABLE: DWORD = 5021;
-pub const ERROR_CLUSTER_SHUTTING_DOWN: DWORD = 5022;
-pub const ERROR_INVALID_STATE: DWORD = 5023;
-pub const ERROR_RESOURCE_PROPERTIES_STORED: DWORD = 5024;
-pub const ERROR_NOT_QUORUM_CLASS: DWORD = 5025;
-pub const ERROR_CORE_RESOURCE: DWORD = 5026;
-pub const ERROR_QUORUM_RESOURCE_ONLINE_FAILED: DWORD = 5027;
-pub const ERROR_QUORUMLOG_OPEN_FAILED: DWORD = 5028;
-pub const ERROR_CLUSTERLOG_CORRUPT: DWORD = 5029;
-pub const ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE: DWORD = 5030;
-pub const ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE: DWORD = 5031;
-pub const ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND: DWORD = 5032;
-pub const ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE: DWORD = 5033;
-pub const ERROR_QUORUM_OWNER_ALIVE: DWORD = 5034;
-pub const ERROR_NETWORK_NOT_AVAILABLE: DWORD = 5035;
-pub const ERROR_NODE_NOT_AVAILABLE: DWORD = 5036;
-pub const ERROR_ALL_NODES_NOT_AVAILABLE: DWORD = 5037;
-pub const ERROR_RESOURCE_FAILED: DWORD = 5038;
-pub const ERROR_CLUSTER_INVALID_NODE: DWORD = 5039;
-pub const ERROR_CLUSTER_NODE_EXISTS: DWORD = 5040;
-pub const ERROR_CLUSTER_JOIN_IN_PROGRESS: DWORD = 5041;
-pub const ERROR_CLUSTER_NODE_NOT_FOUND: DWORD = 5042;
-pub const ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND: DWORD = 5043;
-pub const ERROR_CLUSTER_NETWORK_EXISTS: DWORD = 5044;
-pub const ERROR_CLUSTER_NETWORK_NOT_FOUND: DWORD = 5045;
-pub const ERROR_CLUSTER_NETINTERFACE_EXISTS: DWORD = 5046;
-pub const ERROR_CLUSTER_NETINTERFACE_NOT_FOUND: DWORD = 5047;
-pub const ERROR_CLUSTER_INVALID_REQUEST: DWORD = 5048;
-pub const ERROR_CLUSTER_INVALID_NETWORK_PROVIDER: DWORD = 5049;
-pub const ERROR_CLUSTER_NODE_DOWN: DWORD = 5050;
-pub const ERROR_CLUSTER_NODE_UNREACHABLE: DWORD = 5051;
-pub const ERROR_CLUSTER_NODE_NOT_MEMBER: DWORD = 5052;
-pub const ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS: DWORD = 5053;
-pub const ERROR_CLUSTER_INVALID_NETWORK: DWORD = 5054;
-pub const ERROR_CLUSTER_NODE_UP: DWORD = 5056;
-pub const ERROR_CLUSTER_IPADDR_IN_USE: DWORD = 5057;
-pub const ERROR_CLUSTER_NODE_NOT_PAUSED: DWORD = 5058;
-pub const ERROR_CLUSTER_NO_SECURITY_CONTEXT: DWORD = 5059;
-pub const ERROR_CLUSTER_NETWORK_NOT_INTERNAL: DWORD = 5060;
-pub const ERROR_CLUSTER_NODE_ALREADY_UP: DWORD = 5061;
-pub const ERROR_CLUSTER_NODE_ALREADY_DOWN: DWORD = 5062;
-pub const ERROR_CLUSTER_NETWORK_ALREADY_ONLINE: DWORD = 5063;
-pub const ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE: DWORD = 5064;
-pub const ERROR_CLUSTER_NODE_ALREADY_MEMBER: DWORD = 5065;
-pub const ERROR_CLUSTER_LAST_INTERNAL_NETWORK: DWORD = 5066;
-pub const ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS: DWORD = 5067;
-pub const ERROR_INVALID_OPERATION_ON_QUORUM: DWORD = 5068;
-pub const ERROR_DEPENDENCY_NOT_ALLOWED: DWORD = 5069;
-pub const ERROR_CLUSTER_NODE_PAUSED: DWORD = 5070;
-pub const ERROR_NODE_CANT_HOST_RESOURCE: DWORD = 5071;
-pub const ERROR_CLUSTER_NODE_NOT_READY: DWORD = 5072;
-pub const ERROR_CLUSTER_NODE_SHUTTING_DOWN: DWORD = 5073;
-pub const ERROR_CLUSTER_JOIN_ABORTED: DWORD = 5074;
-pub const ERROR_CLUSTER_INCOMPATIBLE_VERSIONS: DWORD = 5075;
-pub const ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED: DWORD = 5076;
-pub const ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED: DWORD = 5077;
-pub const ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND: DWORD = 5078;
-pub const ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED: DWORD = 5079;
-pub const ERROR_CLUSTER_RESNAME_NOT_FOUND: DWORD = 5080;
-pub const ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED: DWORD = 5081;
-pub const ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST: DWORD = 5082;
-pub const ERROR_CLUSTER_DATABASE_SEQMISMATCH: DWORD = 5083;
-pub const ERROR_RESMON_INVALID_STATE: DWORD = 5084;
-pub const ERROR_CLUSTER_GUM_NOT_LOCKER: DWORD = 5085;
-pub const ERROR_QUORUM_DISK_NOT_FOUND: DWORD = 5086;
-pub const ERROR_DATABASE_BACKUP_CORRUPT: DWORD = 5087;
-pub const ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT: DWORD = 5088;
-pub const ERROR_RESOURCE_PROPERTY_UNCHANGEABLE: DWORD = 5089;
-pub const ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE: DWORD = 5890;
-pub const ERROR_CLUSTER_QUORUMLOG_NOT_FOUND: DWORD = 5891;
-pub const ERROR_CLUSTER_MEMBERSHIP_HALT: DWORD = 5892;
-pub const ERROR_CLUSTER_INSTANCE_ID_MISMATCH: DWORD = 5893;
-pub const ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP: DWORD = 5894;
-pub const ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH: DWORD = 5895;
-pub const ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP: DWORD = 5896;
-pub const ERROR_CLUSTER_PARAMETER_MISMATCH: DWORD = 5897;
-pub const ERROR_NODE_CANNOT_BE_CLUSTERED: DWORD = 5898;
-pub const ERROR_CLUSTER_WRONG_OS_VERSION: DWORD = 5899;
-pub const ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME: DWORD = 5900;
-pub const ERROR_CLUSCFG_ALREADY_COMMITTED: DWORD = 5901;
-pub const ERROR_CLUSCFG_ROLLBACK_FAILED: DWORD = 5902;
-pub const ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT: DWORD = 5903;
-pub const ERROR_CLUSTER_OLD_VERSION: DWORD = 5904;
-pub const ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME: DWORD = 5905;
-pub const ERROR_ENCRYPTION_FAILED: DWORD = 6000;
-pub const ERROR_DECRYPTION_FAILED: DWORD = 6001;
-pub const ERROR_FILE_ENCRYPTED: DWORD = 6002;
-pub const ERROR_NO_RECOVERY_POLICY: DWORD = 6003;
-pub const ERROR_NO_EFS: DWORD = 6004;
-pub const ERROR_WRONG_EFS: DWORD = 6005;
-pub const ERROR_NO_USER_KEYS: DWORD = 6006;
-pub const ERROR_FILE_NOT_ENCRYPTED: DWORD = 6007;
-pub const ERROR_NOT_EXPORT_FORMAT: DWORD = 6008;
-pub const ERROR_FILE_READ_ONLY: DWORD = 6009;
-pub const ERROR_DIR_EFS_DISALLOWED: DWORD = 6010;
-pub const ERROR_EFS_SERVER_NOT_TRUSTED: DWORD = 6011;
-pub const ERROR_BAD_RECOVERY_POLICY: DWORD = 6012;
-pub const ERROR_EFS_ALG_BLOB_TOO_BIG: DWORD = 6013;
-pub const ERROR_VOLUME_NOT_SUPPORT_EFS: DWORD = 6014;
-pub const ERROR_EFS_DISABLED: DWORD = 6015;
-pub const ERROR_EFS_VERSION_NOT_SUPPORT: DWORD = 6016;
-pub const ERROR_NO_BROWSER_SERVERS_FOUND: DWORD = 6118;
-pub const ERROR_CTX_WINSTATION_NAME_INVALID: DWORD = 7001;
-pub const ERROR_CTX_INVALID_PD: DWORD = 7002;
-pub const ERROR_CTX_PD_NOT_FOUND: DWORD = 7003;
-pub const ERROR_CTX_WD_NOT_FOUND: DWORD = 7004;
-pub const ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY: DWORD = 7005;
-pub const ERROR_CTX_SERVICE_NAME_COLLISION: DWORD = 7006;
-pub const ERROR_CTX_CLOSE_PENDING: DWORD = 7007;
-pub const ERROR_CTX_NO_OUTBUF: DWORD = 7008;
-pub const ERROR_CTX_MODEM_INF_NOT_FOUND: DWORD = 7009;
-pub const ERROR_CTX_INVALID_MODEMNAME: DWORD = 7010;
-pub const ERROR_CTX_MODEM_RESPONSE_ERROR: DWORD = 7011;
-pub const ERROR_CTX_MODEM_RESPONSE_TIMEOUT: DWORD = 7012;
-pub const ERROR_CTX_MODEM_RESPONSE_NO_CARRIER: DWORD = 7013;
-pub const ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE: DWORD = 7014;
-pub const ERROR_CTX_MODEM_RESPONSE_BUSY: DWORD = 7015;
-pub const ERROR_CTX_MODEM_RESPONSE_VOICE: DWORD = 7016;
-pub const ERROR_CTX_TD_ERROR: DWORD = 7017;
-pub const ERROR_CTX_WINSTATION_NOT_FOUND: DWORD = 7022;
-pub const ERROR_CTX_WINSTATION_ALREADY_EXISTS: DWORD = 7023;
-pub const ERROR_CTX_WINSTATION_BUSY: DWORD = 7024;
-pub const ERROR_CTX_BAD_VIDEO_MODE: DWORD = 7025;
-pub const ERROR_CTX_GRAPHICS_INVALID: DWORD = 7035;
-pub const ERROR_CTX_LOGON_DISABLED: DWORD = 7037;
-pub const ERROR_CTX_NOT_CONSOLE: DWORD = 7038;
-pub const ERROR_CTX_CLIENT_QUERY_TIMEOUT: DWORD = 7040;
-pub const ERROR_CTX_CONSOLE_DISCONNECT: DWORD = 7041;
-pub const ERROR_CTX_CONSOLE_CONNECT: DWORD = 7042;
-pub const ERROR_CTX_SHADOW_DENIED: DWORD = 7044;
-pub const ERROR_CTX_WINSTATION_ACCESS_DENIED: DWORD = 7045;
-pub const ERROR_CTX_INVALID_WD: DWORD = 7049;
-pub const ERROR_CTX_SHADOW_INVALID: DWORD = 7050;
-pub const ERROR_CTX_SHADOW_DISABLED: DWORD = 7051;
-pub const ERROR_CTX_CLIENT_LICENSE_IN_USE: DWORD = 7052;
-pub const ERROR_CTX_CLIENT_LICENSE_NOT_SET: DWORD = 7053;
-pub const ERROR_CTX_LICENSE_NOT_AVAILABLE: DWORD = 7054;
-pub const ERROR_CTX_LICENSE_CLIENT_INVALID: DWORD = 7055;
-pub const ERROR_CTX_LICENSE_EXPIRED: DWORD = 7056;
-pub const ERROR_CTX_SHADOW_NOT_RUNNING: DWORD = 7057;
-pub const ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE: DWORD = 7058;
-pub const ERROR_ACTIVATION_COUNT_EXCEEDED: DWORD = 7059;
-pub const ERROR_DS_NOT_INSTALLED: DWORD = 8200;
-pub const ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY: DWORD = 8201;
-pub const ERROR_DS_NO_ATTRIBUTE_OR_VALUE: DWORD = 8202;
-pub const ERROR_DS_INVALID_ATTRIBUTE_SYNTAX: DWORD = 8203;
-pub const ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED: DWORD = 8204;
-pub const ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS: DWORD = 8205;
-pub const ERROR_DS_BUSY: DWORD = 8206;
-pub const ERROR_DS_UNAVAILABLE: DWORD = 8207;
-pub const ERROR_DS_NO_RIDS_ALLOCATED: DWORD = 8208;
-pub const ERROR_DS_NO_MORE_RIDS: DWORD = 8209;
-pub const ERROR_DS_INCORRECT_ROLE_OWNER: DWORD = 8210;
-pub const ERROR_DS_RIDMGR_INIT_ERROR: DWORD = 8211;
-pub const ERROR_DS_OBJ_CLASS_VIOLATION: DWORD = 8212;
-pub const ERROR_DS_CANT_ON_NON_LEAF: DWORD = 8213;
-pub const ERROR_DS_CANT_ON_RDN: DWORD = 8214;
-pub const ERROR_DS_CANT_MOD_OBJ_CLASS: DWORD = 8215;
-pub const ERROR_DS_CROSS_DOM_MOVE_ERROR: DWORD = 8216;
-pub const ERROR_DS_GC_NOT_AVAILABLE: DWORD = 8217;
-pub const ERROR_SHARED_POLICY: DWORD = 8218;
-pub const ERROR_POLICY_OBJECT_NOT_FOUND: DWORD = 8219;
-pub const ERROR_POLICY_ONLY_IN_DS: DWORD = 8220;
-pub const ERROR_PROMOTION_ACTIVE: DWORD = 8221;
-pub const ERROR_NO_PROMOTION_ACTIVE: DWORD = 8222;
-pub const ERROR_DS_OPERATIONS_ERROR: DWORD = 8224;
-pub const ERROR_DS_PROTOCOL_ERROR: DWORD = 8225;
-pub const ERROR_DS_TIMELIMIT_EXCEEDED: DWORD = 8226;
-pub const ERROR_DS_SIZELIMIT_EXCEEDED: DWORD = 8227;
-pub const ERROR_DS_ADMIN_LIMIT_EXCEEDED: DWORD = 8228;
-pub const ERROR_DS_COMPARE_FALSE: DWORD = 8229;
-pub const ERROR_DS_COMPARE_TRUE: DWORD = 8230;
-pub const ERROR_DS_AUTH_METHOD_NOT_SUPPORTED: DWORD = 8231;
-pub const ERROR_DS_STRONG_AUTH_REQUIRED: DWORD = 8232;
-pub const ERROR_DS_INAPPROPRIATE_AUTH: DWORD = 8233;
-pub const ERROR_DS_AUTH_UNKNOWN: DWORD = 8234;
-pub const ERROR_DS_REFERRAL: DWORD = 8235;
-pub const ERROR_DS_UNAVAILABLE_CRIT_EXTENSION: DWORD = 8236;
-pub const ERROR_DS_CONFIDENTIALITY_REQUIRED: DWORD = 8237;
-pub const ERROR_DS_INAPPROPRIATE_MATCHING: DWORD = 8238;
-pub const ERROR_DS_CONSTRAINT_VIOLATION: DWORD = 8239;
-pub const ERROR_DS_NO_SUCH_OBJECT: DWORD = 8240;
-pub const ERROR_DS_ALIAS_PROBLEM: DWORD = 8241;
-pub const ERROR_DS_INVALID_DN_SYNTAX: DWORD = 8242;
-pub const ERROR_DS_IS_LEAF: DWORD = 8243;
-pub const ERROR_DS_ALIAS_DEREF_PROBLEM: DWORD = 8244;
-pub const ERROR_DS_UNWILLING_TO_PERFORM: DWORD = 8245;
-pub const ERROR_DS_LOOP_DETECT: DWORD = 8246;
-pub const ERROR_DS_NAMING_VIOLATION: DWORD = 8247;
-pub const ERROR_DS_OBJECT_RESULTS_TOO_LARGE: DWORD = 8248;
-pub const ERROR_DS_AFFECTS_MULTIPLE_DSAS: DWORD = 8249;
-pub const ERROR_DS_SERVER_DOWN: DWORD = 8250;
-pub const ERROR_DS_LOCAL_ERROR: DWORD = 8251;
-pub const ERROR_DS_ENCODING_ERROR: DWORD = 8252;
-pub const ERROR_DS_DECODING_ERROR: DWORD = 8253;
-pub const ERROR_DS_FILTER_UNKNOWN: DWORD = 8254;
-pub const ERROR_DS_PARAM_ERROR: DWORD = 8255;
-pub const ERROR_DS_NOT_SUPPORTED: DWORD = 8256;
-pub const ERROR_DS_NO_RESULTS_RETURNED: DWORD = 8257;
-pub const ERROR_DS_CONTROL_NOT_FOUND: DWORD = 8258;
-pub const ERROR_DS_CLIENT_LOOP: DWORD = 8259;
-pub const ERROR_DS_REFERRAL_LIMIT_EXCEEDED: DWORD = 8260;
-pub const ERROR_DS_SORT_CONTROL_MISSING: DWORD = 8261;
-pub const ERROR_DS_OFFSET_RANGE_ERROR: DWORD = 8262;
-pub const ERROR_DS_ROOT_MUST_BE_NC: DWORD = 8301;
-pub const ERROR_DS_ADD_REPLICA_INHIBITED: DWORD = 8302;
-pub const ERROR_DS_ATT_NOT_DEF_IN_SCHEMA: DWORD = 8303;
-pub const ERROR_DS_MAX_OBJ_SIZE_EXCEEDED: DWORD = 8304;
-pub const ERROR_DS_OBJ_STRING_NAME_EXISTS: DWORD = 8305;
-pub const ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA: DWORD = 8306;
-pub const ERROR_DS_RDN_DOESNT_MATCH_SCHEMA: DWORD = 8307;
-pub const ERROR_DS_NO_REQUESTED_ATTS_FOUND: DWORD = 8308;
-pub const ERROR_DS_USER_BUFFER_TO_SMALL: DWORD = 8309;
-pub const ERROR_DS_ATT_IS_NOT_ON_OBJ: DWORD = 8310;
-pub const ERROR_DS_ILLEGAL_MOD_OPERATION: DWORD = 8311;
-pub const ERROR_DS_OBJ_TOO_LARGE: DWORD = 8312;
-pub const ERROR_DS_BAD_INSTANCE_TYPE: DWORD = 8313;
-pub const ERROR_DS_MASTERDSA_REQUIRED: DWORD = 8314;
-pub const ERROR_DS_OBJECT_CLASS_REQUIRED: DWORD = 8315;
-pub const ERROR_DS_MISSING_REQUIRED_ATT: DWORD = 8316;
-pub const ERROR_DS_ATT_NOT_DEF_FOR_CLASS: DWORD = 8317;
-pub const ERROR_DS_ATT_ALREADY_EXISTS: DWORD = 8318;
-pub const ERROR_DS_CANT_ADD_ATT_VALUES: DWORD = 8320;
-pub const ERROR_DS_SINGLE_VALUE_CONSTRAINT: DWORD = 8321;
-pub const ERROR_DS_RANGE_CONSTRAINT: DWORD = 8322;
-pub const ERROR_DS_ATT_VAL_ALREADY_EXISTS: DWORD = 8323;
-pub const ERROR_DS_CANT_REM_MISSING_ATT: DWORD = 8324;
-pub const ERROR_DS_CANT_REM_MISSING_ATT_VAL: DWORD = 8325;
-pub const ERROR_DS_ROOT_CANT_BE_SUBREF: DWORD = 8326;
-pub const ERROR_DS_NO_CHAINING: DWORD = 8327;
-pub const ERROR_DS_NO_CHAINED_EVAL: DWORD = 8328;
-pub const ERROR_DS_NO_PARENT_OBJECT: DWORD = 8329;
-pub const ERROR_DS_PARENT_IS_AN_ALIAS: DWORD = 8330;
-pub const ERROR_DS_CANT_MIX_MASTER_AND_REPS: DWORD = 8331;
-pub const ERROR_DS_CHILDREN_EXIST: DWORD = 8332;
-pub const ERROR_DS_OBJ_NOT_FOUND: DWORD = 8333;
-pub const ERROR_DS_ALIASED_OBJ_MISSING: DWORD = 8334;
-pub const ERROR_DS_BAD_NAME_SYNTAX: DWORD = 8335;
-pub const ERROR_DS_ALIAS_POINTS_TO_ALIAS: DWORD = 8336;
-pub const ERROR_DS_CANT_DEREF_ALIAS: DWORD = 8337;
-pub const ERROR_DS_OUT_OF_SCOPE: DWORD = 8338;
-pub const ERROR_DS_OBJECT_BEING_REMOVED: DWORD = 8339;
-pub const ERROR_DS_CANT_DELETE_DSA_OBJ: DWORD = 8340;
-pub const ERROR_DS_GENERIC_ERROR: DWORD = 8341;
-pub const ERROR_DS_DSA_MUST_BE_INT_MASTER: DWORD = 8342;
-pub const ERROR_DS_CLASS_NOT_DSA: DWORD = 8343;
-pub const ERROR_DS_INSUFF_ACCESS_RIGHTS: DWORD = 8344;
-pub const ERROR_DS_ILLEGAL_SUPERIOR: DWORD = 8345;
-pub const ERROR_DS_ATTRIBUTE_OWNED_BY_SAM: DWORD = 8346;
-pub const ERROR_DS_NAME_TOO_MANY_PARTS: DWORD = 8347;
-pub const ERROR_DS_NAME_TOO_LONG: DWORD = 8348;
-pub const ERROR_DS_NAME_VALUE_TOO_LONG: DWORD = 8349;
-pub const ERROR_DS_NAME_UNPARSEABLE: DWORD = 8350;
-pub const ERROR_DS_NAME_TYPE_UNKNOWN: DWORD = 8351;
-pub const ERROR_DS_NOT_AN_OBJECT: DWORD = 8352;
-pub const ERROR_DS_SEC_DESC_TOO_SHORT: DWORD = 8353;
-pub const ERROR_DS_SEC_DESC_INVALID: DWORD = 8354;
-pub const ERROR_DS_NO_DELETED_NAME: DWORD = 8355;
-pub const ERROR_DS_SUBREF_MUST_HAVE_PARENT: DWORD = 8356;
-pub const ERROR_DS_NCNAME_MUST_BE_NC: DWORD = 8357;
-pub const ERROR_DS_CANT_ADD_SYSTEM_ONLY: DWORD = 8358;
-pub const ERROR_DS_CLASS_MUST_BE_CONCRETE: DWORD = 8359;
-pub const ERROR_DS_INVALID_DMD: DWORD = 8360;
-pub const ERROR_DS_OBJ_GUID_EXISTS: DWORD = 8361;
-pub const ERROR_DS_NOT_ON_BACKLINK: DWORD = 8362;
-pub const ERROR_DS_NO_CROSSREF_FOR_NC: DWORD = 8363;
-pub const ERROR_DS_SHUTTING_DOWN: DWORD = 8364;
-pub const ERROR_DS_UNKNOWN_OPERATION: DWORD = 8365;
-pub const ERROR_DS_INVALID_ROLE_OWNER: DWORD = 8366;
-pub const ERROR_DS_COULDNT_CONTACT_FSMO: DWORD = 8367;
-pub const ERROR_DS_CROSS_NC_DN_RENAME: DWORD = 8368;
-pub const ERROR_DS_CANT_MOD_SYSTEM_ONLY: DWORD = 8369;
-pub const ERROR_DS_REPLICATOR_ONLY: DWORD = 8370;
-pub const ERROR_DS_OBJ_CLASS_NOT_DEFINED: DWORD = 8371;
-pub const ERROR_DS_OBJ_CLASS_NOT_SUBCLASS: DWORD = 8372;
-pub const ERROR_DS_NAME_REFERENCE_INVALID: DWORD = 8373;
-pub const ERROR_DS_CROSS_REF_EXISTS: DWORD = 8374;
-pub const ERROR_DS_CANT_DEL_MASTER_CROSSREF: DWORD = 8375;
-pub const ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD: DWORD = 8376;
-pub const ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX: DWORD = 8377;
-pub const ERROR_DS_DUP_RDN: DWORD = 8378;
-pub const ERROR_DS_DUP_OID: DWORD = 8379;
-pub const ERROR_DS_DUP_MAPI_ID: DWORD = 8380;
-pub const ERROR_DS_DUP_SCHEMA_ID_GUID: DWORD = 8381;
-pub const ERROR_DS_DUP_LDAP_DISPLAY_NAME: DWORD = 8382;
-pub const ERROR_DS_SEMANTIC_ATT_TEST: DWORD = 8383;
-pub const ERROR_DS_SYNTAX_MISMATCH: DWORD = 8384;
-pub const ERROR_DS_EXISTS_IN_MUST_HAVE: DWORD = 8385;
-pub const ERROR_DS_EXISTS_IN_MAY_HAVE: DWORD = 8386;
-pub const ERROR_DS_NONEXISTENT_MAY_HAVE: DWORD = 8387;
-pub const ERROR_DS_NONEXISTENT_MUST_HAVE: DWORD = 8388;
-pub const ERROR_DS_AUX_CLS_TEST_FAIL: DWORD = 8389;
-pub const ERROR_DS_NONEXISTENT_POSS_SUP: DWORD = 8390;
-pub const ERROR_DS_SUB_CLS_TEST_FAIL: DWORD = 8391;
-pub const ERROR_DS_BAD_RDN_ATT_ID_SYNTAX: DWORD = 8392;
-pub const ERROR_DS_EXISTS_IN_AUX_CLS: DWORD = 8393;
-pub const ERROR_DS_EXISTS_IN_SUB_CLS: DWORD = 8394;
-pub const ERROR_DS_EXISTS_IN_POSS_SUP: DWORD = 8395;
-pub const ERROR_DS_RECALCSCHEMA_FAILED: DWORD = 8396;
-pub const ERROR_DS_TREE_DELETE_NOT_FINISHED: DWORD = 8397;
-pub const ERROR_DS_CANT_DELETE: DWORD = 8398;
-pub const ERROR_DS_ATT_SCHEMA_REQ_ID: DWORD = 8399;
-pub const ERROR_DS_BAD_ATT_SCHEMA_SYNTAX: DWORD = 8400;
-pub const ERROR_DS_CANT_CACHE_ATT: DWORD = 8401;
-pub const ERROR_DS_CANT_CACHE_CLASS: DWORD = 8402;
-pub const ERROR_DS_CANT_REMOVE_ATT_CACHE: DWORD = 8403;
-pub const ERROR_DS_CANT_REMOVE_CLASS_CACHE: DWORD = 8404;
-pub const ERROR_DS_CANT_RETRIEVE_DN: DWORD = 8405;
-pub const ERROR_DS_MISSING_SUPREF: DWORD = 8406;
-pub const ERROR_DS_CANT_RETRIEVE_INSTANCE: DWORD = 8407;
-pub const ERROR_DS_CODE_INCONSISTENCY: DWORD = 8408;
-pub const ERROR_DS_DATABASE_ERROR: DWORD = 8409;
-pub const ERROR_DS_GOVERNSID_MISSING: DWORD = 8410;
-pub const ERROR_DS_MISSING_EXPECTED_ATT: DWORD = 8411;
-pub const ERROR_DS_NCNAME_MISSING_CR_REF: DWORD = 8412;
-pub const ERROR_DS_SECURITY_CHECKING_ERROR: DWORD = 8413;
-pub const ERROR_DS_SCHEMA_NOT_LOADED: DWORD = 8414;
-pub const ERROR_DS_SCHEMA_ALLOC_FAILED: DWORD = 8415;
-pub const ERROR_DS_ATT_SCHEMA_REQ_SYNTAX: DWORD = 8416;
-pub const ERROR_DS_GCVERIFY_ERROR: DWORD = 8417;
-pub const ERROR_DS_DRA_SCHEMA_MISMATCH: DWORD = 8418;
-pub const ERROR_DS_CANT_FIND_DSA_OBJ: DWORD = 8419;
-pub const ERROR_DS_CANT_FIND_EXPECTED_NC: DWORD = 8420;
-pub const ERROR_DS_CANT_FIND_NC_IN_CACHE: DWORD = 8421;
-pub const ERROR_DS_CANT_RETRIEVE_CHILD: DWORD = 8422;
-pub const ERROR_DS_SECURITY_ILLEGAL_MODIFY: DWORD = 8423;
-pub const ERROR_DS_CANT_REPLACE_HIDDEN_REC: DWORD = 8424;
-pub const ERROR_DS_BAD_HIERARCHY_FILE: DWORD = 8425;
-pub const ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED: DWORD = 8426;
-pub const ERROR_DS_CONFIG_PARAM_MISSING: DWORD = 8427;
-pub const ERROR_DS_COUNTING_AB_INDICES_FAILED: DWORD = 8428;
-pub const ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED: DWORD = 8429;
-pub const ERROR_DS_INTERNAL_FAILURE: DWORD = 8430;
-pub const ERROR_DS_UNKNOWN_ERROR: DWORD = 8431;
-pub const ERROR_DS_ROOT_REQUIRES_CLASS_TOP: DWORD = 8432;
-pub const ERROR_DS_REFUSING_FSMO_ROLES: DWORD = 8433;
-pub const ERROR_DS_MISSING_FSMO_SETTINGS: DWORD = 8434;
-pub const ERROR_DS_UNABLE_TO_SURRENDER_ROLES: DWORD = 8435;
-pub const ERROR_DS_DRA_GENERIC: DWORD = 8436;
-pub const ERROR_DS_DRA_INVALID_PARAMETER: DWORD = 8437;
-pub const ERROR_DS_DRA_BUSY: DWORD = 8438;
-pub const ERROR_DS_DRA_BAD_DN: DWORD = 8439;
-pub const ERROR_DS_DRA_BAD_NC: DWORD = 8440;
-pub const ERROR_DS_DRA_DN_EXISTS: DWORD = 8441;
-pub const ERROR_DS_DRA_INTERNAL_ERROR: DWORD = 8442;
-pub const ERROR_DS_DRA_INCONSISTENT_DIT: DWORD = 8443;
-pub const ERROR_DS_DRA_CONNECTION_FAILED: DWORD = 8444;
-pub const ERROR_DS_DRA_BAD_INSTANCE_TYPE: DWORD = 8445;
-pub const ERROR_DS_DRA_OUT_OF_MEM: DWORD = 8446;
-pub const ERROR_DS_DRA_MAIL_PROBLEM: DWORD = 8447;
-pub const ERROR_DS_DRA_REF_ALREADY_EXISTS: DWORD = 8448;
-pub const ERROR_DS_DRA_REF_NOT_FOUND: DWORD = 8449;
-pub const ERROR_DS_DRA_OBJ_IS_REP_SOURCE: DWORD = 8450;
-pub const ERROR_DS_DRA_DB_ERROR: DWORD = 8451;
-pub const ERROR_DS_DRA_NO_REPLICA: DWORD = 8452;
-pub const ERROR_DS_DRA_ACCESS_DENIED: DWORD = 8453;
-pub const ERROR_DS_DRA_NOT_SUPPORTED: DWORD = 8454;
-pub const ERROR_DS_DRA_RPC_CANCELLED: DWORD = 8455;
-pub const ERROR_DS_DRA_SOURCE_DISABLED: DWORD = 8456;
-pub const ERROR_DS_DRA_SINK_DISABLED: DWORD = 8457;
-pub const ERROR_DS_DRA_NAME_COLLISION: DWORD = 8458;
-pub const ERROR_DS_DRA_SOURCE_REINSTALLED: DWORD = 8459;
-pub const ERROR_DS_DRA_MISSING_PARENT: DWORD = 8460;
-pub const ERROR_DS_DRA_PREEMPTED: DWORD = 8461;
-pub const ERROR_DS_DRA_ABANDON_SYNC: DWORD = 8462;
-pub const ERROR_DS_DRA_SHUTDOWN: DWORD = 8463;
-pub const ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET: DWORD = 8464;
-pub const ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA: DWORD = 8465;
-pub const ERROR_DS_DRA_EXTN_CONNECTION_FAILED: DWORD = 8466;
-pub const ERROR_DS_INSTALL_SCHEMA_MISMATCH: DWORD = 8467;
-pub const ERROR_DS_DUP_LINK_ID: DWORD = 8468;
-pub const ERROR_DS_NAME_ERROR_RESOLVING: DWORD = 8469;
-pub const ERROR_DS_NAME_ERROR_NOT_FOUND: DWORD = 8470;
-pub const ERROR_DS_NAME_ERROR_NOT_UNIQUE: DWORD = 8471;
-pub const ERROR_DS_NAME_ERROR_NO_MAPPING: DWORD = 8472;
-pub const ERROR_DS_NAME_ERROR_DOMAIN_ONLY: DWORD = 8473;
-pub const ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING: DWORD = 8474;
-pub const ERROR_DS_CONSTRUCTED_ATT_MOD: DWORD = 8475;
-pub const ERROR_DS_WRONG_OM_OBJ_CLASS: DWORD = 8476;
-pub const ERROR_DS_DRA_REPL_PENDING: DWORD = 8477;
-pub const ERROR_DS_DS_REQUIRED: DWORD = 8478;
-pub const ERROR_DS_INVALID_LDAP_DISPLAY_NAME: DWORD = 8479;
-pub const ERROR_DS_NON_BASE_SEARCH: DWORD = 8480;
-pub const ERROR_DS_CANT_RETRIEVE_ATTS: DWORD = 8481;
-pub const ERROR_DS_BACKLINK_WITHOUT_LINK: DWORD = 8482;
-pub const ERROR_DS_EPOCH_MISMATCH: DWORD = 8483;
-pub const ERROR_DS_SRC_NAME_MISMATCH: DWORD = 8484;
-pub const ERROR_DS_SRC_AND_DST_NC_IDENTICAL: DWORD = 8485;
-pub const ERROR_DS_DST_NC_MISMATCH: DWORD = 8486;
-pub const ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC: DWORD = 8487;
-pub const ERROR_DS_SRC_GUID_MISMATCH: DWORD = 8488;
-pub const ERROR_DS_CANT_MOVE_DELETED_OBJECT: DWORD = 8489;
-pub const ERROR_DS_PDC_OPERATION_IN_PROGRESS: DWORD = 8490;
-pub const ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD: DWORD = 8491;
-pub const ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION: DWORD = 8492;
-pub const ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS: DWORD = 8493;
-pub const ERROR_DS_NC_MUST_HAVE_NC_PARENT: DWORD = 8494;
-pub const ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE: DWORD = 8495;
-pub const ERROR_DS_DST_DOMAIN_NOT_NATIVE: DWORD = 8496;
-pub const ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER: DWORD = 8497;
-pub const ERROR_DS_CANT_MOVE_ACCOUNT_GROUP: DWORD = 8498;
-pub const ERROR_DS_CANT_MOVE_RESOURCE_GROUP: DWORD = 8499;
-pub const ERROR_DS_INVALID_SEARCH_FLAG: DWORD = 8500;
-pub const ERROR_DS_NO_TREE_DELETE_ABOVE_NC: DWORD = 8501;
-pub const ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE: DWORD = 8502;
-pub const ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE: DWORD = 8503;
-pub const ERROR_DS_SAM_INIT_FAILURE: DWORD = 8504;
-pub const ERROR_DS_SENSITIVE_GROUP_VIOLATION: DWORD = 8505;
-pub const ERROR_DS_CANT_MOD_PRIMARYGROUPID: DWORD = 8506;
-pub const ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD: DWORD = 8507;
-pub const ERROR_DS_NONSAFE_SCHEMA_CHANGE: DWORD = 8508;
-pub const ERROR_DS_SCHEMA_UPDATE_DISALLOWED: DWORD = 8509;
-pub const ERROR_DS_CANT_CREATE_UNDER_SCHEMA: DWORD = 8510;
-pub const ERROR_DS_INSTALL_NO_SRC_SCH_VERSION: DWORD = 8511;
-pub const ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE: DWORD = 8512;
-pub const ERROR_DS_INVALID_GROUP_TYPE: DWORD = 8513;
-pub const ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN: DWORD = 8514;
-pub const ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN: DWORD = 8515;
-pub const ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER: DWORD = 8516;
-pub const ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER: DWORD = 8517;
-pub const ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER: DWORD = 8518;
-pub const ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER: DWORD = 8519;
-pub const ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER: DWORD = 8520;
-pub const ERROR_DS_HAVE_PRIMARY_MEMBERS: DWORD = 8521;
-pub const ERROR_DS_STRING_SD_CONVERSION_FAILED: DWORD = 8522;
-pub const ERROR_DS_NAMING_MASTER_GC: DWORD = 8523;
-pub const ERROR_DS_DNS_LOOKUP_FAILURE: DWORD = 8524;
-pub const ERROR_DS_COULDNT_UPDATE_SPNS: DWORD = 8525;
-pub const ERROR_DS_CANT_RETRIEVE_SD: DWORD = 8526;
-pub const ERROR_DS_KEY_NOT_UNIQUE: DWORD = 8527;
-pub const ERROR_DS_WRONG_LINKED_ATT_SYNTAX: DWORD = 8528;
-pub const ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD: DWORD = 8529;
-pub const ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY: DWORD = 8530;
-pub const ERROR_DS_CANT_START: DWORD = 8531;
-pub const ERROR_DS_INIT_FAILURE: DWORD = 8532;
-pub const ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION: DWORD = 8533;
-pub const ERROR_DS_SOURCE_DOMAIN_IN_FOREST: DWORD = 8534;
-pub const ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST: DWORD = 8535;
-pub const ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED: DWORD = 8536;
-pub const ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN: DWORD = 8537;
-pub const ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER: DWORD = 8538;
-pub const ERROR_DS_SRC_SID_EXISTS_IN_FOREST: DWORD = 8539;
-pub const ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH: DWORD = 8540;
-pub const ERROR_SAM_INIT_FAILURE: DWORD = 8541;
-pub const ERROR_DS_DRA_SCHEMA_INFO_SHIP: DWORD = 8542;
-pub const ERROR_DS_DRA_SCHEMA_CONFLICT: DWORD = 8543;
-pub const ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT: DWORD = 8544;
-pub const ERROR_DS_DRA_OBJ_NC_MISMATCH: DWORD = 8545;
-pub const ERROR_DS_NC_STILL_HAS_DSAS: DWORD = 8546;
-pub const ERROR_DS_GC_REQUIRED: DWORD = 8547;
-pub const ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY: DWORD = 8548;
-pub const ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS: DWORD = 8549;
-pub const ERROR_DS_CANT_ADD_TO_GC: DWORD = 8550;
-pub const ERROR_DS_NO_CHECKPOINT_WITH_PDC: DWORD = 8551;
-pub const ERROR_DS_SOURCE_AUDITING_NOT_ENABLED: DWORD = 8552;
-pub const ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC: DWORD = 8553;
-pub const ERROR_DS_INVALID_NAME_FOR_SPN: DWORD = 8554;
-pub const ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS: DWORD = 8555;
-pub const ERROR_DS_UNICODEPWD_NOT_IN_QUOTES: DWORD = 8556;
-pub const ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED: DWORD = 8557;
-pub const ERROR_DS_MUST_BE_RUN_ON_DST_DC: DWORD = 8558;
-pub const ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER: DWORD = 8559;
-pub const ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ: DWORD = 8560;
-pub const ERROR_DS_INIT_FAILURE_CONSOLE: DWORD = 8561;
-pub const ERROR_DS_SAM_INIT_FAILURE_CONSOLE: DWORD = 8562;
-pub const ERROR_DS_FOREST_VERSION_TOO_HIGH: DWORD = 8563;
-pub const ERROR_DS_DOMAIN_VERSION_TOO_HIGH: DWORD = 8564;
-pub const ERROR_DS_FOREST_VERSION_TOO_LOW: DWORD = 8565;
-pub const ERROR_DS_DOMAIN_VERSION_TOO_LOW: DWORD = 8566;
-pub const ERROR_DS_INCOMPATIBLE_VERSION: DWORD = 8567;
-pub const ERROR_DS_LOW_DSA_VERSION: DWORD = 8568;
-pub const ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN: DWORD = 8569;
-pub const ERROR_DS_NOT_SUPPORTED_SORT_ORDER: DWORD = 8570;
-pub const ERROR_DS_NAME_NOT_UNIQUE: DWORD = 8571;
-pub const ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4: DWORD = 8572;
-pub const ERROR_DS_OUT_OF_VERSION_STORE: DWORD = 8573;
-pub const ERROR_DS_INCOMPATIBLE_CONTROLS_USED: DWORD = 8574;
-pub const ERROR_DS_NO_REF_DOMAIN: DWORD = 8575;
-pub const ERROR_DS_RESERVED_LINK_ID: DWORD = 8576;
-pub const ERROR_DS_LINK_ID_NOT_AVAILABLE: DWORD = 8577;
-pub const ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER: DWORD = 8578;
-pub const ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE: DWORD = 8579;
-pub const ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC: DWORD = 8580;
-pub const ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG: DWORD = 8581;
-pub const ERROR_DS_MODIFYDN_WRONG_GRANDPARENT: DWORD = 8582;
-pub const ERROR_DS_NAME_ERROR_TRUST_REFERRAL: DWORD = 8583;
-pub const ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER: DWORD = 8584;
-pub const ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD: DWORD = 8585;
-pub const ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2: DWORD = 8586;
-pub const ERROR_DS_THREAD_LIMIT_EXCEEDED: DWORD = 8587;
-pub const ERROR_DS_NOT_CLOSEST: DWORD = 8588;
-pub const ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF: DWORD = 8589;
-pub const ERROR_DS_SINGLE_USER_MODE_FAILED: DWORD = 8590;
-pub const ERROR_DS_NTDSCRIPT_SYNTAX_ERROR: DWORD = 8591;
-pub const ERROR_DS_NTDSCRIPT_PROCESS_ERROR: DWORD = 8592;
-pub const ERROR_DS_DIFFERENT_REPL_EPOCHS: DWORD = 8593;
-pub const ERROR_DS_DRS_EXTENSIONS_CHANGED: DWORD = 8594;
-pub const ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR: DWORD = 8595;
-pub const ERROR_DS_NO_MSDS_INTID: DWORD = 8596;
-pub const ERROR_DS_DUP_MSDS_INTID: DWORD = 8597;
-pub const ERROR_DS_EXISTS_IN_RDNATTID: DWORD = 8598;
-pub const ERROR_DS_AUTHORIZATION_FAILED: DWORD = 8599;
-pub const ERROR_DS_INVALID_SCRIPT: DWORD = 8600;
-pub const ERROR_DS_REMOTE_CROSSREF_OP_FAILED: DWORD = 8601;
-pub const ERROR_DS_CROSS_REF_BUSY: DWORD = 8602;
-pub const ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN: DWORD = 8603;
-pub const ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC: DWORD = 8604;
-pub const ERROR_DS_DUPLICATE_ID_FOUND: DWORD = 8605;
-pub const ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT: DWORD = 8606;
-pub const ERROR_DS_GROUP_CONVERSION_ERROR: DWORD = 8607;
-pub const ERROR_DS_CANT_MOVE_APP_BASIC_GROUP: DWORD = 8608;
-pub const ERROR_DS_CANT_MOVE_APP_QUERY_GROUP: DWORD = 8609;
-pub const ERROR_DS_ROLE_NOT_VERIFIED: DWORD = 8610;
-pub const ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL: DWORD = 8611;
-pub const ERROR_DS_DOMAIN_RENAME_IN_PROGRESS: DWORD = 8612;
-pub const ERROR_DS_EXISTING_AD_CHILD_NC: DWORD = 8613;
-pub const ERROR_DS_REPL_LIFETIME_EXCEEDED: DWORD = 8614;
-pub const ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER: DWORD = 8615;
-pub const ERROR_DS_LDAP_SEND_QUEUE_FULL: DWORD = 8616;
-pub const ERROR_DS_DRA_OUT_SCHEDULE_WINDOW: DWORD = 8617;
-pub const ERROR_SXS_SECTION_NOT_FOUND: DWORD = 14000;
-pub const ERROR_SXS_CANT_GEN_ACTCTX: DWORD = 14001;
-pub const ERROR_SXS_INVALID_ACTCTXDATA_FORMAT: DWORD = 14002;
-pub const ERROR_SXS_ASSEMBLY_NOT_FOUND: DWORD = 14003;
-pub const ERROR_SXS_MANIFEST_FORMAT_ERROR: DWORD = 14004;
-pub const ERROR_SXS_MANIFEST_PARSE_ERROR: DWORD = 14005;
-pub const ERROR_SXS_ACTIVATION_CONTEXT_DISABLED: DWORD = 14006;
-pub const ERROR_SXS_KEY_NOT_FOUND: DWORD = 14007;
-pub const ERROR_SXS_VERSION_CONFLICT: DWORD = 14008;
-pub const ERROR_SXS_WRONG_SECTION_TYPE: DWORD = 14009;
-pub const ERROR_SXS_THREAD_QUERIES_DISABLED: DWORD = 14010;
-pub const ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET: DWORD = 14011;
-pub const ERROR_SXS_UNKNOWN_ENCODING_GROUP: DWORD = 14012;
-pub const ERROR_SXS_UNKNOWN_ENCODING: DWORD = 14013;
-pub const ERROR_SXS_INVALID_XML_NAMESPACE_URI: DWORD = 14014;
-pub const ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED: DWORD = 14015;
-pub const ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED: DWORD = 14016;
-pub const ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE: DWORD = 14017;
-pub const ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE: DWORD = 14018;
-pub const ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE: DWORD = 14019;
-pub const ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT: DWORD = 14020;
-pub const ERROR_SXS_DUPLICATE_DLL_NAME: DWORD = 14021;
-pub const ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME: DWORD = 14022;
-pub const ERROR_SXS_DUPLICATE_CLSID: DWORD = 14023;
-pub const ERROR_SXS_DUPLICATE_IID: DWORD = 14024;
-pub const ERROR_SXS_DUPLICATE_TLBID: DWORD = 14025;
-pub const ERROR_SXS_DUPLICATE_PROGID: DWORD = 14026;
-pub const ERROR_SXS_DUPLICATE_ASSEMBLY_NAME: DWORD = 14027;
-pub const ERROR_SXS_FILE_HASH_MISMATCH: DWORD = 14028;
-pub const ERROR_SXS_POLICY_PARSE_ERROR: DWORD = 14029;
-pub const ERROR_SXS_XML_E_MISSINGQUOTE: DWORD = 14030;
-pub const ERROR_SXS_XML_E_COMMENTSYNTAX: DWORD = 14031;
-pub const ERROR_SXS_XML_E_BADSTARTNAMECHAR: DWORD = 14032;
-pub const ERROR_SXS_XML_E_BADNAMECHAR: DWORD = 14033;
-pub const ERROR_SXS_XML_E_BADCHARINSTRING: DWORD = 14034;
-pub const ERROR_SXS_XML_E_XMLDECLSYNTAX: DWORD = 14035;
-pub const ERROR_SXS_XML_E_BADCHARDATA: DWORD = 14036;
-pub const ERROR_SXS_XML_E_MISSINGWHITESPACE: DWORD = 14037;
-pub const ERROR_SXS_XML_E_EXPECTINGTAGEND: DWORD = 14038;
-pub const ERROR_SXS_XML_E_MISSINGSEMICOLON: DWORD = 14039;
-pub const ERROR_SXS_XML_E_UNBALANCEDPAREN: DWORD = 14040;
-pub const ERROR_SXS_XML_E_INTERNALERROR: DWORD = 14041;
-pub const ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE: DWORD = 14042;
-pub const ERROR_SXS_XML_E_INCOMPLETE_ENCODING: DWORD = 14043;
-pub const ERROR_SXS_XML_E_MISSING_PAREN: DWORD = 14044;
-pub const ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE: DWORD = 14045;
-pub const ERROR_SXS_XML_E_MULTIPLE_COLONS: DWORD = 14046;
-pub const ERROR_SXS_XML_E_INVALID_DECIMAL: DWORD = 14047;
-pub const ERROR_SXS_XML_E_INVALID_HEXIDECIMAL: DWORD = 14048;
-pub const ERROR_SXS_XML_E_INVALID_UNICODE: DWORD = 14049;
-pub const ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK: DWORD = 14050;
-pub const ERROR_SXS_XML_E_UNEXPECTEDENDTAG: DWORD = 14051;
-pub const ERROR_SXS_XML_E_UNCLOSEDTAG: DWORD = 14052;
-pub const ERROR_SXS_XML_E_DUPLICATEATTRIBUTE: DWORD = 14053;
-pub const ERROR_SXS_XML_E_MULTIPLEROOTS: DWORD = 14054;
-pub const ERROR_SXS_XML_E_INVALIDATROOTLEVEL: DWORD = 14055;
-pub const ERROR_SXS_XML_E_BADXMLDECL: DWORD = 14056;
-pub const ERROR_SXS_XML_E_MISSINGROOT: DWORD = 14057;
-pub const ERROR_SXS_XML_E_UNEXPECTEDEOF: DWORD = 14058;
-pub const ERROR_SXS_XML_E_BADPEREFINSUBSET: DWORD = 14059;
-pub const ERROR_SXS_XML_E_UNCLOSEDSTARTTAG: DWORD = 14060;
-pub const ERROR_SXS_XML_E_UNCLOSEDENDTAG: DWORD = 14061;
-pub const ERROR_SXS_XML_E_UNCLOSEDSTRING: DWORD = 14062;
-pub const ERROR_SXS_XML_E_UNCLOSEDCOMMENT: DWORD = 14063;
-pub const ERROR_SXS_XML_E_UNCLOSEDDECL: DWORD = 14064;
-pub const ERROR_SXS_XML_E_UNCLOSEDCDATA: DWORD = 14065;
-pub const ERROR_SXS_XML_E_RESERVEDNAMESPACE: DWORD = 14066;
-pub const ERROR_SXS_XML_E_INVALIDENCODING: DWORD = 14067;
-pub const ERROR_SXS_XML_E_INVALIDSWITCH: DWORD = 14068;
-pub const ERROR_SXS_XML_E_BADXMLCASE: DWORD = 14069;
-pub const ERROR_SXS_XML_E_INVALID_STANDALONE: DWORD = 14070;
-pub const ERROR_SXS_XML_E_UNEXPECTED_STANDALONE: DWORD = 14071;
-pub const ERROR_SXS_XML_E_INVALID_VERSION: DWORD = 14072;
-pub const ERROR_SXS_XML_E_MISSINGEQUALS: DWORD = 14073;
-pub const ERROR_SXS_PROTECTION_RECOVERY_FAILED: DWORD = 14074;
-pub const ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT: DWORD = 14075;
-pub const ERROR_SXS_PROTECTION_CATALOG_NOT_VALID: DWORD = 14076;
-pub const ERROR_SXS_UNTRANSLATABLE_HRESULT: DWORD = 14077;
-pub const ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING: DWORD = 14078;
-pub const ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE: DWORD = 14079;
-pub const ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME: DWORD = 14080;
-pub const ERROR_SXS_ASSEMBLY_MISSING: DWORD = 14081;
-pub const ERROR_SXS_CORRUPT_ACTIVATION_STACK: DWORD = 14082;
-pub const ERROR_SXS_CORRUPTION: DWORD = 14083;
-pub const ERROR_SXS_EARLY_DEACTIVATION: DWORD = 14084;
-pub const ERROR_SXS_INVALID_DEACTIVATION: DWORD = 14085;
-pub const ERROR_SXS_MULTIPLE_DEACTIVATION: DWORD = 14086;
-pub const ERROR_SXS_PROCESS_TERMINATION_REQUESTED: DWORD = 14087;
-pub const ERROR_SXS_RELEASE_ACTIVATION_CONTEXT: DWORD = 14088;
-pub const ERROR_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY: DWORD = 14089;
-pub const ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE: DWORD = 14090;
-pub const ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME: DWORD = 14091;
-pub const ERROR_SXS_IDENTITY_DUPLICATE_ATTRIBUTE: DWORD = 14092;
-pub const ERROR_SXS_IDENTITY_PARSE_ERROR: DWORD = 14093;
-pub const ERROR_MALFORMED_SUBSTITUTION_STRING: DWORD = 14094;
-pub const ERROR_SXS_INCORRECT_PUBLIC_KEY_TOKEN: DWORD = 14095;
-pub const ERROR_UNMAPPED_SUBSTITUTION_STRING: DWORD = 14096;
-pub const ERROR_SXS_ASSEMBLY_NOT_LOCKED: DWORD = 14097;
-pub const ERROR_SXS_COMPONENT_STORE_CORRUPT: DWORD = 14098;
-pub const ERROR_ADVANCED_INSTALLER_FAILED: DWORD = 14099;
-pub const ERROR_XML_ENCODING_MISMATCH: DWORD = 14100;
-pub const ERROR_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT: DWORD = 14101;
-pub const ERROR_SXS_IDENTITIES_DIFFERENT: DWORD = 14102;
-pub const ERROR_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT: DWORD = 14103;
-pub const ERROR_SXS_FILE_NOT_PART_OF_ASSEMBLY: DWORD = 14104;
-pub const ERROR_SXS_MANIFEST_TOO_BIG: DWORD = 14105;
-pub const ERROR_SXS_SETTING_NOT_REGISTERED: DWORD = 14106;
-pub const ERROR_SXS_TRANSACTION_CLOSURE_INCOMPLETE: DWORD = 14107;
-pub const ERROR_SMI_PRIMITIVE_INSTALLER_FAILED: DWORD = 14108;
-pub const ERROR_GENERIC_COMMAND_FAILED: DWORD = 14109;
-pub const ERROR_SXS_FILE_HASH_MISSING: DWORD = 14110;
-pub const ERROR_IPSEC_QM_POLICY_EXISTS: DWORD = 13000;
-pub const ERROR_IPSEC_QM_POLICY_NOT_FOUND: DWORD = 13001;
-pub const ERROR_IPSEC_QM_POLICY_IN_USE: DWORD = 13002;
-pub const ERROR_IPSEC_MM_POLICY_EXISTS: DWORD = 13003;
-pub const ERROR_IPSEC_MM_POLICY_NOT_FOUND: DWORD = 13004;
-pub const ERROR_IPSEC_MM_POLICY_IN_USE: DWORD = 13005;
-pub const ERROR_IPSEC_MM_FILTER_EXISTS: DWORD = 13006;
-pub const ERROR_IPSEC_MM_FILTER_NOT_FOUND: DWORD = 13007;
-pub const ERROR_IPSEC_TRANSPORT_FILTER_EXISTS: DWORD = 13008;
-pub const ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND: DWORD = 13009;
-pub const ERROR_IPSEC_MM_AUTH_EXISTS: DWORD = 13010;
-pub const ERROR_IPSEC_MM_AUTH_NOT_FOUND: DWORD = 13011;
-pub const ERROR_IPSEC_MM_AUTH_IN_USE: DWORD = 13012;
-pub const ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND: DWORD = 13013;
-pub const ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND: DWORD = 13014;
-pub const ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND: DWORD = 13015;
-pub const ERROR_IPSEC_TUNNEL_FILTER_EXISTS: DWORD = 13016;
-pub const ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND: DWORD = 13017;
-pub const ERROR_IPSEC_MM_FILTER_PENDING_DELETION: DWORD = 13018;
-pub const ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION: DWORD = 13019;
-pub const ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION: DWORD = 13020;
-pub const ERROR_IPSEC_MM_POLICY_PENDING_DELETION: DWORD = 13021;
-pub const ERROR_IPSEC_MM_AUTH_PENDING_DELETION: DWORD = 13022;
-pub const ERROR_IPSEC_QM_POLICY_PENDING_DELETION: DWORD = 13023;
-pub const ERROR_IPSEC_IKE_NEG_STATUS_BEGIN: DWORD = 13800;
-pub const ERROR_IPSEC_IKE_AUTH_FAIL: DWORD = 13801;
-pub const ERROR_IPSEC_IKE_ATTRIB_FAIL: DWORD = 13802;
-pub const ERROR_IPSEC_IKE_NEGOTIATION_PENDING: DWORD = 13803;
-pub const ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR: DWORD = 13804;
-pub const ERROR_IPSEC_IKE_TIMED_OUT: DWORD = 13805;
-pub const ERROR_IPSEC_IKE_NO_CERT: DWORD = 13806;
-pub const ERROR_IPSEC_IKE_SA_DELETED: DWORD = 13807;
-pub const ERROR_IPSEC_IKE_SA_REAPED: DWORD = 13808;
-pub const ERROR_IPSEC_IKE_MM_ACQUIRE_DROP: DWORD = 13809;
-pub const ERROR_IPSEC_IKE_QM_ACQUIRE_DROP: DWORD = 13810;
-pub const ERROR_IPSEC_IKE_QUEUE_DROP_MM: DWORD = 13811;
-pub const ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM: DWORD = 13812;
-pub const ERROR_IPSEC_IKE_DROP_NO_RESPONSE: DWORD = 13813;
-pub const ERROR_IPSEC_IKE_MM_DELAY_DROP: DWORD = 13814;
-pub const ERROR_IPSEC_IKE_QM_DELAY_DROP: DWORD = 13815;
-pub const ERROR_IPSEC_IKE_ERROR: DWORD = 13816;
-pub const ERROR_IPSEC_IKE_CRL_FAILED: DWORD = 13817;
-pub const ERROR_IPSEC_IKE_INVALID_KEY_USAGE: DWORD = 13818;
-pub const ERROR_IPSEC_IKE_INVALID_CERT_TYPE: DWORD = 13819;
-pub const ERROR_IPSEC_IKE_NO_PRIVATE_KEY: DWORD = 13820;
-pub const ERROR_IPSEC_IKE_DH_FAIL: DWORD = 13822;
-pub const ERROR_IPSEC_IKE_INVALID_HEADER: DWORD = 13824;
-pub const ERROR_IPSEC_IKE_NO_POLICY: DWORD = 13825;
-pub const ERROR_IPSEC_IKE_INVALID_SIGNATURE: DWORD = 13826;
-pub const ERROR_IPSEC_IKE_KERBEROS_ERROR: DWORD = 13827;
-pub const ERROR_IPSEC_IKE_NO_PUBLIC_KEY: DWORD = 13828;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR: DWORD = 13829;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_SA: DWORD = 13830;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_PROP: DWORD = 13831;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_TRANS: DWORD = 13832;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_KE: DWORD = 13833;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_ID: DWORD = 13834;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_CERT: DWORD = 13835;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ: DWORD = 13836;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_HASH: DWORD = 13837;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_SIG: DWORD = 13838;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_NONCE: DWORD = 13839;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY: DWORD = 13840;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_DELETE: DWORD = 13841;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR: DWORD = 13842;
-pub const ERROR_IPSEC_IKE_INVALID_PAYLOAD: DWORD = 13843;
-pub const ERROR_IPSEC_IKE_LOAD_SOFT_SA: DWORD = 13844;
-pub const ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN: DWORD = 13845;
-pub const ERROR_IPSEC_IKE_INVALID_COOKIE: DWORD = 13846;
-pub const ERROR_IPSEC_IKE_NO_PEER_CERT: DWORD = 13847;
-pub const ERROR_IPSEC_IKE_PEER_CRL_FAILED: DWORD = 13848;
-pub const ERROR_IPSEC_IKE_POLICY_CHANGE: DWORD = 13849;
-pub const ERROR_IPSEC_IKE_NO_MM_POLICY: DWORD = 13850;
-pub const ERROR_IPSEC_IKE_NOTCBPRIV: DWORD = 13851;
-pub const ERROR_IPSEC_IKE_SECLOADFAIL: DWORD = 13852;
-pub const ERROR_IPSEC_IKE_FAILSSPINIT: DWORD = 13853;
-pub const ERROR_IPSEC_IKE_FAILQUERYSSP: DWORD = 13854;
-pub const ERROR_IPSEC_IKE_SRVACQFAIL: DWORD = 13855;
-pub const ERROR_IPSEC_IKE_SRVQUERYCRED: DWORD = 13856;
-pub const ERROR_IPSEC_IKE_GETSPIFAIL: DWORD = 13857;
-pub const ERROR_IPSEC_IKE_INVALID_FILTER: DWORD = 13858;
-pub const ERROR_IPSEC_IKE_OUT_OF_MEMORY: DWORD = 13859;
-pub const ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED: DWORD = 13860;
-pub const ERROR_IPSEC_IKE_INVALID_POLICY: DWORD = 13861;
-pub const ERROR_IPSEC_IKE_UNKNOWN_DOI: DWORD = 13862;
-pub const ERROR_IPSEC_IKE_INVALID_SITUATION: DWORD = 13863;
-pub const ERROR_IPSEC_IKE_DH_FAILURE: DWORD = 13864;
-pub const ERROR_IPSEC_IKE_INVALID_GROUP: DWORD = 13865;
-pub const ERROR_IPSEC_IKE_ENCRYPT: DWORD = 13866;
-pub const ERROR_IPSEC_IKE_DECRYPT: DWORD = 13867;
-pub const ERROR_IPSEC_IKE_POLICY_MATCH: DWORD = 13868;
-pub const ERROR_IPSEC_IKE_UNSUPPORTED_ID: DWORD = 13869;
-pub const ERROR_IPSEC_IKE_INVALID_HASH: DWORD = 13870;
-pub const ERROR_IPSEC_IKE_INVALID_HASH_ALG: DWORD = 13871;
-pub const ERROR_IPSEC_IKE_INVALID_HASH_SIZE: DWORD = 13872;
-pub const ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG: DWORD = 13873;
-pub const ERROR_IPSEC_IKE_INVALID_AUTH_ALG: DWORD = 13874;
-pub const ERROR_IPSEC_IKE_INVALID_SIG: DWORD = 13875;
-pub const ERROR_IPSEC_IKE_LOAD_FAILED: DWORD = 13876;
-pub const ERROR_IPSEC_IKE_RPC_DELETE: DWORD = 13877;
-pub const ERROR_IPSEC_IKE_BENIGN_REINIT: DWORD = 13878;
-pub const ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY: DWORD = 13879;
-pub const ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN: DWORD = 13881;
-pub const ERROR_IPSEC_IKE_MM_LIMIT: DWORD = 13882;
-pub const ERROR_IPSEC_IKE_NEGOTIATION_DISABLED: DWORD = 13883;
-/*pub const ERROR_IPSEC_IKE_NEG_STATUS_END: DWORD = 13884)*/
-pub const ERROR_IPSEC_IKE_QM_LIMIT: DWORD = 13884;
-pub const ERROR_IPSEC_IKE_MM_EXPIRED: DWORD = 13885;
-pub const ERROR_IPSEC_IKE_PEER_MM_ASSUMED_INVALID: DWORD = 13886;
-pub const ERROR_IPSEC_IKE_CERT_CHAIN_POLICY_MISMATCH: DWORD = 13887;
-pub const ERROR_IPSEC_IKE_UNEXPECTED_MESSAGE_ID: DWORD = 13888;
-pub const ERROR_IPSEC_IKE_INVALID_AUTH_PAYLOAD: DWORD = 13889;
-pub const ERROR_IPSEC_IKE_DOS_COOKIE_SENT: DWORD = 13890;
-pub const ERROR_IPSEC_IKE_SHUTTING_DOWN: DWORD = 13891;
-pub const ERROR_IPSEC_IKE_CGA_AUTH_FAILED: DWORD = 13892;
-pub const ERROR_IPSEC_IKE_PROCESS_ERR_NATOA: DWORD = 13893;
-pub const ERROR_IPSEC_IKE_INVALID_MM_FOR_QM: DWORD = 13894;
-pub const ERROR_IPSEC_IKE_QM_EXPIRED: DWORD = 13895;
-pub const ERROR_IPSEC_IKE_TOO_MANY_FILTERS: DWORD = 13896;
-pub const ERROR_IPSEC_IKE_NEG_STATUS_END: DWORD = 13897;
-pub const ERROR_IPSEC_IKE_KILL_DUMMY_NAP_TUNNEL: DWORD = 13898;
-pub const ERROR_IPSEC_IKE_INNER_IP_ASSIGNMENT_FAILURE: DWORD = 13899;
-pub const ERROR_IPSEC_IKE_REQUIRE_CP_PAYLOAD_MISSING: DWORD = 13900;
-pub const ERROR_IPSEC_KEY_MODULE_IMPERSONATION_NEGOTIATION_PENDING: DWORD = 13901;
-pub const ERROR_IPSEC_IKE_COEXISTENCE_SUPPRESS: DWORD = 13902;
-pub const ERROR_IPSEC_IKE_RATELIMIT_DROP: DWORD = 13903;
-pub const ERROR_IPSEC_IKE_PEER_DOESNT_SUPPORT_MOBIKE: DWORD = 13904;
-pub const ERROR_IPSEC_IKE_AUTHORIZATION_FAILURE: DWORD = 13905;
-pub const ERROR_IPSEC_IKE_STRONG_CRED_AUTHORIZATION_FAILURE: DWORD = 13906;
-pub const ERROR_IPSEC_IKE_AUTHORIZATION_FAILURE_WITH_OPTIONAL_RETRY: DWORD = 13907;
-pub const ERROR_IPSEC_IKE_STRONG_CRED_AUTHORIZATION_AND_CERTMAP_FAILURE: DWORD = 13908;
-pub const ERROR_IPSEC_IKE_NEG_STATUS_EXTENDED_END: DWORD = 13909;
-pub const ERROR_IPSEC_BAD_SPI: DWORD = 13910;
-pub const ERROR_IPSEC_SA_LIFETIME_EXPIRED: DWORD = 13911;
-pub const ERROR_IPSEC_WRONG_SA: DWORD = 13912;
-pub const ERROR_IPSEC_REPLAY_CHECK_FAILED: DWORD = 13913;
-pub const ERROR_IPSEC_INVALID_PACKET: DWORD = 13914;
-pub const ERROR_IPSEC_INTEGRITY_CHECK_FAILED: DWORD = 13915;
-pub const ERROR_IPSEC_CLEAR_TEXT_DROP: DWORD = 13916;
-pub const ERROR_IPSEC_AUTH_FIREWALL_DROP: DWORD = 13917;
-pub const ERROR_IPSEC_THROTTLE_DROP: DWORD = 13918;
-pub const ERROR_IPSEC_DOSP_BLOCK: DWORD = 13925;
-pub const ERROR_IPSEC_DOSP_RECEIVED_MULTICAST: DWORD = 13926;
-pub const ERROR_IPSEC_DOSP_INVALID_PACKET: DWORD = 13927;
-pub const ERROR_IPSEC_DOSP_STATE_LOOKUP_FAILED: DWORD = 13928;
-pub const ERROR_IPSEC_DOSP_MAX_ENTRIES: DWORD = 13929;
-pub const ERROR_IPSEC_DOSP_KEYMOD_NOT_ALLOWED: DWORD = 13930;
-pub const ERROR_IPSEC_DOSP_NOT_INSTALLED: DWORD = 13931;
-pub const ERROR_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES: DWORD = 13932;
-pub const ERROR_EVT_INVALID_CHANNEL_PATH: DWORD = 15000;
-pub const ERROR_EVT_INVALID_QUERY: DWORD = 15001;
-pub const ERROR_EVT_PUBLISHER_METADATA_NOT_FOUND: DWORD = 15002;
-pub const ERROR_EVT_EVENT_TEMPLATE_NOT_FOUND: DWORD = 15003;
-pub const ERROR_EVT_INVALID_PUBLISHER_NAME: DWORD = 15004;
-pub const ERROR_EVT_INVALID_EVENT_DATA: DWORD = 15005;
-pub const ERROR_EVT_CHANNEL_NOT_FOUND: DWORD = 15007;
-pub const ERROR_EVT_MALFORMED_XML_TEXT: DWORD = 15008;
-pub const ERROR_EVT_SUBSCRIPTION_TO_DIRECT_CHANNEL: DWORD = 15009;
-pub const ERROR_EVT_CONFIGURATION_ERROR: DWORD = 15010;
-pub const ERROR_EVT_QUERY_RESULT_STALE: DWORD = 15011;
-pub const ERROR_EVT_QUERY_RESULT_INVALID_POSITION: DWORD = 15012;
-pub const ERROR_EVT_NON_VALIDATING_MSXML: DWORD = 15013;
-pub const ERROR_EVT_FILTER_ALREADYSCOPED: DWORD = 15014;
-pub const ERROR_EVT_FILTER_NOTELTSET: DWORD = 15015;
-pub const ERROR_EVT_FILTER_INVARG: DWORD = 15016;
-pub const ERROR_EVT_FILTER_INVTEST: DWORD = 15017;
-pub const ERROR_EVT_FILTER_INVTYPE: DWORD = 15018;
-pub const ERROR_EVT_FILTER_PARSEERR: DWORD = 15019;
-pub const ERROR_EVT_FILTER_UNSUPPORTEDOP: DWORD = 15020;
-pub const ERROR_EVT_FILTER_UNEXPECTEDTOKEN: DWORD = 15021;
-pub const ERROR_EVT_INVALID_OPERATION_OVER_ENABLED_DIRECT_CHANNEL: DWORD = 15022;
-pub const ERROR_EVT_INVALID_CHANNEL_PROPERTY_VALUE: DWORD = 15023;
-pub const ERROR_EVT_INVALID_PUBLISHER_PROPERTY_VALUE: DWORD = 15024;
-pub const ERROR_EVT_CHANNEL_CANNOT_ACTIVATE: DWORD = 15025;
-pub const ERROR_EVT_FILTER_TOO_COMPLEX: DWORD = 15026;
-pub const ERROR_EVT_MESSAGE_NOT_FOUND: DWORD = 15027;
-pub const ERROR_EVT_MESSAGE_ID_NOT_FOUND: DWORD = 15028;
-pub const ERROR_EVT_UNRESOLVED_VALUE_INSERT: DWORD = 15029;
-pub const ERROR_EVT_UNRESOLVED_PARAMETER_INSERT: DWORD = 15030;
-pub const ERROR_EVT_MAX_INSERTS_REACHED: DWORD = 15031;
-pub const ERROR_EVT_EVENT_DEFINITION_NOT_FOUND: DWORD = 15032;
-pub const ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND: DWORD = 15033;
-pub const ERROR_EVT_VERSION_TOO_OLD: DWORD = 15034;
-pub const ERROR_EVT_VERSION_TOO_NEW: DWORD = 15035;
-pub const ERROR_EVT_CANNOT_OPEN_CHANNEL_OF_QUERY: DWORD = 15036;
-pub const ERROR_EVT_PUBLISHER_DISABLED: DWORD = 15037;
-pub const ERROR_EVT_FILTER_OUT_OF_RANGE: DWORD = 15038;
-pub const ERROR_EC_SUBSCRIPTION_CANNOT_ACTIVATE: DWORD = 15080;
-pub const ERROR_EC_LOG_DISABLED: DWORD = 15081;
-pub const ERROR_EC_CIRCULAR_FORWARDING: DWORD = 15082;
-pub const ERROR_EC_CREDSTORE_FULL: DWORD = 15083;
-pub const ERROR_EC_CRED_NOT_FOUND: DWORD = 15084;
-pub const ERROR_EC_NO_ACTIVE_CHANNEL: DWORD = 15085;
-pub const ERROR_MUI_FILE_NOT_FOUND: DWORD = 15100;
-pub const ERROR_MUI_INVALID_FILE: DWORD = 15101;
-pub const ERROR_MUI_INVALID_RC_CONFIG: DWORD = 15102;
-pub const ERROR_MUI_INVALID_LOCALE_NAME: DWORD = 15103;
-pub const ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME: DWORD = 15104;
-pub const ERROR_MUI_FILE_NOT_LOADED: DWORD = 15105;
-pub const ERROR_RESOURCE_ENUM_USER_STOP: DWORD = 15106;
-pub const ERROR_MUI_INTLSETTINGS_UILANG_NOT_INSTALLED: DWORD = 15107;
-pub const ERROR_MUI_INTLSETTINGS_INVALID_LOCALE_NAME: DWORD = 15108;
-pub const ERROR_MRM_RUNTIME_NO_DEFAULT_OR_NEUTRAL_RESOURCE: DWORD = 15110;
-pub const ERROR_MRM_INVALID_PRICONFIG: DWORD = 15111;
-pub const ERROR_MRM_INVALID_FILE_TYPE: DWORD = 15112;
-pub const ERROR_MRM_UNKNOWN_QUALIFIER: DWORD = 15113;
-pub const ERROR_MRM_INVALID_QUALIFIER_VALUE: DWORD = 15114;
-pub const ERROR_MRM_NO_CANDIDATE: DWORD = 15115;
-pub const ERROR_MRM_NO_MATCH_OR_DEFAULT_CANDIDATE: DWORD = 15116;
-pub const ERROR_MRM_RESOURCE_TYPE_MISMATCH: DWORD = 15117;
-pub const ERROR_MRM_DUPLICATE_MAP_NAME: DWORD = 15118;
-pub const ERROR_MRM_DUPLICATE_ENTRY: DWORD = 15119;
-pub const ERROR_MRM_INVALID_RESOURCE_IDENTIFIER: DWORD = 15120;
-pub const ERROR_MRM_FILEPATH_TOO_LONG: DWORD = 15121;
-pub const ERROR_MRM_UNSUPPORTED_DIRECTORY_TYPE: DWORD = 15122;
-pub const ERROR_MRM_INVALID_PRI_FILE: DWORD = 15126;
-pub const ERROR_MRM_NAMED_RESOURCE_NOT_FOUND: DWORD = 15127;
-pub const ERROR_MRM_MAP_NOT_FOUND: DWORD = 15135;
-pub const ERROR_MRM_UNSUPPORTED_PROFILE_TYPE: DWORD = 15136;
-pub const ERROR_MRM_INVALID_QUALIFIER_OPERATOR: DWORD = 15137;
-pub const ERROR_MRM_INDETERMINATE_QUALIFIER_VALUE: DWORD = 15138;
-pub const ERROR_MRM_AUTOMERGE_ENABLED: DWORD = 15139;
-pub const ERROR_MRM_TOO_MANY_RESOURCES: DWORD = 15140;
-pub const ERROR_MCA_INVALID_CAPABILITIES_STRING: DWORD = 15200;
-pub const ERROR_MCA_INVALID_VCP_VERSION: DWORD = 15201;
-pub const ERROR_MCA_MONITOR_VIOLATES_MCCS_SPECIFICATION: DWORD = 15202;
-pub const ERROR_MCA_MCCS_VERSION_MISMATCH: DWORD = 15203;
-pub const ERROR_MCA_UNSUPPORTED_MCCS_VERSION: DWORD = 15204;
-pub const ERROR_MCA_INTERNAL_ERROR: DWORD = 15205;
-pub const ERROR_MCA_INVALID_TECHNOLOGY_TYPE_RETURNED: DWORD = 15206;
-pub const ERROR_MCA_UNSUPPORTED_COLOR_TEMPERATURE: DWORD = 15207;
-pub const ERROR_AMBIGUOUS_SYSTEM_DEVICE: DWORD = 15250;
-pub const ERROR_SYSTEM_DEVICE_NOT_FOUND: DWORD = 15299;
-pub const ERROR_HASH_NOT_SUPPORTED: DWORD = 15300;
-pub const ERROR_HASH_NOT_PRESENT: DWORD = 15301;
-pub const ERROR_SECONDARY_IC_PROVIDER_NOT_REGISTERED: DWORD = 15321;
-pub const ERROR_GPIO_CLIENT_INFORMATION_INVALID: DWORD = 15322;
-pub const ERROR_GPIO_VERSION_NOT_SUPPORTED: DWORD = 15323;
-pub const ERROR_GPIO_INVALID_REGISTRATION_PACKET: DWORD = 15324;
-pub const ERROR_GPIO_OPERATION_DENIED: DWORD = 15325;
-pub const ERROR_GPIO_INCOMPATIBLE_CONNECT_MODE: DWORD = 15326;
-pub const ERROR_GPIO_INTERRUPT_ALREADY_UNMASKED: DWORD = 15327;
-pub const ERROR_CANNOT_SWITCH_RUNLEVEL: DWORD = 15400;
-pub const ERROR_INVALID_RUNLEVEL_SETTING: DWORD = 15401;
-pub const ERROR_RUNLEVEL_SWITCH_TIMEOUT: DWORD = 15402;
-pub const ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT: DWORD = 15403;
-pub const ERROR_RUNLEVEL_SWITCH_IN_PROGRESS: DWORD = 15404;
-pub const ERROR_SERVICES_FAILED_AUTOSTART: DWORD = 15405;
-pub const ERROR_COM_TASK_STOP_PENDING: DWORD = 15501;
-pub const ERROR_INSTALL_OPEN_PACKAGE_FAILED: DWORD = 15600;
-pub const ERROR_INSTALL_PACKAGE_NOT_FOUND: DWORD = 15601;
-pub const ERROR_INSTALL_INVALID_PACKAGE: DWORD = 15602;
-pub const ERROR_INSTALL_RESOLVE_DEPENDENCY_FAILED: DWORD = 15603;
-pub const ERROR_INSTALL_OUT_OF_DISK_SPACE: DWORD = 15604;
-pub const ERROR_INSTALL_NETWORK_FAILURE: DWORD = 15605;
-pub const ERROR_INSTALL_REGISTRATION_FAILURE: DWORD = 15606;
-pub const ERROR_INSTALL_DEREGISTRATION_FAILURE: DWORD = 15607;
-pub const ERROR_INSTALL_CANCEL: DWORD = 15608;
-pub const ERROR_INSTALL_FAILED: DWORD = 15609;
-pub const ERROR_REMOVE_FAILED: DWORD = 15610;
-pub const ERROR_PACKAGE_ALREADY_EXISTS: DWORD = 15611;
-pub const ERROR_NEEDS_REMEDIATION: DWORD = 15612;
-pub const ERROR_INSTALL_PREREQUISITE_FAILED: DWORD = 15613;
-pub const ERROR_PACKAGE_REPOSITORY_CORRUPTED: DWORD = 15614;
-pub const ERROR_INSTALL_POLICY_FAILURE: DWORD = 15615;
-pub const ERROR_PACKAGE_UPDATING: DWORD = 15616;
-pub const ERROR_DEPLOYMENT_BLOCKED_BY_POLICY: DWORD = 15617;
-pub const ERROR_PACKAGES_IN_USE: DWORD = 15618;
-pub const ERROR_RECOVERY_FILE_CORRUPT: DWORD = 15619;
-pub const ERROR_INVALID_STAGED_SIGNATURE: DWORD = 15620;
-pub const ERROR_DELETING_EXISTING_APPLICATIONDATA_STORE_FAILED: DWORD = 15621;
-pub const ERROR_INSTALL_PACKAGE_DOWNGRADE: DWORD = 15622;
-pub const ERROR_SYSTEM_NEEDS_REMEDIATION: DWORD = 15623;
-pub const ERROR_APPX_INTEGRITY_FAILURE_CLR_NGEN: DWORD = 15624;
-pub const ERROR_RESILIENCY_FILE_CORRUPT: DWORD = 15625;
-pub const ERROR_INSTALL_FIREWALL_SERVICE_NOT_RUNNING: DWORD = 15626;
-pub const ERROR_STATE_LOAD_STORE_FAILED: DWORD = 15800;
-pub const ERROR_STATE_GET_VERSION_FAILED: DWORD = 15801;
-pub const ERROR_STATE_SET_VERSION_FAILED: DWORD = 15802;
-pub const ERROR_STATE_STRUCTURED_RESET_FAILED: DWORD = 15803;
-pub const ERROR_STATE_OPEN_CONTAINER_FAILED: DWORD = 15804;
-pub const ERROR_STATE_CREATE_CONTAINER_FAILED: DWORD = 15805;
-pub const ERROR_STATE_DELETE_CONTAINER_FAILED: DWORD = 15806;
-pub const ERROR_STATE_READ_SETTING_FAILED: DWORD = 15807;
-pub const ERROR_STATE_WRITE_SETTING_FAILED: DWORD = 15808;
-pub const ERROR_STATE_DELETE_SETTING_FAILED: DWORD = 15809;
-pub const ERROR_STATE_QUERY_SETTING_FAILED: DWORD = 15810;
-pub const ERROR_STATE_READ_COMPOSITE_SETTING_FAILED: DWORD = 15811;
-pub const ERROR_STATE_WRITE_COMPOSITE_SETTING_FAILED: DWORD = 15812;
-pub const ERROR_STATE_ENUMERATE_CONTAINER_FAILED: DWORD = 15813;
-pub const ERROR_STATE_ENUMERATE_SETTINGS_FAILED: DWORD = 15814;
-pub const ERROR_STATE_COMPOSITE_SETTING_VALUE_SIZE_LIMIT_EXCEEDED: DWORD = 15815;
-pub const ERROR_STATE_SETTING_VALUE_SIZE_LIMIT_EXCEEDED: DWORD = 15816;
-pub const ERROR_STATE_SETTING_NAME_SIZE_LIMIT_EXCEEDED: DWORD = 15817;
-pub const ERROR_STATE_CONTAINER_NAME_SIZE_LIMIT_EXCEEDED: DWORD = 15818;
-pub const ERROR_API_UNAVAILABLE: DWORD = 15841;
-pub const ERROR_AUDITING_DISABLED: DWORD = 0xC0090001;
-pub const ERROR_ALL_SIDS_FILTERED: DWORD = 0xC0090002;
-
-pub const WSABASEERR: c_int = 10000;
-pub const WSAEINTR: c_int = WSABASEERR + 4;
-pub const WSAEBADF: c_int = WSABASEERR + 9;
-pub const WSAEACCES: c_int = WSABASEERR + 13;
-pub const WSAEFAULT: c_int = WSABASEERR + 14;
-pub const WSAEINVAL: c_int = WSABASEERR + 22;
-pub const WSAEMFILE: c_int = WSABASEERR + 24;
-pub const WSAEWOULDBLOCK: c_int = WSABASEERR + 35;
-pub const WSAEINPROGRESS: c_int = WSABASEERR + 36;
-pub const WSAEALREADY: c_int = WSABASEERR + 37;
-pub const WSAENOTSOCK: c_int = WSABASEERR + 38;
-pub const WSAEDESTADDRREQ: c_int = WSABASEERR + 39;
-pub const WSAEMSGSIZE: c_int = WSABASEERR + 40;
-pub const WSAEPROTOTYPE: c_int = WSABASEERR + 41;
-pub const WSAENOPROTOOPT: c_int = WSABASEERR + 42;
-pub const WSAEPROTONOSUPPORT: c_int = WSABASEERR + 43;
-pub const WSAESOCKTNOSUPPORT: c_int = WSABASEERR + 44;
-pub const WSAEOPNOTSUPP: c_int = WSABASEERR + 45;
-pub const WSAEPFNOSUPPORT: c_int = WSABASEERR + 46;
-pub const WSAEAFNOSUPPORT: c_int = WSABASEERR + 47;
-pub const WSAEADDRINUSE: c_int = WSABASEERR + 48;
-pub const WSAEADDRNOTAVAIL: c_int = WSABASEERR + 49;
-pub const WSAENETDOWN: c_int = WSABASEERR + 50;
-pub const WSAENETUNREACH: c_int = WSABASEERR + 51;
-pub const WSAENETRESET: c_int = WSABASEERR + 52;
-pub const WSAECONNABORTED: c_int = WSABASEERR + 53;
-pub const WSAECONNRESET: c_int = WSABASEERR + 54;
-pub const WSAENOBUFS: c_int = WSABASEERR + 55;
-pub const WSAEISCONN: c_int = WSABASEERR + 56;
-pub const WSAENOTCONN: c_int = WSABASEERR + 57;
-pub const WSAESHUTDOWN: c_int = WSABASEERR + 58;
-pub const WSAETOOMANYREFS: c_int = WSABASEERR + 59;
-pub const WSAETIMEDOUT: c_int = WSABASEERR + 60;
-pub const WSAECONNREFUSED: c_int = WSABASEERR + 61;
-pub const WSAELOOP: c_int = WSABASEERR + 62;
-pub const WSAENAMETOOLONG: c_int = WSABASEERR + 63;
-pub const WSAEHOSTDOWN: c_int = WSABASEERR + 64;
-pub const WSAEHOSTUNREACH: c_int = WSABASEERR + 65;
-pub const WSAENOTEMPTY: c_int = WSABASEERR + 66;
-pub const WSAEPROCLIM: c_int = WSABASEERR + 67;
-pub const WSAEUSERS: c_int = WSABASEERR + 68;
-pub const WSAEDQUOT: c_int = WSABASEERR + 69;
-pub const WSAESTALE: c_int = WSABASEERR + 70;
-pub const WSAEREMOTE: c_int = WSABASEERR + 71;
-pub const WSASYSNOTREADY: c_int = WSABASEERR + 91;
-pub const WSAVERNOTSUPPORTED: c_int = WSABASEERR + 92;
-pub const WSANOTINITIALISED: c_int = WSABASEERR + 93;
-pub const WSAEDISCON: c_int = WSABASEERR + 101;
-pub const WSAENOMORE: c_int = WSABASEERR + 102;
-pub const WSAECANCELLED: c_int = WSABASEERR + 103;
-pub const WSAEINVALIDPROCTABLE: c_int = WSABASEERR + 104;
-pub const WSAEINVALIDPROVIDER: c_int = WSABASEERR + 105;
-pub const WSAEPROVIDERFAILEDINIT: c_int = WSABASEERR + 106;
-pub const WSASYSCALLFAILURE: c_int = WSABASEERR + 107;
-pub const WSASERVICE_NOT_FOUND: c_int = WSABASEERR + 108;
-pub const WSATYPE_NOT_FOUND: c_int = WSABASEERR + 109;
-pub const WSA_E_NO_MORE: c_int = WSABASEERR + 110;
-pub const WSA_E_CANCELLED: c_int = WSABASEERR + 111;
-pub const WSAEREFUSED: c_int = WSABASEERR + 112;
-pub const WSAHOST_NOT_FOUND: c_int = WSABASEERR + 1001;
-pub const WSATRY_AGAIN: c_int = WSABASEERR + 1002;
-pub const WSANO_RECOVERY: c_int = WSABASEERR + 1003;
-pub const WSANO_DATA: c_int = WSABASEERR + 1004;
-pub const WSA_QOS_RECEIVERS: c_int = WSABASEERR + 1005;
-pub const WSA_QOS_SENDERS: c_int = WSABASEERR + 1006;
-pub const WSA_QOS_NO_SENDERS: c_int = WSABASEERR + 1007;
-pub const WSA_QOS_NO_RECEIVERS: c_int = WSABASEERR + 1008;
-pub const WSA_QOS_REQUEST_CONFIRMED: c_int = WSABASEERR + 1009;
-pub const WSA_QOS_ADMISSION_FAILURE: c_int = WSABASEERR + 1010;
-pub const WSA_QOS_POLICY_FAILURE: c_int = WSABASEERR + 1011;
-pub const WSA_QOS_BAD_STYLE: c_int = WSABASEERR + 1012;
-pub const WSA_QOS_BAD_OBJECT: c_int = WSABASEERR + 1013;
-pub const WSA_QOS_TRAFFIC_CTRL_ERROR: c_int = WSABASEERR + 1014;
-pub const WSA_QOS_GENERIC_ERROR: c_int = WSABASEERR + 1015;
-pub const WSA_QOS_ESERVICETYPE: c_int = WSABASEERR + 1016;
-pub const WSA_QOS_EFLOWSPEC: c_int = WSABASEERR + 1017;
-pub const WSA_QOS_EPROVSPECBUF: c_int = WSABASEERR + 1018;
-pub const WSA_QOS_EFILTERSTYLE: c_int = WSABASEERR + 1019;
-pub const WSA_QOS_EFILTERTYPE: c_int = WSABASEERR + 1020;
-pub const WSA_QOS_EFILTERCOUNT: c_int = WSABASEERR + 1021;
-pub const WSA_QOS_EOBJLENGTH: c_int = WSABASEERR + 1022;
-pub const WSA_QOS_EFLOWCOUNT: c_int = WSABASEERR + 1023;
-pub const WSA_QOS_EUNKNOWNPSOBJ: c_int = WSABASEERR + 1024;
-pub const WSA_QOS_EUNKOWNPSOBJ: c_int = WSA_QOS_EUNKNOWNPSOBJ;
-pub const WSA_QOS_EPOLICYOBJ: c_int = WSABASEERR + 1025;
-pub const WSA_QOS_EFLOWDESC: c_int = WSABASEERR + 1026;
-pub const WSA_QOS_EPSFLOWSPEC: c_int = WSABASEERR + 1027;
-pub const WSA_QOS_EPSFILTERSPEC: c_int = WSABASEERR + 1028;
-pub const WSA_QOS_ESDMODEOBJ: c_int = WSABASEERR + 1029;
-pub const WSA_QOS_ESHAPERATEOBJ: c_int = WSABASEERR + 1030;
-pub const WSA_QOS_RESERVED_PETYPE: c_int = WSABASEERR + 1031;
diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst
new file mode 100644
index 00000000000..3e454199f13
--- /dev/null
+++ b/library/std/src/sys/windows/c/windows_sys.lst
@@ -0,0 +1,2590 @@
+// tidy-alphabetical-start
+Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED
+Windows.Wdk.Storage.FileSystem.FILE_CONTAINS_EXTENDED_CREATE_INFORMATION
+Windows.Wdk.Storage.FileSystem.FILE_CREATE
+Windows.Wdk.Storage.FileSystem.FILE_CREATE_TREE_CONNECTION
+Windows.Wdk.Storage.FileSystem.FILE_DELETE_ON_CLOSE
+Windows.Wdk.Storage.FileSystem.FILE_DIRECTORY_FILE
+Windows.Wdk.Storage.FileSystem.FILE_DISALLOW_EXCLUSIVE
+Windows.Wdk.Storage.FileSystem.FILE_NO_COMPRESSION
+Windows.Wdk.Storage.FileSystem.FILE_NO_EA_KNOWLEDGE
+Windows.Wdk.Storage.FileSystem.FILE_NO_INTERMEDIATE_BUFFERING
+Windows.Wdk.Storage.FileSystem.FILE_NON_DIRECTORY_FILE
+Windows.Wdk.Storage.FileSystem.FILE_OPEN
+Windows.Wdk.Storage.FileSystem.FILE_OPEN_BY_FILE_ID
+Windows.Wdk.Storage.FileSystem.FILE_OPEN_FOR_BACKUP_INTENT
+Windows.Wdk.Storage.FileSystem.FILE_OPEN_FOR_FREE_SPACE_QUERY
+Windows.Wdk.Storage.FileSystem.FILE_OPEN_IF
+Windows.Wdk.Storage.FileSystem.FILE_OPEN_NO_RECALL
+Windows.Wdk.Storage.FileSystem.FILE_OPEN_REPARSE_POINT
+Windows.Wdk.Storage.FileSystem.FILE_OPEN_REQUIRING_OPLOCK
+Windows.Wdk.Storage.FileSystem.FILE_OVERWRITE
+Windows.Wdk.Storage.FileSystem.FILE_OVERWRITE_IF
+Windows.Wdk.Storage.FileSystem.FILE_RANDOM_ACCESS
+Windows.Wdk.Storage.FileSystem.FILE_RESERVE_OPFILTER
+Windows.Wdk.Storage.FileSystem.FILE_SEQUENTIAL_ONLY
+Windows.Wdk.Storage.FileSystem.FILE_SESSION_AWARE
+Windows.Wdk.Storage.FileSystem.FILE_SUPERSEDE
+Windows.Wdk.Storage.FileSystem.FILE_SYNCHRONOUS_IO_ALERT
+Windows.Wdk.Storage.FileSystem.FILE_SYNCHRONOUS_IO_NONALERT
+Windows.Wdk.Storage.FileSystem.FILE_WRITE_THROUGH
+Windows.Wdk.Storage.FileSystem.NtCreateFile
+Windows.Wdk.Storage.FileSystem.NTCREATEFILE_CREATE_DISPOSITION
+Windows.Wdk.Storage.FileSystem.NTCREATEFILE_CREATE_OPTIONS
+Windows.Wdk.Storage.FileSystem.NtReadFile
+Windows.Wdk.Storage.FileSystem.NtWriteFile
+Windows.Wdk.Storage.FileSystem.SYMLINK_FLAG_RELATIVE
+Windows.Win32.Foundation.BOOL
+Windows.Win32.Foundation.BOOLEAN
+Windows.Win32.Foundation.CloseHandle
+Windows.Win32.Foundation.DNS_ERROR_ADDRESS_REQUIRED
+Windows.Win32.Foundation.DNS_ERROR_ALIAS_LOOP
+Windows.Win32.Foundation.DNS_ERROR_AUTOZONE_ALREADY_EXISTS
+Windows.Win32.Foundation.DNS_ERROR_AXFR
+Windows.Win32.Foundation.DNS_ERROR_BACKGROUND_LOADING
+Windows.Win32.Foundation.DNS_ERROR_BAD_KEYMASTER
+Windows.Win32.Foundation.DNS_ERROR_BAD_PACKET
+Windows.Win32.Foundation.DNS_ERROR_CANNOT_FIND_ROOT_HINTS
+Windows.Win32.Foundation.DNS_ERROR_CLIENT_SUBNET_ALREADY_EXISTS
+Windows.Win32.Foundation.DNS_ERROR_CLIENT_SUBNET_DOES_NOT_EXIST
+Windows.Win32.Foundation.DNS_ERROR_CLIENT_SUBNET_IS_ACCESSED
+Windows.Win32.Foundation.DNS_ERROR_CNAME_COLLISION
+Windows.Win32.Foundation.DNS_ERROR_CNAME_LOOP
+Windows.Win32.Foundation.DNS_ERROR_DATAFILE_OPEN_FAILURE
+Windows.Win32.Foundation.DNS_ERROR_DATAFILE_PARSING
+Windows.Win32.Foundation.DNS_ERROR_DEFAULT_SCOPE
+Windows.Win32.Foundation.DNS_ERROR_DEFAULT_VIRTUALIZATION_INSTANCE
+Windows.Win32.Foundation.DNS_ERROR_DEFAULT_ZONESCOPE
+Windows.Win32.Foundation.DNS_ERROR_DELEGATION_REQUIRED
+Windows.Win32.Foundation.DNS_ERROR_DNAME_COLLISION
+Windows.Win32.Foundation.DNS_ERROR_DNSSEC_IS_DISABLED
+Windows.Win32.Foundation.DNS_ERROR_DP_ALREADY_ENLISTED
+Windows.Win32.Foundation.DNS_ERROR_DP_ALREADY_EXISTS
+Windows.Win32.Foundation.DNS_ERROR_DP_DOES_NOT_EXIST
+Windows.Win32.Foundation.DNS_ERROR_DP_FSMO_ERROR
+Windows.Win32.Foundation.DNS_ERROR_DP_NOT_AVAILABLE
+Windows.Win32.Foundation.DNS_ERROR_DP_NOT_ENLISTED
+Windows.Win32.Foundation.DNS_ERROR_DS_UNAVAILABLE
+Windows.Win32.Foundation.DNS_ERROR_DS_ZONE_ALREADY_EXISTS
+Windows.Win32.Foundation.DNS_ERROR_DWORD_VALUE_TOO_LARGE
+Windows.Win32.Foundation.DNS_ERROR_DWORD_VALUE_TOO_SMALL
+Windows.Win32.Foundation.DNS_ERROR_FILE_WRITEBACK_FAILED
+Windows.Win32.Foundation.DNS_ERROR_FORWARDER_ALREADY_EXISTS
+Windows.Win32.Foundation.DNS_ERROR_INCONSISTENT_ROOT_HINTS
+Windows.Win32.Foundation.DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME
+Windows.Win32.Foundation.DNS_ERROR_INVALID_CLIENT_SUBNET_NAME
+Windows.Win32.Foundation.DNS_ERROR_INVALID_DATA
+Windows.Win32.Foundation.DNS_ERROR_INVALID_DATAFILE_NAME
+Windows.Win32.Foundation.DNS_ERROR_INVALID_INITIAL_ROLLOVER_OFFSET
+Windows.Win32.Foundation.DNS_ERROR_INVALID_IP_ADDRESS
+Windows.Win32.Foundation.DNS_ERROR_INVALID_KEY_SIZE
+Windows.Win32.Foundation.DNS_ERROR_INVALID_NAME
+Windows.Win32.Foundation.DNS_ERROR_INVALID_NAME_CHAR
+Windows.Win32.Foundation.DNS_ERROR_INVALID_NSEC3_ITERATION_COUNT
+Windows.Win32.Foundation.DNS_ERROR_INVALID_POLICY_TABLE
+Windows.Win32.Foundation.DNS_ERROR_INVALID_PROPERTY
+Windows.Win32.Foundation.DNS_ERROR_INVALID_ROLLOVER_PERIOD
+Windows.Win32.Foundation.DNS_ERROR_INVALID_SCOPE_NAME
+Windows.Win32.Foundation.DNS_ERROR_INVALID_SCOPE_OPERATION
+Windows.Win32.Foundation.DNS_ERROR_INVALID_SIGNATURE_VALIDITY_PERIOD
+Windows.Win32.Foundation.DNS_ERROR_INVALID_TYPE
+Windows.Win32.Foundation.DNS_ERROR_INVALID_XML
+Windows.Win32.Foundation.DNS_ERROR_INVALID_ZONE_OPERATION
+Windows.Win32.Foundation.DNS_ERROR_INVALID_ZONE_TYPE
+Windows.Win32.Foundation.DNS_ERROR_INVALID_ZONESCOPE_NAME
+Windows.Win32.Foundation.DNS_ERROR_KEYMASTER_REQUIRED
+Windows.Win32.Foundation.DNS_ERROR_KSP_DOES_NOT_SUPPORT_PROTECTION
+Windows.Win32.Foundation.DNS_ERROR_KSP_NOT_ACCESSIBLE
+Windows.Win32.Foundation.DNS_ERROR_LOAD_ZONESCOPE_FAILED
+Windows.Win32.Foundation.DNS_ERROR_NAME_DOES_NOT_EXIST
+Windows.Win32.Foundation.DNS_ERROR_NAME_NOT_IN_ZONE
+Windows.Win32.Foundation.DNS_ERROR_NBSTAT_INIT_FAILED
+Windows.Win32.Foundation.DNS_ERROR_NEED_SECONDARY_ADDRESSES
+Windows.Win32.Foundation.DNS_ERROR_NEED_WINS_SERVERS
+Windows.Win32.Foundation.DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE
+Windows.Win32.Foundation.DNS_ERROR_NO_CREATE_CACHE_DATA
+Windows.Win32.Foundation.DNS_ERROR_NO_DNS_SERVERS
+Windows.Win32.Foundation.DNS_ERROR_NO_MEMORY
+Windows.Win32.Foundation.DNS_ERROR_NO_PACKET
+Windows.Win32.Foundation.DNS_ERROR_NO_TCPIP
+Windows.Win32.Foundation.DNS_ERROR_NO_VALID_TRUST_ANCHORS
+Windows.Win32.Foundation.DNS_ERROR_NO_ZONE_INFO
+Windows.Win32.Foundation.DNS_ERROR_NODE_CREATION_FAILED
+Windows.Win32.Foundation.DNS_ERROR_NODE_IS_CNAME
+Windows.Win32.Foundation.DNS_ERROR_NODE_IS_DNAME
+Windows.Win32.Foundation.DNS_ERROR_NON_RFC_NAME
+Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_ON_ACTIVE_SKD
+Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_ON_RODC
+Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER
+Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_ON_SIGNED_ZONE
+Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_ON_UNSIGNED_ZONE
+Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_ON_ZSK
+Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION
+Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_UNDER_DNAME
+Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_WITH_ZONESCOPES
+Windows.Win32.Foundation.DNS_ERROR_NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS
+Windows.Win32.Foundation.DNS_ERROR_NOT_UNIQUE
+Windows.Win32.Foundation.DNS_ERROR_NSEC3_INCOMPATIBLE_WITH_RSA_SHA1
+Windows.Win32.Foundation.DNS_ERROR_NSEC3_NAME_COLLISION
+Windows.Win32.Foundation.DNS_ERROR_NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1
+Windows.Win32.Foundation.DNS_ERROR_NUMERIC_NAME
+Windows.Win32.Foundation.DNS_ERROR_POLICY_ALREADY_EXISTS
+Windows.Win32.Foundation.DNS_ERROR_POLICY_DOES_NOT_EXIST
+Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA
+Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_CLIENT_SUBNET
+Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_FQDN
+Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_INTERFACE
+Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_NETWORK_PROTOCOL
+Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_QUERY_TYPE
+Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_TIME_OF_DAY
+Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_TRANSPORT_PROTOCOL
+Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_NAME
+Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_SETTINGS
+Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_WEIGHT
+Windows.Win32.Foundation.DNS_ERROR_POLICY_LOCKED
+Windows.Win32.Foundation.DNS_ERROR_POLICY_MISSING_CRITERIA
+Windows.Win32.Foundation.DNS_ERROR_POLICY_PROCESSING_ORDER_INVALID
+Windows.Win32.Foundation.DNS_ERROR_POLICY_SCOPE_MISSING
+Windows.Win32.Foundation.DNS_ERROR_POLICY_SCOPE_NOT_ALLOWED
+Windows.Win32.Foundation.DNS_ERROR_PRIMARY_REQUIRES_DATAFILE
+Windows.Win32.Foundation.DNS_ERROR_RCODE
+Windows.Win32.Foundation.DNS_ERROR_RCODE_BADKEY
+Windows.Win32.Foundation.DNS_ERROR_RCODE_BADSIG
+Windows.Win32.Foundation.DNS_ERROR_RCODE_BADTIME
+Windows.Win32.Foundation.DNS_ERROR_RCODE_FORMAT_ERROR
+Windows.Win32.Foundation.DNS_ERROR_RCODE_NAME_ERROR
+Windows.Win32.Foundation.DNS_ERROR_RCODE_NOT_IMPLEMENTED
+Windows.Win32.Foundation.DNS_ERROR_RCODE_NOTAUTH
+Windows.Win32.Foundation.DNS_ERROR_RCODE_NOTZONE
+Windows.Win32.Foundation.DNS_ERROR_RCODE_NXRRSET
+Windows.Win32.Foundation.DNS_ERROR_RCODE_REFUSED
+Windows.Win32.Foundation.DNS_ERROR_RCODE_SERVER_FAILURE
+Windows.Win32.Foundation.DNS_ERROR_RCODE_YXDOMAIN
+Windows.Win32.Foundation.DNS_ERROR_RCODE_YXRRSET
+Windows.Win32.Foundation.DNS_ERROR_RECORD_ALREADY_EXISTS
+Windows.Win32.Foundation.DNS_ERROR_RECORD_DOES_NOT_EXIST
+Windows.Win32.Foundation.DNS_ERROR_RECORD_FORMAT
+Windows.Win32.Foundation.DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT
+Windows.Win32.Foundation.DNS_ERROR_RECORD_TIMED_OUT
+Windows.Win32.Foundation.DNS_ERROR_ROLLOVER_ALREADY_QUEUED
+Windows.Win32.Foundation.DNS_ERROR_ROLLOVER_IN_PROGRESS
+Windows.Win32.Foundation.DNS_ERROR_ROLLOVER_NOT_POKEABLE
+Windows.Win32.Foundation.DNS_ERROR_RRL_INVALID_IPV4_PREFIX
+Windows.Win32.Foundation.DNS_ERROR_RRL_INVALID_IPV6_PREFIX
+Windows.Win32.Foundation.DNS_ERROR_RRL_INVALID_LEAK_RATE
+Windows.Win32.Foundation.DNS_ERROR_RRL_INVALID_TC_RATE
+Windows.Win32.Foundation.DNS_ERROR_RRL_INVALID_WINDOW_SIZE
+Windows.Win32.Foundation.DNS_ERROR_RRL_LEAK_RATE_LESSTHAN_TC_RATE
+Windows.Win32.Foundation.DNS_ERROR_RRL_NOT_ENABLED
+Windows.Win32.Foundation.DNS_ERROR_SCOPE_ALREADY_EXISTS
+Windows.Win32.Foundation.DNS_ERROR_SCOPE_DOES_NOT_EXIST
+Windows.Win32.Foundation.DNS_ERROR_SCOPE_LOCKED
+Windows.Win32.Foundation.DNS_ERROR_SECONDARY_DATA
+Windows.Win32.Foundation.DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP
+Windows.Win32.Foundation.DNS_ERROR_SERVERSCOPE_IS_REFERENCED
+Windows.Win32.Foundation.DNS_ERROR_SIGNING_KEY_NOT_ACCESSIBLE
+Windows.Win32.Foundation.DNS_ERROR_SOA_DELETE_INVALID
+Windows.Win32.Foundation.DNS_ERROR_STANDBY_KEY_NOT_PRESENT
+Windows.Win32.Foundation.DNS_ERROR_SUBNET_ALREADY_EXISTS
+Windows.Win32.Foundation.DNS_ERROR_SUBNET_DOES_NOT_EXIST
+Windows.Win32.Foundation.DNS_ERROR_TOO_MANY_SKDS
+Windows.Win32.Foundation.DNS_ERROR_TRY_AGAIN_LATER
+Windows.Win32.Foundation.DNS_ERROR_UNEXPECTED_CNG_ERROR
+Windows.Win32.Foundation.DNS_ERROR_UNEXPECTED_DATA_PROTECTION_ERROR
+Windows.Win32.Foundation.DNS_ERROR_UNKNOWN_RECORD_TYPE
+Windows.Win32.Foundation.DNS_ERROR_UNKNOWN_SIGNING_PARAMETER_VERSION
+Windows.Win32.Foundation.DNS_ERROR_UNSECURE_PACKET
+Windows.Win32.Foundation.DNS_ERROR_UNSUPPORTED_ALGORITHM
+Windows.Win32.Foundation.DNS_ERROR_VIRTUALIZATION_INSTANCE_ALREADY_EXISTS
+Windows.Win32.Foundation.DNS_ERROR_VIRTUALIZATION_INSTANCE_DOES_NOT_EXIST
+Windows.Win32.Foundation.DNS_ERROR_VIRTUALIZATION_TREE_LOCKED
+Windows.Win32.Foundation.DNS_ERROR_WINS_INIT_FAILED
+Windows.Win32.Foundation.DNS_ERROR_ZONE_ALREADY_EXISTS
+Windows.Win32.Foundation.DNS_ERROR_ZONE_CONFIGURATION_ERROR
+Windows.Win32.Foundation.DNS_ERROR_ZONE_CREATION_FAILED
+Windows.Win32.Foundation.DNS_ERROR_ZONE_DOES_NOT_EXIST
+Windows.Win32.Foundation.DNS_ERROR_ZONE_HAS_NO_NS_RECORDS
+Windows.Win32.Foundation.DNS_ERROR_ZONE_HAS_NO_SOA_RECORD
+Windows.Win32.Foundation.DNS_ERROR_ZONE_IS_SHUTDOWN
+Windows.Win32.Foundation.DNS_ERROR_ZONE_LOCKED
+Windows.Win32.Foundation.DNS_ERROR_ZONE_LOCKED_FOR_SIGNING
+Windows.Win32.Foundation.DNS_ERROR_ZONE_NOT_SECONDARY
+Windows.Win32.Foundation.DNS_ERROR_ZONE_REQUIRES_MASTER_IP
+Windows.Win32.Foundation.DNS_ERROR_ZONESCOPE_ALREADY_EXISTS
+Windows.Win32.Foundation.DNS_ERROR_ZONESCOPE_DOES_NOT_EXIST
+Windows.Win32.Foundation.DNS_ERROR_ZONESCOPE_FILE_WRITEBACK_FAILED
+Windows.Win32.Foundation.DNS_ERROR_ZONESCOPE_IS_REFERENCED
+Windows.Win32.Foundation.DUPLICATE_CLOSE_SOURCE
+Windows.Win32.Foundation.DUPLICATE_HANDLE_OPTIONS
+Windows.Win32.Foundation.DUPLICATE_SAME_ACCESS
+Windows.Win32.Foundation.DuplicateHandle
+Windows.Win32.Foundation.E_NOTIMPL
+Windows.Win32.Foundation.ERROR_ABANDON_HIBERFILE
+Windows.Win32.Foundation.ERROR_ABANDONED_WAIT_0
+Windows.Win32.Foundation.ERROR_ABANDONED_WAIT_63
+Windows.Win32.Foundation.ERROR_ABIOS_ERROR
+Windows.Win32.Foundation.ERROR_ACCESS_AUDIT_BY_POLICY
+Windows.Win32.Foundation.ERROR_ACCESS_DENIED
+Windows.Win32.Foundation.ERROR_ACCESS_DENIED_APPDATA
+Windows.Win32.Foundation.ERROR_ACCESS_DISABLED_BY_POLICY
+Windows.Win32.Foundation.ERROR_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY
+Windows.Win32.Foundation.ERROR_ACCESS_DISABLED_WEBBLADE
+Windows.Win32.Foundation.ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER
+Windows.Win32.Foundation.ERROR_ACCOUNT_DISABLED
+Windows.Win32.Foundation.ERROR_ACCOUNT_EXPIRED
+Windows.Win32.Foundation.ERROR_ACCOUNT_LOCKED_OUT
+Windows.Win32.Foundation.ERROR_ACCOUNT_RESTRICTION
+Windows.Win32.Foundation.ERROR_ACPI_ERROR
+Windows.Win32.Foundation.ERROR_ACTIVE_CONNECTIONS
+Windows.Win32.Foundation.ERROR_ADAP_HDW_ERR
+Windows.Win32.Foundation.ERROR_ADDRESS_ALREADY_ASSOCIATED
+Windows.Win32.Foundation.ERROR_ADDRESS_NOT_ASSOCIATED
+Windows.Win32.Foundation.ERROR_ALERTED
+Windows.Win32.Foundation.ERROR_ALIAS_EXISTS
+Windows.Win32.Foundation.ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED
+Windows.Win32.Foundation.ERROR_ALLOCATE_BUCKET
+Windows.Win32.Foundation.ERROR_ALLOTTED_SPACE_EXCEEDED
+Windows.Win32.Foundation.ERROR_ALREADY_ASSIGNED
+Windows.Win32.Foundation.ERROR_ALREADY_EXISTS
+Windows.Win32.Foundation.ERROR_ALREADY_FIBER
+Windows.Win32.Foundation.ERROR_ALREADY_HAS_STREAM_ID
+Windows.Win32.Foundation.ERROR_ALREADY_INITIALIZED
+Windows.Win32.Foundation.ERROR_ALREADY_REGISTERED
+Windows.Win32.Foundation.ERROR_ALREADY_RUNNING_LKG
+Windows.Win32.Foundation.ERROR_ALREADY_THREAD
+Windows.Win32.Foundation.ERROR_ALREADY_WAITING
+Windows.Win32.Foundation.ERROR_ALREADY_WIN32
+Windows.Win32.Foundation.ERROR_API_UNAVAILABLE
+Windows.Win32.Foundation.ERROR_APP_HANG
+Windows.Win32.Foundation.ERROR_APP_INIT_FAILURE
+Windows.Win32.Foundation.ERROR_APP_WRONG_OS
+Windows.Win32.Foundation.ERROR_APPCONTAINER_REQUIRED
+Windows.Win32.Foundation.ERROR_APPEXEC_APP_COMPAT_BLOCK
+Windows.Win32.Foundation.ERROR_APPEXEC_CALLER_WAIT_TIMEOUT
+Windows.Win32.Foundation.ERROR_APPEXEC_CALLER_WAIT_TIMEOUT_LICENSING
+Windows.Win32.Foundation.ERROR_APPEXEC_CALLER_WAIT_TIMEOUT_RESOURCES
+Windows.Win32.Foundation.ERROR_APPEXEC_CALLER_WAIT_TIMEOUT_TERMINATION
+Windows.Win32.Foundation.ERROR_APPEXEC_CONDITION_NOT_SATISFIED
+Windows.Win32.Foundation.ERROR_APPEXEC_HANDLE_INVALIDATED
+Windows.Win32.Foundation.ERROR_APPEXEC_HOST_ID_MISMATCH
+Windows.Win32.Foundation.ERROR_APPEXEC_INVALID_HOST_GENERATION
+Windows.Win32.Foundation.ERROR_APPEXEC_INVALID_HOST_STATE
+Windows.Win32.Foundation.ERROR_APPEXEC_NO_DONOR
+Windows.Win32.Foundation.ERROR_APPEXEC_UNEXPECTED_PROCESS_REGISTRATION
+Windows.Win32.Foundation.ERROR_APPEXEC_UNKNOWN_USER
+Windows.Win32.Foundation.ERROR_APPHELP_BLOCK
+Windows.Win32.Foundation.ERROR_APPX_FILE_NOT_ENCRYPTED
+Windows.Win32.Foundation.ERROR_ARBITRATION_UNHANDLED
+Windows.Win32.Foundation.ERROR_ARENA_TRASHED
+Windows.Win32.Foundation.ERROR_ARITHMETIC_OVERFLOW
+Windows.Win32.Foundation.ERROR_ASSERTION_FAILURE
+Windows.Win32.Foundation.ERROR_ATOMIC_LOCKS_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_AUDIT_FAILED
+Windows.Win32.Foundation.ERROR_AUTHENTICATION_FIREWALL_FAILED
+Windows.Win32.Foundation.ERROR_AUTHIP_FAILURE
+Windows.Win32.Foundation.ERROR_AUTODATASEG_EXCEEDS_64k
+Windows.Win32.Foundation.ERROR_BACKUP_CONTROLLER
+Windows.Win32.Foundation.ERROR_BAD_ACCESSOR_FLAGS
+Windows.Win32.Foundation.ERROR_BAD_ARGUMENTS
+Windows.Win32.Foundation.ERROR_BAD_COMMAND
+Windows.Win32.Foundation.ERROR_BAD_COMPRESSION_BUFFER
+Windows.Win32.Foundation.ERROR_BAD_CONFIGURATION
+Windows.Win32.Foundation.ERROR_BAD_CURRENT_DIRECTORY
+Windows.Win32.Foundation.ERROR_BAD_DESCRIPTOR_FORMAT
+Windows.Win32.Foundation.ERROR_BAD_DEV_TYPE
+Windows.Win32.Foundation.ERROR_BAD_DEVICE
+Windows.Win32.Foundation.ERROR_BAD_DEVICE_PATH
+Windows.Win32.Foundation.ERROR_BAD_DLL_ENTRYPOINT
+Windows.Win32.Foundation.ERROR_BAD_DRIVER_LEVEL
+Windows.Win32.Foundation.ERROR_BAD_ENVIRONMENT
+Windows.Win32.Foundation.ERROR_BAD_EXE_FORMAT
+Windows.Win32.Foundation.ERROR_BAD_FILE_TYPE
+Windows.Win32.Foundation.ERROR_BAD_FORMAT
+Windows.Win32.Foundation.ERROR_BAD_FUNCTION_TABLE
+Windows.Win32.Foundation.ERROR_BAD_IMPERSONATION_LEVEL
+Windows.Win32.Foundation.ERROR_BAD_INHERITANCE_ACL
+Windows.Win32.Foundation.ERROR_BAD_LENGTH
+Windows.Win32.Foundation.ERROR_BAD_LOGON_SESSION_STATE
+Windows.Win32.Foundation.ERROR_BAD_MCFG_TABLE
+Windows.Win32.Foundation.ERROR_BAD_NET_NAME
+Windows.Win32.Foundation.ERROR_BAD_NET_RESP
+Windows.Win32.Foundation.ERROR_BAD_NETPATH
+Windows.Win32.Foundation.ERROR_BAD_PATHNAME
+Windows.Win32.Foundation.ERROR_BAD_PIPE
+Windows.Win32.Foundation.ERROR_BAD_PROFILE
+Windows.Win32.Foundation.ERROR_BAD_PROVIDER
+Windows.Win32.Foundation.ERROR_BAD_QUERY_SYNTAX
+Windows.Win32.Foundation.ERROR_BAD_RECOVERY_POLICY
+Windows.Win32.Foundation.ERROR_BAD_REM_ADAP
+Windows.Win32.Foundation.ERROR_BAD_SERVICE_ENTRYPOINT
+Windows.Win32.Foundation.ERROR_BAD_STACK
+Windows.Win32.Foundation.ERROR_BAD_THREADID_ADDR
+Windows.Win32.Foundation.ERROR_BAD_TOKEN_TYPE
+Windows.Win32.Foundation.ERROR_BAD_UNIT
+Windows.Win32.Foundation.ERROR_BAD_USER_PROFILE
+Windows.Win32.Foundation.ERROR_BAD_USERNAME
+Windows.Win32.Foundation.ERROR_BAD_VALIDATION_CLASS
+Windows.Win32.Foundation.ERROR_BADDB
+Windows.Win32.Foundation.ERROR_BADKEY
+Windows.Win32.Foundation.ERROR_BADSTARTPOSITION
+Windows.Win32.Foundation.ERROR_BEGINNING_OF_MEDIA
+Windows.Win32.Foundation.ERROR_BEYOND_VDL
+Windows.Win32.Foundation.ERROR_BIOS_FAILED_TO_CONNECT_INTERRUPT
+Windows.Win32.Foundation.ERROR_BLOCK_SHARED
+Windows.Win32.Foundation.ERROR_BLOCK_SOURCE_WEAK_REFERENCE_INVALID
+Windows.Win32.Foundation.ERROR_BLOCK_TARGET_WEAK_REFERENCE_INVALID
+Windows.Win32.Foundation.ERROR_BLOCK_TOO_MANY_REFERENCES
+Windows.Win32.Foundation.ERROR_BLOCK_WEAK_REFERENCE_INVALID
+Windows.Win32.Foundation.ERROR_BLOCKED_BY_PARENTAL_CONTROLS
+Windows.Win32.Foundation.ERROR_BOOT_ALREADY_ACCEPTED
+Windows.Win32.Foundation.ERROR_BROKEN_PIPE
+Windows.Win32.Foundation.ERROR_BUFFER_ALL_ZEROS
+Windows.Win32.Foundation.ERROR_BUFFER_OVERFLOW
+Windows.Win32.Foundation.ERROR_BUS_RESET
+Windows.Win32.Foundation.ERROR_BUSY
+Windows.Win32.Foundation.ERROR_BUSY_DRIVE
+Windows.Win32.Foundation.ERROR_BYPASSIO_FLT_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_CACHE_PAGE_LOCKED
+Windows.Win32.Foundation.ERROR_CALL_NOT_IMPLEMENTED
+Windows.Win32.Foundation.ERROR_CALLBACK_INVOKE_INLINE
+Windows.Win32.Foundation.ERROR_CALLBACK_POP_STACK
+Windows.Win32.Foundation.ERROR_CALLBACK_SUPPLIED_INVALID_DATA
+Windows.Win32.Foundation.ERROR_CAN_NOT_COMPLETE
+Windows.Win32.Foundation.ERROR_CANCEL_VIOLATION
+Windows.Win32.Foundation.ERROR_CANCELLED
+Windows.Win32.Foundation.ERROR_CANNOT_BREAK_OPLOCK
+Windows.Win32.Foundation.ERROR_CANNOT_COPY
+Windows.Win32.Foundation.ERROR_CANNOT_DETECT_DRIVER_FAILURE
+Windows.Win32.Foundation.ERROR_CANNOT_DETECT_PROCESS_ABORT
+Windows.Win32.Foundation.ERROR_CANNOT_FIND_WND_CLASS
+Windows.Win32.Foundation.ERROR_CANNOT_GRANT_REQUESTED_OPLOCK
+Windows.Win32.Foundation.ERROR_CANNOT_IMPERSONATE
+Windows.Win32.Foundation.ERROR_CANNOT_LOAD_REGISTRY_FILE
+Windows.Win32.Foundation.ERROR_CANNOT_MAKE
+Windows.Win32.Foundation.ERROR_CANNOT_OPEN_PROFILE
+Windows.Win32.Foundation.ERROR_CANT_ACCESS_DOMAIN_INFO
+Windows.Win32.Foundation.ERROR_CANT_ACCESS_FILE
+Windows.Win32.Foundation.ERROR_CANT_CLEAR_ENCRYPTION_FLAG
+Windows.Win32.Foundation.ERROR_CANT_DISABLE_MANDATORY
+Windows.Win32.Foundation.ERROR_CANT_ENABLE_DENY_ONLY
+Windows.Win32.Foundation.ERROR_CANT_OPEN_ANONYMOUS
+Windows.Win32.Foundation.ERROR_CANT_RESOLVE_FILENAME
+Windows.Win32.Foundation.ERROR_CANT_TERMINATE_SELF
+Windows.Win32.Foundation.ERROR_CANT_WAIT
+Windows.Win32.Foundation.ERROR_CANTFETCHBACKWARDS
+Windows.Win32.Foundation.ERROR_CANTOPEN
+Windows.Win32.Foundation.ERROR_CANTREAD
+Windows.Win32.Foundation.ERROR_CANTSCROLLBACKWARDS
+Windows.Win32.Foundation.ERROR_CANTWRITE
+Windows.Win32.Foundation.ERROR_CAPAUTHZ_CHANGE_TYPE
+Windows.Win32.Foundation.ERROR_CAPAUTHZ_DB_CORRUPTED
+Windows.Win32.Foundation.ERROR_CAPAUTHZ_NO_POLICY
+Windows.Win32.Foundation.ERROR_CAPAUTHZ_NOT_AUTHORIZED
+Windows.Win32.Foundation.ERROR_CAPAUTHZ_NOT_DEVUNLOCKED
+Windows.Win32.Foundation.ERROR_CAPAUTHZ_NOT_PROVISIONED
+Windows.Win32.Foundation.ERROR_CAPAUTHZ_SCCD_DEV_MODE_REQUIRED
+Windows.Win32.Foundation.ERROR_CAPAUTHZ_SCCD_INVALID_CATALOG
+Windows.Win32.Foundation.ERROR_CAPAUTHZ_SCCD_NO_AUTH_ENTITY
+Windows.Win32.Foundation.ERROR_CAPAUTHZ_SCCD_NO_CAPABILITY_MATCH
+Windows.Win32.Foundation.ERROR_CAPAUTHZ_SCCD_PARSE_ERROR
+Windows.Win32.Foundation.ERROR_CARDBUS_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_CASE_DIFFERING_NAMES_IN_DIR
+Windows.Win32.Foundation.ERROR_CASE_SENSITIVE_PATH
+Windows.Win32.Foundation.ERROR_CERTIFICATE_VALIDATION_PREFERENCE_CONFLICT
+Windows.Win32.Foundation.ERROR_CHECKING_FILE_SYSTEM
+Windows.Win32.Foundation.ERROR_CHECKOUT_REQUIRED
+Windows.Win32.Foundation.ERROR_CHILD_MUST_BE_VOLATILE
+Windows.Win32.Foundation.ERROR_CHILD_NOT_COMPLETE
+Windows.Win32.Foundation.ERROR_CHILD_PROCESS_BLOCKED
+Windows.Win32.Foundation.ERROR_CHILD_WINDOW_MENU
+Windows.Win32.Foundation.ERROR_CIMFS_IMAGE_CORRUPT
+Windows.Win32.Foundation.ERROR_CIMFS_IMAGE_VERSION_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_CIRCULAR_DEPENDENCY
+Windows.Win32.Foundation.ERROR_CLASS_ALREADY_EXISTS
+Windows.Win32.Foundation.ERROR_CLASS_DOES_NOT_EXIST
+Windows.Win32.Foundation.ERROR_CLASS_HAS_WINDOWS
+Windows.Win32.Foundation.ERROR_CLIENT_SERVER_PARAMETERS_INVALID
+Windows.Win32.Foundation.ERROR_CLIPBOARD_NOT_OPEN
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_ACCESS_DENIED
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_ALREADY_CONNECTED
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_AUTHENTICATION_FAILED
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_CONNECTED_PROVIDER_ONLY
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_DEHYDRATION_DISALLOWED
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_IN_USE
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_INCOMPATIBLE_HARDLINKS
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_INSUFFICIENT_RESOURCES
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_INVALID_REQUEST
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_METADATA_CORRUPT
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_METADATA_TOO_LARGE
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_NETWORK_UNAVAILABLE
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_NOT_IN_SYNC
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_NOT_UNDER_SYNC_ROOT
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_PINNED
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROPERTY_BLOB_CHECKSUM_MISMATCH
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROPERTY_BLOB_TOO_LARGE
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROPERTY_CORRUPT
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROPERTY_LOCK_CONFLICT
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROPERTY_VERSION_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROVIDER_NOT_RUNNING
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROVIDER_TERMINATED
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_READ_ONLY_VOLUME
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_REQUEST_ABORTED
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_REQUEST_CANCELED
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_REQUEST_TIMEOUT
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_SYNC_ROOT_METADATA_CORRUPT
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_TOO_MANY_PROPERTY_BLOBS
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_UNSUCCESSFUL
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_US_MESSAGE_TIMEOUT
+Windows.Win32.Foundation.ERROR_CLOUD_FILE_VALIDATION_FAILED
+Windows.Win32.Foundation.ERROR_COMMITMENT_LIMIT
+Windows.Win32.Foundation.ERROR_COMMITMENT_MINIMUM
+Windows.Win32.Foundation.ERROR_COMPRESSED_FILE_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_COMPRESSION_DISABLED
+Windows.Win32.Foundation.ERROR_COMPRESSION_NOT_BENEFICIAL
+Windows.Win32.Foundation.ERROR_CONNECTED_OTHER_PASSWORD
+Windows.Win32.Foundation.ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT
+Windows.Win32.Foundation.ERROR_CONNECTION_ABORTED
+Windows.Win32.Foundation.ERROR_CONNECTION_ACTIVE
+Windows.Win32.Foundation.ERROR_CONNECTION_COUNT_LIMIT
+Windows.Win32.Foundation.ERROR_CONNECTION_INVALID
+Windows.Win32.Foundation.ERROR_CONNECTION_REFUSED
+Windows.Win32.Foundation.ERROR_CONNECTION_UNAVAIL
+Windows.Win32.Foundation.ERROR_CONTAINER_ASSIGNED
+Windows.Win32.Foundation.ERROR_CONTENT_BLOCKED
+Windows.Win32.Foundation.ERROR_CONTEXT_EXPIRED
+Windows.Win32.Foundation.ERROR_CONTINUE
+Windows.Win32.Foundation.ERROR_CONTROL_C_EXIT
+Windows.Win32.Foundation.ERROR_CONTROL_ID_NOT_FOUND
+Windows.Win32.Foundation.ERROR_CONVERT_TO_LARGE
+Windows.Win32.Foundation.ERROR_CORRUPT_LOG_CLEARED
+Windows.Win32.Foundation.ERROR_CORRUPT_LOG_CORRUPTED
+Windows.Win32.Foundation.ERROR_CORRUPT_LOG_DELETED_FULL
+Windows.Win32.Foundation.ERROR_CORRUPT_LOG_OVERFULL
+Windows.Win32.Foundation.ERROR_CORRUPT_LOG_UNAVAILABLE
+Windows.Win32.Foundation.ERROR_CORRUPT_SYSTEM_FILE
+Windows.Win32.Foundation.ERROR_COULD_NOT_INTERPRET
+Windows.Win32.Foundation.ERROR_COUNTER_TIMEOUT
+Windows.Win32.Foundation.ERROR_CPU_SET_INVALID
+Windows.Win32.Foundation.ERROR_CRASH_DUMP
+Windows.Win32.Foundation.ERROR_CRC
+Windows.Win32.Foundation.ERROR_CREATE_FAILED
+Windows.Win32.Foundation.ERROR_CROSS_PARTITION_VIOLATION
+Windows.Win32.Foundation.ERROR_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE
+Windows.Win32.Foundation.ERROR_CS_ENCRYPTION_FILE_NOT_CSE
+Windows.Win32.Foundation.ERROR_CS_ENCRYPTION_INVALID_SERVER_RESPONSE
+Windows.Win32.Foundation.ERROR_CS_ENCRYPTION_NEW_ENCRYPTED_FILE
+Windows.Win32.Foundation.ERROR_CS_ENCRYPTION_UNSUPPORTED_SERVER
+Windows.Win32.Foundation.ERROR_CSCSHARE_OFFLINE
+Windows.Win32.Foundation.ERROR_CTX_CLIENT_QUERY_TIMEOUT
+Windows.Win32.Foundation.ERROR_CTX_MODEM_RESPONSE_TIMEOUT
+Windows.Win32.Foundation.ERROR_CURRENT_DIRECTORY
+Windows.Win32.Foundation.ERROR_CURRENT_DOMAIN_NOT_ALLOWED
+Windows.Win32.Foundation.ERROR_DATA_CHECKSUM_ERROR
+Windows.Win32.Foundation.ERROR_DATA_NOT_ACCEPTED
+Windows.Win32.Foundation.ERROR_DATABASE_DOES_NOT_EXIST
+Windows.Win32.Foundation.ERROR_DATATYPE_MISMATCH
+Windows.Win32.Foundation.ERROR_DAX_MAPPING_EXISTS
+Windows.Win32.Foundation.ERROR_DBG_COMMAND_EXCEPTION
+Windows.Win32.Foundation.ERROR_DBG_CONTINUE
+Windows.Win32.Foundation.ERROR_DBG_CONTROL_BREAK
+Windows.Win32.Foundation.ERROR_DBG_CONTROL_C
+Windows.Win32.Foundation.ERROR_DBG_EXCEPTION_HANDLED
+Windows.Win32.Foundation.ERROR_DBG_EXCEPTION_NOT_HANDLED
+Windows.Win32.Foundation.ERROR_DBG_PRINTEXCEPTION_C
+Windows.Win32.Foundation.ERROR_DBG_REPLY_LATER
+Windows.Win32.Foundation.ERROR_DBG_RIPEXCEPTION
+Windows.Win32.Foundation.ERROR_DBG_TERMINATE_PROCESS
+Windows.Win32.Foundation.ERROR_DBG_TERMINATE_THREAD
+Windows.Win32.Foundation.ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE
+Windows.Win32.Foundation.ERROR_DC_NOT_FOUND
+Windows.Win32.Foundation.ERROR_DDE_FAIL
+Windows.Win32.Foundation.ERROR_DEBUG_ATTACH_FAILED
+Windows.Win32.Foundation.ERROR_DEBUGGER_INACTIVE
+Windows.Win32.Foundation.ERROR_DECRYPTION_FAILED
+Windows.Win32.Foundation.ERROR_DELAY_LOAD_FAILED
+Windows.Win32.Foundation.ERROR_DELETE_PENDING
+Windows.Win32.Foundation.ERROR_DEPENDENT_SERVICES_RUNNING
+Windows.Win32.Foundation.ERROR_DESTINATION_ELEMENT_FULL
+Windows.Win32.Foundation.ERROR_DESTROY_OBJECT_OF_OTHER_THREAD
+Windows.Win32.Foundation.ERROR_DEV_NOT_EXIST
+Windows.Win32.Foundation.ERROR_DEVICE_ALREADY_ATTACHED
+Windows.Win32.Foundation.ERROR_DEVICE_ALREADY_REMEMBERED
+Windows.Win32.Foundation.ERROR_DEVICE_DOOR_OPEN
+Windows.Win32.Foundation.ERROR_DEVICE_ENUMERATION_ERROR
+Windows.Win32.Foundation.ERROR_DEVICE_FEATURE_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_DEVICE_HARDWARE_ERROR
+Windows.Win32.Foundation.ERROR_DEVICE_HINT_NAME_BUFFER_TOO_SMALL
+Windows.Win32.Foundation.ERROR_DEVICE_IN_MAINTENANCE
+Windows.Win32.Foundation.ERROR_DEVICE_IN_USE
+Windows.Win32.Foundation.ERROR_DEVICE_NO_RESOURCES
+Windows.Win32.Foundation.ERROR_DEVICE_NOT_CONNECTED
+Windows.Win32.Foundation.ERROR_DEVICE_NOT_PARTITIONED
+Windows.Win32.Foundation.ERROR_DEVICE_REINITIALIZATION_NEEDED
+Windows.Win32.Foundation.ERROR_DEVICE_REMOVED
+Windows.Win32.Foundation.ERROR_DEVICE_REQUIRES_CLEANING
+Windows.Win32.Foundation.ERROR_DEVICE_RESET_REQUIRED
+Windows.Win32.Foundation.ERROR_DEVICE_SUPPORT_IN_PROGRESS
+Windows.Win32.Foundation.ERROR_DEVICE_UNREACHABLE
+Windows.Win32.Foundation.ERROR_DHCP_ADDRESS_CONFLICT
+Windows.Win32.Foundation.ERROR_DIFFERENT_SERVICE_ACCOUNT
+Windows.Win32.Foundation.ERROR_DIR_EFS_DISALLOWED
+Windows.Win32.Foundation.ERROR_DIR_NOT_EMPTY
+Windows.Win32.Foundation.ERROR_DIR_NOT_ROOT
+Windows.Win32.Foundation.ERROR_DIRECT_ACCESS_HANDLE
+Windows.Win32.Foundation.ERROR_DIRECTORY
+Windows.Win32.Foundation.ERROR_DIRECTORY_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_DISCARDED
+Windows.Win32.Foundation.ERROR_DISK_CHANGE
+Windows.Win32.Foundation.ERROR_DISK_CORRUPT
+Windows.Win32.Foundation.ERROR_DISK_FULL
+Windows.Win32.Foundation.ERROR_DISK_OPERATION_FAILED
+Windows.Win32.Foundation.ERROR_DISK_QUOTA_EXCEEDED
+Windows.Win32.Foundation.ERROR_DISK_RECALIBRATE_FAILED
+Windows.Win32.Foundation.ERROR_DISK_REPAIR_DISABLED
+Windows.Win32.Foundation.ERROR_DISK_REPAIR_REDIRECTED
+Windows.Win32.Foundation.ERROR_DISK_REPAIR_UNSUCCESSFUL
+Windows.Win32.Foundation.ERROR_DISK_RESET_FAILED
+Windows.Win32.Foundation.ERROR_DISK_RESOURCES_EXHAUSTED
+Windows.Win32.Foundation.ERROR_DISK_TOO_FRAGMENTED
+Windows.Win32.Foundation.ERROR_DLL_INIT_FAILED
+Windows.Win32.Foundation.ERROR_DLL_INIT_FAILED_LOGOFF
+Windows.Win32.Foundation.ERROR_DLL_MIGHT_BE_INCOMPATIBLE
+Windows.Win32.Foundation.ERROR_DLL_MIGHT_BE_INSECURE
+Windows.Win32.Foundation.ERROR_DLL_NOT_FOUND
+Windows.Win32.Foundation.ERROR_DLP_POLICY_DENIES_OPERATION
+Windows.Win32.Foundation.ERROR_DLP_POLICY_SILENTLY_FAIL
+Windows.Win32.Foundation.ERROR_DLP_POLICY_WARNS_AGAINST_OPERATION
+Windows.Win32.Foundation.ERROR_DOMAIN_CONTROLLER_EXISTS
+Windows.Win32.Foundation.ERROR_DOMAIN_CONTROLLER_NOT_FOUND
+Windows.Win32.Foundation.ERROR_DOMAIN_CTRLR_CONFIG_ERROR
+Windows.Win32.Foundation.ERROR_DOMAIN_EXISTS
+Windows.Win32.Foundation.ERROR_DOMAIN_LIMIT_EXCEEDED
+Windows.Win32.Foundation.ERROR_DOMAIN_SID_SAME_AS_LOCAL_WORKSTATION
+Windows.Win32.Foundation.ERROR_DOMAIN_TRUST_INCONSISTENT
+Windows.Win32.Foundation.ERROR_DOWNGRADE_DETECTED
+Windows.Win32.Foundation.ERROR_DPL_NOT_SUPPORTED_FOR_USER
+Windows.Win32.Foundation.ERROR_DRIVE_LOCKED
+Windows.Win32.Foundation.ERROR_DRIVER_BLOCKED
+Windows.Win32.Foundation.ERROR_DRIVER_CANCEL_TIMEOUT
+Windows.Win32.Foundation.ERROR_DRIVER_DATABASE_ERROR
+Windows.Win32.Foundation.ERROR_DRIVER_FAILED_PRIOR_UNLOAD
+Windows.Win32.Foundation.ERROR_DRIVER_FAILED_SLEEP
+Windows.Win32.Foundation.ERROR_DRIVER_PROCESS_TERMINATED
+Windows.Win32.Foundation.ERROR_DRIVERS_LEAKING_LOCKED_PAGES
+Windows.Win32.Foundation.ERROR_DS_ADD_REPLICA_INHIBITED
+Windows.Win32.Foundation.ERROR_DS_ADMIN_LIMIT_EXCEEDED
+Windows.Win32.Foundation.ERROR_DS_AFFECTS_MULTIPLE_DSAS
+Windows.Win32.Foundation.ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER
+Windows.Win32.Foundation.ERROR_DS_ALIAS_DEREF_PROBLEM
+Windows.Win32.Foundation.ERROR_DS_ALIAS_POINTS_TO_ALIAS
+Windows.Win32.Foundation.ERROR_DS_ALIAS_PROBLEM
+Windows.Win32.Foundation.ERROR_DS_ALIASED_OBJ_MISSING
+Windows.Win32.Foundation.ERROR_DS_ATT_ALREADY_EXISTS
+Windows.Win32.Foundation.ERROR_DS_ATT_IS_NOT_ON_OBJ
+Windows.Win32.Foundation.ERROR_DS_ATT_NOT_DEF_FOR_CLASS
+Windows.Win32.Foundation.ERROR_DS_ATT_NOT_DEF_IN_SCHEMA
+Windows.Win32.Foundation.ERROR_DS_ATT_SCHEMA_REQ_ID
+Windows.Win32.Foundation.ERROR_DS_ATT_SCHEMA_REQ_SYNTAX
+Windows.Win32.Foundation.ERROR_DS_ATT_VAL_ALREADY_EXISTS
+Windows.Win32.Foundation.ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS
+Windows.Win32.Foundation.ERROR_DS_ATTRIBUTE_OWNED_BY_SAM
+Windows.Win32.Foundation.ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED
+Windows.Win32.Foundation.ERROR_DS_AUDIT_FAILURE
+Windows.Win32.Foundation.ERROR_DS_AUTH_METHOD_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_DS_AUTH_UNKNOWN
+Windows.Win32.Foundation.ERROR_DS_AUTHORIZATION_FAILED
+Windows.Win32.Foundation.ERROR_DS_AUX_CLS_TEST_FAIL
+Windows.Win32.Foundation.ERROR_DS_BACKLINK_WITHOUT_LINK
+Windows.Win32.Foundation.ERROR_DS_BAD_ATT_SCHEMA_SYNTAX
+Windows.Win32.Foundation.ERROR_DS_BAD_HIERARCHY_FILE
+Windows.Win32.Foundation.ERROR_DS_BAD_INSTANCE_TYPE
+Windows.Win32.Foundation.ERROR_DS_BAD_NAME_SYNTAX
+Windows.Win32.Foundation.ERROR_DS_BAD_RDN_ATT_ID_SYNTAX
+Windows.Win32.Foundation.ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED
+Windows.Win32.Foundation.ERROR_DS_BUSY
+Windows.Win32.Foundation.ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD
+Windows.Win32.Foundation.ERROR_DS_CANT_ADD_ATT_VALUES
+Windows.Win32.Foundation.ERROR_DS_CANT_ADD_SYSTEM_ONLY
+Windows.Win32.Foundation.ERROR_DS_CANT_ADD_TO_GC
+Windows.Win32.Foundation.ERROR_DS_CANT_CACHE_ATT
+Windows.Win32.Foundation.ERROR_DS_CANT_CACHE_CLASS
+Windows.Win32.Foundation.ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC
+Windows.Win32.Foundation.ERROR_DS_CANT_CREATE_UNDER_SCHEMA
+Windows.Win32.Foundation.ERROR_DS_CANT_DEL_MASTER_CROSSREF
+Windows.Win32.Foundation.ERROR_DS_CANT_DELETE
+Windows.Win32.Foundation.ERROR_DS_CANT_DELETE_DSA_OBJ
+Windows.Win32.Foundation.ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC
+Windows.Win32.Foundation.ERROR_DS_CANT_DEREF_ALIAS
+Windows.Win32.Foundation.ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN
+Windows.Win32.Foundation.ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF
+Windows.Win32.Foundation.ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN
+Windows.Win32.Foundation.ERROR_DS_CANT_FIND_DSA_OBJ
+Windows.Win32.Foundation.ERROR_DS_CANT_FIND_EXPECTED_NC
+Windows.Win32.Foundation.ERROR_DS_CANT_FIND_NC_IN_CACHE
+Windows.Win32.Foundation.ERROR_DS_CANT_MIX_MASTER_AND_REPS
+Windows.Win32.Foundation.ERROR_DS_CANT_MOD_OBJ_CLASS
+Windows.Win32.Foundation.ERROR_DS_CANT_MOD_PRIMARYGROUPID
+Windows.Win32.Foundation.ERROR_DS_CANT_MOD_SYSTEM_ONLY
+Windows.Win32.Foundation.ERROR_DS_CANT_MOVE_ACCOUNT_GROUP
+Windows.Win32.Foundation.ERROR_DS_CANT_MOVE_APP_BASIC_GROUP
+Windows.Win32.Foundation.ERROR_DS_CANT_MOVE_APP_QUERY_GROUP
+Windows.Win32.Foundation.ERROR_DS_CANT_MOVE_DELETED_OBJECT
+Windows.Win32.Foundation.ERROR_DS_CANT_MOVE_RESOURCE_GROUP
+Windows.Win32.Foundation.ERROR_DS_CANT_ON_NON_LEAF
+Windows.Win32.Foundation.ERROR_DS_CANT_ON_RDN
+Windows.Win32.Foundation.ERROR_DS_CANT_REM_MISSING_ATT
+Windows.Win32.Foundation.ERROR_DS_CANT_REM_MISSING_ATT_VAL
+Windows.Win32.Foundation.ERROR_DS_CANT_REMOVE_ATT_CACHE
+Windows.Win32.Foundation.ERROR_DS_CANT_REMOVE_CLASS_CACHE
+Windows.Win32.Foundation.ERROR_DS_CANT_REPLACE_HIDDEN_REC
+Windows.Win32.Foundation.ERROR_DS_CANT_RETRIEVE_ATTS
+Windows.Win32.Foundation.ERROR_DS_CANT_RETRIEVE_CHILD
+Windows.Win32.Foundation.ERROR_DS_CANT_RETRIEVE_DN
+Windows.Win32.Foundation.ERROR_DS_CANT_RETRIEVE_INSTANCE
+Windows.Win32.Foundation.ERROR_DS_CANT_RETRIEVE_SD
+Windows.Win32.Foundation.ERROR_DS_CANT_START
+Windows.Win32.Foundation.ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ
+Windows.Win32.Foundation.ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS
+Windows.Win32.Foundation.ERROR_DS_CHILDREN_EXIST
+Windows.Win32.Foundation.ERROR_DS_CLASS_MUST_BE_CONCRETE
+Windows.Win32.Foundation.ERROR_DS_CLASS_NOT_DSA
+Windows.Win32.Foundation.ERROR_DS_CLIENT_LOOP
+Windows.Win32.Foundation.ERROR_DS_CODE_INCONSISTENCY
+Windows.Win32.Foundation.ERROR_DS_COMPARE_FALSE
+Windows.Win32.Foundation.ERROR_DS_COMPARE_TRUE
+Windows.Win32.Foundation.ERROR_DS_CONFIDENTIALITY_REQUIRED
+Windows.Win32.Foundation.ERROR_DS_CONFIG_PARAM_MISSING
+Windows.Win32.Foundation.ERROR_DS_CONSTRAINT_VIOLATION
+Windows.Win32.Foundation.ERROR_DS_CONSTRUCTED_ATT_MOD
+Windows.Win32.Foundation.ERROR_DS_CONTROL_NOT_FOUND
+Windows.Win32.Foundation.ERROR_DS_COULDNT_CONTACT_FSMO
+Windows.Win32.Foundation.ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE
+Windows.Win32.Foundation.ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE
+Windows.Win32.Foundation.ERROR_DS_COULDNT_UPDATE_SPNS
+Windows.Win32.Foundation.ERROR_DS_COUNTING_AB_INDICES_FAILED
+Windows.Win32.Foundation.ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE
+Windows.Win32.Foundation.ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2
+Windows.Win32.Foundation.ERROR_DS_CROSS_DOM_MOVE_ERROR
+Windows.Win32.Foundation.ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD
+Windows.Win32.Foundation.ERROR_DS_CROSS_NC_DN_RENAME
+Windows.Win32.Foundation.ERROR_DS_CROSS_REF_BUSY
+Windows.Win32.Foundation.ERROR_DS_CROSS_REF_EXISTS
+Windows.Win32.Foundation.ERROR_DS_DATABASE_ERROR
+Windows.Win32.Foundation.ERROR_DS_DECODING_ERROR
+Windows.Win32.Foundation.ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED
+Windows.Win32.Foundation.ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST
+Windows.Win32.Foundation.ERROR_DS_DIFFERENT_REPL_EPOCHS
+Windows.Win32.Foundation.ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER
+Windows.Win32.Foundation.ERROR_DS_DISALLOWED_NC_REDIRECT
+Windows.Win32.Foundation.ERROR_DS_DNS_LOOKUP_FAILURE
+Windows.Win32.Foundation.ERROR_DS_DOMAIN_NAME_EXISTS_IN_FOREST
+Windows.Win32.Foundation.ERROR_DS_DOMAIN_RENAME_IN_PROGRESS
+Windows.Win32.Foundation.ERROR_DS_DOMAIN_VERSION_TOO_HIGH
+Windows.Win32.Foundation.ERROR_DS_DOMAIN_VERSION_TOO_LOW
+Windows.Win32.Foundation.ERROR_DS_DRA_ABANDON_SYNC
+Windows.Win32.Foundation.ERROR_DS_DRA_ACCESS_DENIED
+Windows.Win32.Foundation.ERROR_DS_DRA_BAD_DN
+Windows.Win32.Foundation.ERROR_DS_DRA_BAD_INSTANCE_TYPE
+Windows.Win32.Foundation.ERROR_DS_DRA_BAD_NC
+Windows.Win32.Foundation.ERROR_DS_DRA_BUSY
+Windows.Win32.Foundation.ERROR_DS_DRA_CONNECTION_FAILED
+Windows.Win32.Foundation.ERROR_DS_DRA_CORRUPT_UTD_VECTOR
+Windows.Win32.Foundation.ERROR_DS_DRA_DB_ERROR
+Windows.Win32.Foundation.ERROR_DS_DRA_DN_EXISTS
+Windows.Win32.Foundation.ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT
+Windows.Win32.Foundation.ERROR_DS_DRA_EXTN_CONNECTION_FAILED
+Windows.Win32.Foundation.ERROR_DS_DRA_GENERIC
+Windows.Win32.Foundation.ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET
+Windows.Win32.Foundation.ERROR_DS_DRA_INCONSISTENT_DIT
+Windows.Win32.Foundation.ERROR_DS_DRA_INTERNAL_ERROR
+Windows.Win32.Foundation.ERROR_DS_DRA_INVALID_PARAMETER
+Windows.Win32.Foundation.ERROR_DS_DRA_MAIL_PROBLEM
+Windows.Win32.Foundation.ERROR_DS_DRA_MISSING_KRBTGT_SECRET
+Windows.Win32.Foundation.ERROR_DS_DRA_MISSING_PARENT
+Windows.Win32.Foundation.ERROR_DS_DRA_NAME_COLLISION
+Windows.Win32.Foundation.ERROR_DS_DRA_NO_REPLICA
+Windows.Win32.Foundation.ERROR_DS_DRA_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_DS_DRA_OBJ_IS_REP_SOURCE
+Windows.Win32.Foundation.ERROR_DS_DRA_OBJ_NC_MISMATCH
+Windows.Win32.Foundation.ERROR_DS_DRA_OUT_OF_MEM
+Windows.Win32.Foundation.ERROR_DS_DRA_OUT_SCHEDULE_WINDOW
+Windows.Win32.Foundation.ERROR_DS_DRA_PREEMPTED
+Windows.Win32.Foundation.ERROR_DS_DRA_RECYCLED_TARGET
+Windows.Win32.Foundation.ERROR_DS_DRA_REF_ALREADY_EXISTS
+Windows.Win32.Foundation.ERROR_DS_DRA_REF_NOT_FOUND
+Windows.Win32.Foundation.ERROR_DS_DRA_REPL_PENDING
+Windows.Win32.Foundation.ERROR_DS_DRA_RPC_CANCELLED
+Windows.Win32.Foundation.ERROR_DS_DRA_SCHEMA_CONFLICT
+Windows.Win32.Foundation.ERROR_DS_DRA_SCHEMA_INFO_SHIP
+Windows.Win32.Foundation.ERROR_DS_DRA_SCHEMA_MISMATCH
+Windows.Win32.Foundation.ERROR_DS_DRA_SECRETS_DENIED
+Windows.Win32.Foundation.ERROR_DS_DRA_SHUTDOWN
+Windows.Win32.Foundation.ERROR_DS_DRA_SINK_DISABLED
+Windows.Win32.Foundation.ERROR_DS_DRA_SOURCE_DISABLED
+Windows.Win32.Foundation.ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA
+Windows.Win32.Foundation.ERROR_DS_DRA_SOURCE_REINSTALLED
+Windows.Win32.Foundation.ERROR_DS_DRS_EXTENSIONS_CHANGED
+Windows.Win32.Foundation.ERROR_DS_DS_REQUIRED
+Windows.Win32.Foundation.ERROR_DS_DSA_MUST_BE_INT_MASTER
+Windows.Win32.Foundation.ERROR_DS_DST_DOMAIN_NOT_NATIVE
+Windows.Win32.Foundation.ERROR_DS_DST_NC_MISMATCH
+Windows.Win32.Foundation.ERROR_DS_DUP_LDAP_DISPLAY_NAME
+Windows.Win32.Foundation.ERROR_DS_DUP_LINK_ID
+Windows.Win32.Foundation.ERROR_DS_DUP_MAPI_ID
+Windows.Win32.Foundation.ERROR_DS_DUP_MSDS_INTID
+Windows.Win32.Foundation.ERROR_DS_DUP_OID
+Windows.Win32.Foundation.ERROR_DS_DUP_RDN
+Windows.Win32.Foundation.ERROR_DS_DUP_SCHEMA_ID_GUID
+Windows.Win32.Foundation.ERROR_DS_DUPLICATE_ID_FOUND
+Windows.Win32.Foundation.ERROR_DS_ENCODING_ERROR
+Windows.Win32.Foundation.ERROR_DS_EPOCH_MISMATCH
+Windows.Win32.Foundation.ERROR_DS_EXISTING_AD_CHILD_NC
+Windows.Win32.Foundation.ERROR_DS_EXISTS_IN_AUX_CLS
+Windows.Win32.Foundation.ERROR_DS_EXISTS_IN_MAY_HAVE
+Windows.Win32.Foundation.ERROR_DS_EXISTS_IN_MUST_HAVE
+Windows.Win32.Foundation.ERROR_DS_EXISTS_IN_POSS_SUP
+Windows.Win32.Foundation.ERROR_DS_EXISTS_IN_RDNATTID
+Windows.Win32.Foundation.ERROR_DS_EXISTS_IN_SUB_CLS
+Windows.Win32.Foundation.ERROR_DS_FILTER_UNKNOWN
+Windows.Win32.Foundation.ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS
+Windows.Win32.Foundation.ERROR_DS_FLAT_NAME_EXISTS_IN_FOREST
+Windows.Win32.Foundation.ERROR_DS_FOREST_VERSION_TOO_HIGH
+Windows.Win32.Foundation.ERROR_DS_FOREST_VERSION_TOO_LOW
+Windows.Win32.Foundation.ERROR_DS_GC_NOT_AVAILABLE
+Windows.Win32.Foundation.ERROR_DS_GC_REQUIRED
+Windows.Win32.Foundation.ERROR_DS_GCVERIFY_ERROR
+Windows.Win32.Foundation.ERROR_DS_GENERIC_ERROR
+Windows.Win32.Foundation.ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER
+Windows.Win32.Foundation.ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER
+Windows.Win32.Foundation.ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER
+Windows.Win32.Foundation.ERROR_DS_GOVERNSID_MISSING
+Windows.Win32.Foundation.ERROR_DS_GROUP_CONVERSION_ERROR
+Windows.Win32.Foundation.ERROR_DS_HAVE_PRIMARY_MEMBERS
+Windows.Win32.Foundation.ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED
+Windows.Win32.Foundation.ERROR_DS_HIERARCHY_TABLE_TOO_DEEP
+Windows.Win32.Foundation.ERROR_DS_HIGH_ADLDS_FFL
+Windows.Win32.Foundation.ERROR_DS_HIGH_DSA_VERSION
+Windows.Win32.Foundation.ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD
+Windows.Win32.Foundation.ERROR_DS_ILLEGAL_MOD_OPERATION
+Windows.Win32.Foundation.ERROR_DS_ILLEGAL_SUPERIOR
+Windows.Win32.Foundation.ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION
+Windows.Win32.Foundation.ERROR_DS_INAPPROPRIATE_AUTH
+Windows.Win32.Foundation.ERROR_DS_INAPPROPRIATE_MATCHING
+Windows.Win32.Foundation.ERROR_DS_INCOMPATIBLE_CONTROLS_USED
+Windows.Win32.Foundation.ERROR_DS_INCOMPATIBLE_VERSION
+Windows.Win32.Foundation.ERROR_DS_INCORRECT_ROLE_OWNER
+Windows.Win32.Foundation.ERROR_DS_INIT_FAILURE
+Windows.Win32.Foundation.ERROR_DS_INIT_FAILURE_CONSOLE
+Windows.Win32.Foundation.ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE
+Windows.Win32.Foundation.ERROR_DS_INSTALL_NO_SRC_SCH_VERSION
+Windows.Win32.Foundation.ERROR_DS_INSTALL_SCHEMA_MISMATCH
+Windows.Win32.Foundation.ERROR_DS_INSUFF_ACCESS_RIGHTS
+Windows.Win32.Foundation.ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT
+Windows.Win32.Foundation.ERROR_DS_INTERNAL_FAILURE
+Windows.Win32.Foundation.ERROR_DS_INVALID_ATTRIBUTE_SYNTAX
+Windows.Win32.Foundation.ERROR_DS_INVALID_DMD
+Windows.Win32.Foundation.ERROR_DS_INVALID_DN_SYNTAX
+Windows.Win32.Foundation.ERROR_DS_INVALID_GROUP_TYPE
+Windows.Win32.Foundation.ERROR_DS_INVALID_LDAP_DISPLAY_NAME
+Windows.Win32.Foundation.ERROR_DS_INVALID_NAME_FOR_SPN
+Windows.Win32.Foundation.ERROR_DS_INVALID_ROLE_OWNER
+Windows.Win32.Foundation.ERROR_DS_INVALID_SCRIPT
+Windows.Win32.Foundation.ERROR_DS_INVALID_SEARCH_FLAG
+Windows.Win32.Foundation.ERROR_DS_INVALID_SEARCH_FLAG_SUBTREE
+Windows.Win32.Foundation.ERROR_DS_INVALID_SEARCH_FLAG_TUPLE
+Windows.Win32.Foundation.ERROR_DS_IS_LEAF
+Windows.Win32.Foundation.ERROR_DS_KEY_NOT_UNIQUE
+Windows.Win32.Foundation.ERROR_DS_LDAP_SEND_QUEUE_FULL
+Windows.Win32.Foundation.ERROR_DS_LINK_ID_NOT_AVAILABLE
+Windows.Win32.Foundation.ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER
+Windows.Win32.Foundation.ERROR_DS_LOCAL_ERROR
+Windows.Win32.Foundation.ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY
+Windows.Win32.Foundation.ERROR_DS_LOOP_DETECT
+Windows.Win32.Foundation.ERROR_DS_LOW_ADLDS_FFL
+Windows.Win32.Foundation.ERROR_DS_LOW_DSA_VERSION
+Windows.Win32.Foundation.ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4
+Windows.Win32.Foundation.ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED
+Windows.Win32.Foundation.ERROR_DS_MAPI_ID_NOT_AVAILABLE
+Windows.Win32.Foundation.ERROR_DS_MASTERDSA_REQUIRED
+Windows.Win32.Foundation.ERROR_DS_MAX_OBJ_SIZE_EXCEEDED
+Windows.Win32.Foundation.ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY
+Windows.Win32.Foundation.ERROR_DS_MISSING_EXPECTED_ATT
+Windows.Win32.Foundation.ERROR_DS_MISSING_FOREST_TRUST
+Windows.Win32.Foundation.ERROR_DS_MISSING_FSMO_SETTINGS
+Windows.Win32.Foundation.ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER
+Windows.Win32.Foundation.ERROR_DS_MISSING_REQUIRED_ATT
+Windows.Win32.Foundation.ERROR_DS_MISSING_SUPREF
+Windows.Win32.Foundation.ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG
+Windows.Win32.Foundation.ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE
+Windows.Win32.Foundation.ERROR_DS_MODIFYDN_WRONG_GRANDPARENT
+Windows.Win32.Foundation.ERROR_DS_MUST_BE_RUN_ON_DST_DC
+Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_DOMAIN_ONLY
+Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_NO_MAPPING
+Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING
+Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_NOT_FOUND
+Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_NOT_UNIQUE
+Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_RESOLVING
+Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_TRUST_REFERRAL
+Windows.Win32.Foundation.ERROR_DS_NAME_NOT_UNIQUE
+Windows.Win32.Foundation.ERROR_DS_NAME_REFERENCE_INVALID
+Windows.Win32.Foundation.ERROR_DS_NAME_TOO_LONG
+Windows.Win32.Foundation.ERROR_DS_NAME_TOO_MANY_PARTS
+Windows.Win32.Foundation.ERROR_DS_NAME_TYPE_UNKNOWN
+Windows.Win32.Foundation.ERROR_DS_NAME_UNPARSEABLE
+Windows.Win32.Foundation.ERROR_DS_NAME_VALUE_TOO_LONG
+Windows.Win32.Foundation.ERROR_DS_NAMING_MASTER_GC
+Windows.Win32.Foundation.ERROR_DS_NAMING_VIOLATION
+Windows.Win32.Foundation.ERROR_DS_NC_MUST_HAVE_NC_PARENT
+Windows.Win32.Foundation.ERROR_DS_NC_STILL_HAS_DSAS
+Windows.Win32.Foundation.ERROR_DS_NCNAME_MISSING_CR_REF
+Windows.Win32.Foundation.ERROR_DS_NCNAME_MUST_BE_NC
+Windows.Win32.Foundation.ERROR_DS_NO_ATTRIBUTE_OR_VALUE
+Windows.Win32.Foundation.ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN
+Windows.Win32.Foundation.ERROR_DS_NO_CHAINED_EVAL
+Windows.Win32.Foundation.ERROR_DS_NO_CHAINING
+Windows.Win32.Foundation.ERROR_DS_NO_CHECKPOINT_WITH_PDC
+Windows.Win32.Foundation.ERROR_DS_NO_CROSSREF_FOR_NC
+Windows.Win32.Foundation.ERROR_DS_NO_DELETED_NAME
+Windows.Win32.Foundation.ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS
+Windows.Win32.Foundation.ERROR_DS_NO_MORE_RIDS
+Windows.Win32.Foundation.ERROR_DS_NO_MSDS_INTID
+Windows.Win32.Foundation.ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN
+Windows.Win32.Foundation.ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN
+Windows.Win32.Foundation.ERROR_DS_NO_NTDSA_OBJECT
+Windows.Win32.Foundation.ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC
+Windows.Win32.Foundation.ERROR_DS_NO_PARENT_OBJECT
+Windows.Win32.Foundation.ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION
+Windows.Win32.Foundation.ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA
+Windows.Win32.Foundation.ERROR_DS_NO_REF_DOMAIN
+Windows.Win32.Foundation.ERROR_DS_NO_REQUESTED_ATTS_FOUND
+Windows.Win32.Foundation.ERROR_DS_NO_RESULTS_RETURNED
+Windows.Win32.Foundation.ERROR_DS_NO_RIDS_ALLOCATED
+Windows.Win32.Foundation.ERROR_DS_NO_SERVER_OBJECT
+Windows.Win32.Foundation.ERROR_DS_NO_SUCH_OBJECT
+Windows.Win32.Foundation.ERROR_DS_NO_TREE_DELETE_ABOVE_NC
+Windows.Win32.Foundation.ERROR_DS_NON_ASQ_SEARCH
+Windows.Win32.Foundation.ERROR_DS_NON_BASE_SEARCH
+Windows.Win32.Foundation.ERROR_DS_NONEXISTENT_MAY_HAVE
+Windows.Win32.Foundation.ERROR_DS_NONEXISTENT_MUST_HAVE
+Windows.Win32.Foundation.ERROR_DS_NONEXISTENT_POSS_SUP
+Windows.Win32.Foundation.ERROR_DS_NONSAFE_SCHEMA_CHANGE
+Windows.Win32.Foundation.ERROR_DS_NOT_AN_OBJECT
+Windows.Win32.Foundation.ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC
+Windows.Win32.Foundation.ERROR_DS_NOT_CLOSEST
+Windows.Win32.Foundation.ERROR_DS_NOT_INSTALLED
+Windows.Win32.Foundation.ERROR_DS_NOT_ON_BACKLINK
+Windows.Win32.Foundation.ERROR_DS_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_DS_NOT_SUPPORTED_SORT_ORDER
+Windows.Win32.Foundation.ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX
+Windows.Win32.Foundation.ERROR_DS_NTDSCRIPT_PROCESS_ERROR
+Windows.Win32.Foundation.ERROR_DS_NTDSCRIPT_SYNTAX_ERROR
+Windows.Win32.Foundation.ERROR_DS_OBJ_CLASS_NOT_DEFINED
+Windows.Win32.Foundation.ERROR_DS_OBJ_CLASS_NOT_SUBCLASS
+Windows.Win32.Foundation.ERROR_DS_OBJ_CLASS_VIOLATION
+Windows.Win32.Foundation.ERROR_DS_OBJ_GUID_EXISTS
+Windows.Win32.Foundation.ERROR_DS_OBJ_NOT_FOUND
+Windows.Win32.Foundation.ERROR_DS_OBJ_STRING_NAME_EXISTS
+Windows.Win32.Foundation.ERROR_DS_OBJ_TOO_LARGE
+Windows.Win32.Foundation.ERROR_DS_OBJECT_BEING_REMOVED
+Windows.Win32.Foundation.ERROR_DS_OBJECT_CLASS_REQUIRED
+Windows.Win32.Foundation.ERROR_DS_OBJECT_RESULTS_TOO_LARGE
+Windows.Win32.Foundation.ERROR_DS_OFFSET_RANGE_ERROR
+Windows.Win32.Foundation.ERROR_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS
+Windows.Win32.Foundation.ERROR_DS_OID_NOT_FOUND
+Windows.Win32.Foundation.ERROR_DS_OPERATIONS_ERROR
+Windows.Win32.Foundation.ERROR_DS_OUT_OF_SCOPE
+Windows.Win32.Foundation.ERROR_DS_OUT_OF_VERSION_STORE
+Windows.Win32.Foundation.ERROR_DS_PARAM_ERROR
+Windows.Win32.Foundation.ERROR_DS_PARENT_IS_AN_ALIAS
+Windows.Win32.Foundation.ERROR_DS_PDC_OPERATION_IN_PROGRESS
+Windows.Win32.Foundation.ERROR_DS_PER_ATTRIBUTE_AUTHZ_FAILED_DURING_ADD
+Windows.Win32.Foundation.ERROR_DS_POLICY_NOT_KNOWN
+Windows.Win32.Foundation.ERROR_DS_PROTOCOL_ERROR
+Windows.Win32.Foundation.ERROR_DS_RANGE_CONSTRAINT
+Windows.Win32.Foundation.ERROR_DS_RDN_DOESNT_MATCH_SCHEMA
+Windows.Win32.Foundation.ERROR_DS_RECALCSCHEMA_FAILED
+Windows.Win32.Foundation.ERROR_DS_REFERRAL
+Windows.Win32.Foundation.ERROR_DS_REFERRAL_LIMIT_EXCEEDED
+Windows.Win32.Foundation.ERROR_DS_REFUSING_FSMO_ROLES
+Windows.Win32.Foundation.ERROR_DS_REMOTE_CROSSREF_OP_FAILED
+Windows.Win32.Foundation.ERROR_DS_REPL_LIFETIME_EXCEEDED
+Windows.Win32.Foundation.ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR
+Windows.Win32.Foundation.ERROR_DS_REPLICATOR_ONLY
+Windows.Win32.Foundation.ERROR_DS_RESERVED_LINK_ID
+Windows.Win32.Foundation.ERROR_DS_RESERVED_MAPI_ID
+Windows.Win32.Foundation.ERROR_DS_RIDMGR_DISABLED
+Windows.Win32.Foundation.ERROR_DS_RIDMGR_INIT_ERROR
+Windows.Win32.Foundation.ERROR_DS_ROLE_NOT_VERIFIED
+Windows.Win32.Foundation.ERROR_DS_ROOT_CANT_BE_SUBREF
+Windows.Win32.Foundation.ERROR_DS_ROOT_MUST_BE_NC
+Windows.Win32.Foundation.ERROR_DS_ROOT_REQUIRES_CLASS_TOP
+Windows.Win32.Foundation.ERROR_DS_SAM_INIT_FAILURE
+Windows.Win32.Foundation.ERROR_DS_SAM_INIT_FAILURE_CONSOLE
+Windows.Win32.Foundation.ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY
+Windows.Win32.Foundation.ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD
+Windows.Win32.Foundation.ERROR_DS_SCHEMA_ALLOC_FAILED
+Windows.Win32.Foundation.ERROR_DS_SCHEMA_NOT_LOADED
+Windows.Win32.Foundation.ERROR_DS_SCHEMA_UPDATE_DISALLOWED
+Windows.Win32.Foundation.ERROR_DS_SEC_DESC_INVALID
+Windows.Win32.Foundation.ERROR_DS_SEC_DESC_TOO_SHORT
+Windows.Win32.Foundation.ERROR_DS_SECURITY_CHECKING_ERROR
+Windows.Win32.Foundation.ERROR_DS_SECURITY_ILLEGAL_MODIFY
+Windows.Win32.Foundation.ERROR_DS_SEMANTIC_ATT_TEST
+Windows.Win32.Foundation.ERROR_DS_SENSITIVE_GROUP_VIOLATION
+Windows.Win32.Foundation.ERROR_DS_SERVER_DOWN
+Windows.Win32.Foundation.ERROR_DS_SHUTTING_DOWN
+Windows.Win32.Foundation.ERROR_DS_SINGLE_USER_MODE_FAILED
+Windows.Win32.Foundation.ERROR_DS_SINGLE_VALUE_CONSTRAINT
+Windows.Win32.Foundation.ERROR_DS_SIZELIMIT_EXCEEDED
+Windows.Win32.Foundation.ERROR_DS_SORT_CONTROL_MISSING
+Windows.Win32.Foundation.ERROR_DS_SOURCE_AUDITING_NOT_ENABLED
+Windows.Win32.Foundation.ERROR_DS_SOURCE_DOMAIN_IN_FOREST
+Windows.Win32.Foundation.ERROR_DS_SPN_VALUE_NOT_UNIQUE_IN_FOREST
+Windows.Win32.Foundation.ERROR_DS_SRC_AND_DST_NC_IDENTICAL
+Windows.Win32.Foundation.ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH
+Windows.Win32.Foundation.ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER
+Windows.Win32.Foundation.ERROR_DS_SRC_GUID_MISMATCH
+Windows.Win32.Foundation.ERROR_DS_SRC_NAME_MISMATCH
+Windows.Win32.Foundation.ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER
+Windows.Win32.Foundation.ERROR_DS_SRC_SID_EXISTS_IN_FOREST
+Windows.Win32.Foundation.ERROR_DS_STRING_SD_CONVERSION_FAILED
+Windows.Win32.Foundation.ERROR_DS_STRONG_AUTH_REQUIRED
+Windows.Win32.Foundation.ERROR_DS_SUB_CLS_TEST_FAIL
+Windows.Win32.Foundation.ERROR_DS_SUBREF_MUST_HAVE_PARENT
+Windows.Win32.Foundation.ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD
+Windows.Win32.Foundation.ERROR_DS_SYNTAX_MISMATCH
+Windows.Win32.Foundation.ERROR_DS_THREAD_LIMIT_EXCEEDED
+Windows.Win32.Foundation.ERROR_DS_TIMELIMIT_EXCEEDED
+Windows.Win32.Foundation.ERROR_DS_TREE_DELETE_NOT_FINISHED
+Windows.Win32.Foundation.ERROR_DS_UNABLE_TO_SURRENDER_ROLES
+Windows.Win32.Foundation.ERROR_DS_UNAVAILABLE
+Windows.Win32.Foundation.ERROR_DS_UNAVAILABLE_CRIT_EXTENSION
+Windows.Win32.Foundation.ERROR_DS_UNDELETE_SAM_VALIDATION_FAILED
+Windows.Win32.Foundation.ERROR_DS_UNICODEPWD_NOT_IN_QUOTES
+Windows.Win32.Foundation.ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER
+Windows.Win32.Foundation.ERROR_DS_UNKNOWN_ERROR
+Windows.Win32.Foundation.ERROR_DS_UNKNOWN_OPERATION
+Windows.Win32.Foundation.ERROR_DS_UNWILLING_TO_PERFORM
+Windows.Win32.Foundation.ERROR_DS_UPN_VALUE_NOT_UNIQUE_IN_FOREST
+Windows.Win32.Foundation.ERROR_DS_USER_BUFFER_TO_SMALL
+Windows.Win32.Foundation.ERROR_DS_VALUE_KEY_NOT_UNIQUE
+Windows.Win32.Foundation.ERROR_DS_VERSION_CHECK_FAILURE
+Windows.Win32.Foundation.ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL
+Windows.Win32.Foundation.ERROR_DS_WRONG_LINKED_ATT_SYNTAX
+Windows.Win32.Foundation.ERROR_DS_WRONG_OM_OBJ_CLASS
+Windows.Win32.Foundation.ERROR_DUP_DOMAINNAME
+Windows.Win32.Foundation.ERROR_DUP_NAME
+Windows.Win32.Foundation.ERROR_DUPLICATE_PRIVILEGES
+Windows.Win32.Foundation.ERROR_DUPLICATE_SERVICE_NAME
+Windows.Win32.Foundation.ERROR_DYNAMIC_CODE_BLOCKED
+Windows.Win32.Foundation.ERROR_DYNLINK_FROM_INVALID_RING
+Windows.Win32.Foundation.ERROR_EA_ACCESS_DENIED
+Windows.Win32.Foundation.ERROR_EA_FILE_CORRUPT
+Windows.Win32.Foundation.ERROR_EA_LIST_INCONSISTENT
+Windows.Win32.Foundation.ERROR_EA_TABLE_FULL
+Windows.Win32.Foundation.ERROR_EAS_DIDNT_FIT
+Windows.Win32.Foundation.ERROR_EAS_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_EDP_DPL_POLICY_CANT_BE_SATISFIED
+Windows.Win32.Foundation.ERROR_EDP_POLICY_DENIES_OPERATION
+Windows.Win32.Foundation.ERROR_EFS_ALG_BLOB_TOO_BIG
+Windows.Win32.Foundation.ERROR_EFS_DISABLED
+Windows.Win32.Foundation.ERROR_EFS_SERVER_NOT_TRUSTED
+Windows.Win32.Foundation.ERROR_EFS_VERSION_NOT_SUPPORT
+Windows.Win32.Foundation.ERROR_ELEVATION_REQUIRED
+Windows.Win32.Foundation.ERROR_ENCLAVE_FAILURE
+Windows.Win32.Foundation.ERROR_ENCLAVE_NOT_TERMINATED
+Windows.Win32.Foundation.ERROR_ENCLAVE_VIOLATION
+Windows.Win32.Foundation.ERROR_ENCRYPTED_FILE_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_ENCRYPTED_IO_NOT_POSSIBLE
+Windows.Win32.Foundation.ERROR_ENCRYPTING_METADATA_DISALLOWED
+Windows.Win32.Foundation.ERROR_ENCRYPTION_DISABLED
+Windows.Win32.Foundation.ERROR_ENCRYPTION_FAILED
+Windows.Win32.Foundation.ERROR_ENCRYPTION_POLICY_DENIES_OPERATION
+Windows.Win32.Foundation.ERROR_END_OF_MEDIA
+Windows.Win32.Foundation.ERROR_ENVVAR_NOT_FOUND
+Windows.Win32.Foundation.ERROR_EOM_OVERFLOW
+Windows.Win32.Foundation.ERROR_ERRORS_ENCOUNTERED
+Windows.Win32.Foundation.ERROR_EVALUATION_EXPIRATION
+Windows.Win32.Foundation.ERROR_EVENT_DONE
+Windows.Win32.Foundation.ERROR_EVENT_PENDING
+Windows.Win32.Foundation.ERROR_EVENTLOG_CANT_START
+Windows.Win32.Foundation.ERROR_EVENTLOG_FILE_CHANGED
+Windows.Win32.Foundation.ERROR_EVENTLOG_FILE_CORRUPT
+Windows.Win32.Foundation.ERROR_EXCEPTION_IN_SERVICE
+Windows.Win32.Foundation.ERROR_EXCL_SEM_ALREADY_OWNED
+Windows.Win32.Foundation.ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY
+Windows.Win32.Foundation.ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY
+Windows.Win32.Foundation.ERROR_EXE_MACHINE_TYPE_MISMATCH
+Windows.Win32.Foundation.ERROR_EXE_MARKED_INVALID
+Windows.Win32.Foundation.ERROR_EXTENDED_ERROR
+Windows.Win32.Foundation.ERROR_EXTERNAL_BACKING_PROVIDER_UNKNOWN
+Windows.Win32.Foundation.ERROR_EXTERNAL_SYSKEY_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_EXTRANEOUS_INFORMATION
+Windows.Win32.Foundation.ERROR_FAIL_FAST_EXCEPTION
+Windows.Win32.Foundation.ERROR_FAIL_I24
+Windows.Win32.Foundation.ERROR_FAIL_NOACTION_REBOOT
+Windows.Win32.Foundation.ERROR_FAIL_RESTART
+Windows.Win32.Foundation.ERROR_FAIL_SHUTDOWN
+Windows.Win32.Foundation.ERROR_FAILED_DRIVER_ENTRY
+Windows.Win32.Foundation.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
+Windows.Win32.Foundation.ERROR_FATAL_APP_EXIT
+Windows.Win32.Foundation.ERROR_FILE_CHECKED_OUT
+Windows.Win32.Foundation.ERROR_FILE_CORRUPT
+Windows.Win32.Foundation.ERROR_FILE_ENCRYPTED
+Windows.Win32.Foundation.ERROR_FILE_EXISTS
+Windows.Win32.Foundation.ERROR_FILE_HANDLE_REVOKED
+Windows.Win32.Foundation.ERROR_FILE_INVALID
+Windows.Win32.Foundation.ERROR_FILE_LEVEL_TRIM_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_FILE_METADATA_OPTIMIZATION_IN_PROGRESS
+Windows.Win32.Foundation.ERROR_FILE_NOT_ENCRYPTED
+Windows.Win32.Foundation.ERROR_FILE_NOT_FOUND
+Windows.Win32.Foundation.ERROR_FILE_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_FILE_OFFLINE
+Windows.Win32.Foundation.ERROR_FILE_PROTECTED_UNDER_DPL
+Windows.Win32.Foundation.ERROR_FILE_READ_ONLY
+Windows.Win32.Foundation.ERROR_FILE_SNAP_IN_PROGRESS
+Windows.Win32.Foundation.ERROR_FILE_SNAP_INVALID_PARAMETER
+Windows.Win32.Foundation.ERROR_FILE_SNAP_IO_NOT_COORDINATED
+Windows.Win32.Foundation.ERROR_FILE_SNAP_MODIFY_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_FILE_SNAP_UNEXPECTED_ERROR
+Windows.Win32.Foundation.ERROR_FILE_SNAP_USER_SECTION_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_FILE_SYSTEM_LIMITATION
+Windows.Win32.Foundation.ERROR_FILE_SYSTEM_VIRTUALIZATION_BUSY
+Windows.Win32.Foundation.ERROR_FILE_SYSTEM_VIRTUALIZATION_INVALID_OPERATION
+Windows.Win32.Foundation.ERROR_FILE_SYSTEM_VIRTUALIZATION_METADATA_CORRUPT
+Windows.Win32.Foundation.ERROR_FILE_SYSTEM_VIRTUALIZATION_PROVIDER_UNKNOWN
+Windows.Win32.Foundation.ERROR_FILE_SYSTEM_VIRTUALIZATION_UNAVAILABLE
+Windows.Win32.Foundation.ERROR_FILE_TOO_LARGE
+Windows.Win32.Foundation.ERROR_FILEMARK_DETECTED
+Windows.Win32.Foundation.ERROR_FILENAME_EXCED_RANGE
+Windows.Win32.Foundation.ERROR_FIRMWARE_UPDATED
+Windows.Win32.Foundation.ERROR_FLOAT_MULTIPLE_FAULTS
+Windows.Win32.Foundation.ERROR_FLOAT_MULTIPLE_TRAPS
+Windows.Win32.Foundation.ERROR_FLOPPY_BAD_REGISTERS
+Windows.Win32.Foundation.ERROR_FLOPPY_ID_MARK_NOT_FOUND
+Windows.Win32.Foundation.ERROR_FLOPPY_UNKNOWN_ERROR
+Windows.Win32.Foundation.ERROR_FLOPPY_VOLUME
+Windows.Win32.Foundation.ERROR_FLOPPY_WRONG_CYLINDER
+Windows.Win32.Foundation.ERROR_FORMS_AUTH_REQUIRED
+Windows.Win32.Foundation.ERROR_FOUND_OUT_OF_SCOPE
+Windows.Win32.Foundation.ERROR_FS_DRIVER_REQUIRED
+Windows.Win32.Foundation.ERROR_FS_METADATA_INCONSISTENT
+Windows.Win32.Foundation.ERROR_FSFILTER_OP_COMPLETED_SUCCESSFULLY
+Windows.Win32.Foundation.ERROR_FT_DI_SCAN_REQUIRED
+Windows.Win32.Foundation.ERROR_FT_READ_FAILURE
+Windows.Win32.Foundation.ERROR_FT_READ_FROM_COPY_FAILURE
+Windows.Win32.Foundation.ERROR_FT_READ_RECOVERY_FROM_BACKUP
+Windows.Win32.Foundation.ERROR_FT_WRITE_FAILURE
+Windows.Win32.Foundation.ERROR_FT_WRITE_RECOVERY
+Windows.Win32.Foundation.ERROR_FULLSCREEN_MODE
+Windows.Win32.Foundation.ERROR_FUNCTION_FAILED
+Windows.Win32.Foundation.ERROR_FUNCTION_NOT_CALLED
+Windows.Win32.Foundation.ERROR_GDI_HANDLE_LEAK
+Windows.Win32.Foundation.ERROR_GEN_FAILURE
+Windows.Win32.Foundation.ERROR_GENERIC_NOT_MAPPED
+Windows.Win32.Foundation.ERROR_GLOBAL_ONLY_HOOK
+Windows.Win32.Foundation.ERROR_GRACEFUL_DISCONNECT
+Windows.Win32.Foundation.ERROR_GROUP_EXISTS
+Windows.Win32.Foundation.ERROR_GUID_SUBSTITUTION_MADE
+Windows.Win32.Foundation.ERROR_HANDLE_DISK_FULL
+Windows.Win32.Foundation.ERROR_HANDLE_EOF
+Windows.Win32.Foundation.ERROR_HANDLE_REVOKED
+Windows.Win32.Foundation.ERROR_HANDLES_CLOSED
+Windows.Win32.Foundation.ERROR_HAS_SYSTEM_CRITICAL_FILES
+Windows.Win32.Foundation.ERROR_HIBERNATED
+Windows.Win32.Foundation.ERROR_HIBERNATION_FAILURE
+Windows.Win32.Foundation.ERROR_HOOK_NEEDS_HMOD
+Windows.Win32.Foundation.ERROR_HOOK_NOT_INSTALLED
+Windows.Win32.Foundation.ERROR_HOOK_TYPE_NOT_ALLOWED
+Windows.Win32.Foundation.ERROR_HOST_DOWN
+Windows.Win32.Foundation.ERROR_HOST_UNREACHABLE
+Windows.Win32.Foundation.ERROR_HOTKEY_ALREADY_REGISTERED
+Windows.Win32.Foundation.ERROR_HOTKEY_NOT_REGISTERED
+Windows.Win32.Foundation.ERROR_HWNDS_HAVE_DIFF_PARENT
+Windows.Win32.Foundation.ERROR_ILL_FORMED_PASSWORD
+Windows.Win32.Foundation.ERROR_ILLEGAL_CHARACTER
+Windows.Win32.Foundation.ERROR_ILLEGAL_DLL_RELOCATION
+Windows.Win32.Foundation.ERROR_ILLEGAL_ELEMENT_ADDRESS
+Windows.Win32.Foundation.ERROR_ILLEGAL_FLOAT_CONTEXT
+Windows.Win32.Foundation.ERROR_IMAGE_AT_DIFFERENT_BASE
+Windows.Win32.Foundation.ERROR_IMAGE_MACHINE_TYPE_MISMATCH
+Windows.Win32.Foundation.ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE
+Windows.Win32.Foundation.ERROR_IMAGE_NOT_AT_BASE
+Windows.Win32.Foundation.ERROR_IMAGE_SUBSYSTEM_NOT_PRESENT
+Windows.Win32.Foundation.ERROR_IMPLEMENTATION_LIMIT
+Windows.Win32.Foundation.ERROR_INCOMPATIBLE_SERVICE_PRIVILEGE
+Windows.Win32.Foundation.ERROR_INCOMPATIBLE_SERVICE_SID_TYPE
+Windows.Win32.Foundation.ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING
+Windows.Win32.Foundation.ERROR_INCORRECT_ACCOUNT_TYPE
+Windows.Win32.Foundation.ERROR_INCORRECT_ADDRESS
+Windows.Win32.Foundation.ERROR_INCORRECT_SIZE
+Windows.Win32.Foundation.ERROR_INDEX_ABSENT
+Windows.Win32.Foundation.ERROR_INDEX_OUT_OF_BOUNDS
+Windows.Win32.Foundation.ERROR_INFLOOP_IN_RELOC_CHAIN
+Windows.Win32.Foundation.ERROR_INSTALL_ALREADY_RUNNING
+Windows.Win32.Foundation.ERROR_INSTALL_FAILURE
+Windows.Win32.Foundation.ERROR_INSTALL_LANGUAGE_UNSUPPORTED
+Windows.Win32.Foundation.ERROR_INSTALL_LOG_FAILURE
+Windows.Win32.Foundation.ERROR_INSTALL_NOTUSED
+Windows.Win32.Foundation.ERROR_INSTALL_PACKAGE_INVALID
+Windows.Win32.Foundation.ERROR_INSTALL_PACKAGE_OPEN_FAILED
+Windows.Win32.Foundation.ERROR_INSTALL_PACKAGE_REJECTED
+Windows.Win32.Foundation.ERROR_INSTALL_PACKAGE_VERSION
+Windows.Win32.Foundation.ERROR_INSTALL_PLATFORM_UNSUPPORTED
+Windows.Win32.Foundation.ERROR_INSTALL_REJECTED
+Windows.Win32.Foundation.ERROR_INSTALL_REMOTE_DISALLOWED
+Windows.Win32.Foundation.ERROR_INSTALL_REMOTE_PROHIBITED
+Windows.Win32.Foundation.ERROR_INSTALL_SERVICE_FAILURE
+Windows.Win32.Foundation.ERROR_INSTALL_SERVICE_SAFEBOOT
+Windows.Win32.Foundation.ERROR_INSTALL_SOURCE_ABSENT
+Windows.Win32.Foundation.ERROR_INSTALL_SUSPEND
+Windows.Win32.Foundation.ERROR_INSTALL_TEMP_UNWRITABLE
+Windows.Win32.Foundation.ERROR_INSTALL_TRANSFORM_FAILURE
+Windows.Win32.Foundation.ERROR_INSTALL_TRANSFORM_REJECTED
+Windows.Win32.Foundation.ERROR_INSTALL_UI_FAILURE
+Windows.Win32.Foundation.ERROR_INSTALL_USEREXIT
+Windows.Win32.Foundation.ERROR_INSTRUCTION_MISALIGNMENT
+Windows.Win32.Foundation.ERROR_INSUFFICIENT_BUFFER
+Windows.Win32.Foundation.ERROR_INSUFFICIENT_LOGON_INFO
+Windows.Win32.Foundation.ERROR_INSUFFICIENT_POWER
+Windows.Win32.Foundation.ERROR_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE
+Windows.Win32.Foundation.ERROR_INSUFFICIENT_VIRTUAL_ADDR_RESOURCES
+Windows.Win32.Foundation.ERROR_INTERMIXED_KERNEL_EA_OPERATION
+Windows.Win32.Foundation.ERROR_INTERNAL_DB_CORRUPTION
+Windows.Win32.Foundation.ERROR_INTERNAL_DB_ERROR
+Windows.Win32.Foundation.ERROR_INTERNAL_ERROR
+Windows.Win32.Foundation.ERROR_INTERRUPT_STILL_CONNECTED
+Windows.Win32.Foundation.ERROR_INTERRUPT_VECTOR_ALREADY_CONNECTED
+Windows.Win32.Foundation.ERROR_INVALID_ACCEL_HANDLE
+Windows.Win32.Foundation.ERROR_INVALID_ACCESS
+Windows.Win32.Foundation.ERROR_INVALID_ACCOUNT_NAME
+Windows.Win32.Foundation.ERROR_INVALID_ACE_CONDITION
+Windows.Win32.Foundation.ERROR_INVALID_ACL
+Windows.Win32.Foundation.ERROR_INVALID_ADDRESS
+Windows.Win32.Foundation.ERROR_INVALID_AT_INTERRUPT_TIME
+Windows.Win32.Foundation.ERROR_INVALID_BLOCK
+Windows.Win32.Foundation.ERROR_INVALID_BLOCK_LENGTH
+Windows.Win32.Foundation.ERROR_INVALID_CAP
+Windows.Win32.Foundation.ERROR_INVALID_CATEGORY
+Windows.Win32.Foundation.ERROR_INVALID_COMBOBOX_MESSAGE
+Windows.Win32.Foundation.ERROR_INVALID_COMMAND_LINE
+Windows.Win32.Foundation.ERROR_INVALID_COMPUTERNAME
+Windows.Win32.Foundation.ERROR_INVALID_CRUNTIME_PARAMETER
+Windows.Win32.Foundation.ERROR_INVALID_CURSOR_HANDLE
+Windows.Win32.Foundation.ERROR_INVALID_DATA
+Windows.Win32.Foundation.ERROR_INVALID_DATATYPE
+Windows.Win32.Foundation.ERROR_INVALID_DEVICE_OBJECT_PARAMETER
+Windows.Win32.Foundation.ERROR_INVALID_DLL
+Windows.Win32.Foundation.ERROR_INVALID_DOMAIN_ROLE
+Windows.Win32.Foundation.ERROR_INVALID_DOMAIN_STATE
+Windows.Win32.Foundation.ERROR_INVALID_DOMAINNAME
+Windows.Win32.Foundation.ERROR_INVALID_DRIVE
+Windows.Win32.Foundation.ERROR_INVALID_DWP_HANDLE
+Windows.Win32.Foundation.ERROR_INVALID_EA_HANDLE
+Windows.Win32.Foundation.ERROR_INVALID_EA_NAME
+Windows.Win32.Foundation.ERROR_INVALID_EDIT_HEIGHT
+Windows.Win32.Foundation.ERROR_INVALID_ENVIRONMENT
+Windows.Win32.Foundation.ERROR_INVALID_EVENT_COUNT
+Windows.Win32.Foundation.ERROR_INVALID_EVENTNAME
+Windows.Win32.Foundation.ERROR_INVALID_EXCEPTION_HANDLER
+Windows.Win32.Foundation.ERROR_INVALID_EXE_SIGNATURE
+Windows.Win32.Foundation.ERROR_INVALID_FIELD
+Windows.Win32.Foundation.ERROR_INVALID_FIELD_IN_PARAMETER_LIST
+Windows.Win32.Foundation.ERROR_INVALID_FILTER_PROC
+Windows.Win32.Foundation.ERROR_INVALID_FLAG_NUMBER
+Windows.Win32.Foundation.ERROR_INVALID_FLAGS
+Windows.Win32.Foundation.ERROR_INVALID_FORM_NAME
+Windows.Win32.Foundation.ERROR_INVALID_FORM_SIZE
+Windows.Win32.Foundation.ERROR_INVALID_FUNCTION
+Windows.Win32.Foundation.ERROR_INVALID_GROUP_ATTRIBUTES
+Windows.Win32.Foundation.ERROR_INVALID_GROUPNAME
+Windows.Win32.Foundation.ERROR_INVALID_GW_COMMAND
+Windows.Win32.Foundation.ERROR_INVALID_HANDLE
+Windows.Win32.Foundation.ERROR_INVALID_HANDLE_STATE
+Windows.Win32.Foundation.ERROR_INVALID_HOOK_FILTER
+Windows.Win32.Foundation.ERROR_INVALID_HOOK_HANDLE
+Windows.Win32.Foundation.ERROR_INVALID_HW_PROFILE
+Windows.Win32.Foundation.ERROR_INVALID_ICON_HANDLE
+Windows.Win32.Foundation.ERROR_INVALID_ID_AUTHORITY
+Windows.Win32.Foundation.ERROR_INVALID_IMAGE_HASH
+Windows.Win32.Foundation.ERROR_INVALID_IMPORT_OF_NON_DLL
+Windows.Win32.Foundation.ERROR_INVALID_INDEX
+Windows.Win32.Foundation.ERROR_INVALID_KERNEL_INFO_VERSION
+Windows.Win32.Foundation.ERROR_INVALID_KEYBOARD_HANDLE
+Windows.Win32.Foundation.ERROR_INVALID_LABEL
+Windows.Win32.Foundation.ERROR_INVALID_LB_MESSAGE
+Windows.Win32.Foundation.ERROR_INVALID_LDT_DESCRIPTOR
+Windows.Win32.Foundation.ERROR_INVALID_LDT_OFFSET
+Windows.Win32.Foundation.ERROR_INVALID_LDT_SIZE
+Windows.Win32.Foundation.ERROR_INVALID_LEVEL
+Windows.Win32.Foundation.ERROR_INVALID_LIST_FORMAT
+Windows.Win32.Foundation.ERROR_INVALID_LOCK_RANGE
+Windows.Win32.Foundation.ERROR_INVALID_LOGON_HOURS
+Windows.Win32.Foundation.ERROR_INVALID_LOGON_TYPE
+Windows.Win32.Foundation.ERROR_INVALID_MEMBER
+Windows.Win32.Foundation.ERROR_INVALID_MENU_HANDLE
+Windows.Win32.Foundation.ERROR_INVALID_MESSAGE
+Windows.Win32.Foundation.ERROR_INVALID_MESSAGEDEST
+Windows.Win32.Foundation.ERROR_INVALID_MESSAGENAME
+Windows.Win32.Foundation.ERROR_INVALID_MINALLOCSIZE
+Windows.Win32.Foundation.ERROR_INVALID_MODULETYPE
+Windows.Win32.Foundation.ERROR_INVALID_MONITOR_HANDLE
+Windows.Win32.Foundation.ERROR_INVALID_MSGBOX_STYLE
+Windows.Win32.Foundation.ERROR_INVALID_NAME
+Windows.Win32.Foundation.ERROR_INVALID_NETNAME
+Windows.Win32.Foundation.ERROR_INVALID_OPLOCK_PROTOCOL
+Windows.Win32.Foundation.ERROR_INVALID_ORDINAL
+Windows.Win32.Foundation.ERROR_INVALID_OWNER
+Windows.Win32.Foundation.ERROR_INVALID_PACKAGE_SID_LENGTH
+Windows.Win32.Foundation.ERROR_INVALID_PARAMETER
+Windows.Win32.Foundation.ERROR_INVALID_PASSWORD
+Windows.Win32.Foundation.ERROR_INVALID_PASSWORDNAME
+Windows.Win32.Foundation.ERROR_INVALID_PATCH_XML
+Windows.Win32.Foundation.ERROR_INVALID_PEP_INFO_VERSION
+Windows.Win32.Foundation.ERROR_INVALID_PLUGPLAY_DEVICE_PATH
+Windows.Win32.Foundation.ERROR_INVALID_PORT_ATTRIBUTES
+Windows.Win32.Foundation.ERROR_INVALID_PRIMARY_GROUP
+Windows.Win32.Foundation.ERROR_INVALID_PRINTER_COMMAND
+Windows.Win32.Foundation.ERROR_INVALID_PRINTER_NAME
+Windows.Win32.Foundation.ERROR_INVALID_PRINTER_STATE
+Windows.Win32.Foundation.ERROR_INVALID_PRIORITY
+Windows.Win32.Foundation.ERROR_INVALID_QUOTA_LOWER
+Windows.Win32.Foundation.ERROR_INVALID_REPARSE_DATA
+Windows.Win32.Foundation.ERROR_INVALID_SCROLLBAR_RANGE
+Windows.Win32.Foundation.ERROR_INVALID_SECURITY_DESCR
+Windows.Win32.Foundation.ERROR_INVALID_SEGDPL
+Windows.Win32.Foundation.ERROR_INVALID_SEGMENT_NUMBER
+Windows.Win32.Foundation.ERROR_INVALID_SEPARATOR_FILE
+Windows.Win32.Foundation.ERROR_INVALID_SERVER_STATE
+Windows.Win32.Foundation.ERROR_INVALID_SERVICE_ACCOUNT
+Windows.Win32.Foundation.ERROR_INVALID_SERVICE_CONTROL
+Windows.Win32.Foundation.ERROR_INVALID_SERVICE_LOCK
+Windows.Win32.Foundation.ERROR_INVALID_SERVICENAME
+Windows.Win32.Foundation.ERROR_INVALID_SHARENAME
+Windows.Win32.Foundation.ERROR_INVALID_SHOWWIN_COMMAND
+Windows.Win32.Foundation.ERROR_INVALID_SID
+Windows.Win32.Foundation.ERROR_INVALID_SIGNAL_NUMBER
+Windows.Win32.Foundation.ERROR_INVALID_SPI_VALUE
+Windows.Win32.Foundation.ERROR_INVALID_STACKSEG
+Windows.Win32.Foundation.ERROR_INVALID_STARTING_CODESEG
+Windows.Win32.Foundation.ERROR_INVALID_SUB_AUTHORITY
+Windows.Win32.Foundation.ERROR_INVALID_TABLE
+Windows.Win32.Foundation.ERROR_INVALID_TARGET_HANDLE
+Windows.Win32.Foundation.ERROR_INVALID_TASK_INDEX
+Windows.Win32.Foundation.ERROR_INVALID_TASK_NAME
+Windows.Win32.Foundation.ERROR_INVALID_THREAD_ID
+Windows.Win32.Foundation.ERROR_INVALID_TIME
+Windows.Win32.Foundation.ERROR_INVALID_TOKEN
+Windows.Win32.Foundation.ERROR_INVALID_UNWIND_TARGET
+Windows.Win32.Foundation.ERROR_INVALID_USER_BUFFER
+Windows.Win32.Foundation.ERROR_INVALID_USER_PRINCIPAL_NAME
+Windows.Win32.Foundation.ERROR_INVALID_VARIANT
+Windows.Win32.Foundation.ERROR_INVALID_VERIFY_SWITCH
+Windows.Win32.Foundation.ERROR_INVALID_WINDOW_HANDLE
+Windows.Win32.Foundation.ERROR_INVALID_WORKSTATION
+Windows.Win32.Foundation.ERROR_IO_DEVICE
+Windows.Win32.Foundation.ERROR_IO_INCOMPLETE
+Windows.Win32.Foundation.ERROR_IO_PENDING
+Windows.Win32.Foundation.ERROR_IO_PRIVILEGE_FAILED
+Windows.Win32.Foundation.ERROR_IO_REISSUE_AS_CACHED
+Windows.Win32.Foundation.ERROR_IOPL_NOT_ENABLED
+Windows.Win32.Foundation.ERROR_IP_ADDRESS_CONFLICT1
+Windows.Win32.Foundation.ERROR_IP_ADDRESS_CONFLICT2
+Windows.Win32.Foundation.ERROR_IPSEC_IKE_TIMED_OUT
+Windows.Win32.Foundation.ERROR_IRQ_BUSY
+Windows.Win32.Foundation.ERROR_IS_JOIN_PATH
+Windows.Win32.Foundation.ERROR_IS_JOIN_TARGET
+Windows.Win32.Foundation.ERROR_IS_JOINED
+Windows.Win32.Foundation.ERROR_IS_SUBST_PATH
+Windows.Win32.Foundation.ERROR_IS_SUBST_TARGET
+Windows.Win32.Foundation.ERROR_IS_SUBSTED
+Windows.Win32.Foundation.ERROR_ITERATED_DATA_EXCEEDS_64k
+Windows.Win32.Foundation.ERROR_JOB_NO_CONTAINER
+Windows.Win32.Foundation.ERROR_JOIN_TO_JOIN
+Windows.Win32.Foundation.ERROR_JOIN_TO_SUBST
+Windows.Win32.Foundation.ERROR_JOURNAL_DELETE_IN_PROGRESS
+Windows.Win32.Foundation.ERROR_JOURNAL_ENTRY_DELETED
+Windows.Win32.Foundation.ERROR_JOURNAL_HOOK_SET
+Windows.Win32.Foundation.ERROR_JOURNAL_NOT_ACTIVE
+Windows.Win32.Foundation.ERROR_KERNEL_APC
+Windows.Win32.Foundation.ERROR_KEY_DELETED
+Windows.Win32.Foundation.ERROR_KEY_HAS_CHILDREN
+Windows.Win32.Foundation.ERROR_KM_DRIVER_BLOCKED
+Windows.Win32.Foundation.ERROR_LABEL_TOO_LONG
+Windows.Win32.Foundation.ERROR_LAST_ADMIN
+Windows.Win32.Foundation.ERROR_LB_WITHOUT_TABSTOPS
+Windows.Win32.Foundation.ERROR_LICENSE_QUOTA_EXCEEDED
+Windows.Win32.Foundation.ERROR_LINUX_SUBSYSTEM_NOT_PRESENT
+Windows.Win32.Foundation.ERROR_LINUX_SUBSYSTEM_UPDATE_REQUIRED
+Windows.Win32.Foundation.ERROR_LISTBOX_ID_NOT_FOUND
+Windows.Win32.Foundation.ERROR_LM_CROSS_ENCRYPTION_REQUIRED
+Windows.Win32.Foundation.ERROR_LOCAL_POLICY_MODIFICATION_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_LOCAL_USER_SESSION_KEY
+Windows.Win32.Foundation.ERROR_LOCK_FAILED
+Windows.Win32.Foundation.ERROR_LOCK_VIOLATION
+Windows.Win32.Foundation.ERROR_LOCKED
+Windows.Win32.Foundation.ERROR_LOG_FILE_FULL
+Windows.Win32.Foundation.ERROR_LOG_HARD_ERROR
+Windows.Win32.Foundation.ERROR_LOGIN_TIME_RESTRICTION
+Windows.Win32.Foundation.ERROR_LOGIN_WKSTA_RESTRICTION
+Windows.Win32.Foundation.ERROR_LOGON_FAILURE
+Windows.Win32.Foundation.ERROR_LOGON_NOT_GRANTED
+Windows.Win32.Foundation.ERROR_LOGON_SERVER_CONFLICT
+Windows.Win32.Foundation.ERROR_LOGON_SESSION_COLLISION
+Windows.Win32.Foundation.ERROR_LOGON_SESSION_EXISTS
+Windows.Win32.Foundation.ERROR_LOGON_TYPE_NOT_GRANTED
+Windows.Win32.Foundation.ERROR_LONGJUMP
+Windows.Win32.Foundation.ERROR_LOST_MODE_LOGON_RESTRICTION
+Windows.Win32.Foundation.ERROR_LOST_WRITEBEHIND_DATA
+Windows.Win32.Foundation.ERROR_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR
+Windows.Win32.Foundation.ERROR_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED
+Windows.Win32.Foundation.ERROR_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR
+Windows.Win32.Foundation.ERROR_LUIDS_EXHAUSTED
+Windows.Win32.Foundation.ERROR_MACHINE_LOCKED
+Windows.Win32.Foundation.ERROR_MAGAZINE_NOT_PRESENT
+Windows.Win32.Foundation.ERROR_MAPPED_ALIGNMENT
+Windows.Win32.Foundation.ERROR_MARKED_TO_DISALLOW_WRITES
+Windows.Win32.Foundation.ERROR_MARSHALL_OVERFLOW
+Windows.Win32.Foundation.ERROR_MAX_SESSIONS_REACHED
+Windows.Win32.Foundation.ERROR_MAX_THRDS_REACHED
+Windows.Win32.Foundation.ERROR_MCA_EXCEPTION
+Windows.Win32.Foundation.ERROR_MCA_OCCURED
+Windows.Win32.Foundation.ERROR_MEDIA_CHANGED
+Windows.Win32.Foundation.ERROR_MEDIA_CHECK
+Windows.Win32.Foundation.ERROR_MEMBER_IN_ALIAS
+Windows.Win32.Foundation.ERROR_MEMBER_IN_GROUP
+Windows.Win32.Foundation.ERROR_MEMBER_NOT_IN_ALIAS
+Windows.Win32.Foundation.ERROR_MEMBER_NOT_IN_GROUP
+Windows.Win32.Foundation.ERROR_MEMBERS_PRIMARY_GROUP
+Windows.Win32.Foundation.ERROR_MEMORY_HARDWARE
+Windows.Win32.Foundation.ERROR_MENU_ITEM_NOT_FOUND
+Windows.Win32.Foundation.ERROR_MESSAGE_SYNC_ONLY
+Windows.Win32.Foundation.ERROR_META_EXPANSION_TOO_LONG
+Windows.Win32.Foundation.ERROR_MISSING_SYSTEMFILE
+Windows.Win32.Foundation.ERROR_MOD_NOT_FOUND
+Windows.Win32.Foundation.ERROR_MORE_DATA
+Windows.Win32.Foundation.ERROR_MORE_WRITES
+Windows.Win32.Foundation.ERROR_MOUNT_POINT_NOT_RESOLVED
+Windows.Win32.Foundation.ERROR_MP_PROCESSOR_MISMATCH
+Windows.Win32.Foundation.ERROR_MR_MID_NOT_FOUND
+Windows.Win32.Foundation.ERROR_MULTIPLE_FAULT_VIOLATION
+Windows.Win32.Foundation.ERROR_MUTANT_LIMIT_EXCEEDED
+Windows.Win32.Foundation.ERROR_MUTUAL_AUTH_FAILED
+Windows.Win32.Foundation.ERROR_NEGATIVE_SEEK
+Windows.Win32.Foundation.ERROR_NESTING_NOT_ALLOWED
+Windows.Win32.Foundation.ERROR_NET_OPEN_FAILED
+Windows.Win32.Foundation.ERROR_NET_WRITE_FAULT
+Windows.Win32.Foundation.ERROR_NETLOGON_NOT_STARTED
+Windows.Win32.Foundation.ERROR_NETNAME_DELETED
+Windows.Win32.Foundation.ERROR_NETWORK_ACCESS_DENIED
+Windows.Win32.Foundation.ERROR_NETWORK_ACCESS_DENIED_EDP
+Windows.Win32.Foundation.ERROR_NETWORK_BUSY
+Windows.Win32.Foundation.ERROR_NETWORK_UNREACHABLE
+Windows.Win32.Foundation.ERROR_NO_ACE_CONDITION
+Windows.Win32.Foundation.ERROR_NO_ASSOCIATION
+Windows.Win32.Foundation.ERROR_NO_BYPASSIO_DRIVER_SUPPORT
+Windows.Win32.Foundation.ERROR_NO_CALLBACK_ACTIVE
+Windows.Win32.Foundation.ERROR_NO_DATA
+Windows.Win32.Foundation.ERROR_NO_DATA_DETECTED
+Windows.Win32.Foundation.ERROR_NO_EFS
+Windows.Win32.Foundation.ERROR_NO_EVENT_PAIR
+Windows.Win32.Foundation.ERROR_NO_GUID_TRANSLATION
+Windows.Win32.Foundation.ERROR_NO_IMPERSONATION_TOKEN
+Windows.Win32.Foundation.ERROR_NO_INHERITANCE
+Windows.Win32.Foundation.ERROR_NO_LOG_SPACE
+Windows.Win32.Foundation.ERROR_NO_LOGON_SERVERS
+Windows.Win32.Foundation.ERROR_NO_MATCH
+Windows.Win32.Foundation.ERROR_NO_MEDIA_IN_DRIVE
+Windows.Win32.Foundation.ERROR_NO_MORE_DEVICES
+Windows.Win32.Foundation.ERROR_NO_MORE_FILES
+Windows.Win32.Foundation.ERROR_NO_MORE_ITEMS
+Windows.Win32.Foundation.ERROR_NO_MORE_MATCHES
+Windows.Win32.Foundation.ERROR_NO_MORE_SEARCH_HANDLES
+Windows.Win32.Foundation.ERROR_NO_MORE_USER_HANDLES
+Windows.Win32.Foundation.ERROR_NO_NET_OR_BAD_PATH
+Windows.Win32.Foundation.ERROR_NO_NETWORK
+Windows.Win32.Foundation.ERROR_NO_NVRAM_RESOURCES
+Windows.Win32.Foundation.ERROR_NO_PAGEFILE
+Windows.Win32.Foundation.ERROR_NO_PHYSICALLY_ALIGNED_FREE_SPACE_FOUND
+Windows.Win32.Foundation.ERROR_NO_PROC_SLOTS
+Windows.Win32.Foundation.ERROR_NO_PROMOTION_ACTIVE
+Windows.Win32.Foundation.ERROR_NO_QUOTAS_FOR_ACCOUNT
+Windows.Win32.Foundation.ERROR_NO_RANGES_PROCESSED
+Windows.Win32.Foundation.ERROR_NO_RECOVERY_POLICY
+Windows.Win32.Foundation.ERROR_NO_RECOVERY_PROGRAM
+Windows.Win32.Foundation.ERROR_NO_SCROLLBARS
+Windows.Win32.Foundation.ERROR_NO_SECRETS
+Windows.Win32.Foundation.ERROR_NO_SECURITY_ON_OBJECT
+Windows.Win32.Foundation.ERROR_NO_SHUTDOWN_IN_PROGRESS
+Windows.Win32.Foundation.ERROR_NO_SIGNAL_SENT
+Windows.Win32.Foundation.ERROR_NO_SITE_SETTINGS_OBJECT
+Windows.Win32.Foundation.ERROR_NO_SITENAME
+Windows.Win32.Foundation.ERROR_NO_SPOOL_SPACE
+Windows.Win32.Foundation.ERROR_NO_SUCH_ALIAS
+Windows.Win32.Foundation.ERROR_NO_SUCH_DEVICE
+Windows.Win32.Foundation.ERROR_NO_SUCH_DOMAIN
+Windows.Win32.Foundation.ERROR_NO_SUCH_GROUP
+Windows.Win32.Foundation.ERROR_NO_SUCH_LOGON_SESSION
+Windows.Win32.Foundation.ERROR_NO_SUCH_MEMBER
+Windows.Win32.Foundation.ERROR_NO_SUCH_PACKAGE
+Windows.Win32.Foundation.ERROR_NO_SUCH_PRIVILEGE
+Windows.Win32.Foundation.ERROR_NO_SUCH_SITE
+Windows.Win32.Foundation.ERROR_NO_SUCH_USER
+Windows.Win32.Foundation.ERROR_NO_SYSTEM_MENU
+Windows.Win32.Foundation.ERROR_NO_SYSTEM_RESOURCES
+Windows.Win32.Foundation.ERROR_NO_TASK_QUEUE
+Windows.Win32.Foundation.ERROR_NO_TOKEN
+Windows.Win32.Foundation.ERROR_NO_TRACKING_SERVICE
+Windows.Win32.Foundation.ERROR_NO_TRUST_LSA_SECRET
+Windows.Win32.Foundation.ERROR_NO_TRUST_SAM_ACCOUNT
+Windows.Win32.Foundation.ERROR_NO_UNICODE_TRANSLATION
+Windows.Win32.Foundation.ERROR_NO_USER_KEYS
+Windows.Win32.Foundation.ERROR_NO_USER_SESSION_KEY
+Windows.Win32.Foundation.ERROR_NO_VOLUME_ID
+Windows.Win32.Foundation.ERROR_NO_VOLUME_LABEL
+Windows.Win32.Foundation.ERROR_NO_WILDCARD_CHARACTERS
+Windows.Win32.Foundation.ERROR_NO_WORK_DONE
+Windows.Win32.Foundation.ERROR_NO_WRITABLE_DC_FOUND
+Windows.Win32.Foundation.ERROR_NO_YIELD_PERFORMED
+Windows.Win32.Foundation.ERROR_NOACCESS
+Windows.Win32.Foundation.ERROR_NOINTERFACE
+Windows.Win32.Foundation.ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT
+Windows.Win32.Foundation.ERROR_NOLOGON_SERVER_TRUST_ACCOUNT
+Windows.Win32.Foundation.ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT
+Windows.Win32.Foundation.ERROR_NON_ACCOUNT_SID
+Windows.Win32.Foundation.ERROR_NON_DOMAIN_SID
+Windows.Win32.Foundation.ERROR_NON_MDICHILD_WINDOW
+Windows.Win32.Foundation.ERROR_NONE_MAPPED
+Windows.Win32.Foundation.ERROR_NONPAGED_SYSTEM_RESOURCES
+Windows.Win32.Foundation.ERROR_NOT_A_CLOUD_FILE
+Windows.Win32.Foundation.ERROR_NOT_A_CLOUD_SYNC_ROOT
+Windows.Win32.Foundation.ERROR_NOT_A_DAX_VOLUME
+Windows.Win32.Foundation.ERROR_NOT_A_REPARSE_POINT
+Windows.Win32.Foundation.ERROR_NOT_ALL_ASSIGNED
+Windows.Win32.Foundation.ERROR_NOT_ALLOWED_ON_SYSTEM_FILE
+Windows.Win32.Foundation.ERROR_NOT_APPCONTAINER
+Windows.Win32.Foundation.ERROR_NOT_AUTHENTICATED
+Windows.Win32.Foundation.ERROR_NOT_CAPABLE
+Windows.Win32.Foundation.ERROR_NOT_CHILD_WINDOW
+Windows.Win32.Foundation.ERROR_NOT_CONNECTED
+Windows.Win32.Foundation.ERROR_NOT_CONTAINER
+Windows.Win32.Foundation.ERROR_NOT_DAX_MAPPABLE
+Windows.Win32.Foundation.ERROR_NOT_DOS_DISK
+Windows.Win32.Foundation.ERROR_NOT_ENOUGH_MEMORY
+Windows.Win32.Foundation.ERROR_NOT_ENOUGH_QUOTA
+Windows.Win32.Foundation.ERROR_NOT_ENOUGH_SERVER_MEMORY
+Windows.Win32.Foundation.ERROR_NOT_EXPORT_FORMAT
+Windows.Win32.Foundation.ERROR_NOT_FOUND
+Windows.Win32.Foundation.ERROR_NOT_GUI_PROCESS
+Windows.Win32.Foundation.ERROR_NOT_JOINED
+Windows.Win32.Foundation.ERROR_NOT_LOCKED
+Windows.Win32.Foundation.ERROR_NOT_LOGGED_ON
+Windows.Win32.Foundation.ERROR_NOT_LOGON_PROCESS
+Windows.Win32.Foundation.ERROR_NOT_OWNER
+Windows.Win32.Foundation.ERROR_NOT_READ_FROM_COPY
+Windows.Win32.Foundation.ERROR_NOT_READY
+Windows.Win32.Foundation.ERROR_NOT_REDUNDANT_STORAGE
+Windows.Win32.Foundation.ERROR_NOT_REGISTRY_FILE
+Windows.Win32.Foundation.ERROR_NOT_SAFE_MODE_DRIVER
+Windows.Win32.Foundation.ERROR_NOT_SAFEBOOT_SERVICE
+Windows.Win32.Foundation.ERROR_NOT_SAME_DEVICE
+Windows.Win32.Foundation.ERROR_NOT_SAME_OBJECT
+Windows.Win32.Foundation.ERROR_NOT_SUBSTED
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_IN_APPCONTAINER
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_ON_DAX
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_ON_SBS
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_AUDITING
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_BTT
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_BYPASSIO
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_CACHED_HANDLE
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_COMPRESSION
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_DEDUPLICATION
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_ENCRYPTION
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_MONITORING
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_REPLICATION
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_SNAPSHOT
+Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_VIRTUALIZATION
+Windows.Win32.Foundation.ERROR_NOT_TINY_STREAM
+Windows.Win32.Foundation.ERROR_NOTHING_TO_TERMINATE
+Windows.Win32.Foundation.ERROR_NOTIFICATION_GUID_ALREADY_DEFINED
+Windows.Win32.Foundation.ERROR_NOTIFY_CLEANUP
+Windows.Win32.Foundation.ERROR_NOTIFY_ENUM_DIR
+Windows.Win32.Foundation.ERROR_NT_CROSS_ENCRYPTION_REQUIRED
+Windows.Win32.Foundation.ERROR_NTLM_BLOCKED
+Windows.Win32.Foundation.ERROR_NULL_LM_PASSWORD
+Windows.Win32.Foundation.ERROR_OBJECT_IS_IMMUTABLE
+Windows.Win32.Foundation.ERROR_OBJECT_NAME_EXISTS
+Windows.Win32.Foundation.ERROR_OBJECT_NOT_EXTERNALLY_BACKED
+Windows.Win32.Foundation.ERROR_OFFLOAD_READ_FILE_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_OFFLOAD_READ_FLT_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_OFFLOAD_WRITE_FILE_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_OFFLOAD_WRITE_FLT_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_OFFSET_ALIGNMENT_VIOLATION
+Windows.Win32.Foundation.ERROR_OLD_WIN_VERSION
+Windows.Win32.Foundation.ERROR_ONLY_IF_CONNECTED
+Windows.Win32.Foundation.ERROR_OPEN_FAILED
+Windows.Win32.Foundation.ERROR_OPEN_FILES
+Windows.Win32.Foundation.ERROR_OPERATION_ABORTED
+Windows.Win32.Foundation.ERROR_OPERATION_IN_PROGRESS
+Windows.Win32.Foundation.ERROR_OPLOCK_BREAK_IN_PROGRESS
+Windows.Win32.Foundation.ERROR_OPLOCK_HANDLE_CLOSED
+Windows.Win32.Foundation.ERROR_OPLOCK_NOT_GRANTED
+Windows.Win32.Foundation.ERROR_OPLOCK_SWITCHED_TO_NEW_HANDLE
+Windows.Win32.Foundation.ERROR_ORPHAN_NAME_EXHAUSTED
+Windows.Win32.Foundation.ERROR_OUT_OF_PAPER
+Windows.Win32.Foundation.ERROR_OUT_OF_STRUCTURES
+Windows.Win32.Foundation.ERROR_OUTOFMEMORY
+Windows.Win32.Foundation.ERROR_OVERRIDE_NOCHANGES
+Windows.Win32.Foundation.ERROR_PAGE_FAULT_COPY_ON_WRITE
+Windows.Win32.Foundation.ERROR_PAGE_FAULT_DEMAND_ZERO
+Windows.Win32.Foundation.ERROR_PAGE_FAULT_GUARD_PAGE
+Windows.Win32.Foundation.ERROR_PAGE_FAULT_PAGING_FILE
+Windows.Win32.Foundation.ERROR_PAGE_FAULT_TRANSITION
+Windows.Win32.Foundation.ERROR_PAGED_SYSTEM_RESOURCES
+Windows.Win32.Foundation.ERROR_PAGEFILE_CREATE_FAILED
+Windows.Win32.Foundation.ERROR_PAGEFILE_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_PAGEFILE_QUOTA
+Windows.Win32.Foundation.ERROR_PAGEFILE_QUOTA_EXCEEDED
+Windows.Win32.Foundation.ERROR_PARAMETER_QUOTA_EXCEEDED
+Windows.Win32.Foundation.ERROR_PARTIAL_COPY
+Windows.Win32.Foundation.ERROR_PARTITION_FAILURE
+Windows.Win32.Foundation.ERROR_PARTITION_TERMINATING
+Windows.Win32.Foundation.ERROR_PASSWORD_CHANGE_REQUIRED
+Windows.Win32.Foundation.ERROR_PASSWORD_EXPIRED
+Windows.Win32.Foundation.ERROR_PASSWORD_MUST_CHANGE
+Windows.Win32.Foundation.ERROR_PASSWORD_RESTRICTION
+Windows.Win32.Foundation.ERROR_PATCH_MANAGED_ADVERTISED_PRODUCT
+Windows.Win32.Foundation.ERROR_PATCH_NO_SEQUENCE
+Windows.Win32.Foundation.ERROR_PATCH_PACKAGE_INVALID
+Windows.Win32.Foundation.ERROR_PATCH_PACKAGE_OPEN_FAILED
+Windows.Win32.Foundation.ERROR_PATCH_PACKAGE_REJECTED
+Windows.Win32.Foundation.ERROR_PATCH_PACKAGE_UNSUPPORTED
+Windows.Win32.Foundation.ERROR_PATCH_REMOVAL_DISALLOWED
+Windows.Win32.Foundation.ERROR_PATCH_REMOVAL_UNSUPPORTED
+Windows.Win32.Foundation.ERROR_PATCH_TARGET_NOT_FOUND
+Windows.Win32.Foundation.ERROR_PATH_BUSY
+Windows.Win32.Foundation.ERROR_PATH_NOT_FOUND
+Windows.Win32.Foundation.ERROR_PER_USER_TRUST_QUOTA_EXCEEDED
+Windows.Win32.Foundation.ERROR_PIPE_BUSY
+Windows.Win32.Foundation.ERROR_PIPE_CONNECTED
+Windows.Win32.Foundation.ERROR_PIPE_LISTENING
+Windows.Win32.Foundation.ERROR_PIPE_LOCAL
+Windows.Win32.Foundation.ERROR_PIPE_NOT_CONNECTED
+Windows.Win32.Foundation.ERROR_PKINIT_FAILURE
+Windows.Win32.Foundation.ERROR_PLUGPLAY_QUERY_VETOED
+Windows.Win32.Foundation.ERROR_PNP_BAD_MPS_TABLE
+Windows.Win32.Foundation.ERROR_PNP_INVALID_ID
+Windows.Win32.Foundation.ERROR_PNP_IRQ_TRANSLATION_FAILED
+Windows.Win32.Foundation.ERROR_PNP_QUERY_REMOVE_DEVICE_TIMEOUT
+Windows.Win32.Foundation.ERROR_PNP_QUERY_REMOVE_RELATED_DEVICE_TIMEOUT
+Windows.Win32.Foundation.ERROR_PNP_QUERY_REMOVE_UNRELATED_DEVICE_TIMEOUT
+Windows.Win32.Foundation.ERROR_PNP_REBOOT_REQUIRED
+Windows.Win32.Foundation.ERROR_PNP_RESTART_ENUMERATION
+Windows.Win32.Foundation.ERROR_PNP_TRANSLATION_FAILED
+Windows.Win32.Foundation.ERROR_POINT_NOT_FOUND
+Windows.Win32.Foundation.ERROR_POLICY_OBJECT_NOT_FOUND
+Windows.Win32.Foundation.ERROR_POLICY_ONLY_IN_DS
+Windows.Win32.Foundation.ERROR_POPUP_ALREADY_ACTIVE
+Windows.Win32.Foundation.ERROR_PORT_MESSAGE_TOO_LONG
+Windows.Win32.Foundation.ERROR_PORT_NOT_SET
+Windows.Win32.Foundation.ERROR_PORT_UNREACHABLE
+Windows.Win32.Foundation.ERROR_POSSIBLE_DEADLOCK
+Windows.Win32.Foundation.ERROR_POTENTIAL_FILE_FOUND
+Windows.Win32.Foundation.ERROR_PREDEFINED_HANDLE
+Windows.Win32.Foundation.ERROR_PRIMARY_TRANSPORT_CONNECT_FAILED
+Windows.Win32.Foundation.ERROR_PRINT_CANCELLED
+Windows.Win32.Foundation.ERROR_PRINTER_ALREADY_EXISTS
+Windows.Win32.Foundation.ERROR_PRINTER_DELETED
+Windows.Win32.Foundation.ERROR_PRINTER_DRIVER_ALREADY_INSTALLED
+Windows.Win32.Foundation.ERROR_PRINTQ_FULL
+Windows.Win32.Foundation.ERROR_PRIVATE_DIALOG_INDEX
+Windows.Win32.Foundation.ERROR_PRIVILEGE_NOT_HELD
+Windows.Win32.Foundation.ERROR_PROC_NOT_FOUND
+Windows.Win32.Foundation.ERROR_PROCESS_ABORTED
+Windows.Win32.Foundation.ERROR_PROCESS_IN_JOB
+Windows.Win32.Foundation.ERROR_PROCESS_IS_PROTECTED
+Windows.Win32.Foundation.ERROR_PROCESS_MODE_ALREADY_BACKGROUND
+Windows.Win32.Foundation.ERROR_PROCESS_MODE_NOT_BACKGROUND
+Windows.Win32.Foundation.ERROR_PROCESS_NOT_IN_JOB
+Windows.Win32.Foundation.ERROR_PRODUCT_UNINSTALLED
+Windows.Win32.Foundation.ERROR_PRODUCT_VERSION
+Windows.Win32.Foundation.ERROR_PROFILING_AT_LIMIT
+Windows.Win32.Foundation.ERROR_PROFILING_NOT_STARTED
+Windows.Win32.Foundation.ERROR_PROFILING_NOT_STOPPED
+Windows.Win32.Foundation.ERROR_PROMOTION_ACTIVE
+Windows.Win32.Foundation.ERROR_PROTOCOL_UNREACHABLE
+Windows.Win32.Foundation.ERROR_PWD_HISTORY_CONFLICT
+Windows.Win32.Foundation.ERROR_PWD_TOO_LONG
+Windows.Win32.Foundation.ERROR_PWD_TOO_RECENT
+Windows.Win32.Foundation.ERROR_PWD_TOO_SHORT
+Windows.Win32.Foundation.ERROR_QUOTA_ACTIVITY
+Windows.Win32.Foundation.ERROR_QUOTA_LIST_INCONSISTENT
+Windows.Win32.Foundation.ERROR_RANGE_LIST_CONFLICT
+Windows.Win32.Foundation.ERROR_RANGE_NOT_FOUND
+Windows.Win32.Foundation.ERROR_READ_FAULT
+Windows.Win32.Foundation.ERROR_RECEIVE_EXPEDITED
+Windows.Win32.Foundation.ERROR_RECEIVE_PARTIAL
+Windows.Win32.Foundation.ERROR_RECEIVE_PARTIAL_EXPEDITED
+Windows.Win32.Foundation.ERROR_RECOVERY_FAILURE
+Windows.Win32.Foundation.ERROR_REDIR_PAUSED
+Windows.Win32.Foundation.ERROR_REDIRECTOR_HAS_OPEN_HANDLES
+Windows.Win32.Foundation.ERROR_REG_NAT_CONSUMPTION
+Windows.Win32.Foundation.ERROR_REGISTRY_CORRUPT
+Windows.Win32.Foundation.ERROR_REGISTRY_HIVE_RECOVERED
+Windows.Win32.Foundation.ERROR_REGISTRY_IO_FAILED
+Windows.Win32.Foundation.ERROR_REGISTRY_QUOTA_LIMIT
+Windows.Win32.Foundation.ERROR_REGISTRY_RECOVERED
+Windows.Win32.Foundation.ERROR_RELOC_CHAIN_XEEDS_SEGLIM
+Windows.Win32.Foundation.ERROR_REM_NOT_LIST
+Windows.Win32.Foundation.ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED
+Windows.Win32.Foundation.ERROR_REMOTE_SESSION_LIMIT_EXCEEDED
+Windows.Win32.Foundation.ERROR_REMOTE_STORAGE_MEDIA_ERROR
+Windows.Win32.Foundation.ERROR_REMOTE_STORAGE_NOT_ACTIVE
+Windows.Win32.Foundation.ERROR_REPARSE
+Windows.Win32.Foundation.ERROR_REPARSE_ATTRIBUTE_CONFLICT
+Windows.Win32.Foundation.ERROR_REPARSE_OBJECT
+Windows.Win32.Foundation.ERROR_REPARSE_POINT_ENCOUNTERED
+Windows.Win32.Foundation.ERROR_REPARSE_TAG_INVALID
+Windows.Win32.Foundation.ERROR_REPARSE_TAG_MISMATCH
+Windows.Win32.Foundation.ERROR_REPLY_MESSAGE_MISMATCH
+Windows.Win32.Foundation.ERROR_REQ_NOT_ACCEP
+Windows.Win32.Foundation.ERROR_REQUEST_ABORTED
+Windows.Win32.Foundation.ERROR_REQUEST_OUT_OF_SEQUENCE
+Windows.Win32.Foundation.ERROR_REQUEST_PAUSED
+Windows.Win32.Foundation.ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
+Windows.Win32.Foundation.ERROR_RESIDENT_FILE_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_RESOURCE_CALL_TIMED_OUT
+Windows.Win32.Foundation.ERROR_RESOURCE_DATA_NOT_FOUND
+Windows.Win32.Foundation.ERROR_RESOURCE_LANG_NOT_FOUND
+Windows.Win32.Foundation.ERROR_RESOURCE_NAME_NOT_FOUND
+Windows.Win32.Foundation.ERROR_RESOURCE_REQUIREMENTS_CHANGED
+Windows.Win32.Foundation.ERROR_RESOURCE_TYPE_NOT_FOUND
+Windows.Win32.Foundation.ERROR_RESTART_APPLICATION
+Windows.Win32.Foundation.ERROR_RESUME_HIBERNATION
+Windows.Win32.Foundation.ERROR_RETRY
+Windows.Win32.Foundation.ERROR_RETURN_ADDRESS_HIJACK_ATTEMPT
+Windows.Win32.Foundation.ERROR_REVISION_MISMATCH
+Windows.Win32.Foundation.ERROR_RING2_STACK_IN_USE
+Windows.Win32.Foundation.ERROR_RING2SEG_MUST_BE_MOVABLE
+Windows.Win32.Foundation.ERROR_RMODE_APP
+Windows.Win32.Foundation.ERROR_ROWSNOTRELEASED
+Windows.Win32.Foundation.ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT
+Windows.Win32.Foundation.ERROR_RUNLEVEL_SWITCH_TIMEOUT
+Windows.Win32.Foundation.ERROR_RWRAW_ENCRYPTED_FILE_NOT_ENCRYPTED
+Windows.Win32.Foundation.ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILEOFFSET
+Windows.Win32.Foundation.ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILERANGE
+Windows.Win32.Foundation.ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_PARAMETER
+Windows.Win32.Foundation.ERROR_RXACT_COMMIT_FAILURE
+Windows.Win32.Foundation.ERROR_RXACT_COMMIT_NECESSARY
+Windows.Win32.Foundation.ERROR_RXACT_COMMITTED
+Windows.Win32.Foundation.ERROR_RXACT_INVALID_STATE
+Windows.Win32.Foundation.ERROR_RXACT_STATE_CREATED
+Windows.Win32.Foundation.ERROR_SAM_INIT_FAILURE
+Windows.Win32.Foundation.ERROR_SAME_DRIVE
+Windows.Win32.Foundation.ERROR_SCOPE_NOT_FOUND
+Windows.Win32.Foundation.ERROR_SCREEN_ALREADY_LOCKED
+Windows.Win32.Foundation.ERROR_SCRUB_DATA_DISABLED
+Windows.Win32.Foundation.ERROR_SECRET_TOO_LONG
+Windows.Win32.Foundation.ERROR_SECTION_DIRECT_MAP_ONLY
+Windows.Win32.Foundation.ERROR_SECTOR_NOT_FOUND
+Windows.Win32.Foundation.ERROR_SECURITY_DENIES_OPERATION
+Windows.Win32.Foundation.ERROR_SECURITY_STREAM_IS_INCONSISTENT
+Windows.Win32.Foundation.ERROR_SEEK
+Windows.Win32.Foundation.ERROR_SEEK_ON_DEVICE
+Windows.Win32.Foundation.ERROR_SEGMENT_NOTIFICATION
+Windows.Win32.Foundation.ERROR_SEM_IS_SET
+Windows.Win32.Foundation.ERROR_SEM_NOT_FOUND
+Windows.Win32.Foundation.ERROR_SEM_OWNER_DIED
+Windows.Win32.Foundation.ERROR_SEM_TIMEOUT
+Windows.Win32.Foundation.ERROR_SEM_USER_LIMIT
+Windows.Win32.Foundation.ERROR_SERIAL_NO_DEVICE
+Windows.Win32.Foundation.ERROR_SERVER_DISABLED
+Windows.Win32.Foundation.ERROR_SERVER_HAS_OPEN_HANDLES
+Windows.Win32.Foundation.ERROR_SERVER_NOT_DISABLED
+Windows.Win32.Foundation.ERROR_SERVER_SHUTDOWN_IN_PROGRESS
+Windows.Win32.Foundation.ERROR_SERVER_SID_MISMATCH
+Windows.Win32.Foundation.ERROR_SERVER_TRANSPORT_CONFLICT
+Windows.Win32.Foundation.ERROR_SERVICE_ALREADY_RUNNING
+Windows.Win32.Foundation.ERROR_SERVICE_CANNOT_ACCEPT_CTRL
+Windows.Win32.Foundation.ERROR_SERVICE_DATABASE_LOCKED
+Windows.Win32.Foundation.ERROR_SERVICE_DEPENDENCY_DELETED
+Windows.Win32.Foundation.ERROR_SERVICE_DEPENDENCY_FAIL
+Windows.Win32.Foundation.ERROR_SERVICE_DISABLED
+Windows.Win32.Foundation.ERROR_SERVICE_DOES_NOT_EXIST
+Windows.Win32.Foundation.ERROR_SERVICE_EXISTS
+Windows.Win32.Foundation.ERROR_SERVICE_LOGON_FAILED
+Windows.Win32.Foundation.ERROR_SERVICE_MARKED_FOR_DELETE
+Windows.Win32.Foundation.ERROR_SERVICE_NEVER_STARTED
+Windows.Win32.Foundation.ERROR_SERVICE_NO_THREAD
+Windows.Win32.Foundation.ERROR_SERVICE_NOT_ACTIVE
+Windows.Win32.Foundation.ERROR_SERVICE_NOT_FOUND
+Windows.Win32.Foundation.ERROR_SERVICE_NOT_IN_EXE
+Windows.Win32.Foundation.ERROR_SERVICE_NOTIFICATION
+Windows.Win32.Foundation.ERROR_SERVICE_NOTIFY_CLIENT_LAGGING
+Windows.Win32.Foundation.ERROR_SERVICE_REQUEST_TIMEOUT
+Windows.Win32.Foundation.ERROR_SERVICE_SPECIFIC_ERROR
+Windows.Win32.Foundation.ERROR_SERVICE_START_HANG
+Windows.Win32.Foundation.ERROR_SESSION_CREDENTIAL_CONFLICT
+Windows.Win32.Foundation.ERROR_SESSION_KEY_TOO_SHORT
+Windows.Win32.Foundation.ERROR_SET_CONTEXT_DENIED
+Windows.Win32.Foundation.ERROR_SET_NOT_FOUND
+Windows.Win32.Foundation.ERROR_SET_POWER_STATE_FAILED
+Windows.Win32.Foundation.ERROR_SET_POWER_STATE_VETOED
+Windows.Win32.Foundation.ERROR_SETCOUNT_ON_BAD_LB
+Windows.Win32.Foundation.ERROR_SETMARK_DETECTED
+Windows.Win32.Foundation.ERROR_SHARED_POLICY
+Windows.Win32.Foundation.ERROR_SHARING_BUFFER_EXCEEDED
+Windows.Win32.Foundation.ERROR_SHARING_PAUSED
+Windows.Win32.Foundation.ERROR_SHARING_VIOLATION
+Windows.Win32.Foundation.ERROR_SHORT_NAMES_NOT_ENABLED_ON_VOLUME
+Windows.Win32.Foundation.ERROR_SHUTDOWN_DISKS_NOT_IN_MAINTENANCE_MODE
+Windows.Win32.Foundation.ERROR_SHUTDOWN_IN_PROGRESS
+Windows.Win32.Foundation.ERROR_SHUTDOWN_IS_SCHEDULED
+Windows.Win32.Foundation.ERROR_SHUTDOWN_USERS_LOGGED_ON
+Windows.Win32.Foundation.ERROR_SIGNAL_PENDING
+Windows.Win32.Foundation.ERROR_SIGNAL_REFUSED
+Windows.Win32.Foundation.ERROR_SINGLE_INSTANCE_APP
+Windows.Win32.Foundation.ERROR_SMARTCARD_SUBSYSTEM_FAILURE
+Windows.Win32.Foundation.ERROR_SMB1_NOT_AVAILABLE
+Windows.Win32.Foundation.ERROR_SMB_GUEST_LOGON_BLOCKED
+Windows.Win32.Foundation.ERROR_SMR_GARBAGE_COLLECTION_REQUIRED
+Windows.Win32.Foundation.ERROR_SOME_NOT_MAPPED
+Windows.Win32.Foundation.ERROR_SOURCE_ELEMENT_EMPTY
+Windows.Win32.Foundation.ERROR_SPARSE_FILE_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_SPECIAL_ACCOUNT
+Windows.Win32.Foundation.ERROR_SPECIAL_GROUP
+Windows.Win32.Foundation.ERROR_SPECIAL_USER
+Windows.Win32.Foundation.ERROR_SRC_SRV_DLL_LOAD_FAILED
+Windows.Win32.Foundation.ERROR_STACK_BUFFER_OVERRUN
+Windows.Win32.Foundation.ERROR_STACK_OVERFLOW
+Windows.Win32.Foundation.ERROR_STACK_OVERFLOW_READ
+Windows.Win32.Foundation.ERROR_STOPPED_ON_SYMLINK
+Windows.Win32.Foundation.ERROR_STORAGE_LOST_DATA_PERSISTENCE
+Windows.Win32.Foundation.ERROR_STORAGE_RESERVE_ALREADY_EXISTS
+Windows.Win32.Foundation.ERROR_STORAGE_RESERVE_DOES_NOT_EXIST
+Windows.Win32.Foundation.ERROR_STORAGE_RESERVE_ID_INVALID
+Windows.Win32.Foundation.ERROR_STORAGE_RESERVE_NOT_EMPTY
+Windows.Win32.Foundation.ERROR_STORAGE_STACK_ACCESS_DENIED
+Windows.Win32.Foundation.ERROR_STORAGE_TOPOLOGY_ID_MISMATCH
+Windows.Win32.Foundation.ERROR_STRICT_CFG_VIOLATION
+Windows.Win32.Foundation.ERROR_SUBST_TO_JOIN
+Windows.Win32.Foundation.ERROR_SUBST_TO_SUBST
+Windows.Win32.Foundation.ERROR_SUCCESS
+Windows.Win32.Foundation.ERROR_SUCCESS_REBOOT_INITIATED
+Windows.Win32.Foundation.ERROR_SWAPERROR
+Windows.Win32.Foundation.ERROR_SYMLINK_CLASS_DISABLED
+Windows.Win32.Foundation.ERROR_SYMLINK_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED
+Windows.Win32.Foundation.ERROR_SYNCHRONIZATION_REQUIRED
+Windows.Win32.Foundation.ERROR_SYSTEM_HIVE_TOO_LARGE
+Windows.Win32.Foundation.ERROR_SYSTEM_IMAGE_BAD_SIGNATURE
+Windows.Win32.Foundation.ERROR_SYSTEM_POWERSTATE_COMPLEX_TRANSITION
+Windows.Win32.Foundation.ERROR_SYSTEM_POWERSTATE_TRANSITION
+Windows.Win32.Foundation.ERROR_SYSTEM_PROCESS_TERMINATED
+Windows.Win32.Foundation.ERROR_SYSTEM_SHUTDOWN
+Windows.Win32.Foundation.ERROR_SYSTEM_TRACE
+Windows.Win32.Foundation.ERROR_THREAD_1_INACTIVE
+Windows.Win32.Foundation.ERROR_THREAD_ALREADY_IN_TASK
+Windows.Win32.Foundation.ERROR_THREAD_MODE_ALREADY_BACKGROUND
+Windows.Win32.Foundation.ERROR_THREAD_MODE_NOT_BACKGROUND
+Windows.Win32.Foundation.ERROR_THREAD_NOT_IN_PROCESS
+Windows.Win32.Foundation.ERROR_THREAD_WAS_SUSPENDED
+Windows.Win32.Foundation.ERROR_TIME_SENSITIVE_THREAD
+Windows.Win32.Foundation.ERROR_TIME_SKEW
+Windows.Win32.Foundation.ERROR_TIMEOUT
+Windows.Win32.Foundation.ERROR_TIMER_NOT_CANCELED
+Windows.Win32.Foundation.ERROR_TIMER_RESOLUTION_NOT_SET
+Windows.Win32.Foundation.ERROR_TIMER_RESUME_IGNORED
+Windows.Win32.Foundation.ERROR_TLW_WITH_WSCHILD
+Windows.Win32.Foundation.ERROR_TOKEN_ALREADY_IN_USE
+Windows.Win32.Foundation.ERROR_TOO_MANY_CMDS
+Windows.Win32.Foundation.ERROR_TOO_MANY_CONTEXT_IDS
+Windows.Win32.Foundation.ERROR_TOO_MANY_DESCRIPTORS
+Windows.Win32.Foundation.ERROR_TOO_MANY_LINKS
+Windows.Win32.Foundation.ERROR_TOO_MANY_LUIDS_REQUESTED
+Windows.Win32.Foundation.ERROR_TOO_MANY_MODULES
+Windows.Win32.Foundation.ERROR_TOO_MANY_MUXWAITERS
+Windows.Win32.Foundation.ERROR_TOO_MANY_NAMES
+Windows.Win32.Foundation.ERROR_TOO_MANY_OPEN_FILES
+Windows.Win32.Foundation.ERROR_TOO_MANY_POSTS
+Windows.Win32.Foundation.ERROR_TOO_MANY_SECRETS
+Windows.Win32.Foundation.ERROR_TOO_MANY_SEM_REQUESTS
+Windows.Win32.Foundation.ERROR_TOO_MANY_SEMAPHORES
+Windows.Win32.Foundation.ERROR_TOO_MANY_SESS
+Windows.Win32.Foundation.ERROR_TOO_MANY_SIDS
+Windows.Win32.Foundation.ERROR_TOO_MANY_TCBS
+Windows.Win32.Foundation.ERROR_TOO_MANY_THREADS
+Windows.Win32.Foundation.ERROR_TRANSLATION_COMPLETE
+Windows.Win32.Foundation.ERROR_TRUST_FAILURE
+Windows.Win32.Foundation.ERROR_TRUSTED_DOMAIN_FAILURE
+Windows.Win32.Foundation.ERROR_TRUSTED_RELATIONSHIP_FAILURE
+Windows.Win32.Foundation.ERROR_UNABLE_TO_LOCK_MEDIA
+Windows.Win32.Foundation.ERROR_UNABLE_TO_MOVE_REPLACEMENT
+Windows.Win32.Foundation.ERROR_UNABLE_TO_MOVE_REPLACEMENT_2
+Windows.Win32.Foundation.ERROR_UNABLE_TO_REMOVE_REPLACED
+Windows.Win32.Foundation.ERROR_UNABLE_TO_UNLOAD_MEDIA
+Windows.Win32.Foundation.ERROR_UNDEFINED_CHARACTER
+Windows.Win32.Foundation.ERROR_UNDEFINED_SCOPE
+Windows.Win32.Foundation.ERROR_UNEXP_NET_ERR
+Windows.Win32.Foundation.ERROR_UNEXPECTED_MM_CREATE_ERR
+Windows.Win32.Foundation.ERROR_UNEXPECTED_MM_EXTEND_ERR
+Windows.Win32.Foundation.ERROR_UNEXPECTED_MM_MAP_ERROR
+Windows.Win32.Foundation.ERROR_UNEXPECTED_NTCACHEMANAGER_ERROR
+Windows.Win32.Foundation.ERROR_UNHANDLED_EXCEPTION
+Windows.Win32.Foundation.ERROR_UNIDENTIFIED_ERROR
+Windows.Win32.Foundation.ERROR_UNKNOWN_COMPONENT
+Windows.Win32.Foundation.ERROR_UNKNOWN_FEATURE
+Windows.Win32.Foundation.ERROR_UNKNOWN_PATCH
+Windows.Win32.Foundation.ERROR_UNKNOWN_PORT
+Windows.Win32.Foundation.ERROR_UNKNOWN_PRINTER_DRIVER
+Windows.Win32.Foundation.ERROR_UNKNOWN_PRINTPROCESSOR
+Windows.Win32.Foundation.ERROR_UNKNOWN_PRODUCT
+Windows.Win32.Foundation.ERROR_UNKNOWN_PROPERTY
+Windows.Win32.Foundation.ERROR_UNKNOWN_REVISION
+Windows.Win32.Foundation.ERROR_UNRECOGNIZED_MEDIA
+Windows.Win32.Foundation.ERROR_UNRECOGNIZED_VOLUME
+Windows.Win32.Foundation.ERROR_UNSATISFIED_DEPENDENCIES
+Windows.Win32.Foundation.ERROR_UNSUPPORTED_COMPRESSION
+Windows.Win32.Foundation.ERROR_UNSUPPORTED_TYPE
+Windows.Win32.Foundation.ERROR_UNTRUSTED_MOUNT_POINT
+Windows.Win32.Foundation.ERROR_UNWIND
+Windows.Win32.Foundation.ERROR_UNWIND_CONSOLIDATE
+Windows.Win32.Foundation.ERROR_USER_APC
+Windows.Win32.Foundation.ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED
+Windows.Win32.Foundation.ERROR_USER_EXISTS
+Windows.Win32.Foundation.ERROR_USER_MAPPED_FILE
+Windows.Win32.Foundation.ERROR_USER_PROFILE_LOAD
+Windows.Win32.Foundation.ERROR_VALIDATE_CONTINUE
+Windows.Win32.Foundation.ERROR_VC_DISCONNECTED
+Windows.Win32.Foundation.ERROR_VDM_DISALLOWED
+Windows.Win32.Foundation.ERROR_VDM_HARD_ERROR
+Windows.Win32.Foundation.ERROR_VERIFIER_STOP
+Windows.Win32.Foundation.ERROR_VERSION_PARSE_ERROR
+Windows.Win32.Foundation.ERROR_VIRUS_DELETED
+Windows.Win32.Foundation.ERROR_VIRUS_INFECTED
+Windows.Win32.Foundation.ERROR_VOLSNAP_HIBERNATE_READY
+Windows.Win32.Foundation.ERROR_VOLSNAP_PREPARE_HIBERNATE
+Windows.Win32.Foundation.ERROR_VOLUME_MOUNTED
+Windows.Win32.Foundation.ERROR_VOLUME_NOT_CLUSTER_ALIGNED
+Windows.Win32.Foundation.ERROR_VOLUME_NOT_SIS_ENABLED
+Windows.Win32.Foundation.ERROR_VOLUME_NOT_SUPPORT_EFS
+Windows.Win32.Foundation.ERROR_VOLUME_NOT_SUPPORTED
+Windows.Win32.Foundation.ERROR_VOLUME_WRITE_ACCESS_DENIED
+Windows.Win32.Foundation.ERROR_WAIT_1
+Windows.Win32.Foundation.ERROR_WAIT_2
+Windows.Win32.Foundation.ERROR_WAIT_3
+Windows.Win32.Foundation.ERROR_WAIT_63
+Windows.Win32.Foundation.ERROR_WAIT_FOR_OPLOCK
+Windows.Win32.Foundation.ERROR_WAIT_NO_CHILDREN
+Windows.Win32.Foundation.ERROR_WAKE_SYSTEM
+Windows.Win32.Foundation.ERROR_WAKE_SYSTEM_DEBUGGER
+Windows.Win32.Foundation.ERROR_WAS_LOCKED
+Windows.Win32.Foundation.ERROR_WAS_UNLOCKED
+Windows.Win32.Foundation.ERROR_WEAK_WHFBKEY_BLOCKED
+Windows.Win32.Foundation.ERROR_WINDOW_NOT_COMBOBOX
+Windows.Win32.Foundation.ERROR_WINDOW_NOT_DIALOG
+Windows.Win32.Foundation.ERROR_WINDOW_OF_OTHER_THREAD
+Windows.Win32.Foundation.ERROR_WIP_ENCRYPTION_FAILED
+Windows.Win32.Foundation.ERROR_WOF_FILE_RESOURCE_TABLE_CORRUPT
+Windows.Win32.Foundation.ERROR_WOF_WIM_HEADER_CORRUPT
+Windows.Win32.Foundation.ERROR_WOF_WIM_RESOURCE_TABLE_CORRUPT
+Windows.Win32.Foundation.ERROR_WORKING_SET_QUOTA
+Windows.Win32.Foundation.ERROR_WOW_ASSERTION
+Windows.Win32.Foundation.ERROR_WRITE_FAULT
+Windows.Win32.Foundation.ERROR_WRITE_PROTECT
+Windows.Win32.Foundation.ERROR_WRONG_COMPARTMENT
+Windows.Win32.Foundation.ERROR_WRONG_DISK
+Windows.Win32.Foundation.ERROR_WRONG_EFS
+Windows.Win32.Foundation.ERROR_WRONG_PASSWORD
+Windows.Win32.Foundation.ERROR_WRONG_TARGET_NAME
+Windows.Win32.Foundation.ERROR_WX86_ERROR
+Windows.Win32.Foundation.ERROR_WX86_WARNING
+Windows.Win32.Foundation.ERROR_XML_PARSE_ERROR
+Windows.Win32.Foundation.ERROR_XMLDSIG_ERROR
+Windows.Win32.Foundation.EXCEPTION_STACK_OVERFLOW
+Windows.Win32.Foundation.FALSE
+Windows.Win32.Foundation.FARPROC
+Windows.Win32.Foundation.FILETIME
+Windows.Win32.Foundation.FRS_ERR_SYSVOL_POPULATE_TIMEOUT
+Windows.Win32.Foundation.GENERIC_ACCESS_RIGHTS
+Windows.Win32.Foundation.GENERIC_ALL
+Windows.Win32.Foundation.GENERIC_EXECUTE
+Windows.Win32.Foundation.GENERIC_READ
+Windows.Win32.Foundation.GENERIC_WRITE
+Windows.Win32.Foundation.GetLastError
+Windows.Win32.Foundation.HANDLE
+Windows.Win32.Foundation.HANDLE_FLAG_INHERIT
+Windows.Win32.Foundation.HANDLE_FLAG_PROTECT_FROM_CLOSE
+Windows.Win32.Foundation.HANDLE_FLAGS
+Windows.Win32.Foundation.HMODULE
+Windows.Win32.Foundation.INVALID_HANDLE_VALUE
+Windows.Win32.Foundation.MAX_PATH
+Windows.Win32.Foundation.NO_ERROR
+Windows.Win32.Foundation.NTSTATUS
+Windows.Win32.Foundation.RtlNtStatusToDosError
+Windows.Win32.Foundation.SetHandleInformation
+Windows.Win32.Foundation.SetLastError
+Windows.Win32.Foundation.STATUS_DELETE_PENDING
+Windows.Win32.Foundation.STATUS_END_OF_FILE
+Windows.Win32.Foundation.STATUS_INVALID_PARAMETER
+Windows.Win32.Foundation.STATUS_PENDING
+Windows.Win32.Foundation.STATUS_SUCCESS
+Windows.Win32.Foundation.TRUE
+Windows.Win32.Foundation.UNICODE_STRING
+Windows.Win32.Foundation.WAIT_ABANDONED
+Windows.Win32.Foundation.WAIT_ABANDONED_0
+Windows.Win32.Foundation.WAIT_FAILED
+Windows.Win32.Foundation.WAIT_IO_COMPLETION
+Windows.Win32.Foundation.WAIT_OBJECT_0
+Windows.Win32.Foundation.WAIT_TIMEOUT
+Windows.Win32.Foundation.WIN32_ERROR
+Windows.Win32.Globalization.COMPARESTRING_RESULT
+Windows.Win32.Globalization.CompareStringOrdinal
+Windows.Win32.Globalization.CP_UTF8
+Windows.Win32.Globalization.CSTR_EQUAL
+Windows.Win32.Globalization.CSTR_GREATER_THAN
+Windows.Win32.Globalization.CSTR_LESS_THAN
+Windows.Win32.Globalization.MB_COMPOSITE
+Windows.Win32.Globalization.MB_ERR_INVALID_CHARS
+Windows.Win32.Globalization.MB_PRECOMPOSED
+Windows.Win32.Globalization.MB_USEGLYPHCHARS
+Windows.Win32.Globalization.MULTI_BYTE_TO_WIDE_CHAR_FLAGS
+Windows.Win32.Globalization.MultiByteToWideChar
+Windows.Win32.Globalization.WC_ERR_INVALID_CHARS
+Windows.Win32.Globalization.WideCharToMultiByte
+Windows.Win32.Networking.WinSock.accept
+Windows.Win32.Networking.WinSock.ADDRESS_FAMILY
+Windows.Win32.Networking.WinSock.ADDRINFOA
+Windows.Win32.Networking.WinSock.AF_INET
+Windows.Win32.Networking.WinSock.AF_INET6
+Windows.Win32.Networking.WinSock.AF_UNSPEC
+Windows.Win32.Networking.WinSock.bind
+Windows.Win32.Networking.WinSock.closesocket
+Windows.Win32.Networking.WinSock.connect
+Windows.Win32.Networking.WinSock.FD_SET
+Windows.Win32.Networking.WinSock.FIONBIO
+Windows.Win32.Networking.WinSock.freeaddrinfo
+Windows.Win32.Networking.WinSock.getaddrinfo
+Windows.Win32.Networking.WinSock.getpeername
+Windows.Win32.Networking.WinSock.getsockname
+Windows.Win32.Networking.WinSock.getsockopt
+Windows.Win32.Networking.WinSock.IN6_ADDR
+Windows.Win32.Networking.WinSock.IN_ADDR
+Windows.Win32.Networking.WinSock.INVALID_SOCKET
+Windows.Win32.Networking.WinSock.ioctlsocket
+Windows.Win32.Networking.WinSock.IP_ADD_MEMBERSHIP
+Windows.Win32.Networking.WinSock.IP_DROP_MEMBERSHIP
+Windows.Win32.Networking.WinSock.IP_MREQ
+Windows.Win32.Networking.WinSock.IP_MULTICAST_LOOP
+Windows.Win32.Networking.WinSock.IP_MULTICAST_TTL
+Windows.Win32.Networking.WinSock.IP_TTL
+Windows.Win32.Networking.WinSock.IPPROTO
+Windows.Win32.Networking.WinSock.IPPROTO_AH
+Windows.Win32.Networking.WinSock.IPPROTO_CBT
+Windows.Win32.Networking.WinSock.IPPROTO_DSTOPTS
+Windows.Win32.Networking.WinSock.IPPROTO_EGP
+Windows.Win32.Networking.WinSock.IPPROTO_ESP
+Windows.Win32.Networking.WinSock.IPPROTO_FRAGMENT
+Windows.Win32.Networking.WinSock.IPPROTO_GGP
+Windows.Win32.Networking.WinSock.IPPROTO_HOPOPTS
+Windows.Win32.Networking.WinSock.IPPROTO_ICLFXBM
+Windows.Win32.Networking.WinSock.IPPROTO_ICMP
+Windows.Win32.Networking.WinSock.IPPROTO_ICMPV6
+Windows.Win32.Networking.WinSock.IPPROTO_IDP
+Windows.Win32.Networking.WinSock.IPPROTO_IGMP
+Windows.Win32.Networking.WinSock.IPPROTO_IGP
+Windows.Win32.Networking.WinSock.IPPROTO_IP
+Windows.Win32.Networking.WinSock.IPPROTO_IPV4
+Windows.Win32.Networking.WinSock.IPPROTO_IPV6
+Windows.Win32.Networking.WinSock.IPPROTO_L2TP
+Windows.Win32.Networking.WinSock.IPPROTO_MAX
+Windows.Win32.Networking.WinSock.IPPROTO_ND
+Windows.Win32.Networking.WinSock.IPPROTO_NONE
+Windows.Win32.Networking.WinSock.IPPROTO_PGM
+Windows.Win32.Networking.WinSock.IPPROTO_PIM
+Windows.Win32.Networking.WinSock.IPPROTO_PUP
+Windows.Win32.Networking.WinSock.IPPROTO_RAW
+Windows.Win32.Networking.WinSock.IPPROTO_RDP
+Windows.Win32.Networking.WinSock.IPPROTO_RESERVED_IPSEC
+Windows.Win32.Networking.WinSock.IPPROTO_RESERVED_IPSECOFFLOAD
+Windows.Win32.Networking.WinSock.IPPROTO_RESERVED_MAX
+Windows.Win32.Networking.WinSock.IPPROTO_RESERVED_RAW
+Windows.Win32.Networking.WinSock.IPPROTO_RESERVED_WNV
+Windows.Win32.Networking.WinSock.IPPROTO_RM
+Windows.Win32.Networking.WinSock.IPPROTO_ROUTING
+Windows.Win32.Networking.WinSock.IPPROTO_SCTP
+Windows.Win32.Networking.WinSock.IPPROTO_ST
+Windows.Win32.Networking.WinSock.IPPROTO_TCP
+Windows.Win32.Networking.WinSock.IPPROTO_UDP
+Windows.Win32.Networking.WinSock.IPV6_ADD_MEMBERSHIP
+Windows.Win32.Networking.WinSock.IPV6_DROP_MEMBERSHIP
+Windows.Win32.Networking.WinSock.IPV6_MREQ
+Windows.Win32.Networking.WinSock.IPV6_MULTICAST_LOOP
+Windows.Win32.Networking.WinSock.IPV6_V6ONLY
+Windows.Win32.Networking.WinSock.LINGER
+Windows.Win32.Networking.WinSock.listen
+Windows.Win32.Networking.WinSock.LPWSAOVERLAPPED_COMPLETION_ROUTINE
+Windows.Win32.Networking.WinSock.MSG_DONTROUTE
+Windows.Win32.Networking.WinSock.MSG_OOB
+Windows.Win32.Networking.WinSock.MSG_PEEK
+Windows.Win32.Networking.WinSock.MSG_PUSH_IMMEDIATE
+Windows.Win32.Networking.WinSock.MSG_WAITALL
+Windows.Win32.Networking.WinSock.recv
+Windows.Win32.Networking.WinSock.recvfrom
+Windows.Win32.Networking.WinSock.SD_BOTH
+Windows.Win32.Networking.WinSock.SD_RECEIVE
+Windows.Win32.Networking.WinSock.SD_SEND
+Windows.Win32.Networking.WinSock.select
+Windows.Win32.Networking.WinSock.send
+Windows.Win32.Networking.WinSock.SEND_RECV_FLAGS
+Windows.Win32.Networking.WinSock.sendto
+Windows.Win32.Networking.WinSock.setsockopt
+Windows.Win32.Networking.WinSock.shutdown
+Windows.Win32.Networking.WinSock.SO_BROADCAST
+Windows.Win32.Networking.WinSock.SO_ERROR
+Windows.Win32.Networking.WinSock.SO_LINGER
+Windows.Win32.Networking.WinSock.SO_RCVTIMEO
+Windows.Win32.Networking.WinSock.SO_SNDTIMEO
+Windows.Win32.Networking.WinSock.SOCK_DGRAM
+Windows.Win32.Networking.WinSock.SOCK_RAW
+Windows.Win32.Networking.WinSock.SOCK_RDM
+Windows.Win32.Networking.WinSock.SOCK_SEQPACKET
+Windows.Win32.Networking.WinSock.SOCK_STREAM
+Windows.Win32.Networking.WinSock.SOCKADDR
+Windows.Win32.Networking.WinSock.SOCKET
+Windows.Win32.Networking.WinSock.SOCKET_ERROR
+Windows.Win32.Networking.WinSock.SOL_SOCKET
+Windows.Win32.Networking.WinSock.TCP_NODELAY
+Windows.Win32.Networking.WinSock.TIMEVAL
+Windows.Win32.Networking.WinSock.WINSOCK_SHUTDOWN_HOW
+Windows.Win32.Networking.WinSock.WINSOCK_SOCKET_TYPE
+Windows.Win32.Networking.WinSock.WSA_E_CANCELLED
+Windows.Win32.Networking.WinSock.WSA_E_NO_MORE
+Windows.Win32.Networking.WinSock.WSA_ERROR
+Windows.Win32.Networking.WinSock.WSA_FLAG_NO_HANDLE_INHERIT
+Windows.Win32.Networking.WinSock.WSA_FLAG_OVERLAPPED
+Windows.Win32.Networking.WinSock.WSA_INVALID_HANDLE
+Windows.Win32.Networking.WinSock.WSA_INVALID_PARAMETER
+Windows.Win32.Networking.WinSock.WSA_IO_INCOMPLETE
+Windows.Win32.Networking.WinSock.WSA_IO_PENDING
+Windows.Win32.Networking.WinSock.WSA_IPSEC_NAME_POLICY_ERROR
+Windows.Win32.Networking.WinSock.WSA_NOT_ENOUGH_MEMORY
+Windows.Win32.Networking.WinSock.WSA_OPERATION_ABORTED
+Windows.Win32.Networking.WinSock.WSA_QOS_ADMISSION_FAILURE
+Windows.Win32.Networking.WinSock.WSA_QOS_BAD_OBJECT
+Windows.Win32.Networking.WinSock.WSA_QOS_BAD_STYLE
+Windows.Win32.Networking.WinSock.WSA_QOS_EFILTERCOUNT
+Windows.Win32.Networking.WinSock.WSA_QOS_EFILTERSTYLE
+Windows.Win32.Networking.WinSock.WSA_QOS_EFILTERTYPE
+Windows.Win32.Networking.WinSock.WSA_QOS_EFLOWCOUNT
+Windows.Win32.Networking.WinSock.WSA_QOS_EFLOWDESC
+Windows.Win32.Networking.WinSock.WSA_QOS_EFLOWSPEC
+Windows.Win32.Networking.WinSock.WSA_QOS_EOBJLENGTH
+Windows.Win32.Networking.WinSock.WSA_QOS_EPOLICYOBJ
+Windows.Win32.Networking.WinSock.WSA_QOS_EPROVSPECBUF
+Windows.Win32.Networking.WinSock.WSA_QOS_EPSFILTERSPEC
+Windows.Win32.Networking.WinSock.WSA_QOS_EPSFLOWSPEC
+Windows.Win32.Networking.WinSock.WSA_QOS_ESDMODEOBJ
+Windows.Win32.Networking.WinSock.WSA_QOS_ESERVICETYPE
+Windows.Win32.Networking.WinSock.WSA_QOS_ESHAPERATEOBJ
+Windows.Win32.Networking.WinSock.WSA_QOS_EUNKOWNPSOBJ
+Windows.Win32.Networking.WinSock.WSA_QOS_GENERIC_ERROR
+Windows.Win32.Networking.WinSock.WSA_QOS_NO_RECEIVERS
+Windows.Win32.Networking.WinSock.WSA_QOS_NO_SENDERS
+Windows.Win32.Networking.WinSock.WSA_QOS_POLICY_FAILURE
+Windows.Win32.Networking.WinSock.WSA_QOS_RECEIVERS
+Windows.Win32.Networking.WinSock.WSA_QOS_REQUEST_CONFIRMED
+Windows.Win32.Networking.WinSock.WSA_QOS_RESERVED_PETYPE
+Windows.Win32.Networking.WinSock.WSA_QOS_SENDERS
+Windows.Win32.Networking.WinSock.WSA_QOS_TRAFFIC_CTRL_ERROR
+Windows.Win32.Networking.WinSock.WSA_SECURE_HOST_NOT_FOUND
+Windows.Win32.Networking.WinSock.WSA_WAIT_EVENT_0
+Windows.Win32.Networking.WinSock.WSA_WAIT_IO_COMPLETION
+Windows.Win32.Networking.WinSock.WSABASEERR
+Windows.Win32.Networking.WinSock.WSABUF
+Windows.Win32.Networking.WinSock.WSACleanup
+Windows.Win32.Networking.WinSock.WSADATA
+Windows.Win32.Networking.WinSock.WSADATA
+Windows.Win32.Networking.WinSock.WSADuplicateSocketW
+Windows.Win32.Networking.WinSock.WSAEACCES
+Windows.Win32.Networking.WinSock.WSAEADDRINUSE
+Windows.Win32.Networking.WinSock.WSAEADDRNOTAVAIL
+Windows.Win32.Networking.WinSock.WSAEAFNOSUPPORT
+Windows.Win32.Networking.WinSock.WSAEALREADY
+Windows.Win32.Networking.WinSock.WSAEBADF
+Windows.Win32.Networking.WinSock.WSAECANCELLED
+Windows.Win32.Networking.WinSock.WSAECONNABORTED
+Windows.Win32.Networking.WinSock.WSAECONNREFUSED
+Windows.Win32.Networking.WinSock.WSAECONNRESET
+Windows.Win32.Networking.WinSock.WSAEDESTADDRREQ
+Windows.Win32.Networking.WinSock.WSAEDISCON
+Windows.Win32.Networking.WinSock.WSAEDQUOT
+Windows.Win32.Networking.WinSock.WSAEFAULT
+Windows.Win32.Networking.WinSock.WSAEHOSTDOWN
+Windows.Win32.Networking.WinSock.WSAEHOSTUNREACH
+Windows.Win32.Networking.WinSock.WSAEINPROGRESS
+Windows.Win32.Networking.WinSock.WSAEINTR
+Windows.Win32.Networking.WinSock.WSAEINVAL
+Windows.Win32.Networking.WinSock.WSAEINVALIDPROCTABLE
+Windows.Win32.Networking.WinSock.WSAEINVALIDPROVIDER
+Windows.Win32.Networking.WinSock.WSAEISCONN
+Windows.Win32.Networking.WinSock.WSAELOOP
+Windows.Win32.Networking.WinSock.WSAEMFILE
+Windows.Win32.Networking.WinSock.WSAEMSGSIZE
+Windows.Win32.Networking.WinSock.WSAENAMETOOLONG
+Windows.Win32.Networking.WinSock.WSAENETDOWN
+Windows.Win32.Networking.WinSock.WSAENETRESET
+Windows.Win32.Networking.WinSock.WSAENETUNREACH
+Windows.Win32.Networking.WinSock.WSAENOBUFS
+Windows.Win32.Networking.WinSock.WSAENOMORE
+Windows.Win32.Networking.WinSock.WSAENOPROTOOPT
+Windows.Win32.Networking.WinSock.WSAENOTCONN
+Windows.Win32.Networking.WinSock.WSAENOTEMPTY
+Windows.Win32.Networking.WinSock.WSAENOTSOCK
+Windows.Win32.Networking.WinSock.WSAEOPNOTSUPP
+Windows.Win32.Networking.WinSock.WSAEPFNOSUPPORT
+Windows.Win32.Networking.WinSock.WSAEPROCLIM
+Windows.Win32.Networking.WinSock.WSAEPROTONOSUPPORT
+Windows.Win32.Networking.WinSock.WSAEPROTOTYPE
+Windows.Win32.Networking.WinSock.WSAEPROVIDERFAILEDINIT
+Windows.Win32.Networking.WinSock.WSAEREFUSED
+Windows.Win32.Networking.WinSock.WSAEREMOTE
+Windows.Win32.Networking.WinSock.WSAESHUTDOWN
+Windows.Win32.Networking.WinSock.WSAESOCKTNOSUPPORT
+Windows.Win32.Networking.WinSock.WSAESTALE
+Windows.Win32.Networking.WinSock.WSAETIMEDOUT
+Windows.Win32.Networking.WinSock.WSAETOOMANYREFS
+Windows.Win32.Networking.WinSock.WSAEUSERS
+Windows.Win32.Networking.WinSock.WSAEWOULDBLOCK
+Windows.Win32.Networking.WinSock.WSAGetLastError
+Windows.Win32.Networking.WinSock.WSAHOST_NOT_FOUND
+Windows.Win32.Networking.WinSock.WSANO_DATA
+Windows.Win32.Networking.WinSock.WSANO_RECOVERY
+Windows.Win32.Networking.WinSock.WSANOTINITIALISED
+Windows.Win32.Networking.WinSock.WSAPROTOCOL_INFOW
+Windows.Win32.Networking.WinSock.WSAPROTOCOLCHAIN
+Windows.Win32.Networking.WinSock.WSARecv
+Windows.Win32.Networking.WinSock.WSASend
+Windows.Win32.Networking.WinSock.WSASERVICE_NOT_FOUND
+Windows.Win32.Networking.WinSock.WSASocketW
+Windows.Win32.Networking.WinSock.WSAStartup
+Windows.Win32.Networking.WinSock.WSASYSCALLFAILURE
+Windows.Win32.Networking.WinSock.WSASYSNOTREADY
+Windows.Win32.Networking.WinSock.WSATRY_AGAIN
+Windows.Win32.Networking.WinSock.WSATYPE_NOT_FOUND
+Windows.Win32.Networking.WinSock.WSAVERNOTSUPPORTED
+Windows.Win32.Security.Authentication.Identity.RtlGenRandom
+Windows.Win32.Security.Cryptography.BCRYPT_ALG_HANDLE
+Windows.Win32.Security.Cryptography.BCRYPT_USE_SYSTEM_PREFERRED_RNG
+Windows.Win32.Security.Cryptography.BCryptGenRandom
+Windows.Win32.Security.Cryptography.BCRYPTGENRANDOM_FLAGS
+Windows.Win32.Security.SECURITY_ATTRIBUTES
+Windows.Win32.Security.TOKEN_ACCESS_MASK
+Windows.Win32.Security.TOKEN_ACCESS_PSEUDO_HANDLE
+Windows.Win32.Security.TOKEN_ACCESS_PSEUDO_HANDLE_WIN8
+Windows.Win32.Security.TOKEN_ACCESS_SYSTEM_SECURITY
+Windows.Win32.Security.TOKEN_ADJUST_DEFAULT
+Windows.Win32.Security.TOKEN_ADJUST_GROUPS
+Windows.Win32.Security.TOKEN_ADJUST_PRIVILEGES
+Windows.Win32.Security.TOKEN_ADJUST_SESSIONID
+Windows.Win32.Security.TOKEN_ALL_ACCESS
+Windows.Win32.Security.TOKEN_ASSIGN_PRIMARY
+Windows.Win32.Security.TOKEN_DELETE
+Windows.Win32.Security.TOKEN_DUPLICATE
+Windows.Win32.Security.TOKEN_EXECUTE
+Windows.Win32.Security.TOKEN_IMPERSONATE
+Windows.Win32.Security.TOKEN_QUERY
+Windows.Win32.Security.TOKEN_QUERY_SOURCE
+Windows.Win32.Security.TOKEN_READ
+Windows.Win32.Security.TOKEN_READ_CONTROL
+Windows.Win32.Security.TOKEN_TRUST_CONSTRAINT_MASK
+Windows.Win32.Security.TOKEN_WRITE
+Windows.Win32.Security.TOKEN_WRITE_DAC
+Windows.Win32.Security.TOKEN_WRITE_OWNER
+Windows.Win32.Storage.FileSystem.BY_HANDLE_FILE_INFORMATION
+Windows.Win32.Storage.FileSystem.CALLBACK_CHUNK_FINISHED
+Windows.Win32.Storage.FileSystem.CALLBACK_STREAM_SWITCH
+Windows.Win32.Storage.FileSystem.CopyFileExW
+Windows.Win32.Storage.FileSystem.CREATE_ALWAYS
+Windows.Win32.Storage.FileSystem.CREATE_NEW
+Windows.Win32.Storage.FileSystem.CreateDirectoryW
+Windows.Win32.Storage.FileSystem.CreateFileW
+Windows.Win32.Storage.FileSystem.CreateHardLinkW
+Windows.Win32.Storage.FileSystem.CreateSymbolicLinkW
+Windows.Win32.Storage.FileSystem.DELETE
+Windows.Win32.Storage.FileSystem.DeleteFileW
+Windows.Win32.Storage.FileSystem.FILE_ACCESS_RIGHTS
+Windows.Win32.Storage.FileSystem.FILE_ADD_FILE
+Windows.Win32.Storage.FileSystem.FILE_ADD_SUBDIRECTORY
+Windows.Win32.Storage.FileSystem.FILE_ALL_ACCESS
+Windows.Win32.Storage.FileSystem.FILE_APPEND_DATA
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_ARCHIVE
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_COMPRESSED
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_DEVICE
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_DIRECTORY
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_EA
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_ENCRYPTED
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_HIDDEN
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_INTEGRITY_STREAM
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_NO_SCRUB_DATA
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_NORMAL
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_OFFLINE
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_PINNED
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_READONLY
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_RECALL_ON_OPEN
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_REPARSE_POINT
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_SPARSE_FILE
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_SYSTEM
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_TAG_INFO
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_TEMPORARY
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_UNPINNED
+Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_VIRTUAL
+Windows.Win32.Storage.FileSystem.FILE_BASIC_INFO
+Windows.Win32.Storage.FileSystem.FILE_BEGIN
+Windows.Win32.Storage.FileSystem.FILE_CREATE_PIPE_INSTANCE
+Windows.Win32.Storage.FileSystem.FILE_CREATION_DISPOSITION
+Windows.Win32.Storage.FileSystem.FILE_CURRENT
+Windows.Win32.Storage.FileSystem.FILE_DELETE_CHILD
+Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_FLAG_DELETE
+Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_FLAG_DO_NOT_DELETE
+Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_FLAG_FORCE_IMAGE_SECTION_CHECK
+Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE
+Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_FLAG_ON_CLOSE
+Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_FLAG_POSIX_SEMANTICS
+Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_INFO
+Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_INFO_EX
+Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_INFO_EX_FLAGS
+Windows.Win32.Storage.FileSystem.FILE_END
+Windows.Win32.Storage.FileSystem.FILE_END_OF_FILE_INFO
+Windows.Win32.Storage.FileSystem.FILE_EXECUTE
+Windows.Win32.Storage.FileSystem.FILE_FLAG_BACKUP_SEMANTICS
+Windows.Win32.Storage.FileSystem.FILE_FLAG_DELETE_ON_CLOSE
+Windows.Win32.Storage.FileSystem.FILE_FLAG_FIRST_PIPE_INSTANCE
+Windows.Win32.Storage.FileSystem.FILE_FLAG_NO_BUFFERING
+Windows.Win32.Storage.FileSystem.FILE_FLAG_OPEN_NO_RECALL
+Windows.Win32.Storage.FileSystem.FILE_FLAG_OPEN_REPARSE_POINT
+Windows.Win32.Storage.FileSystem.FILE_FLAG_OVERLAPPED
+Windows.Win32.Storage.FileSystem.FILE_FLAG_POSIX_SEMANTICS
+Windows.Win32.Storage.FileSystem.FILE_FLAG_RANDOM_ACCESS
+Windows.Win32.Storage.FileSystem.FILE_FLAG_SEQUENTIAL_SCAN
+Windows.Win32.Storage.FileSystem.FILE_FLAG_SESSION_AWARE
+Windows.Win32.Storage.FileSystem.FILE_FLAG_WRITE_THROUGH
+Windows.Win32.Storage.FileSystem.FILE_FLAGS_AND_ATTRIBUTES
+Windows.Win32.Storage.FileSystem.FILE_GENERIC_EXECUTE
+Windows.Win32.Storage.FileSystem.FILE_GENERIC_READ
+Windows.Win32.Storage.FileSystem.FILE_GENERIC_WRITE
+Windows.Win32.Storage.FileSystem.FILE_ID_BOTH_DIR_INFO
+Windows.Win32.Storage.FileSystem.FILE_INFO_BY_HANDLE_CLASS
+Windows.Win32.Storage.FileSystem.FILE_LIST_DIRECTORY
+Windows.Win32.Storage.FileSystem.FILE_NAME_NORMALIZED
+Windows.Win32.Storage.FileSystem.FILE_NAME_OPENED
+Windows.Win32.Storage.FileSystem.FILE_READ_ATTRIBUTES
+Windows.Win32.Storage.FileSystem.FILE_READ_DATA
+Windows.Win32.Storage.FileSystem.FILE_READ_EA
+Windows.Win32.Storage.FileSystem.FILE_SHARE_DELETE
+Windows.Win32.Storage.FileSystem.FILE_SHARE_MODE
+Windows.Win32.Storage.FileSystem.FILE_SHARE_NONE
+Windows.Win32.Storage.FileSystem.FILE_SHARE_READ
+Windows.Win32.Storage.FileSystem.FILE_SHARE_WRITE
+Windows.Win32.Storage.FileSystem.FILE_STANDARD_INFO
+Windows.Win32.Storage.FileSystem.FILE_TRAVERSE
+Windows.Win32.Storage.FileSystem.FILE_TYPE
+Windows.Win32.Storage.FileSystem.FILE_TYPE_CHAR
+Windows.Win32.Storage.FileSystem.FILE_TYPE_DISK
+Windows.Win32.Storage.FileSystem.FILE_TYPE_PIPE
+Windows.Win32.Storage.FileSystem.FILE_TYPE_REMOTE
+Windows.Win32.Storage.FileSystem.FILE_TYPE_UNKNOWN
+Windows.Win32.Storage.FileSystem.FILE_WRITE_ATTRIBUTES
+Windows.Win32.Storage.FileSystem.FILE_WRITE_DATA
+Windows.Win32.Storage.FileSystem.FILE_WRITE_EA
+Windows.Win32.Storage.FileSystem.FileAlignmentInfo
+Windows.Win32.Storage.FileSystem.FileAllocationInfo
+Windows.Win32.Storage.FileSystem.FileAttributeTagInfo
+Windows.Win32.Storage.FileSystem.FileBasicInfo
+Windows.Win32.Storage.FileSystem.FileCaseSensitiveInfo
+Windows.Win32.Storage.FileSystem.FileCompressionInfo
+Windows.Win32.Storage.FileSystem.FileDispositionInfo
+Windows.Win32.Storage.FileSystem.FileDispositionInfoEx
+Windows.Win32.Storage.FileSystem.FileEndOfFileInfo
+Windows.Win32.Storage.FileSystem.FileFullDirectoryInfo
+Windows.Win32.Storage.FileSystem.FileFullDirectoryRestartInfo
+Windows.Win32.Storage.FileSystem.FileIdBothDirectoryInfo
+Windows.Win32.Storage.FileSystem.FileIdBothDirectoryRestartInfo
+Windows.Win32.Storage.FileSystem.FileIdExtdDirectoryInfo
+Windows.Win32.Storage.FileSystem.FileIdExtdDirectoryRestartInfo
+Windows.Win32.Storage.FileSystem.FileIdInfo
+Windows.Win32.Storage.FileSystem.FileIoPriorityHintInfo
+Windows.Win32.Storage.FileSystem.FileNameInfo
+Windows.Win32.Storage.FileSystem.FileNormalizedNameInfo
+Windows.Win32.Storage.FileSystem.FileRemoteProtocolInfo
+Windows.Win32.Storage.FileSystem.FileRenameInfo
+Windows.Win32.Storage.FileSystem.FileRenameInfoEx
+Windows.Win32.Storage.FileSystem.FileStandardInfo
+Windows.Win32.Storage.FileSystem.FileStorageInfo
+Windows.Win32.Storage.FileSystem.FileStreamInfo
+Windows.Win32.Storage.FileSystem.FindClose
+Windows.Win32.Storage.FileSystem.FindFileHandle
+Windows.Win32.Storage.FileSystem.FindFirstFileW
+Windows.Win32.Storage.FileSystem.FindNextFileW
+Windows.Win32.Storage.FileSystem.FlushFileBuffers
+Windows.Win32.Storage.FileSystem.GetFileAttributesW
+Windows.Win32.Storage.FileSystem.GetFileInformationByHandle
+Windows.Win32.Storage.FileSystem.GetFileInformationByHandleEx
+Windows.Win32.Storage.FileSystem.GetFileType
+Windows.Win32.Storage.FileSystem.GETFINALPATHNAMEBYHANDLE_FLAGS
+Windows.Win32.Storage.FileSystem.GetFinalPathNameByHandleW
+Windows.Win32.Storage.FileSystem.GetFullPathNameW
+Windows.Win32.Storage.FileSystem.GetTempPathW
+Windows.Win32.Storage.FileSystem.INVALID_FILE_ATTRIBUTES
+Windows.Win32.Storage.FileSystem.LPPROGRESS_ROUTINE
+Windows.Win32.Storage.FileSystem.LPPROGRESS_ROUTINE_CALLBACK_REASON
+Windows.Win32.Storage.FileSystem.MAXIMUM_REPARSE_DATA_BUFFER_SIZE
+Windows.Win32.Storage.FileSystem.MaximumFileInfoByHandleClass
+Windows.Win32.Storage.FileSystem.MOVE_FILE_FLAGS
+Windows.Win32.Storage.FileSystem.MOVEFILE_COPY_ALLOWED
+Windows.Win32.Storage.FileSystem.MOVEFILE_CREATE_HARDLINK
+Windows.Win32.Storage.FileSystem.MOVEFILE_DELAY_UNTIL_REBOOT
+Windows.Win32.Storage.FileSystem.MOVEFILE_FAIL_IF_NOT_TRACKABLE
+Windows.Win32.Storage.FileSystem.MOVEFILE_REPLACE_EXISTING
+Windows.Win32.Storage.FileSystem.MOVEFILE_WRITE_THROUGH
+Windows.Win32.Storage.FileSystem.MoveFileExW
+Windows.Win32.Storage.FileSystem.OPEN_ALWAYS
+Windows.Win32.Storage.FileSystem.OPEN_EXISTING
+Windows.Win32.Storage.FileSystem.PIPE_ACCESS_DUPLEX
+Windows.Win32.Storage.FileSystem.PIPE_ACCESS_INBOUND
+Windows.Win32.Storage.FileSystem.PIPE_ACCESS_OUTBOUND
+Windows.Win32.Storage.FileSystem.READ_CONTROL
+Windows.Win32.Storage.FileSystem.ReadFile
+Windows.Win32.Storage.FileSystem.ReadFileEx
+Windows.Win32.Storage.FileSystem.RemoveDirectoryW
+Windows.Win32.Storage.FileSystem.SECURITY_ANONYMOUS
+Windows.Win32.Storage.FileSystem.SECURITY_CONTEXT_TRACKING
+Windows.Win32.Storage.FileSystem.SECURITY_DELEGATION
+Windows.Win32.Storage.FileSystem.SECURITY_EFFECTIVE_ONLY
+Windows.Win32.Storage.FileSystem.SECURITY_IDENTIFICATION
+Windows.Win32.Storage.FileSystem.SECURITY_IMPERSONATION
+Windows.Win32.Storage.FileSystem.SECURITY_SQOS_PRESENT
+Windows.Win32.Storage.FileSystem.SECURITY_VALID_SQOS_FLAGS
+Windows.Win32.Storage.FileSystem.SET_FILE_POINTER_MOVE_METHOD
+Windows.Win32.Storage.FileSystem.SetFileAttributesW
+Windows.Win32.Storage.FileSystem.SetFileInformationByHandle
+Windows.Win32.Storage.FileSystem.SetFilePointerEx
+Windows.Win32.Storage.FileSystem.SetFileTime
+Windows.Win32.Storage.FileSystem.SPECIFIC_RIGHTS_ALL
+Windows.Win32.Storage.FileSystem.STANDARD_RIGHTS_ALL
+Windows.Win32.Storage.FileSystem.STANDARD_RIGHTS_EXECUTE
+Windows.Win32.Storage.FileSystem.STANDARD_RIGHTS_READ
+Windows.Win32.Storage.FileSystem.STANDARD_RIGHTS_REQUIRED
+Windows.Win32.Storage.FileSystem.STANDARD_RIGHTS_WRITE
+Windows.Win32.Storage.FileSystem.SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
+Windows.Win32.Storage.FileSystem.SYMBOLIC_LINK_FLAG_DIRECTORY
+Windows.Win32.Storage.FileSystem.SYMBOLIC_LINK_FLAGS
+Windows.Win32.Storage.FileSystem.SYNCHRONIZE
+Windows.Win32.Storage.FileSystem.TRUNCATE_EXISTING
+Windows.Win32.Storage.FileSystem.VOLUME_NAME_DOS
+Windows.Win32.Storage.FileSystem.VOLUME_NAME_GUID
+Windows.Win32.Storage.FileSystem.VOLUME_NAME_NONE
+Windows.Win32.Storage.FileSystem.WIN32_FIND_DATAW
+Windows.Win32.Storage.FileSystem.WRITE_DAC
+Windows.Win32.Storage.FileSystem.WRITE_OWNER
+Windows.Win32.Storage.FileSystem.WriteFileEx
+Windows.Win32.System.Console.CONSOLE_MODE
+Windows.Win32.System.Console.CONSOLE_READCONSOLE_CONTROL
+Windows.Win32.System.Console.DISABLE_NEWLINE_AUTO_RETURN
+Windows.Win32.System.Console.ENABLE_AUTO_POSITION
+Windows.Win32.System.Console.ENABLE_ECHO_INPUT
+Windows.Win32.System.Console.ENABLE_EXTENDED_FLAGS
+Windows.Win32.System.Console.ENABLE_INSERT_MODE
+Windows.Win32.System.Console.ENABLE_LINE_INPUT
+Windows.Win32.System.Console.ENABLE_LVB_GRID_WORLDWIDE
+Windows.Win32.System.Console.ENABLE_MOUSE_INPUT
+Windows.Win32.System.Console.ENABLE_PROCESSED_INPUT
+Windows.Win32.System.Console.ENABLE_PROCESSED_OUTPUT
+Windows.Win32.System.Console.ENABLE_QUICK_EDIT_MODE
+Windows.Win32.System.Console.ENABLE_VIRTUAL_TERMINAL_INPUT
+Windows.Win32.System.Console.ENABLE_VIRTUAL_TERMINAL_PROCESSING
+Windows.Win32.System.Console.ENABLE_WINDOW_INPUT
+Windows.Win32.System.Console.ENABLE_WRAP_AT_EOL_OUTPUT
+Windows.Win32.System.Console.GetConsoleMode
+Windows.Win32.System.Console.GetStdHandle
+Windows.Win32.System.Console.ReadConsoleW
+Windows.Win32.System.Console.STD_ERROR_HANDLE
+Windows.Win32.System.Console.STD_HANDLE
+Windows.Win32.System.Console.STD_INPUT_HANDLE
+Windows.Win32.System.Console.STD_OUTPUT_HANDLE
+Windows.Win32.System.Console.WriteConsoleW
+Windows.Win32.System.Diagnostics.Debug.AddVectoredExceptionHandler
+Windows.Win32.System.Diagnostics.Debug.ARM64_NT_NEON128
+Windows.Win32.System.Diagnostics.Debug.CONTEXT
+Windows.Win32.System.Diagnostics.Debug.CONTEXT
+Windows.Win32.System.Diagnostics.Debug.CONTEXT
+Windows.Win32.System.Diagnostics.Debug.EXCEPTION_POINTERS
+Windows.Win32.System.Diagnostics.Debug.EXCEPTION_RECORD
+Windows.Win32.System.Diagnostics.Debug.FACILITY_CODE
+Windows.Win32.System.Diagnostics.Debug.FACILITY_NT_BIT
+Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_ALLOCATE_BUFFER
+Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_ARGUMENT_ARRAY
+Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_FROM_HMODULE
+Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_FROM_STRING
+Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_FROM_SYSTEM
+Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_IGNORE_INSERTS
+Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_OPTIONS
+Windows.Win32.System.Diagnostics.Debug.FormatMessageW
+Windows.Win32.System.Diagnostics.Debug.M128A
+Windows.Win32.System.Diagnostics.Debug.PVECTORED_EXCEPTION_HANDLER
+Windows.Win32.System.Diagnostics.Debug.XSAVE_FORMAT
+Windows.Win32.System.Diagnostics.Debug.XSAVE_FORMAT
+Windows.Win32.System.Environment.FreeEnvironmentStringsW
+Windows.Win32.System.Environment.GetCommandLineW
+Windows.Win32.System.Environment.GetCurrentDirectoryW
+Windows.Win32.System.Environment.GetEnvironmentStringsW
+Windows.Win32.System.Environment.GetEnvironmentVariableW
+Windows.Win32.System.Environment.SetCurrentDirectoryW
+Windows.Win32.System.Environment.SetEnvironmentVariableW
+Windows.Win32.System.IO.CancelIo
+Windows.Win32.System.IO.DeviceIoControl
+Windows.Win32.System.IO.GetOverlappedResult
+Windows.Win32.System.IO.LPOVERLAPPED_COMPLETION_ROUTINE
+Windows.Win32.System.IO.OVERLAPPED
+Windows.Win32.System.Ioctl.FSCTL_GET_REPARSE_POINT
+Windows.Win32.System.Ioctl.FSCTL_SET_REPARSE_POINT
+Windows.Win32.System.Kernel.EXCEPTION_DISPOSITION
+Windows.Win32.System.Kernel.ExceptionCollidedUnwind
+Windows.Win32.System.Kernel.ExceptionContinueExecution
+Windows.Win32.System.Kernel.ExceptionContinueSearch
+Windows.Win32.System.Kernel.ExceptionNestedException
+Windows.Win32.System.Kernel.FLOATING_SAVE_AREA
+Windows.Win32.System.Kernel.FLOATING_SAVE_AREA
+Windows.Win32.System.Kernel.OBJ_DONT_REPARSE
+Windows.Win32.System.LibraryLoader.GetModuleFileNameW
+Windows.Win32.System.LibraryLoader.GetModuleHandleA
+Windows.Win32.System.LibraryLoader.GetModuleHandleW
+Windows.Win32.System.LibraryLoader.GetProcAddress
+Windows.Win32.System.Performance.QueryPerformanceCounter
+Windows.Win32.System.Performance.QueryPerformanceFrequency
+Windows.Win32.System.Pipes.CreateNamedPipeW
+Windows.Win32.System.Pipes.NAMED_PIPE_MODE
+Windows.Win32.System.Pipes.PIPE_ACCEPT_REMOTE_CLIENTS
+Windows.Win32.System.Pipes.PIPE_CLIENT_END
+Windows.Win32.System.Pipes.PIPE_NOWAIT
+Windows.Win32.System.Pipes.PIPE_READMODE_BYTE
+Windows.Win32.System.Pipes.PIPE_READMODE_MESSAGE
+Windows.Win32.System.Pipes.PIPE_REJECT_REMOTE_CLIENTS
+Windows.Win32.System.Pipes.PIPE_SERVER_END
+Windows.Win32.System.Pipes.PIPE_TYPE_BYTE
+Windows.Win32.System.Pipes.PIPE_TYPE_MESSAGE
+Windows.Win32.System.Pipes.PIPE_WAIT
+Windows.Win32.System.SystemInformation.GetSystemDirectoryW
+Windows.Win32.System.SystemInformation.GetSystemInfo
+Windows.Win32.System.SystemInformation.GetSystemTimeAsFileTime
+Windows.Win32.System.SystemInformation.GetWindowsDirectoryW
+Windows.Win32.System.SystemInformation.PROCESSOR_ARCHITECTURE
+Windows.Win32.System.SystemInformation.SYSTEM_INFO
+Windows.Win32.System.SystemServices.DLL_PROCESS_DETACH
+Windows.Win32.System.SystemServices.DLL_THREAD_DETACH
+Windows.Win32.System.SystemServices.EXCEPTION_MAXIMUM_PARAMETERS
+Windows.Win32.System.SystemServices.IO_REPARSE_TAG_MOUNT_POINT
+Windows.Win32.System.SystemServices.IO_REPARSE_TAG_SYMLINK
+Windows.Win32.System.Threading.ABOVE_NORMAL_PRIORITY_CLASS
+Windows.Win32.System.Threading.AcquireSRWLockExclusive
+Windows.Win32.System.Threading.AcquireSRWLockShared
+Windows.Win32.System.Threading.BELOW_NORMAL_PRIORITY_CLASS
+Windows.Win32.System.Threading.CREATE_BREAKAWAY_FROM_JOB
+Windows.Win32.System.Threading.CREATE_DEFAULT_ERROR_MODE
+Windows.Win32.System.Threading.CREATE_FORCEDOS
+Windows.Win32.System.Threading.CREATE_IGNORE_SYSTEM_DEFAULT
+Windows.Win32.System.Threading.CREATE_NEW_CONSOLE
+Windows.Win32.System.Threading.CREATE_NEW_PROCESS_GROUP
+Windows.Win32.System.Threading.CREATE_NO_WINDOW
+Windows.Win32.System.Threading.CREATE_PRESERVE_CODE_AUTHZ_LEVEL
+Windows.Win32.System.Threading.CREATE_PROTECTED_PROCESS
+Windows.Win32.System.Threading.CREATE_SECURE_PROCESS
+Windows.Win32.System.Threading.CREATE_SEPARATE_WOW_VDM
+Windows.Win32.System.Threading.CREATE_SHARED_WOW_VDM
+Windows.Win32.System.Threading.CREATE_SUSPENDED
+Windows.Win32.System.Threading.CREATE_UNICODE_ENVIRONMENT
+Windows.Win32.System.Threading.CreateEventW
+Windows.Win32.System.Threading.CreateProcessW
+Windows.Win32.System.Threading.CreateThread
+Windows.Win32.System.Threading.DEBUG_ONLY_THIS_PROCESS
+Windows.Win32.System.Threading.DEBUG_PROCESS
+Windows.Win32.System.Threading.DETACHED_PROCESS
+Windows.Win32.System.Threading.ExitProcess
+Windows.Win32.System.Threading.EXTENDED_STARTUPINFO_PRESENT
+Windows.Win32.System.Threading.GetCurrentProcess
+Windows.Win32.System.Threading.GetCurrentProcessId
+Windows.Win32.System.Threading.GetCurrentThread
+Windows.Win32.System.Threading.GetExitCodeProcess
+Windows.Win32.System.Threading.GetProcessId
+Windows.Win32.System.Threading.HIGH_PRIORITY_CLASS
+Windows.Win32.System.Threading.IDLE_PRIORITY_CLASS
+Windows.Win32.System.Threading.INFINITE
+Windows.Win32.System.Threading.INHERIT_CALLER_PRIORITY
+Windows.Win32.System.Threading.INHERIT_PARENT_AFFINITY
+Windows.Win32.System.Threading.INIT_ONCE_INIT_FAILED
+Windows.Win32.System.Threading.InitOnceBeginInitialize
+Windows.Win32.System.Threading.InitOnceComplete
+Windows.Win32.System.Threading.LPTHREAD_START_ROUTINE
+Windows.Win32.System.Threading.NORMAL_PRIORITY_CLASS
+Windows.Win32.System.Threading.OpenProcessToken
+Windows.Win32.System.Threading.PROCESS_CREATION_FLAGS
+Windows.Win32.System.Threading.PROCESS_INFORMATION
+Windows.Win32.System.Threading.PROCESS_MODE_BACKGROUND_BEGIN
+Windows.Win32.System.Threading.PROCESS_MODE_BACKGROUND_END
+Windows.Win32.System.Threading.PROFILE_KERNEL
+Windows.Win32.System.Threading.PROFILE_SERVER
+Windows.Win32.System.Threading.PROFILE_USER
+Windows.Win32.System.Threading.REALTIME_PRIORITY_CLASS
+Windows.Win32.System.Threading.ReleaseSRWLockExclusive
+Windows.Win32.System.Threading.ReleaseSRWLockShared
+Windows.Win32.System.Threading.RTL_CONDITION_VARIABLE
+Windows.Win32.System.Threading.RTL_RUN_ONCE
+Windows.Win32.System.Threading.RTL_SRWLOCK
+Windows.Win32.System.Threading.SetThreadStackGuarantee
+Windows.Win32.System.Threading.Sleep
+Windows.Win32.System.Threading.SleepConditionVariableSRW
+Windows.Win32.System.Threading.SleepEx
+Windows.Win32.System.Threading.STACK_SIZE_PARAM_IS_A_RESERVATION
+Windows.Win32.System.Threading.STARTF_FORCEOFFFEEDBACK
+Windows.Win32.System.Threading.STARTF_FORCEONFEEDBACK
+Windows.Win32.System.Threading.STARTF_PREVENTPINNING
+Windows.Win32.System.Threading.STARTF_RUNFULLSCREEN
+Windows.Win32.System.Threading.STARTF_TITLEISAPPID
+Windows.Win32.System.Threading.STARTF_TITLEISLINKNAME
+Windows.Win32.System.Threading.STARTF_UNTRUSTEDSOURCE
+Windows.Win32.System.Threading.STARTF_USECOUNTCHARS
+Windows.Win32.System.Threading.STARTF_USEFILLATTRIBUTE
+Windows.Win32.System.Threading.STARTF_USEHOTKEY
+Windows.Win32.System.Threading.STARTF_USEPOSITION
+Windows.Win32.System.Threading.STARTF_USESHOWWINDOW
+Windows.Win32.System.Threading.STARTF_USESIZE
+Windows.Win32.System.Threading.STARTF_USESTDHANDLES
+Windows.Win32.System.Threading.STARTUPINFOW
+Windows.Win32.System.Threading.STARTUPINFOW_FLAGS
+Windows.Win32.System.Threading.SwitchToThread
+Windows.Win32.System.Threading.TerminateProcess
+Windows.Win32.System.Threading.THREAD_CREATE_RUN_IMMEDIATELY
+Windows.Win32.System.Threading.THREAD_CREATE_SUSPENDED
+Windows.Win32.System.Threading.THREAD_CREATION_FLAGS
+Windows.Win32.System.Threading.TLS_OUT_OF_INDEXES
+Windows.Win32.System.Threading.TlsAlloc
+Windows.Win32.System.Threading.TlsFree
+Windows.Win32.System.Threading.TlsGetValue
+Windows.Win32.System.Threading.TlsSetValue
+Windows.Win32.System.Threading.TryAcquireSRWLockExclusive
+Windows.Win32.System.Threading.TryAcquireSRWLockShared
+Windows.Win32.System.Threading.WaitForMultipleObjects
+Windows.Win32.System.Threading.WaitForSingleObject
+Windows.Win32.System.Threading.WakeAllConditionVariable
+Windows.Win32.System.Threading.WakeConditionVariable
+Windows.Win32.System.WindowsProgramming.IO_STATUS_BLOCK
+Windows.Win32.System.WindowsProgramming.OBJECT_ATTRIBUTES
+Windows.Win32.System.WindowsProgramming.PROGRESS_CONTINUE
+Windows.Win32.UI.Shell.GetUserProfileDirectoryW
+// tidy-alphabetical-end
+
diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs
new file mode 100644
index 00000000000..36a30f6ba56
--- /dev/null
+++ b/library/std/src/sys/windows/c/windows_sys.rs
@@ -0,0 +1,4276 @@
+// This file is autogenerated.
+//
+// To add bindings, edit windows_sys.lst then use `./x run generate-windows-sys` to
+// regenerate the bindings.
+//
+// ignore-tidy-filelength
+// Bindings generated by `windows-bindgen` 0.49.0
+
+#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
+#[link(name = "advapi32")]
+extern "system" {
+ pub fn OpenProcessToken(
+ processhandle: HANDLE,
+ desiredaccess: TOKEN_ACCESS_MASK,
+ tokenhandle: *mut HANDLE,
+ ) -> BOOL;
+}
+#[link(name = "advapi32")]
+extern "system" {
+ #[link_name = "SystemFunction036"]
+ pub fn RtlGenRandom(randombuffer: *mut ::core::ffi::c_void, randombufferlength: u32)
+ -> BOOLEAN;
+}
+#[link(name = "bcrypt")]
+extern "system" {
+ pub fn BCryptGenRandom(
+ halgorithm: BCRYPT_ALG_HANDLE,
+ pbbuffer: *mut u8,
+ cbbuffer: u32,
+ dwflags: BCRYPTGENRANDOM_FLAGS,
+ ) -> NTSTATUS;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn AcquireSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> ();
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn AcquireSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> ();
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn AddVectoredExceptionHandler(
+ first: u32,
+ handler: PVECTORED_EXCEPTION_HANDLER,
+ ) -> *mut ::core::ffi::c_void;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn CancelIo(hfile: HANDLE) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn CloseHandle(hobject: HANDLE) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn CompareStringOrdinal(
+ lpstring1: PCWSTR,
+ cchcount1: i32,
+ lpstring2: PCWSTR,
+ cchcount2: i32,
+ bignorecase: BOOL,
+ ) -> COMPARESTRING_RESULT;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn CopyFileExW(
+ lpexistingfilename: PCWSTR,
+ lpnewfilename: PCWSTR,
+ lpprogressroutine: LPPROGRESS_ROUTINE,
+ lpdata: *const ::core::ffi::c_void,
+ pbcancel: *mut i32,
+ dwcopyflags: u32,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn CreateDirectoryW(
+ lppathname: PCWSTR,
+ lpsecurityattributes: *const SECURITY_ATTRIBUTES,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn CreateEventW(
+ lpeventattributes: *const SECURITY_ATTRIBUTES,
+ bmanualreset: BOOL,
+ binitialstate: BOOL,
+ lpname: PCWSTR,
+ ) -> HANDLE;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn CreateFileW(
+ lpfilename: PCWSTR,
+ dwdesiredaccess: u32,
+ dwsharemode: FILE_SHARE_MODE,
+ lpsecurityattributes: *const SECURITY_ATTRIBUTES,
+ dwcreationdisposition: FILE_CREATION_DISPOSITION,
+ dwflagsandattributes: FILE_FLAGS_AND_ATTRIBUTES,
+ htemplatefile: HANDLE,
+ ) -> HANDLE;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn CreateHardLinkW(
+ lpfilename: PCWSTR,
+ lpexistingfilename: PCWSTR,
+ lpsecurityattributes: *const SECURITY_ATTRIBUTES,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn CreateNamedPipeW(
+ lpname: PCWSTR,
+ dwopenmode: FILE_FLAGS_AND_ATTRIBUTES,
+ dwpipemode: NAMED_PIPE_MODE,
+ nmaxinstances: u32,
+ noutbuffersize: u32,
+ ninbuffersize: u32,
+ ndefaulttimeout: u32,
+ lpsecurityattributes: *const SECURITY_ATTRIBUTES,
+ ) -> HANDLE;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn CreateProcessW(
+ lpapplicationname: PCWSTR,
+ lpcommandline: PWSTR,
+ lpprocessattributes: *const SECURITY_ATTRIBUTES,
+ lpthreadattributes: *const SECURITY_ATTRIBUTES,
+ binherithandles: BOOL,
+ dwcreationflags: PROCESS_CREATION_FLAGS,
+ lpenvironment: *const ::core::ffi::c_void,
+ lpcurrentdirectory: PCWSTR,
+ lpstartupinfo: *const STARTUPINFOW,
+ lpprocessinformation: *mut PROCESS_INFORMATION,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn CreateSymbolicLinkW(
+ lpsymlinkfilename: PCWSTR,
+ lptargetfilename: PCWSTR,
+ dwflags: SYMBOLIC_LINK_FLAGS,
+ ) -> BOOLEAN;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn CreateThread(
+ lpthreadattributes: *const SECURITY_ATTRIBUTES,
+ dwstacksize: usize,
+ lpstartaddress: LPTHREAD_START_ROUTINE,
+ lpparameter: *const ::core::ffi::c_void,
+ dwcreationflags: THREAD_CREATION_FLAGS,
+ lpthreadid: *mut u32,
+ ) -> HANDLE;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn DeleteFileW(lpfilename: PCWSTR) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn DeviceIoControl(
+ hdevice: HANDLE,
+ dwiocontrolcode: u32,
+ lpinbuffer: *const ::core::ffi::c_void,
+ ninbuffersize: u32,
+ lpoutbuffer: *mut ::core::ffi::c_void,
+ noutbuffersize: u32,
+ lpbytesreturned: *mut u32,
+ lpoverlapped: *mut OVERLAPPED,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn DuplicateHandle(
+ hsourceprocesshandle: HANDLE,
+ hsourcehandle: HANDLE,
+ htargetprocesshandle: HANDLE,
+ lptargethandle: *mut HANDLE,
+ dwdesiredaccess: u32,
+ binherithandle: BOOL,
+ dwoptions: DUPLICATE_HANDLE_OPTIONS,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn ExitProcess(uexitcode: u32) -> !;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn FindClose(hfindfile: FindFileHandle) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn FindFirstFileW(
+ lpfilename: PCWSTR,
+ lpfindfiledata: *mut WIN32_FIND_DATAW,
+ ) -> FindFileHandle;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn FindNextFileW(hfindfile: FindFileHandle, lpfindfiledata: *mut WIN32_FIND_DATAW) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn FlushFileBuffers(hfile: HANDLE) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn FormatMessageW(
+ dwflags: FORMAT_MESSAGE_OPTIONS,
+ lpsource: *const ::core::ffi::c_void,
+ dwmessageid: u32,
+ dwlanguageid: u32,
+ lpbuffer: PWSTR,
+ nsize: u32,
+ arguments: *const *const i8,
+ ) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn FreeEnvironmentStringsW(penv: PCWSTR) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetCommandLineW() -> PCWSTR;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetConsoleMode(hconsolehandle: HANDLE, lpmode: *mut CONSOLE_MODE) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetCurrentDirectoryW(nbufferlength: u32, lpbuffer: PWSTR) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetCurrentProcess() -> HANDLE;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetCurrentProcessId() -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetCurrentThread() -> HANDLE;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetEnvironmentStringsW() -> PWSTR;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetEnvironmentVariableW(lpname: PCWSTR, lpbuffer: PWSTR, nsize: u32) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetExitCodeProcess(hprocess: HANDLE, lpexitcode: *mut u32) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetFileAttributesW(lpfilename: PCWSTR) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetFileInformationByHandle(
+ hfile: HANDLE,
+ lpfileinformation: *mut BY_HANDLE_FILE_INFORMATION,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetFileInformationByHandleEx(
+ hfile: HANDLE,
+ fileinformationclass: FILE_INFO_BY_HANDLE_CLASS,
+ lpfileinformation: *mut ::core::ffi::c_void,
+ dwbuffersize: u32,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetFileType(hfile: HANDLE) -> FILE_TYPE;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetFinalPathNameByHandleW(
+ hfile: HANDLE,
+ lpszfilepath: PWSTR,
+ cchfilepath: u32,
+ dwflags: GETFINALPATHNAMEBYHANDLE_FLAGS,
+ ) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetFullPathNameW(
+ lpfilename: PCWSTR,
+ nbufferlength: u32,
+ lpbuffer: PWSTR,
+ lpfilepart: *mut PWSTR,
+ ) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetLastError() -> WIN32_ERROR;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetModuleFileNameW(hmodule: HMODULE, lpfilename: PWSTR, nsize: u32) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetModuleHandleA(lpmodulename: PCSTR) -> HMODULE;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetModuleHandleW(lpmodulename: PCWSTR) -> HMODULE;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetOverlappedResult(
+ hfile: HANDLE,
+ lpoverlapped: *const OVERLAPPED,
+ lpnumberofbytestransferred: *mut u32,
+ bwait: BOOL,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetProcAddress(hmodule: HMODULE, lpprocname: PCSTR) -> FARPROC;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetProcessId(process: HANDLE) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetStdHandle(nstdhandle: STD_HANDLE) -> HANDLE;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetSystemDirectoryW(lpbuffer: PWSTR, usize: u32) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetSystemInfo(lpsysteminfo: *mut SYSTEM_INFO) -> ();
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetSystemTimeAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> ();
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetTempPathW(nbufferlength: u32, lpbuffer: PWSTR) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn GetWindowsDirectoryW(lpbuffer: PWSTR, usize: u32) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn InitOnceBeginInitialize(
+ lpinitonce: *mut RTL_RUN_ONCE,
+ dwflags: u32,
+ fpending: *mut BOOL,
+ lpcontext: *mut *mut ::core::ffi::c_void,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn InitOnceComplete(
+ lpinitonce: *mut RTL_RUN_ONCE,
+ dwflags: u32,
+ lpcontext: *const ::core::ffi::c_void,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn MoveFileExW(
+ lpexistingfilename: PCWSTR,
+ lpnewfilename: PCWSTR,
+ dwflags: MOVE_FILE_FLAGS,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn MultiByteToWideChar(
+ codepage: u32,
+ dwflags: MULTI_BYTE_TO_WIDE_CHAR_FLAGS,
+ lpmultibytestr: PCSTR,
+ cbmultibyte: i32,
+ lpwidecharstr: PWSTR,
+ cchwidechar: i32,
+ ) -> i32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn QueryPerformanceCounter(lpperformancecount: *mut i64) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn QueryPerformanceFrequency(lpfrequency: *mut i64) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn ReadConsoleW(
+ hconsoleinput: HANDLE,
+ lpbuffer: *mut ::core::ffi::c_void,
+ nnumberofcharstoread: u32,
+ lpnumberofcharsread: *mut u32,
+ pinputcontrol: *const CONSOLE_READCONSOLE_CONTROL,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn ReadFile(
+ hfile: HANDLE,
+ lpbuffer: *mut ::core::ffi::c_void,
+ nnumberofbytestoread: u32,
+ lpnumberofbytesread: *mut u32,
+ lpoverlapped: *mut OVERLAPPED,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn ReadFileEx(
+ hfile: HANDLE,
+ lpbuffer: *mut ::core::ffi::c_void,
+ nnumberofbytestoread: u32,
+ lpoverlapped: *mut OVERLAPPED,
+ lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn ReleaseSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> ();
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn ReleaseSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> ();
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn RemoveDirectoryW(lppathname: PCWSTR) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn SetCurrentDirectoryW(lppathname: PCWSTR) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn SetEnvironmentVariableW(lpname: PCWSTR, lpvalue: PCWSTR) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn SetFileAttributesW(
+ lpfilename: PCWSTR,
+ dwfileattributes: FILE_FLAGS_AND_ATTRIBUTES,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn SetFileInformationByHandle(
+ hfile: HANDLE,
+ fileinformationclass: FILE_INFO_BY_HANDLE_CLASS,
+ lpfileinformation: *const ::core::ffi::c_void,
+ dwbuffersize: u32,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn SetFilePointerEx(
+ hfile: HANDLE,
+ lidistancetomove: i64,
+ lpnewfilepointer: *mut i64,
+ dwmovemethod: SET_FILE_POINTER_MOVE_METHOD,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn SetFileTime(
+ hfile: HANDLE,
+ lpcreationtime: *const FILETIME,
+ lplastaccesstime: *const FILETIME,
+ lplastwritetime: *const FILETIME,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn SetHandleInformation(hobject: HANDLE, dwmask: u32, dwflags: HANDLE_FLAGS) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn SetLastError(dwerrcode: WIN32_ERROR) -> ();
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn SetThreadStackGuarantee(stacksizeinbytes: *mut u32) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn Sleep(dwmilliseconds: u32) -> ();
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn SleepConditionVariableSRW(
+ conditionvariable: *mut RTL_CONDITION_VARIABLE,
+ srwlock: *mut RTL_SRWLOCK,
+ dwmilliseconds: u32,
+ flags: u32,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn SleepEx(dwmilliseconds: u32, balertable: BOOL) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn SwitchToThread() -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn TerminateProcess(hprocess: HANDLE, uexitcode: u32) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn TlsAlloc() -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn TlsFree(dwtlsindex: u32) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn TlsGetValue(dwtlsindex: u32) -> *mut ::core::ffi::c_void;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn TlsSetValue(dwtlsindex: u32, lptlsvalue: *const ::core::ffi::c_void) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn TryAcquireSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> BOOLEAN;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn TryAcquireSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> BOOLEAN;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn WaitForMultipleObjects(
+ ncount: u32,
+ lphandles: *const HANDLE,
+ bwaitall: BOOL,
+ dwmilliseconds: u32,
+ ) -> WIN32_ERROR;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WIN32_ERROR;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn WakeAllConditionVariable(conditionvariable: *mut RTL_CONDITION_VARIABLE) -> ();
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn WakeConditionVariable(conditionvariable: *mut RTL_CONDITION_VARIABLE) -> ();
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn WideCharToMultiByte(
+ codepage: u32,
+ dwflags: u32,
+ lpwidecharstr: PCWSTR,
+ cchwidechar: i32,
+ lpmultibytestr: PSTR,
+ cbmultibyte: i32,
+ lpdefaultchar: PCSTR,
+ lpuseddefaultchar: *mut i32,
+ ) -> i32;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn WriteConsoleW(
+ hconsoleoutput: HANDLE,
+ lpbuffer: *const ::core::ffi::c_void,
+ nnumberofcharstowrite: u32,
+ lpnumberofcharswritten: *mut u32,
+ lpreserved: *const ::core::ffi::c_void,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn WriteFileEx(
+ hfile: HANDLE,
+ lpbuffer: *const u8,
+ nnumberofbytestowrite: u32,
+ lpoverlapped: *mut OVERLAPPED,
+ lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE,
+ ) -> BOOL;
+}
+#[link(name = "ntdll")]
+extern "system" {
+ pub fn NtCreateFile(
+ filehandle: *mut HANDLE,
+ desiredaccess: FILE_ACCESS_RIGHTS,
+ objectattributes: *const OBJECT_ATTRIBUTES,
+ iostatusblock: *mut IO_STATUS_BLOCK,
+ allocationsize: *const i64,
+ fileattributes: FILE_FLAGS_AND_ATTRIBUTES,
+ shareaccess: FILE_SHARE_MODE,
+ createdisposition: NTCREATEFILE_CREATE_DISPOSITION,
+ createoptions: NTCREATEFILE_CREATE_OPTIONS,
+ eabuffer: *const ::core::ffi::c_void,
+ ealength: u32,
+ ) -> NTSTATUS;
+}
+#[link(name = "ntdll")]
+extern "system" {
+ pub fn NtReadFile(
+ filehandle: HANDLE,
+ event: HANDLE,
+ apcroutine: PIO_APC_ROUTINE,
+ apccontext: *const ::core::ffi::c_void,
+ iostatusblock: *mut IO_STATUS_BLOCK,
+ buffer: *mut ::core::ffi::c_void,
+ length: u32,
+ byteoffset: *const i64,
+ key: *const u32,
+ ) -> NTSTATUS;
+}
+#[link(name = "ntdll")]
+extern "system" {
+ pub fn NtWriteFile(
+ filehandle: HANDLE,
+ event: HANDLE,
+ apcroutine: PIO_APC_ROUTINE,
+ apccontext: *const ::core::ffi::c_void,
+ iostatusblock: *mut IO_STATUS_BLOCK,
+ buffer: *const ::core::ffi::c_void,
+ length: u32,
+ byteoffset: *const i64,
+ key: *const u32,
+ ) -> NTSTATUS;
+}
+#[link(name = "ntdll")]
+extern "system" {
+ pub fn RtlNtStatusToDosError(status: NTSTATUS) -> u32;
+}
+#[link(name = "userenv")]
+extern "system" {
+ pub fn GetUserProfileDirectoryW(
+ htoken: HANDLE,
+ lpprofiledir: PWSTR,
+ lpcchsize: *mut u32,
+ ) -> BOOL;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn WSACleanup() -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn WSADuplicateSocketW(
+ s: SOCKET,
+ dwprocessid: u32,
+ lpprotocolinfo: *mut WSAPROTOCOL_INFOW,
+ ) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn WSAGetLastError() -> WSA_ERROR;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn WSARecv(
+ s: SOCKET,
+ lpbuffers: *const WSABUF,
+ dwbuffercount: u32,
+ lpnumberofbytesrecvd: *mut u32,
+ lpflags: *mut u32,
+ lpoverlapped: *mut OVERLAPPED,
+ lpcompletionroutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+ ) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn WSASend(
+ s: SOCKET,
+ lpbuffers: *const WSABUF,
+ dwbuffercount: u32,
+ lpnumberofbytessent: *mut u32,
+ dwflags: u32,
+ lpoverlapped: *mut OVERLAPPED,
+ lpcompletionroutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+ ) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn WSASocketW(
+ af: i32,
+ r#type: i32,
+ protocol: i32,
+ lpprotocolinfo: *const WSAPROTOCOL_INFOW,
+ g: u32,
+ dwflags: u32,
+ ) -> SOCKET;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn WSAStartup(wversionrequested: u16, lpwsadata: *mut WSADATA) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn accept(s: SOCKET, addr: *mut SOCKADDR, addrlen: *mut i32) -> SOCKET;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn bind(s: SOCKET, name: *const SOCKADDR, namelen: i32) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn closesocket(s: SOCKET) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn connect(s: SOCKET, name: *const SOCKADDR, namelen: i32) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn freeaddrinfo(paddrinfo: *const ADDRINFOA) -> ();
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn getaddrinfo(
+ pnodename: PCSTR,
+ pservicename: PCSTR,
+ phints: *const ADDRINFOA,
+ ppresult: *mut *mut ADDRINFOA,
+ ) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn getpeername(s: SOCKET, name: *mut SOCKADDR, namelen: *mut i32) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn getsockname(s: SOCKET, name: *mut SOCKADDR, namelen: *mut i32) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn getsockopt(s: SOCKET, level: i32, optname: i32, optval: PSTR, optlen: *mut i32) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn ioctlsocket(s: SOCKET, cmd: i32, argp: *mut u32) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn listen(s: SOCKET, backlog: i32) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn recv(s: SOCKET, buf: PSTR, len: i32, flags: SEND_RECV_FLAGS) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn recvfrom(
+ s: SOCKET,
+ buf: PSTR,
+ len: i32,
+ flags: i32,
+ from: *mut SOCKADDR,
+ fromlen: *mut i32,
+ ) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn select(
+ nfds: i32,
+ readfds: *mut FD_SET,
+ writefds: *mut FD_SET,
+ exceptfds: *mut FD_SET,
+ timeout: *const TIMEVAL,
+ ) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn send(s: SOCKET, buf: PCSTR, len: i32, flags: SEND_RECV_FLAGS) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn sendto(
+ s: SOCKET,
+ buf: PCSTR,
+ len: i32,
+ flags: i32,
+ to: *const SOCKADDR,
+ tolen: i32,
+ ) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn setsockopt(s: SOCKET, level: i32, optname: i32, optval: PCSTR, optlen: i32) -> i32;
+}
+#[link(name = "ws2_32")]
+extern "system" {
+ pub fn shutdown(s: SOCKET, how: WINSOCK_SHUTDOWN_HOW) -> i32;
+}
+pub const ABOVE_NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 32768u32;
+pub type ADDRESS_FAMILY = u16;
+#[repr(C)]
+pub struct ADDRINFOA {
+ pub ai_flags: i32,
+ pub ai_family: i32,
+ pub ai_socktype: i32,
+ pub ai_protocol: i32,
+ pub ai_addrlen: usize,
+ pub ai_canonname: PSTR,
+ pub ai_addr: *mut SOCKADDR,
+ pub ai_next: *mut ADDRINFOA,
+}
+impl ::core::marker::Copy for ADDRINFOA {}
+impl ::core::clone::Clone for ADDRINFOA {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const AF_INET: ADDRESS_FAMILY = 2u16;
+pub const AF_INET6: ADDRESS_FAMILY = 23u16;
+pub const AF_UNSPEC: ADDRESS_FAMILY = 0u16;
+#[repr(C)]
+pub union ARM64_NT_NEON128 {
+ pub Anonymous: ARM64_NT_NEON128_0,
+ pub D: [f64; 2],
+ pub S: [f32; 4],
+ pub H: [u16; 8],
+ pub B: [u8; 16],
+}
+impl ::core::marker::Copy for ARM64_NT_NEON128 {}
+impl ::core::clone::Clone for ARM64_NT_NEON128 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub struct ARM64_NT_NEON128_0 {
+ pub Low: u64,
+ pub High: i64,
+}
+impl ::core::marker::Copy for ARM64_NT_NEON128_0 {}
+impl ::core::clone::Clone for ARM64_NT_NEON128_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub type BCRYPTGENRANDOM_FLAGS = u32;
+pub type BCRYPT_ALG_HANDLE = *mut ::core::ffi::c_void;
+pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: BCRYPTGENRANDOM_FLAGS = 2u32;
+pub const BELOW_NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 16384u32;
+pub type BOOL = i32;
+pub type BOOLEAN = u8;
+#[repr(C)]
+pub struct BY_HANDLE_FILE_INFORMATION {
+ pub dwFileAttributes: u32,
+ pub ftCreationTime: FILETIME,
+ pub ftLastAccessTime: FILETIME,
+ pub ftLastWriteTime: FILETIME,
+ pub dwVolumeSerialNumber: u32,
+ pub nFileSizeHigh: u32,
+ pub nFileSizeLow: u32,
+ pub nNumberOfLinks: u32,
+ pub nFileIndexHigh: u32,
+ pub nFileIndexLow: u32,
+}
+impl ::core::marker::Copy for BY_HANDLE_FILE_INFORMATION {}
+impl ::core::clone::Clone for BY_HANDLE_FILE_INFORMATION {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const CALLBACK_CHUNK_FINISHED: LPPROGRESS_ROUTINE_CALLBACK_REASON = 0u32;
+pub const CALLBACK_STREAM_SWITCH: LPPROGRESS_ROUTINE_CALLBACK_REASON = 1u32;
+pub type COMPARESTRING_RESULT = u32;
+pub type CONSOLE_MODE = u32;
+#[repr(C)]
+pub struct CONSOLE_READCONSOLE_CONTROL {
+ pub nLength: u32,
+ pub nInitialChars: u32,
+ pub dwCtrlWakeupMask: u32,
+ pub dwControlKeyState: u32,
+}
+impl ::core::marker::Copy for CONSOLE_READCONSOLE_CONTROL {}
+impl ::core::clone::Clone for CONSOLE_READCONSOLE_CONTROL {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+#[cfg(target_arch = "aarch64")]
+pub struct CONTEXT {
+ pub ContextFlags: u32,
+ pub Cpsr: u32,
+ pub Anonymous: CONTEXT_0,
+ pub Sp: u64,
+ pub Pc: u64,
+ pub V: [ARM64_NT_NEON128; 32],
+ pub Fpcr: u32,
+ pub Fpsr: u32,
+ pub Bcr: [u32; 8],
+ pub Bvr: [u64; 8],
+ pub Wcr: [u32; 2],
+ pub Wvr: [u64; 2],
+}
+#[cfg(target_arch = "aarch64")]
+impl ::core::marker::Copy for CONTEXT {}
+#[cfg(target_arch = "aarch64")]
+impl ::core::clone::Clone for CONTEXT {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+#[cfg(target_arch = "aarch64")]
+pub union CONTEXT_0 {
+ pub Anonymous: CONTEXT_0_0,
+ pub X: [u64; 31],
+}
+#[cfg(target_arch = "aarch64")]
+impl ::core::marker::Copy for CONTEXT_0 {}
+#[cfg(target_arch = "aarch64")]
+impl ::core::clone::Clone for CONTEXT_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+#[cfg(target_arch = "aarch64")]
+pub struct CONTEXT_0_0 {
+ pub X0: u64,
+ pub X1: u64,
+ pub X2: u64,
+ pub X3: u64,
+ pub X4: u64,
+ pub X5: u64,
+ pub X6: u64,
+ pub X7: u64,
+ pub X8: u64,
+ pub X9: u64,
+ pub X10: u64,
+ pub X11: u64,
+ pub X12: u64,
+ pub X13: u64,
+ pub X14: u64,
+ pub X15: u64,
+ pub X16: u64,
+ pub X17: u64,
+ pub X18: u64,
+ pub X19: u64,
+ pub X20: u64,
+ pub X21: u64,
+ pub X22: u64,
+ pub X23: u64,
+ pub X24: u64,
+ pub X25: u64,
+ pub X26: u64,
+ pub X27: u64,
+ pub X28: u64,
+ pub Fp: u64,
+ pub Lr: u64,
+}
+#[cfg(target_arch = "aarch64")]
+impl ::core::marker::Copy for CONTEXT_0_0 {}
+#[cfg(target_arch = "aarch64")]
+impl ::core::clone::Clone for CONTEXT_0_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+#[cfg(target_arch = "x86_64")]
+pub struct CONTEXT {
+ pub P1Home: u64,
+ pub P2Home: u64,
+ pub P3Home: u64,
+ pub P4Home: u64,
+ pub P5Home: u64,
+ pub P6Home: u64,
+ pub ContextFlags: u32,
+ pub MxCsr: u32,
+ pub SegCs: u16,
+ pub SegDs: u16,
+ pub SegEs: u16,
+ pub SegFs: u16,
+ pub SegGs: u16,
+ pub SegSs: u16,
+ pub EFlags: u32,
+ pub Dr0: u64,
+ pub Dr1: u64,
+ pub Dr2: u64,
+ pub Dr3: u64,
+ pub Dr6: u64,
+ pub Dr7: u64,
+ pub Rax: u64,
+ pub Rcx: u64,
+ pub Rdx: u64,
+ pub Rbx: u64,
+ pub Rsp: u64,
+ pub Rbp: u64,
+ pub Rsi: u64,
+ pub Rdi: u64,
+ pub R8: u64,
+ pub R9: u64,
+ pub R10: u64,
+ pub R11: u64,
+ pub R12: u64,
+ pub R13: u64,
+ pub R14: u64,
+ pub R15: u64,
+ pub Rip: u64,
+ pub Anonymous: CONTEXT_0,
+ pub VectorRegister: [M128A; 26],
+ pub VectorControl: u64,
+ pub DebugControl: u64,
+ pub LastBranchToRip: u64,
+ pub LastBranchFromRip: u64,
+ pub LastExceptionToRip: u64,
+ pub LastExceptionFromRip: u64,
+}
+#[cfg(target_arch = "x86_64")]
+impl ::core::marker::Copy for CONTEXT {}
+#[cfg(target_arch = "x86_64")]
+impl ::core::clone::Clone for CONTEXT {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+#[cfg(target_arch = "x86_64")]
+pub union CONTEXT_0 {
+ pub FltSave: XSAVE_FORMAT,
+ pub Anonymous: CONTEXT_0_0,
+}
+#[cfg(target_arch = "x86_64")]
+impl ::core::marker::Copy for CONTEXT_0 {}
+#[cfg(target_arch = "x86_64")]
+impl ::core::clone::Clone for CONTEXT_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+#[cfg(target_arch = "x86_64")]
+pub struct CONTEXT_0_0 {
+ pub Header: [M128A; 2],
+ pub Legacy: [M128A; 8],
+ pub Xmm0: M128A,
+ pub Xmm1: M128A,
+ pub Xmm2: M128A,
+ pub Xmm3: M128A,
+ pub Xmm4: M128A,
+ pub Xmm5: M128A,
+ pub Xmm6: M128A,
+ pub Xmm7: M128A,
+ pub Xmm8: M128A,
+ pub Xmm9: M128A,
+ pub Xmm10: M128A,
+ pub Xmm11: M128A,
+ pub Xmm12: M128A,
+ pub Xmm13: M128A,
+ pub Xmm14: M128A,
+ pub Xmm15: M128A,
+}
+#[cfg(target_arch = "x86_64")]
+impl ::core::marker::Copy for CONTEXT_0_0 {}
+#[cfg(target_arch = "x86_64")]
+impl ::core::clone::Clone for CONTEXT_0_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+#[cfg(target_arch = "x86")]
+pub struct CONTEXT {
+ pub ContextFlags: u32,
+ pub Dr0: u32,
+ pub Dr1: u32,
+ pub Dr2: u32,
+ pub Dr3: u32,
+ pub Dr6: u32,
+ pub Dr7: u32,
+ pub FloatSave: FLOATING_SAVE_AREA,
+ pub SegGs: u32,
+ pub SegFs: u32,
+ pub SegEs: u32,
+ pub SegDs: u32,
+ pub Edi: u32,
+ pub Esi: u32,
+ pub Ebx: u32,
+ pub Edx: u32,
+ pub Ecx: u32,
+ pub Eax: u32,
+ pub Ebp: u32,
+ pub Eip: u32,
+ pub SegCs: u32,
+ pub EFlags: u32,
+ pub Esp: u32,
+ pub SegSs: u32,
+ pub ExtendedRegisters: [u8; 512],
+}
+#[cfg(target_arch = "x86")]
+impl ::core::marker::Copy for CONTEXT {}
+#[cfg(target_arch = "x86")]
+impl ::core::clone::Clone for CONTEXT {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const CP_UTF8: u32 = 65001u32;
+pub const CREATE_ALWAYS: FILE_CREATION_DISPOSITION = 2u32;
+pub const CREATE_BREAKAWAY_FROM_JOB: PROCESS_CREATION_FLAGS = 16777216u32;
+pub const CREATE_DEFAULT_ERROR_MODE: PROCESS_CREATION_FLAGS = 67108864u32;
+pub const CREATE_FORCEDOS: PROCESS_CREATION_FLAGS = 8192u32;
+pub const CREATE_IGNORE_SYSTEM_DEFAULT: PROCESS_CREATION_FLAGS = 2147483648u32;
+pub const CREATE_NEW: FILE_CREATION_DISPOSITION = 1u32;
+pub const CREATE_NEW_CONSOLE: PROCESS_CREATION_FLAGS = 16u32;
+pub const CREATE_NEW_PROCESS_GROUP: PROCESS_CREATION_FLAGS = 512u32;
+pub const CREATE_NO_WINDOW: PROCESS_CREATION_FLAGS = 134217728u32;
+pub const CREATE_PRESERVE_CODE_AUTHZ_LEVEL: PROCESS_CREATION_FLAGS = 33554432u32;
+pub const CREATE_PROTECTED_PROCESS: PROCESS_CREATION_FLAGS = 262144u32;
+pub const CREATE_SECURE_PROCESS: PROCESS_CREATION_FLAGS = 4194304u32;
+pub const CREATE_SEPARATE_WOW_VDM: PROCESS_CREATION_FLAGS = 2048u32;
+pub const CREATE_SHARED_WOW_VDM: PROCESS_CREATION_FLAGS = 4096u32;
+pub const CREATE_SUSPENDED: PROCESS_CREATION_FLAGS = 4u32;
+pub const CREATE_UNICODE_ENVIRONMENT: PROCESS_CREATION_FLAGS = 1024u32;
+pub const CSTR_EQUAL: COMPARESTRING_RESULT = 2u32;
+pub const CSTR_GREATER_THAN: COMPARESTRING_RESULT = 3u32;
+pub const CSTR_LESS_THAN: COMPARESTRING_RESULT = 1u32;
+pub const DEBUG_ONLY_THIS_PROCESS: PROCESS_CREATION_FLAGS = 2u32;
+pub const DEBUG_PROCESS: PROCESS_CREATION_FLAGS = 1u32;
+pub const DELETE: FILE_ACCESS_RIGHTS = 65536u32;
+pub const DETACHED_PROCESS: PROCESS_CREATION_FLAGS = 8u32;
+pub const DISABLE_NEWLINE_AUTO_RETURN: CONSOLE_MODE = 8u32;
+pub const DLL_PROCESS_DETACH: u32 = 0u32;
+pub const DLL_THREAD_DETACH: u32 = 3u32;
+pub const DNS_ERROR_ADDRESS_REQUIRED: WIN32_ERROR = 9573u32;
+pub const DNS_ERROR_ALIAS_LOOP: WIN32_ERROR = 9722u32;
+pub const DNS_ERROR_AUTOZONE_ALREADY_EXISTS: WIN32_ERROR = 9610u32;
+pub const DNS_ERROR_AXFR: WIN32_ERROR = 9752u32;
+pub const DNS_ERROR_BACKGROUND_LOADING: WIN32_ERROR = 9568u32;
+pub const DNS_ERROR_BAD_KEYMASTER: WIN32_ERROR = 9122u32;
+pub const DNS_ERROR_BAD_PACKET: WIN32_ERROR = 9502u32;
+pub const DNS_ERROR_CANNOT_FIND_ROOT_HINTS: WIN32_ERROR = 9564u32;
+pub const DNS_ERROR_CLIENT_SUBNET_ALREADY_EXISTS: WIN32_ERROR = 9977u32;
+pub const DNS_ERROR_CLIENT_SUBNET_DOES_NOT_EXIST: WIN32_ERROR = 9976u32;
+pub const DNS_ERROR_CLIENT_SUBNET_IS_ACCESSED: WIN32_ERROR = 9975u32;
+pub const DNS_ERROR_CNAME_COLLISION: WIN32_ERROR = 9709u32;
+pub const DNS_ERROR_CNAME_LOOP: WIN32_ERROR = 9707u32;
+pub const DNS_ERROR_DATAFILE_OPEN_FAILURE: WIN32_ERROR = 9653u32;
+pub const DNS_ERROR_DATAFILE_PARSING: WIN32_ERROR = 9655u32;
+pub const DNS_ERROR_DEFAULT_SCOPE: WIN32_ERROR = 9960u32;
+pub const DNS_ERROR_DEFAULT_VIRTUALIZATION_INSTANCE: WIN32_ERROR = 9925u32;
+pub const DNS_ERROR_DEFAULT_ZONESCOPE: WIN32_ERROR = 9953u32;
+pub const DNS_ERROR_DELEGATION_REQUIRED: WIN32_ERROR = 9571u32;
+pub const DNS_ERROR_DNAME_COLLISION: WIN32_ERROR = 9721u32;
+pub const DNS_ERROR_DNSSEC_IS_DISABLED: WIN32_ERROR = 9125u32;
+pub const DNS_ERROR_DP_ALREADY_ENLISTED: WIN32_ERROR = 9904u32;
+pub const DNS_ERROR_DP_ALREADY_EXISTS: WIN32_ERROR = 9902u32;
+pub const DNS_ERROR_DP_DOES_NOT_EXIST: WIN32_ERROR = 9901u32;
+pub const DNS_ERROR_DP_FSMO_ERROR: WIN32_ERROR = 9906u32;
+pub const DNS_ERROR_DP_NOT_AVAILABLE: WIN32_ERROR = 9905u32;
+pub const DNS_ERROR_DP_NOT_ENLISTED: WIN32_ERROR = 9903u32;
+pub const DNS_ERROR_DS_UNAVAILABLE: WIN32_ERROR = 9717u32;
+pub const DNS_ERROR_DS_ZONE_ALREADY_EXISTS: WIN32_ERROR = 9718u32;
+pub const DNS_ERROR_DWORD_VALUE_TOO_LARGE: WIN32_ERROR = 9567u32;
+pub const DNS_ERROR_DWORD_VALUE_TOO_SMALL: WIN32_ERROR = 9566u32;
+pub const DNS_ERROR_FILE_WRITEBACK_FAILED: WIN32_ERROR = 9654u32;
+pub const DNS_ERROR_FORWARDER_ALREADY_EXISTS: WIN32_ERROR = 9619u32;
+pub const DNS_ERROR_INCONSISTENT_ROOT_HINTS: WIN32_ERROR = 9565u32;
+pub const DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME: WIN32_ERROR = 9924u32;
+pub const DNS_ERROR_INVALID_CLIENT_SUBNET_NAME: WIN32_ERROR = 9984u32;
+pub const DNS_ERROR_INVALID_DATA: WIN32_ERROR = 13u32;
+pub const DNS_ERROR_INVALID_DATAFILE_NAME: WIN32_ERROR = 9652u32;
+pub const DNS_ERROR_INVALID_INITIAL_ROLLOVER_OFFSET: WIN32_ERROR = 9115u32;
+pub const DNS_ERROR_INVALID_IP_ADDRESS: WIN32_ERROR = 9552u32;
+pub const DNS_ERROR_INVALID_KEY_SIZE: WIN32_ERROR = 9106u32;
+pub const DNS_ERROR_INVALID_NAME: WIN32_ERROR = 123u32;
+pub const DNS_ERROR_INVALID_NAME_CHAR: WIN32_ERROR = 9560u32;
+pub const DNS_ERROR_INVALID_NSEC3_ITERATION_COUNT: WIN32_ERROR = 9124u32;
+pub const DNS_ERROR_INVALID_POLICY_TABLE: WIN32_ERROR = 9572u32;
+pub const DNS_ERROR_INVALID_PROPERTY: WIN32_ERROR = 9553u32;
+pub const DNS_ERROR_INVALID_ROLLOVER_PERIOD: WIN32_ERROR = 9114u32;
+pub const DNS_ERROR_INVALID_SCOPE_NAME: WIN32_ERROR = 9958u32;
+pub const DNS_ERROR_INVALID_SCOPE_OPERATION: WIN32_ERROR = 9961u32;
+pub const DNS_ERROR_INVALID_SIGNATURE_VALIDITY_PERIOD: WIN32_ERROR = 9123u32;
+pub const DNS_ERROR_INVALID_TYPE: WIN32_ERROR = 9551u32;
+pub const DNS_ERROR_INVALID_XML: WIN32_ERROR = 9126u32;
+pub const DNS_ERROR_INVALID_ZONESCOPE_NAME: WIN32_ERROR = 9954u32;
+pub const DNS_ERROR_INVALID_ZONE_OPERATION: WIN32_ERROR = 9603u32;
+pub const DNS_ERROR_INVALID_ZONE_TYPE: WIN32_ERROR = 9611u32;
+pub const DNS_ERROR_KEYMASTER_REQUIRED: WIN32_ERROR = 9101u32;
+pub const DNS_ERROR_KSP_DOES_NOT_SUPPORT_PROTECTION: WIN32_ERROR = 9108u32;
+pub const DNS_ERROR_KSP_NOT_ACCESSIBLE: WIN32_ERROR = 9112u32;
+pub const DNS_ERROR_LOAD_ZONESCOPE_FAILED: WIN32_ERROR = 9956u32;
+pub const DNS_ERROR_NAME_DOES_NOT_EXIST: WIN32_ERROR = 9714u32;
+pub const DNS_ERROR_NAME_NOT_IN_ZONE: WIN32_ERROR = 9706u32;
+pub const DNS_ERROR_NBSTAT_INIT_FAILED: WIN32_ERROR = 9617u32;
+pub const DNS_ERROR_NEED_SECONDARY_ADDRESSES: WIN32_ERROR = 9614u32;
+pub const DNS_ERROR_NEED_WINS_SERVERS: WIN32_ERROR = 9616u32;
+pub const DNS_ERROR_NODE_CREATION_FAILED: WIN32_ERROR = 9703u32;
+pub const DNS_ERROR_NODE_IS_CNAME: WIN32_ERROR = 9708u32;
+pub const DNS_ERROR_NODE_IS_DNAME: WIN32_ERROR = 9720u32;
+pub const DNS_ERROR_NON_RFC_NAME: WIN32_ERROR = 9556u32;
+pub const DNS_ERROR_NOT_ALLOWED_ON_ACTIVE_SKD: WIN32_ERROR = 9119u32;
+pub const DNS_ERROR_NOT_ALLOWED_ON_RODC: WIN32_ERROR = 9569u32;
+pub const DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER: WIN32_ERROR = 9562u32;
+pub const DNS_ERROR_NOT_ALLOWED_ON_SIGNED_ZONE: WIN32_ERROR = 9102u32;
+pub const DNS_ERROR_NOT_ALLOWED_ON_UNSIGNED_ZONE: WIN32_ERROR = 9121u32;
+pub const DNS_ERROR_NOT_ALLOWED_ON_ZSK: WIN32_ERROR = 9118u32;
+pub const DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION: WIN32_ERROR = 9563u32;
+pub const DNS_ERROR_NOT_ALLOWED_UNDER_DNAME: WIN32_ERROR = 9570u32;
+pub const DNS_ERROR_NOT_ALLOWED_WITH_ZONESCOPES: WIN32_ERROR = 9955u32;
+pub const DNS_ERROR_NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS: WIN32_ERROR = 9104u32;
+pub const DNS_ERROR_NOT_UNIQUE: WIN32_ERROR = 9555u32;
+pub const DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE: WIN32_ERROR = 9719u32;
+pub const DNS_ERROR_NO_CREATE_CACHE_DATA: WIN32_ERROR = 9713u32;
+pub const DNS_ERROR_NO_DNS_SERVERS: WIN32_ERROR = 9852u32;
+pub const DNS_ERROR_NO_MEMORY: WIN32_ERROR = 14u32;
+pub const DNS_ERROR_NO_PACKET: WIN32_ERROR = 9503u32;
+pub const DNS_ERROR_NO_TCPIP: WIN32_ERROR = 9851u32;
+pub const DNS_ERROR_NO_VALID_TRUST_ANCHORS: WIN32_ERROR = 9127u32;
+pub const DNS_ERROR_NO_ZONE_INFO: WIN32_ERROR = 9602u32;
+pub const DNS_ERROR_NSEC3_INCOMPATIBLE_WITH_RSA_SHA1: WIN32_ERROR = 9103u32;
+pub const DNS_ERROR_NSEC3_NAME_COLLISION: WIN32_ERROR = 9129u32;
+pub const DNS_ERROR_NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1: WIN32_ERROR = 9130u32;
+pub const DNS_ERROR_NUMERIC_NAME: WIN32_ERROR = 9561u32;
+pub const DNS_ERROR_POLICY_ALREADY_EXISTS: WIN32_ERROR = 9971u32;
+pub const DNS_ERROR_POLICY_DOES_NOT_EXIST: WIN32_ERROR = 9972u32;
+pub const DNS_ERROR_POLICY_INVALID_CRITERIA: WIN32_ERROR = 9973u32;
+pub const DNS_ERROR_POLICY_INVALID_CRITERIA_CLIENT_SUBNET: WIN32_ERROR = 9990u32;
+pub const DNS_ERROR_POLICY_INVALID_CRITERIA_FQDN: WIN32_ERROR = 9994u32;
+pub const DNS_ERROR_POLICY_INVALID_CRITERIA_INTERFACE: WIN32_ERROR = 9993u32;
+pub const DNS_ERROR_POLICY_INVALID_CRITERIA_NETWORK_PROTOCOL: WIN32_ERROR = 9992u32;
+pub const DNS_ERROR_POLICY_INVALID_CRITERIA_QUERY_TYPE: WIN32_ERROR = 9995u32;
+pub const DNS_ERROR_POLICY_INVALID_CRITERIA_TIME_OF_DAY: WIN32_ERROR = 9996u32;
+pub const DNS_ERROR_POLICY_INVALID_CRITERIA_TRANSPORT_PROTOCOL: WIN32_ERROR = 9991u32;
+pub const DNS_ERROR_POLICY_INVALID_NAME: WIN32_ERROR = 9982u32;
+pub const DNS_ERROR_POLICY_INVALID_SETTINGS: WIN32_ERROR = 9974u32;
+pub const DNS_ERROR_POLICY_INVALID_WEIGHT: WIN32_ERROR = 9981u32;
+pub const DNS_ERROR_POLICY_LOCKED: WIN32_ERROR = 9980u32;
+pub const DNS_ERROR_POLICY_MISSING_CRITERIA: WIN32_ERROR = 9983u32;
+pub const DNS_ERROR_POLICY_PROCESSING_ORDER_INVALID: WIN32_ERROR = 9985u32;
+pub const DNS_ERROR_POLICY_SCOPE_MISSING: WIN32_ERROR = 9986u32;
+pub const DNS_ERROR_POLICY_SCOPE_NOT_ALLOWED: WIN32_ERROR = 9987u32;
+pub const DNS_ERROR_PRIMARY_REQUIRES_DATAFILE: WIN32_ERROR = 9651u32;
+pub const DNS_ERROR_RCODE: WIN32_ERROR = 9504u32;
+pub const DNS_ERROR_RCODE_BADKEY: WIN32_ERROR = 9017u32;
+pub const DNS_ERROR_RCODE_BADSIG: WIN32_ERROR = 9016u32;
+pub const DNS_ERROR_RCODE_BADTIME: WIN32_ERROR = 9018u32;
+pub const DNS_ERROR_RCODE_FORMAT_ERROR: WIN32_ERROR = 9001u32;
+pub const DNS_ERROR_RCODE_NAME_ERROR: WIN32_ERROR = 9003u32;
+pub const DNS_ERROR_RCODE_NOTAUTH: WIN32_ERROR = 9009u32;
+pub const DNS_ERROR_RCODE_NOTZONE: WIN32_ERROR = 9010u32;
+pub const DNS_ERROR_RCODE_NOT_IMPLEMENTED: WIN32_ERROR = 9004u32;
+pub const DNS_ERROR_RCODE_NXRRSET: WIN32_ERROR = 9008u32;
+pub const DNS_ERROR_RCODE_REFUSED: WIN32_ERROR = 9005u32;
+pub const DNS_ERROR_RCODE_SERVER_FAILURE: WIN32_ERROR = 9002u32;
+pub const DNS_ERROR_RCODE_YXDOMAIN: WIN32_ERROR = 9006u32;
+pub const DNS_ERROR_RCODE_YXRRSET: WIN32_ERROR = 9007u32;
+pub const DNS_ERROR_RECORD_ALREADY_EXISTS: WIN32_ERROR = 9711u32;
+pub const DNS_ERROR_RECORD_DOES_NOT_EXIST: WIN32_ERROR = 9701u32;
+pub const DNS_ERROR_RECORD_FORMAT: WIN32_ERROR = 9702u32;
+pub const DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT: WIN32_ERROR = 9710u32;
+pub const DNS_ERROR_RECORD_TIMED_OUT: WIN32_ERROR = 9705u32;
+pub const DNS_ERROR_ROLLOVER_ALREADY_QUEUED: WIN32_ERROR = 9120u32;
+pub const DNS_ERROR_ROLLOVER_IN_PROGRESS: WIN32_ERROR = 9116u32;
+pub const DNS_ERROR_ROLLOVER_NOT_POKEABLE: WIN32_ERROR = 9128u32;
+pub const DNS_ERROR_RRL_INVALID_IPV4_PREFIX: WIN32_ERROR = 9913u32;
+pub const DNS_ERROR_RRL_INVALID_IPV6_PREFIX: WIN32_ERROR = 9914u32;
+pub const DNS_ERROR_RRL_INVALID_LEAK_RATE: WIN32_ERROR = 9916u32;
+pub const DNS_ERROR_RRL_INVALID_TC_RATE: WIN32_ERROR = 9915u32;
+pub const DNS_ERROR_RRL_INVALID_WINDOW_SIZE: WIN32_ERROR = 9912u32;
+pub const DNS_ERROR_RRL_LEAK_RATE_LESSTHAN_TC_RATE: WIN32_ERROR = 9917u32;
+pub const DNS_ERROR_RRL_NOT_ENABLED: WIN32_ERROR = 9911u32;
+pub const DNS_ERROR_SCOPE_ALREADY_EXISTS: WIN32_ERROR = 9963u32;
+pub const DNS_ERROR_SCOPE_DOES_NOT_EXIST: WIN32_ERROR = 9959u32;
+pub const DNS_ERROR_SCOPE_LOCKED: WIN32_ERROR = 9962u32;
+pub const DNS_ERROR_SECONDARY_DATA: WIN32_ERROR = 9712u32;
+pub const DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP: WIN32_ERROR = 9612u32;
+pub const DNS_ERROR_SERVERSCOPE_IS_REFERENCED: WIN32_ERROR = 9988u32;
+pub const DNS_ERROR_SIGNING_KEY_NOT_ACCESSIBLE: WIN32_ERROR = 9107u32;
+pub const DNS_ERROR_SOA_DELETE_INVALID: WIN32_ERROR = 9618u32;
+pub const DNS_ERROR_STANDBY_KEY_NOT_PRESENT: WIN32_ERROR = 9117u32;
+pub const DNS_ERROR_SUBNET_ALREADY_EXISTS: WIN32_ERROR = 9979u32;
+pub const DNS_ERROR_SUBNET_DOES_NOT_EXIST: WIN32_ERROR = 9978u32;
+pub const DNS_ERROR_TOO_MANY_SKDS: WIN32_ERROR = 9113u32;
+pub const DNS_ERROR_TRY_AGAIN_LATER: WIN32_ERROR = 9554u32;
+pub const DNS_ERROR_UNEXPECTED_CNG_ERROR: WIN32_ERROR = 9110u32;
+pub const DNS_ERROR_UNEXPECTED_DATA_PROTECTION_ERROR: WIN32_ERROR = 9109u32;
+pub const DNS_ERROR_UNKNOWN_RECORD_TYPE: WIN32_ERROR = 9704u32;
+pub const DNS_ERROR_UNKNOWN_SIGNING_PARAMETER_VERSION: WIN32_ERROR = 9111u32;
+pub const DNS_ERROR_UNSECURE_PACKET: WIN32_ERROR = 9505u32;
+pub const DNS_ERROR_UNSUPPORTED_ALGORITHM: WIN32_ERROR = 9105u32;
+pub const DNS_ERROR_VIRTUALIZATION_INSTANCE_ALREADY_EXISTS: WIN32_ERROR = 9921u32;
+pub const DNS_ERROR_VIRTUALIZATION_INSTANCE_DOES_NOT_EXIST: WIN32_ERROR = 9922u32;
+pub const DNS_ERROR_VIRTUALIZATION_TREE_LOCKED: WIN32_ERROR = 9923u32;
+pub const DNS_ERROR_WINS_INIT_FAILED: WIN32_ERROR = 9615u32;
+pub const DNS_ERROR_ZONESCOPE_ALREADY_EXISTS: WIN32_ERROR = 9951u32;
+pub const DNS_ERROR_ZONESCOPE_DOES_NOT_EXIST: WIN32_ERROR = 9952u32;
+pub const DNS_ERROR_ZONESCOPE_FILE_WRITEBACK_FAILED: WIN32_ERROR = 9957u32;
+pub const DNS_ERROR_ZONESCOPE_IS_REFERENCED: WIN32_ERROR = 9989u32;
+pub const DNS_ERROR_ZONE_ALREADY_EXISTS: WIN32_ERROR = 9609u32;
+pub const DNS_ERROR_ZONE_CONFIGURATION_ERROR: WIN32_ERROR = 9604u32;
+pub const DNS_ERROR_ZONE_CREATION_FAILED: WIN32_ERROR = 9608u32;
+pub const DNS_ERROR_ZONE_DOES_NOT_EXIST: WIN32_ERROR = 9601u32;
+pub const DNS_ERROR_ZONE_HAS_NO_NS_RECORDS: WIN32_ERROR = 9606u32;
+pub const DNS_ERROR_ZONE_HAS_NO_SOA_RECORD: WIN32_ERROR = 9605u32;
+pub const DNS_ERROR_ZONE_IS_SHUTDOWN: WIN32_ERROR = 9621u32;
+pub const DNS_ERROR_ZONE_LOCKED: WIN32_ERROR = 9607u32;
+pub const DNS_ERROR_ZONE_LOCKED_FOR_SIGNING: WIN32_ERROR = 9622u32;
+pub const DNS_ERROR_ZONE_NOT_SECONDARY: WIN32_ERROR = 9613u32;
+pub const DNS_ERROR_ZONE_REQUIRES_MASTER_IP: WIN32_ERROR = 9620u32;
+pub const DUPLICATE_CLOSE_SOURCE: DUPLICATE_HANDLE_OPTIONS = 1u32;
+pub type DUPLICATE_HANDLE_OPTIONS = u32;
+pub const DUPLICATE_SAME_ACCESS: DUPLICATE_HANDLE_OPTIONS = 2u32;
+pub const ENABLE_AUTO_POSITION: CONSOLE_MODE = 256u32;
+pub const ENABLE_ECHO_INPUT: CONSOLE_MODE = 4u32;
+pub const ENABLE_EXTENDED_FLAGS: CONSOLE_MODE = 128u32;
+pub const ENABLE_INSERT_MODE: CONSOLE_MODE = 32u32;
+pub const ENABLE_LINE_INPUT: CONSOLE_MODE = 2u32;
+pub const ENABLE_LVB_GRID_WORLDWIDE: CONSOLE_MODE = 16u32;
+pub const ENABLE_MOUSE_INPUT: CONSOLE_MODE = 16u32;
+pub const ENABLE_PROCESSED_INPUT: CONSOLE_MODE = 1u32;
+pub const ENABLE_PROCESSED_OUTPUT: CONSOLE_MODE = 1u32;
+pub const ENABLE_QUICK_EDIT_MODE: CONSOLE_MODE = 64u32;
+pub const ENABLE_VIRTUAL_TERMINAL_INPUT: CONSOLE_MODE = 512u32;
+pub const ENABLE_VIRTUAL_TERMINAL_PROCESSING: CONSOLE_MODE = 4u32;
+pub const ENABLE_WINDOW_INPUT: CONSOLE_MODE = 8u32;
+pub const ENABLE_WRAP_AT_EOL_OUTPUT: CONSOLE_MODE = 2u32;
+pub const ERROR_ABANDONED_WAIT_0: WIN32_ERROR = 735u32;
+pub const ERROR_ABANDONED_WAIT_63: WIN32_ERROR = 736u32;
+pub const ERROR_ABANDON_HIBERFILE: WIN32_ERROR = 787u32;
+pub const ERROR_ABIOS_ERROR: WIN32_ERROR = 538u32;
+pub const ERROR_ACCESS_AUDIT_BY_POLICY: WIN32_ERROR = 785u32;
+pub const ERROR_ACCESS_DENIED: WIN32_ERROR = 5u32;
+pub const ERROR_ACCESS_DENIED_APPDATA: WIN32_ERROR = 502u32;
+pub const ERROR_ACCESS_DISABLED_BY_POLICY: WIN32_ERROR = 1260u32;
+pub const ERROR_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY: WIN32_ERROR = 786u32;
+pub const ERROR_ACCESS_DISABLED_WEBBLADE: WIN32_ERROR = 1277u32;
+pub const ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER: WIN32_ERROR = 1278u32;
+pub const ERROR_ACCOUNT_DISABLED: WIN32_ERROR = 1331u32;
+pub const ERROR_ACCOUNT_EXPIRED: WIN32_ERROR = 1793u32;
+pub const ERROR_ACCOUNT_LOCKED_OUT: WIN32_ERROR = 1909u32;
+pub const ERROR_ACCOUNT_RESTRICTION: WIN32_ERROR = 1327u32;
+pub const ERROR_ACPI_ERROR: WIN32_ERROR = 669u32;
+pub const ERROR_ACTIVE_CONNECTIONS: WIN32_ERROR = 2402u32;
+pub const ERROR_ADAP_HDW_ERR: WIN32_ERROR = 57u32;
+pub const ERROR_ADDRESS_ALREADY_ASSOCIATED: WIN32_ERROR = 1227u32;
+pub const ERROR_ADDRESS_NOT_ASSOCIATED: WIN32_ERROR = 1228u32;
+pub const ERROR_ALERTED: WIN32_ERROR = 739u32;
+pub const ERROR_ALIAS_EXISTS: WIN32_ERROR = 1379u32;
+pub const ERROR_ALLOCATE_BUCKET: WIN32_ERROR = 602u32;
+pub const ERROR_ALLOTTED_SPACE_EXCEEDED: WIN32_ERROR = 1344u32;
+pub const ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED: WIN32_ERROR = 1933u32;
+pub const ERROR_ALREADY_ASSIGNED: WIN32_ERROR = 85u32;
+pub const ERROR_ALREADY_EXISTS: WIN32_ERROR = 183u32;
+pub const ERROR_ALREADY_FIBER: WIN32_ERROR = 1280u32;
+pub const ERROR_ALREADY_HAS_STREAM_ID: WIN32_ERROR = 4444u32;
+pub const ERROR_ALREADY_INITIALIZED: WIN32_ERROR = 1247u32;
+pub const ERROR_ALREADY_REGISTERED: WIN32_ERROR = 1242u32;
+pub const ERROR_ALREADY_RUNNING_LKG: WIN32_ERROR = 1074u32;
+pub const ERROR_ALREADY_THREAD: WIN32_ERROR = 1281u32;
+pub const ERROR_ALREADY_WAITING: WIN32_ERROR = 1904u32;
+pub const ERROR_ALREADY_WIN32: WIN32_ERROR = 719u32;
+pub const ERROR_API_UNAVAILABLE: WIN32_ERROR = 15841u32;
+pub const ERROR_APPCONTAINER_REQUIRED: WIN32_ERROR = 4251u32;
+pub const ERROR_APPEXEC_APP_COMPAT_BLOCK: WIN32_ERROR = 3068u32;
+pub const ERROR_APPEXEC_CALLER_WAIT_TIMEOUT: WIN32_ERROR = 3069u32;
+pub const ERROR_APPEXEC_CALLER_WAIT_TIMEOUT_LICENSING: WIN32_ERROR = 3071u32;
+pub const ERROR_APPEXEC_CALLER_WAIT_TIMEOUT_RESOURCES: WIN32_ERROR = 3072u32;
+pub const ERROR_APPEXEC_CALLER_WAIT_TIMEOUT_TERMINATION: WIN32_ERROR = 3070u32;
+pub const ERROR_APPEXEC_CONDITION_NOT_SATISFIED: WIN32_ERROR = 3060u32;
+pub const ERROR_APPEXEC_HANDLE_INVALIDATED: WIN32_ERROR = 3061u32;
+pub const ERROR_APPEXEC_HOST_ID_MISMATCH: WIN32_ERROR = 3066u32;
+pub const ERROR_APPEXEC_INVALID_HOST_GENERATION: WIN32_ERROR = 3062u32;
+pub const ERROR_APPEXEC_INVALID_HOST_STATE: WIN32_ERROR = 3064u32;
+pub const ERROR_APPEXEC_NO_DONOR: WIN32_ERROR = 3065u32;
+pub const ERROR_APPEXEC_UNEXPECTED_PROCESS_REGISTRATION: WIN32_ERROR = 3063u32;
+pub const ERROR_APPEXEC_UNKNOWN_USER: WIN32_ERROR = 3067u32;
+pub const ERROR_APPHELP_BLOCK: WIN32_ERROR = 1259u32;
+pub const ERROR_APPX_FILE_NOT_ENCRYPTED: WIN32_ERROR = 409u32;
+pub const ERROR_APP_HANG: WIN32_ERROR = 1298u32;
+pub const ERROR_APP_INIT_FAILURE: WIN32_ERROR = 575u32;
+pub const ERROR_APP_WRONG_OS: WIN32_ERROR = 1151u32;
+pub const ERROR_ARBITRATION_UNHANDLED: WIN32_ERROR = 723u32;
+pub const ERROR_ARENA_TRASHED: WIN32_ERROR = 7u32;
+pub const ERROR_ARITHMETIC_OVERFLOW: WIN32_ERROR = 534u32;
+pub const ERROR_ASSERTION_FAILURE: WIN32_ERROR = 668u32;
+pub const ERROR_ATOMIC_LOCKS_NOT_SUPPORTED: WIN32_ERROR = 174u32;
+pub const ERROR_AUDIT_FAILED: WIN32_ERROR = 606u32;
+pub const ERROR_AUTHENTICATION_FIREWALL_FAILED: WIN32_ERROR = 1935u32;
+pub const ERROR_AUTHIP_FAILURE: WIN32_ERROR = 1469u32;
+pub const ERROR_AUTODATASEG_EXCEEDS_64k: WIN32_ERROR = 199u32;
+pub const ERROR_BACKUP_CONTROLLER: WIN32_ERROR = 586u32;
+pub const ERROR_BADDB: WIN32_ERROR = 1009u32;
+pub const ERROR_BADKEY: WIN32_ERROR = 1010u32;
+pub const ERROR_BADSTARTPOSITION: WIN32_ERROR = 778u32;
+pub const ERROR_BAD_ACCESSOR_FLAGS: WIN32_ERROR = 773u32;
+pub const ERROR_BAD_ARGUMENTS: WIN32_ERROR = 160u32;
+pub const ERROR_BAD_COMMAND: WIN32_ERROR = 22u32;
+pub const ERROR_BAD_COMPRESSION_BUFFER: WIN32_ERROR = 605u32;
+pub const ERROR_BAD_CONFIGURATION: WIN32_ERROR = 1610u32;
+pub const ERROR_BAD_CURRENT_DIRECTORY: WIN32_ERROR = 703u32;
+pub const ERROR_BAD_DESCRIPTOR_FORMAT: WIN32_ERROR = 1361u32;
+pub const ERROR_BAD_DEVICE: WIN32_ERROR = 1200u32;
+pub const ERROR_BAD_DEVICE_PATH: WIN32_ERROR = 330u32;
+pub const ERROR_BAD_DEV_TYPE: WIN32_ERROR = 66u32;
+pub const ERROR_BAD_DLL_ENTRYPOINT: WIN32_ERROR = 609u32;
+pub const ERROR_BAD_DRIVER_LEVEL: WIN32_ERROR = 119u32;
+pub const ERROR_BAD_ENVIRONMENT: WIN32_ERROR = 10u32;
+pub const ERROR_BAD_EXE_FORMAT: WIN32_ERROR = 193u32;
+pub const ERROR_BAD_FILE_TYPE: WIN32_ERROR = 222u32;
+pub const ERROR_BAD_FORMAT: WIN32_ERROR = 11u32;
+pub const ERROR_BAD_FUNCTION_TABLE: WIN32_ERROR = 559u32;
+pub const ERROR_BAD_IMPERSONATION_LEVEL: WIN32_ERROR = 1346u32;
+pub const ERROR_BAD_INHERITANCE_ACL: WIN32_ERROR = 1340u32;
+pub const ERROR_BAD_LENGTH: WIN32_ERROR = 24u32;
+pub const ERROR_BAD_LOGON_SESSION_STATE: WIN32_ERROR = 1365u32;
+pub const ERROR_BAD_MCFG_TABLE: WIN32_ERROR = 791u32;
+pub const ERROR_BAD_NETPATH: WIN32_ERROR = 53u32;
+pub const ERROR_BAD_NET_NAME: WIN32_ERROR = 67u32;
+pub const ERROR_BAD_NET_RESP: WIN32_ERROR = 58u32;
+pub const ERROR_BAD_PATHNAME: WIN32_ERROR = 161u32;
+pub const ERROR_BAD_PIPE: WIN32_ERROR = 230u32;
+pub const ERROR_BAD_PROFILE: WIN32_ERROR = 1206u32;
+pub const ERROR_BAD_PROVIDER: WIN32_ERROR = 1204u32;
+pub const ERROR_BAD_QUERY_SYNTAX: WIN32_ERROR = 1615u32;
+pub const ERROR_BAD_RECOVERY_POLICY: WIN32_ERROR = 6012u32;
+pub const ERROR_BAD_REM_ADAP: WIN32_ERROR = 60u32;
+pub const ERROR_BAD_SERVICE_ENTRYPOINT: WIN32_ERROR = 610u32;
+pub const ERROR_BAD_STACK: WIN32_ERROR = 543u32;
+pub const ERROR_BAD_THREADID_ADDR: WIN32_ERROR = 159u32;
+pub const ERROR_BAD_TOKEN_TYPE: WIN32_ERROR = 1349u32;
+pub const ERROR_BAD_UNIT: WIN32_ERROR = 20u32;
+pub const ERROR_BAD_USERNAME: WIN32_ERROR = 2202u32;
+pub const ERROR_BAD_USER_PROFILE: WIN32_ERROR = 1253u32;
+pub const ERROR_BAD_VALIDATION_CLASS: WIN32_ERROR = 1348u32;
+pub const ERROR_BEGINNING_OF_MEDIA: WIN32_ERROR = 1102u32;
+pub const ERROR_BEYOND_VDL: WIN32_ERROR = 1289u32;
+pub const ERROR_BIOS_FAILED_TO_CONNECT_INTERRUPT: WIN32_ERROR = 585u32;
+pub const ERROR_BLOCKED_BY_PARENTAL_CONTROLS: WIN32_ERROR = 346u32;
+pub const ERROR_BLOCK_SHARED: WIN32_ERROR = 514u32;
+pub const ERROR_BLOCK_SOURCE_WEAK_REFERENCE_INVALID: WIN32_ERROR = 512u32;
+pub const ERROR_BLOCK_TARGET_WEAK_REFERENCE_INVALID: WIN32_ERROR = 513u32;
+pub const ERROR_BLOCK_TOO_MANY_REFERENCES: WIN32_ERROR = 347u32;
+pub const ERROR_BLOCK_WEAK_REFERENCE_INVALID: WIN32_ERROR = 511u32;
+pub const ERROR_BOOT_ALREADY_ACCEPTED: WIN32_ERROR = 1076u32;
+pub const ERROR_BROKEN_PIPE: WIN32_ERROR = 109u32;
+pub const ERROR_BUFFER_ALL_ZEROS: WIN32_ERROR = 754u32;
+pub const ERROR_BUFFER_OVERFLOW: WIN32_ERROR = 111u32;
+pub const ERROR_BUSY: WIN32_ERROR = 170u32;
+pub const ERROR_BUSY_DRIVE: WIN32_ERROR = 142u32;
+pub const ERROR_BUS_RESET: WIN32_ERROR = 1111u32;
+pub const ERROR_BYPASSIO_FLT_NOT_SUPPORTED: WIN32_ERROR = 506u32;
+pub const ERROR_CACHE_PAGE_LOCKED: WIN32_ERROR = 752u32;
+pub const ERROR_CALLBACK_INVOKE_INLINE: WIN32_ERROR = 812u32;
+pub const ERROR_CALLBACK_POP_STACK: WIN32_ERROR = 768u32;
+pub const ERROR_CALLBACK_SUPPLIED_INVALID_DATA: WIN32_ERROR = 1273u32;
+pub const ERROR_CALL_NOT_IMPLEMENTED: WIN32_ERROR = 120u32;
+pub const ERROR_CANCELLED: WIN32_ERROR = 1223u32;
+pub const ERROR_CANCEL_VIOLATION: WIN32_ERROR = 173u32;
+pub const ERROR_CANNOT_BREAK_OPLOCK: WIN32_ERROR = 802u32;
+pub const ERROR_CANNOT_COPY: WIN32_ERROR = 266u32;
+pub const ERROR_CANNOT_DETECT_DRIVER_FAILURE: WIN32_ERROR = 1080u32;
+pub const ERROR_CANNOT_DETECT_PROCESS_ABORT: WIN32_ERROR = 1081u32;
+pub const ERROR_CANNOT_FIND_WND_CLASS: WIN32_ERROR = 1407u32;
+pub const ERROR_CANNOT_GRANT_REQUESTED_OPLOCK: WIN32_ERROR = 801u32;
+pub const ERROR_CANNOT_IMPERSONATE: WIN32_ERROR = 1368u32;
+pub const ERROR_CANNOT_LOAD_REGISTRY_FILE: WIN32_ERROR = 589u32;
+pub const ERROR_CANNOT_MAKE: WIN32_ERROR = 82u32;
+pub const ERROR_CANNOT_OPEN_PROFILE: WIN32_ERROR = 1205u32;
+pub const ERROR_CANTFETCHBACKWARDS: WIN32_ERROR = 770u32;
+pub const ERROR_CANTOPEN: WIN32_ERROR = 1011u32;
+pub const ERROR_CANTREAD: WIN32_ERROR = 1012u32;
+pub const ERROR_CANTSCROLLBACKWARDS: WIN32_ERROR = 771u32;
+pub const ERROR_CANTWRITE: WIN32_ERROR = 1013u32;
+pub const ERROR_CANT_ACCESS_DOMAIN_INFO: WIN32_ERROR = 1351u32;
+pub const ERROR_CANT_ACCESS_FILE: WIN32_ERROR = 1920u32;
+pub const ERROR_CANT_CLEAR_ENCRYPTION_FLAG: WIN32_ERROR = 432u32;
+pub const ERROR_CANT_DISABLE_MANDATORY: WIN32_ERROR = 1310u32;
+pub const ERROR_CANT_ENABLE_DENY_ONLY: WIN32_ERROR = 629u32;
+pub const ERROR_CANT_OPEN_ANONYMOUS: WIN32_ERROR = 1347u32;
+pub const ERROR_CANT_RESOLVE_FILENAME: WIN32_ERROR = 1921u32;
+pub const ERROR_CANT_TERMINATE_SELF: WIN32_ERROR = 555u32;
+pub const ERROR_CANT_WAIT: WIN32_ERROR = 554u32;
+pub const ERROR_CAN_NOT_COMPLETE: WIN32_ERROR = 1003u32;
+pub const ERROR_CAPAUTHZ_CHANGE_TYPE: WIN32_ERROR = 451u32;
+pub const ERROR_CAPAUTHZ_DB_CORRUPTED: WIN32_ERROR = 455u32;
+pub const ERROR_CAPAUTHZ_NOT_AUTHORIZED: WIN32_ERROR = 453u32;
+pub const ERROR_CAPAUTHZ_NOT_DEVUNLOCKED: WIN32_ERROR = 450u32;
+pub const ERROR_CAPAUTHZ_NOT_PROVISIONED: WIN32_ERROR = 452u32;
+pub const ERROR_CAPAUTHZ_NO_POLICY: WIN32_ERROR = 454u32;
+pub const ERROR_CAPAUTHZ_SCCD_DEV_MODE_REQUIRED: WIN32_ERROR = 459u32;
+pub const ERROR_CAPAUTHZ_SCCD_INVALID_CATALOG: WIN32_ERROR = 456u32;
+pub const ERROR_CAPAUTHZ_SCCD_NO_AUTH_ENTITY: WIN32_ERROR = 457u32;
+pub const ERROR_CAPAUTHZ_SCCD_NO_CAPABILITY_MATCH: WIN32_ERROR = 460u32;
+pub const ERROR_CAPAUTHZ_SCCD_PARSE_ERROR: WIN32_ERROR = 458u32;
+pub const ERROR_CARDBUS_NOT_SUPPORTED: WIN32_ERROR = 724u32;
+pub const ERROR_CASE_DIFFERING_NAMES_IN_DIR: WIN32_ERROR = 424u32;
+pub const ERROR_CASE_SENSITIVE_PATH: WIN32_ERROR = 442u32;
+pub const ERROR_CERTIFICATE_VALIDATION_PREFERENCE_CONFLICT: WIN32_ERROR = 817u32;
+pub const ERROR_CHECKING_FILE_SYSTEM: WIN32_ERROR = 712u32;
+pub const ERROR_CHECKOUT_REQUIRED: WIN32_ERROR = 221u32;
+pub const ERROR_CHILD_MUST_BE_VOLATILE: WIN32_ERROR = 1021u32;
+pub const ERROR_CHILD_NOT_COMPLETE: WIN32_ERROR = 129u32;
+pub const ERROR_CHILD_PROCESS_BLOCKED: WIN32_ERROR = 367u32;
+pub const ERROR_CHILD_WINDOW_MENU: WIN32_ERROR = 1436u32;
+pub const ERROR_CIMFS_IMAGE_CORRUPT: WIN32_ERROR = 470u32;
+pub const ERROR_CIMFS_IMAGE_VERSION_NOT_SUPPORTED: WIN32_ERROR = 471u32;
+pub const ERROR_CIRCULAR_DEPENDENCY: WIN32_ERROR = 1059u32;
+pub const ERROR_CLASS_ALREADY_EXISTS: WIN32_ERROR = 1410u32;
+pub const ERROR_CLASS_DOES_NOT_EXIST: WIN32_ERROR = 1411u32;
+pub const ERROR_CLASS_HAS_WINDOWS: WIN32_ERROR = 1412u32;
+pub const ERROR_CLIENT_SERVER_PARAMETERS_INVALID: WIN32_ERROR = 597u32;
+pub const ERROR_CLIPBOARD_NOT_OPEN: WIN32_ERROR = 1418u32;
+pub const ERROR_CLOUD_FILE_ACCESS_DENIED: WIN32_ERROR = 395u32;
+pub const ERROR_CLOUD_FILE_ALREADY_CONNECTED: WIN32_ERROR = 378u32;
+pub const ERROR_CLOUD_FILE_AUTHENTICATION_FAILED: WIN32_ERROR = 386u32;
+pub const ERROR_CLOUD_FILE_CONNECTED_PROVIDER_ONLY: WIN32_ERROR = 382u32;
+pub const ERROR_CLOUD_FILE_DEHYDRATION_DISALLOWED: WIN32_ERROR = 434u32;
+pub const ERROR_CLOUD_FILE_INCOMPATIBLE_HARDLINKS: WIN32_ERROR = 396u32;
+pub const ERROR_CLOUD_FILE_INSUFFICIENT_RESOURCES: WIN32_ERROR = 387u32;
+pub const ERROR_CLOUD_FILE_INVALID_REQUEST: WIN32_ERROR = 380u32;
+pub const ERROR_CLOUD_FILE_IN_USE: WIN32_ERROR = 391u32;
+pub const ERROR_CLOUD_FILE_METADATA_CORRUPT: WIN32_ERROR = 363u32;
+pub const ERROR_CLOUD_FILE_METADATA_TOO_LARGE: WIN32_ERROR = 364u32;
+pub const ERROR_CLOUD_FILE_NETWORK_UNAVAILABLE: WIN32_ERROR = 388u32;
+pub const ERROR_CLOUD_FILE_NOT_IN_SYNC: WIN32_ERROR = 377u32;
+pub const ERROR_CLOUD_FILE_NOT_SUPPORTED: WIN32_ERROR = 379u32;
+pub const ERROR_CLOUD_FILE_NOT_UNDER_SYNC_ROOT: WIN32_ERROR = 390u32;
+pub const ERROR_CLOUD_FILE_PINNED: WIN32_ERROR = 392u32;
+pub const ERROR_CLOUD_FILE_PROPERTY_BLOB_CHECKSUM_MISMATCH: WIN32_ERROR = 366u32;
+pub const ERROR_CLOUD_FILE_PROPERTY_BLOB_TOO_LARGE: WIN32_ERROR = 365u32;
+pub const ERROR_CLOUD_FILE_PROPERTY_CORRUPT: WIN32_ERROR = 394u32;
+pub const ERROR_CLOUD_FILE_PROPERTY_LOCK_CONFLICT: WIN32_ERROR = 397u32;
+pub const ERROR_CLOUD_FILE_PROPERTY_VERSION_NOT_SUPPORTED: WIN32_ERROR = 375u32;
+pub const ERROR_CLOUD_FILE_PROVIDER_NOT_RUNNING: WIN32_ERROR = 362u32;
+pub const ERROR_CLOUD_FILE_PROVIDER_TERMINATED: WIN32_ERROR = 404u32;
+pub const ERROR_CLOUD_FILE_READ_ONLY_VOLUME: WIN32_ERROR = 381u32;
+pub const ERROR_CLOUD_FILE_REQUEST_ABORTED: WIN32_ERROR = 393u32;
+pub const ERROR_CLOUD_FILE_REQUEST_CANCELED: WIN32_ERROR = 398u32;
+pub const ERROR_CLOUD_FILE_REQUEST_TIMEOUT: WIN32_ERROR = 426u32;
+pub const ERROR_CLOUD_FILE_SYNC_ROOT_METADATA_CORRUPT: WIN32_ERROR = 358u32;
+pub const ERROR_CLOUD_FILE_TOO_MANY_PROPERTY_BLOBS: WIN32_ERROR = 374u32;
+pub const ERROR_CLOUD_FILE_UNSUCCESSFUL: WIN32_ERROR = 389u32;
+pub const ERROR_CLOUD_FILE_US_MESSAGE_TIMEOUT: WIN32_ERROR = 475u32;
+pub const ERROR_CLOUD_FILE_VALIDATION_FAILED: WIN32_ERROR = 383u32;
+pub const ERROR_COMMITMENT_LIMIT: WIN32_ERROR = 1455u32;
+pub const ERROR_COMMITMENT_MINIMUM: WIN32_ERROR = 635u32;
+pub const ERROR_COMPRESSED_FILE_NOT_SUPPORTED: WIN32_ERROR = 335u32;
+pub const ERROR_COMPRESSION_DISABLED: WIN32_ERROR = 769u32;
+pub const ERROR_COMPRESSION_NOT_BENEFICIAL: WIN32_ERROR = 344u32;
+pub const ERROR_CONNECTED_OTHER_PASSWORD: WIN32_ERROR = 2108u32;
+pub const ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT: WIN32_ERROR = 2109u32;
+pub const ERROR_CONNECTION_ABORTED: WIN32_ERROR = 1236u32;
+pub const ERROR_CONNECTION_ACTIVE: WIN32_ERROR = 1230u32;
+pub const ERROR_CONNECTION_COUNT_LIMIT: WIN32_ERROR = 1238u32;
+pub const ERROR_CONNECTION_INVALID: WIN32_ERROR = 1229u32;
+pub const ERROR_CONNECTION_REFUSED: WIN32_ERROR = 1225u32;
+pub const ERROR_CONNECTION_UNAVAIL: WIN32_ERROR = 1201u32;
+pub const ERROR_CONTAINER_ASSIGNED: WIN32_ERROR = 1504u32;
+pub const ERROR_CONTENT_BLOCKED: WIN32_ERROR = 1296u32;
+pub const ERROR_CONTEXT_EXPIRED: WIN32_ERROR = 1931u32;
+pub const ERROR_CONTINUE: WIN32_ERROR = 1246u32;
+pub const ERROR_CONTROL_C_EXIT: WIN32_ERROR = 572u32;
+pub const ERROR_CONTROL_ID_NOT_FOUND: WIN32_ERROR = 1421u32;
+pub const ERROR_CONVERT_TO_LARGE: WIN32_ERROR = 600u32;
+pub const ERROR_CORRUPT_LOG_CLEARED: WIN32_ERROR = 798u32;
+pub const ERROR_CORRUPT_LOG_CORRUPTED: WIN32_ERROR = 795u32;
+pub const ERROR_CORRUPT_LOG_DELETED_FULL: WIN32_ERROR = 797u32;
+pub const ERROR_CORRUPT_LOG_OVERFULL: WIN32_ERROR = 794u32;
+pub const ERROR_CORRUPT_LOG_UNAVAILABLE: WIN32_ERROR = 796u32;
+pub const ERROR_CORRUPT_SYSTEM_FILE: WIN32_ERROR = 634u32;
+pub const ERROR_COULD_NOT_INTERPRET: WIN32_ERROR = 552u32;
+pub const ERROR_COUNTER_TIMEOUT: WIN32_ERROR = 1121u32;
+pub const ERROR_CPU_SET_INVALID: WIN32_ERROR = 813u32;
+pub const ERROR_CRASH_DUMP: WIN32_ERROR = 753u32;
+pub const ERROR_CRC: WIN32_ERROR = 23u32;
+pub const ERROR_CREATE_FAILED: WIN32_ERROR = 1631u32;
+pub const ERROR_CROSS_PARTITION_VIOLATION: WIN32_ERROR = 1661u32;
+pub const ERROR_CSCSHARE_OFFLINE: WIN32_ERROR = 1262u32;
+pub const ERROR_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE: WIN32_ERROR = 6019u32;
+pub const ERROR_CS_ENCRYPTION_FILE_NOT_CSE: WIN32_ERROR = 6021u32;
+pub const ERROR_CS_ENCRYPTION_INVALID_SERVER_RESPONSE: WIN32_ERROR = 6017u32;
+pub const ERROR_CS_ENCRYPTION_NEW_ENCRYPTED_FILE: WIN32_ERROR = 6020u32;
+pub const ERROR_CS_ENCRYPTION_UNSUPPORTED_SERVER: WIN32_ERROR = 6018u32;
+pub const ERROR_CTX_CLIENT_QUERY_TIMEOUT: WIN32_ERROR = 7040u32;
+pub const ERROR_CTX_MODEM_RESPONSE_TIMEOUT: WIN32_ERROR = 7012u32;
+pub const ERROR_CURRENT_DIRECTORY: WIN32_ERROR = 16u32;
+pub const ERROR_CURRENT_DOMAIN_NOT_ALLOWED: WIN32_ERROR = 1399u32;
+pub const ERROR_DATABASE_DOES_NOT_EXIST: WIN32_ERROR = 1065u32;
+pub const ERROR_DATATYPE_MISMATCH: WIN32_ERROR = 1629u32;
+pub const ERROR_DATA_CHECKSUM_ERROR: WIN32_ERROR = 323u32;
+pub const ERROR_DATA_NOT_ACCEPTED: WIN32_ERROR = 592u32;
+pub const ERROR_DAX_MAPPING_EXISTS: WIN32_ERROR = 361u32;
+pub const ERROR_DBG_COMMAND_EXCEPTION: WIN32_ERROR = 697u32;
+pub const ERROR_DBG_CONTINUE: WIN32_ERROR = 767u32;
+pub const ERROR_DBG_CONTROL_BREAK: WIN32_ERROR = 696u32;
+pub const ERROR_DBG_CONTROL_C: WIN32_ERROR = 693u32;
+pub const ERROR_DBG_EXCEPTION_HANDLED: WIN32_ERROR = 766u32;
+pub const ERROR_DBG_EXCEPTION_NOT_HANDLED: WIN32_ERROR = 688u32;
+pub const ERROR_DBG_PRINTEXCEPTION_C: WIN32_ERROR = 694u32;
+pub const ERROR_DBG_REPLY_LATER: WIN32_ERROR = 689u32;
+pub const ERROR_DBG_RIPEXCEPTION: WIN32_ERROR = 695u32;
+pub const ERROR_DBG_TERMINATE_PROCESS: WIN32_ERROR = 692u32;
+pub const ERROR_DBG_TERMINATE_THREAD: WIN32_ERROR = 691u32;
+pub const ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE: WIN32_ERROR = 690u32;
+pub const ERROR_DC_NOT_FOUND: WIN32_ERROR = 1425u32;
+pub const ERROR_DDE_FAIL: WIN32_ERROR = 1156u32;
+pub const ERROR_DEBUGGER_INACTIVE: WIN32_ERROR = 1284u32;
+pub const ERROR_DEBUG_ATTACH_FAILED: WIN32_ERROR = 590u32;
+pub const ERROR_DECRYPTION_FAILED: WIN32_ERROR = 6001u32;
+pub const ERROR_DELAY_LOAD_FAILED: WIN32_ERROR = 1285u32;
+pub const ERROR_DELETE_PENDING: WIN32_ERROR = 303u32;
+pub const ERROR_DEPENDENT_SERVICES_RUNNING: WIN32_ERROR = 1051u32;
+pub const ERROR_DESTINATION_ELEMENT_FULL: WIN32_ERROR = 1161u32;
+pub const ERROR_DESTROY_OBJECT_OF_OTHER_THREAD: WIN32_ERROR = 1435u32;
+pub const ERROR_DEVICE_ALREADY_ATTACHED: WIN32_ERROR = 548u32;
+pub const ERROR_DEVICE_ALREADY_REMEMBERED: WIN32_ERROR = 1202u32;
+pub const ERROR_DEVICE_DOOR_OPEN: WIN32_ERROR = 1166u32;
+pub const ERROR_DEVICE_ENUMERATION_ERROR: WIN32_ERROR = 648u32;
+pub const ERROR_DEVICE_FEATURE_NOT_SUPPORTED: WIN32_ERROR = 316u32;
+pub const ERROR_DEVICE_HARDWARE_ERROR: WIN32_ERROR = 483u32;
+pub const ERROR_DEVICE_HINT_NAME_BUFFER_TOO_SMALL: WIN32_ERROR = 355u32;
+pub const ERROR_DEVICE_IN_MAINTENANCE: WIN32_ERROR = 359u32;
+pub const ERROR_DEVICE_IN_USE: WIN32_ERROR = 2404u32;
+pub const ERROR_DEVICE_NOT_CONNECTED: WIN32_ERROR = 1167u32;
+pub const ERROR_DEVICE_NOT_PARTITIONED: WIN32_ERROR = 1107u32;
+pub const ERROR_DEVICE_NO_RESOURCES: WIN32_ERROR = 322u32;
+pub const ERROR_DEVICE_REINITIALIZATION_NEEDED: WIN32_ERROR = 1164u32;
+pub const ERROR_DEVICE_REMOVED: WIN32_ERROR = 1617u32;
+pub const ERROR_DEVICE_REQUIRES_CLEANING: WIN32_ERROR = 1165u32;
+pub const ERROR_DEVICE_RESET_REQUIRED: WIN32_ERROR = 507u32;
+pub const ERROR_DEVICE_SUPPORT_IN_PROGRESS: WIN32_ERROR = 171u32;
+pub const ERROR_DEVICE_UNREACHABLE: WIN32_ERROR = 321u32;
+pub const ERROR_DEV_NOT_EXIST: WIN32_ERROR = 55u32;
+pub const ERROR_DHCP_ADDRESS_CONFLICT: WIN32_ERROR = 4100u32;
+pub const ERROR_DIFFERENT_SERVICE_ACCOUNT: WIN32_ERROR = 1079u32;
+pub const ERROR_DIRECTORY: WIN32_ERROR = 267u32;
+pub const ERROR_DIRECTORY_NOT_SUPPORTED: WIN32_ERROR = 336u32;
+pub const ERROR_DIRECT_ACCESS_HANDLE: WIN32_ERROR = 130u32;
+pub const ERROR_DIR_EFS_DISALLOWED: WIN32_ERROR = 6010u32;
+pub const ERROR_DIR_NOT_EMPTY: WIN32_ERROR = 145u32;
+pub const ERROR_DIR_NOT_ROOT: WIN32_ERROR = 144u32;
+pub const ERROR_DISCARDED: WIN32_ERROR = 157u32;
+pub const ERROR_DISK_CHANGE: WIN32_ERROR = 107u32;
+pub const ERROR_DISK_CORRUPT: WIN32_ERROR = 1393u32;
+pub const ERROR_DISK_FULL: WIN32_ERROR = 112u32;
+pub const ERROR_DISK_OPERATION_FAILED: WIN32_ERROR = 1127u32;
+pub const ERROR_DISK_QUOTA_EXCEEDED: WIN32_ERROR = 1295u32;
+pub const ERROR_DISK_RECALIBRATE_FAILED: WIN32_ERROR = 1126u32;
+pub const ERROR_DISK_REPAIR_DISABLED: WIN32_ERROR = 780u32;
+pub const ERROR_DISK_REPAIR_REDIRECTED: WIN32_ERROR = 792u32;
+pub const ERROR_DISK_REPAIR_UNSUCCESSFUL: WIN32_ERROR = 793u32;
+pub const ERROR_DISK_RESET_FAILED: WIN32_ERROR = 1128u32;
+pub const ERROR_DISK_RESOURCES_EXHAUSTED: WIN32_ERROR = 314u32;
+pub const ERROR_DISK_TOO_FRAGMENTED: WIN32_ERROR = 302u32;
+pub const ERROR_DLL_INIT_FAILED: WIN32_ERROR = 1114u32;
+pub const ERROR_DLL_INIT_FAILED_LOGOFF: WIN32_ERROR = 624u32;
+pub const ERROR_DLL_MIGHT_BE_INCOMPATIBLE: WIN32_ERROR = 687u32;
+pub const ERROR_DLL_MIGHT_BE_INSECURE: WIN32_ERROR = 686u32;
+pub const ERROR_DLL_NOT_FOUND: WIN32_ERROR = 1157u32;
+pub const ERROR_DLP_POLICY_DENIES_OPERATION: WIN32_ERROR = 446u32;
+pub const ERROR_DLP_POLICY_SILENTLY_FAIL: WIN32_ERROR = 449u32;
+pub const ERROR_DLP_POLICY_WARNS_AGAINST_OPERATION: WIN32_ERROR = 445u32;
+pub const ERROR_DOMAIN_CONTROLLER_EXISTS: WIN32_ERROR = 1250u32;
+pub const ERROR_DOMAIN_CONTROLLER_NOT_FOUND: WIN32_ERROR = 1908u32;
+pub const ERROR_DOMAIN_CTRLR_CONFIG_ERROR: WIN32_ERROR = 581u32;
+pub const ERROR_DOMAIN_EXISTS: WIN32_ERROR = 1356u32;
+pub const ERROR_DOMAIN_LIMIT_EXCEEDED: WIN32_ERROR = 1357u32;
+pub const ERROR_DOMAIN_SID_SAME_AS_LOCAL_WORKSTATION: WIN32_ERROR = 8644u32;
+pub const ERROR_DOMAIN_TRUST_INCONSISTENT: WIN32_ERROR = 1810u32;
+pub const ERROR_DOWNGRADE_DETECTED: WIN32_ERROR = 1265u32;
+pub const ERROR_DPL_NOT_SUPPORTED_FOR_USER: WIN32_ERROR = 423u32;
+pub const ERROR_DRIVERS_LEAKING_LOCKED_PAGES: WIN32_ERROR = 729u32;
+pub const ERROR_DRIVER_BLOCKED: WIN32_ERROR = 1275u32;
+pub const ERROR_DRIVER_CANCEL_TIMEOUT: WIN32_ERROR = 594u32;
+pub const ERROR_DRIVER_DATABASE_ERROR: WIN32_ERROR = 652u32;
+pub const ERROR_DRIVER_FAILED_PRIOR_UNLOAD: WIN32_ERROR = 654u32;
+pub const ERROR_DRIVER_FAILED_SLEEP: WIN32_ERROR = 633u32;
+pub const ERROR_DRIVER_PROCESS_TERMINATED: WIN32_ERROR = 1291u32;
+pub const ERROR_DRIVE_LOCKED: WIN32_ERROR = 108u32;
+pub const ERROR_DS_ADD_REPLICA_INHIBITED: WIN32_ERROR = 8302u32;
+pub const ERROR_DS_ADMIN_LIMIT_EXCEEDED: WIN32_ERROR = 8228u32;
+pub const ERROR_DS_AFFECTS_MULTIPLE_DSAS: WIN32_ERROR = 8249u32;
+pub const ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER: WIN32_ERROR = 8578u32;
+pub const ERROR_DS_ALIASED_OBJ_MISSING: WIN32_ERROR = 8334u32;
+pub const ERROR_DS_ALIAS_DEREF_PROBLEM: WIN32_ERROR = 8244u32;
+pub const ERROR_DS_ALIAS_POINTS_TO_ALIAS: WIN32_ERROR = 8336u32;
+pub const ERROR_DS_ALIAS_PROBLEM: WIN32_ERROR = 8241u32;
+pub const ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS: WIN32_ERROR = 8205u32;
+pub const ERROR_DS_ATTRIBUTE_OWNED_BY_SAM: WIN32_ERROR = 8346u32;
+pub const ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED: WIN32_ERROR = 8204u32;
+pub const ERROR_DS_ATT_ALREADY_EXISTS: WIN32_ERROR = 8318u32;
+pub const ERROR_DS_ATT_IS_NOT_ON_OBJ: WIN32_ERROR = 8310u32;
+pub const ERROR_DS_ATT_NOT_DEF_FOR_CLASS: WIN32_ERROR = 8317u32;
+pub const ERROR_DS_ATT_NOT_DEF_IN_SCHEMA: WIN32_ERROR = 8303u32;
+pub const ERROR_DS_ATT_SCHEMA_REQ_ID: WIN32_ERROR = 8399u32;
+pub const ERROR_DS_ATT_SCHEMA_REQ_SYNTAX: WIN32_ERROR = 8416u32;
+pub const ERROR_DS_ATT_VAL_ALREADY_EXISTS: WIN32_ERROR = 8323u32;
+pub const ERROR_DS_AUDIT_FAILURE: WIN32_ERROR = 8625u32;
+pub const ERROR_DS_AUTHORIZATION_FAILED: WIN32_ERROR = 8599u32;
+pub const ERROR_DS_AUTH_METHOD_NOT_SUPPORTED: WIN32_ERROR = 8231u32;
+pub const ERROR_DS_AUTH_UNKNOWN: WIN32_ERROR = 8234u32;
+pub const ERROR_DS_AUX_CLS_TEST_FAIL: WIN32_ERROR = 8389u32;
+pub const ERROR_DS_BACKLINK_WITHOUT_LINK: WIN32_ERROR = 8482u32;
+pub const ERROR_DS_BAD_ATT_SCHEMA_SYNTAX: WIN32_ERROR = 8400u32;
+pub const ERROR_DS_BAD_HIERARCHY_FILE: WIN32_ERROR = 8425u32;
+pub const ERROR_DS_BAD_INSTANCE_TYPE: WIN32_ERROR = 8313u32;
+pub const ERROR_DS_BAD_NAME_SYNTAX: WIN32_ERROR = 8335u32;
+pub const ERROR_DS_BAD_RDN_ATT_ID_SYNTAX: WIN32_ERROR = 8392u32;
+pub const ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED: WIN32_ERROR = 8426u32;
+pub const ERROR_DS_BUSY: WIN32_ERROR = 8206u32;
+pub const ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD: WIN32_ERROR = 8585u32;
+pub const ERROR_DS_CANT_ADD_ATT_VALUES: WIN32_ERROR = 8320u32;
+pub const ERROR_DS_CANT_ADD_SYSTEM_ONLY: WIN32_ERROR = 8358u32;
+pub const ERROR_DS_CANT_ADD_TO_GC: WIN32_ERROR = 8550u32;
+pub const ERROR_DS_CANT_CACHE_ATT: WIN32_ERROR = 8401u32;
+pub const ERROR_DS_CANT_CACHE_CLASS: WIN32_ERROR = 8402u32;
+pub const ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC: WIN32_ERROR = 8553u32;
+pub const ERROR_DS_CANT_CREATE_UNDER_SCHEMA: WIN32_ERROR = 8510u32;
+pub const ERROR_DS_CANT_DELETE: WIN32_ERROR = 8398u32;
+pub const ERROR_DS_CANT_DELETE_DSA_OBJ: WIN32_ERROR = 8340u32;
+pub const ERROR_DS_CANT_DEL_MASTER_CROSSREF: WIN32_ERROR = 8375u32;
+pub const ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC: WIN32_ERROR = 8604u32;
+pub const ERROR_DS_CANT_DEREF_ALIAS: WIN32_ERROR = 8337u32;
+pub const ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN: WIN32_ERROR = 8603u32;
+pub const ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF: WIN32_ERROR = 8589u32;
+pub const ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN: WIN32_ERROR = 8537u32;
+pub const ERROR_DS_CANT_FIND_DSA_OBJ: WIN32_ERROR = 8419u32;
+pub const ERROR_DS_CANT_FIND_EXPECTED_NC: WIN32_ERROR = 8420u32;
+pub const ERROR_DS_CANT_FIND_NC_IN_CACHE: WIN32_ERROR = 8421u32;
+pub const ERROR_DS_CANT_MIX_MASTER_AND_REPS: WIN32_ERROR = 8331u32;
+pub const ERROR_DS_CANT_MOD_OBJ_CLASS: WIN32_ERROR = 8215u32;
+pub const ERROR_DS_CANT_MOD_PRIMARYGROUPID: WIN32_ERROR = 8506u32;
+pub const ERROR_DS_CANT_MOD_SYSTEM_ONLY: WIN32_ERROR = 8369u32;
+pub const ERROR_DS_CANT_MOVE_ACCOUNT_GROUP: WIN32_ERROR = 8498u32;
+pub const ERROR_DS_CANT_MOVE_APP_BASIC_GROUP: WIN32_ERROR = 8608u32;
+pub const ERROR_DS_CANT_MOVE_APP_QUERY_GROUP: WIN32_ERROR = 8609u32;
+pub const ERROR_DS_CANT_MOVE_DELETED_OBJECT: WIN32_ERROR = 8489u32;
+pub const ERROR_DS_CANT_MOVE_RESOURCE_GROUP: WIN32_ERROR = 8499u32;
+pub const ERROR_DS_CANT_ON_NON_LEAF: WIN32_ERROR = 8213u32;
+pub const ERROR_DS_CANT_ON_RDN: WIN32_ERROR = 8214u32;
+pub const ERROR_DS_CANT_REMOVE_ATT_CACHE: WIN32_ERROR = 8403u32;
+pub const ERROR_DS_CANT_REMOVE_CLASS_CACHE: WIN32_ERROR = 8404u32;
+pub const ERROR_DS_CANT_REM_MISSING_ATT: WIN32_ERROR = 8324u32;
+pub const ERROR_DS_CANT_REM_MISSING_ATT_VAL: WIN32_ERROR = 8325u32;
+pub const ERROR_DS_CANT_REPLACE_HIDDEN_REC: WIN32_ERROR = 8424u32;
+pub const ERROR_DS_CANT_RETRIEVE_ATTS: WIN32_ERROR = 8481u32;
+pub const ERROR_DS_CANT_RETRIEVE_CHILD: WIN32_ERROR = 8422u32;
+pub const ERROR_DS_CANT_RETRIEVE_DN: WIN32_ERROR = 8405u32;
+pub const ERROR_DS_CANT_RETRIEVE_INSTANCE: WIN32_ERROR = 8407u32;
+pub const ERROR_DS_CANT_RETRIEVE_SD: WIN32_ERROR = 8526u32;
+pub const ERROR_DS_CANT_START: WIN32_ERROR = 8531u32;
+pub const ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ: WIN32_ERROR = 8560u32;
+pub const ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS: WIN32_ERROR = 8493u32;
+pub const ERROR_DS_CHILDREN_EXIST: WIN32_ERROR = 8332u32;
+pub const ERROR_DS_CLASS_MUST_BE_CONCRETE: WIN32_ERROR = 8359u32;
+pub const ERROR_DS_CLASS_NOT_DSA: WIN32_ERROR = 8343u32;
+pub const ERROR_DS_CLIENT_LOOP: WIN32_ERROR = 8259u32;
+pub const ERROR_DS_CODE_INCONSISTENCY: WIN32_ERROR = 8408u32;
+pub const ERROR_DS_COMPARE_FALSE: WIN32_ERROR = 8229u32;
+pub const ERROR_DS_COMPARE_TRUE: WIN32_ERROR = 8230u32;
+pub const ERROR_DS_CONFIDENTIALITY_REQUIRED: WIN32_ERROR = 8237u32;
+pub const ERROR_DS_CONFIG_PARAM_MISSING: WIN32_ERROR = 8427u32;
+pub const ERROR_DS_CONSTRAINT_VIOLATION: WIN32_ERROR = 8239u32;
+pub const ERROR_DS_CONSTRUCTED_ATT_MOD: WIN32_ERROR = 8475u32;
+pub const ERROR_DS_CONTROL_NOT_FOUND: WIN32_ERROR = 8258u32;
+pub const ERROR_DS_COULDNT_CONTACT_FSMO: WIN32_ERROR = 8367u32;
+pub const ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE: WIN32_ERROR = 8503u32;
+pub const ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE: WIN32_ERROR = 8502u32;
+pub const ERROR_DS_COULDNT_UPDATE_SPNS: WIN32_ERROR = 8525u32;
+pub const ERROR_DS_COUNTING_AB_INDICES_FAILED: WIN32_ERROR = 8428u32;
+pub const ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD: WIN32_ERROR = 8491u32;
+pub const ERROR_DS_CROSS_DOM_MOVE_ERROR: WIN32_ERROR = 8216u32;
+pub const ERROR_DS_CROSS_NC_DN_RENAME: WIN32_ERROR = 8368u32;
+pub const ERROR_DS_CROSS_REF_BUSY: WIN32_ERROR = 8602u32;
+pub const ERROR_DS_CROSS_REF_EXISTS: WIN32_ERROR = 8374u32;
+pub const ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE: WIN32_ERROR = 8495u32;
+pub const ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2: WIN32_ERROR = 8586u32;
+pub const ERROR_DS_DATABASE_ERROR: WIN32_ERROR = 8409u32;
+pub const ERROR_DS_DECODING_ERROR: WIN32_ERROR = 8253u32;
+pub const ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED: WIN32_ERROR = 8536u32;
+pub const ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST: WIN32_ERROR = 8535u32;
+pub const ERROR_DS_DIFFERENT_REPL_EPOCHS: WIN32_ERROR = 8593u32;
+pub const ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER: WIN32_ERROR = 8615u32;
+pub const ERROR_DS_DISALLOWED_NC_REDIRECT: WIN32_ERROR = 8640u32;
+pub const ERROR_DS_DNS_LOOKUP_FAILURE: WIN32_ERROR = 8524u32;
+pub const ERROR_DS_DOMAIN_NAME_EXISTS_IN_FOREST: WIN32_ERROR = 8634u32;
+pub const ERROR_DS_DOMAIN_RENAME_IN_PROGRESS: WIN32_ERROR = 8612u32;
+pub const ERROR_DS_DOMAIN_VERSION_TOO_HIGH: WIN32_ERROR = 8564u32;
+pub const ERROR_DS_DOMAIN_VERSION_TOO_LOW: WIN32_ERROR = 8566u32;
+pub const ERROR_DS_DRA_ABANDON_SYNC: WIN32_ERROR = 8462u32;
+pub const ERROR_DS_DRA_ACCESS_DENIED: WIN32_ERROR = 8453u32;
+pub const ERROR_DS_DRA_BAD_DN: WIN32_ERROR = 8439u32;
+pub const ERROR_DS_DRA_BAD_INSTANCE_TYPE: WIN32_ERROR = 8445u32;
+pub const ERROR_DS_DRA_BAD_NC: WIN32_ERROR = 8440u32;
+pub const ERROR_DS_DRA_BUSY: WIN32_ERROR = 8438u32;
+pub const ERROR_DS_DRA_CONNECTION_FAILED: WIN32_ERROR = 8444u32;
+pub const ERROR_DS_DRA_CORRUPT_UTD_VECTOR: WIN32_ERROR = 8629u32;
+pub const ERROR_DS_DRA_DB_ERROR: WIN32_ERROR = 8451u32;
+pub const ERROR_DS_DRA_DN_EXISTS: WIN32_ERROR = 8441u32;
+pub const ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT: WIN32_ERROR = 8544u32;
+pub const ERROR_DS_DRA_EXTN_CONNECTION_FAILED: WIN32_ERROR = 8466u32;
+pub const ERROR_DS_DRA_GENERIC: WIN32_ERROR = 8436u32;
+pub const ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET: WIN32_ERROR = 8464u32;
+pub const ERROR_DS_DRA_INCONSISTENT_DIT: WIN32_ERROR = 8443u32;
+pub const ERROR_DS_DRA_INTERNAL_ERROR: WIN32_ERROR = 8442u32;
+pub const ERROR_DS_DRA_INVALID_PARAMETER: WIN32_ERROR = 8437u32;
+pub const ERROR_DS_DRA_MAIL_PROBLEM: WIN32_ERROR = 8447u32;
+pub const ERROR_DS_DRA_MISSING_KRBTGT_SECRET: WIN32_ERROR = 8633u32;
+pub const ERROR_DS_DRA_MISSING_PARENT: WIN32_ERROR = 8460u32;
+pub const ERROR_DS_DRA_NAME_COLLISION: WIN32_ERROR = 8458u32;
+pub const ERROR_DS_DRA_NOT_SUPPORTED: WIN32_ERROR = 8454u32;
+pub const ERROR_DS_DRA_NO_REPLICA: WIN32_ERROR = 8452u32;
+pub const ERROR_DS_DRA_OBJ_IS_REP_SOURCE: WIN32_ERROR = 8450u32;
+pub const ERROR_DS_DRA_OBJ_NC_MISMATCH: WIN32_ERROR = 8545u32;
+pub const ERROR_DS_DRA_OUT_OF_MEM: WIN32_ERROR = 8446u32;
+pub const ERROR_DS_DRA_OUT_SCHEDULE_WINDOW: WIN32_ERROR = 8617u32;
+pub const ERROR_DS_DRA_PREEMPTED: WIN32_ERROR = 8461u32;
+pub const ERROR_DS_DRA_RECYCLED_TARGET: WIN32_ERROR = 8639u32;
+pub const ERROR_DS_DRA_REF_ALREADY_EXISTS: WIN32_ERROR = 8448u32;
+pub const ERROR_DS_DRA_REF_NOT_FOUND: WIN32_ERROR = 8449u32;
+pub const ERROR_DS_DRA_REPL_PENDING: WIN32_ERROR = 8477u32;
+pub const ERROR_DS_DRA_RPC_CANCELLED: WIN32_ERROR = 8455u32;
+pub const ERROR_DS_DRA_SCHEMA_CONFLICT: WIN32_ERROR = 8543u32;
+pub const ERROR_DS_DRA_SCHEMA_INFO_SHIP: WIN32_ERROR = 8542u32;
+pub const ERROR_DS_DRA_SCHEMA_MISMATCH: WIN32_ERROR = 8418u32;
+pub const ERROR_DS_DRA_SECRETS_DENIED: WIN32_ERROR = 8630u32;
+pub const ERROR_DS_DRA_SHUTDOWN: WIN32_ERROR = 8463u32;
+pub const ERROR_DS_DRA_SINK_DISABLED: WIN32_ERROR = 8457u32;
+pub const ERROR_DS_DRA_SOURCE_DISABLED: WIN32_ERROR = 8456u32;
+pub const ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA: WIN32_ERROR = 8465u32;
+pub const ERROR_DS_DRA_SOURCE_REINSTALLED: WIN32_ERROR = 8459u32;
+pub const ERROR_DS_DRS_EXTENSIONS_CHANGED: WIN32_ERROR = 8594u32;
+pub const ERROR_DS_DSA_MUST_BE_INT_MASTER: WIN32_ERROR = 8342u32;
+pub const ERROR_DS_DST_DOMAIN_NOT_NATIVE: WIN32_ERROR = 8496u32;
+pub const ERROR_DS_DST_NC_MISMATCH: WIN32_ERROR = 8486u32;
+pub const ERROR_DS_DS_REQUIRED: WIN32_ERROR = 8478u32;
+pub const ERROR_DS_DUPLICATE_ID_FOUND: WIN32_ERROR = 8605u32;
+pub const ERROR_DS_DUP_LDAP_DISPLAY_NAME: WIN32_ERROR = 8382u32;
+pub const ERROR_DS_DUP_LINK_ID: WIN32_ERROR = 8468u32;
+pub const ERROR_DS_DUP_MAPI_ID: WIN32_ERROR = 8380u32;
+pub const ERROR_DS_DUP_MSDS_INTID: WIN32_ERROR = 8597u32;
+pub const ERROR_DS_DUP_OID: WIN32_ERROR = 8379u32;
+pub const ERROR_DS_DUP_RDN: WIN32_ERROR = 8378u32;
+pub const ERROR_DS_DUP_SCHEMA_ID_GUID: WIN32_ERROR = 8381u32;
+pub const ERROR_DS_ENCODING_ERROR: WIN32_ERROR = 8252u32;
+pub const ERROR_DS_EPOCH_MISMATCH: WIN32_ERROR = 8483u32;
+pub const ERROR_DS_EXISTING_AD_CHILD_NC: WIN32_ERROR = 8613u32;
+pub const ERROR_DS_EXISTS_IN_AUX_CLS: WIN32_ERROR = 8393u32;
+pub const ERROR_DS_EXISTS_IN_MAY_HAVE: WIN32_ERROR = 8386u32;
+pub const ERROR_DS_EXISTS_IN_MUST_HAVE: WIN32_ERROR = 8385u32;
+pub const ERROR_DS_EXISTS_IN_POSS_SUP: WIN32_ERROR = 8395u32;
+pub const ERROR_DS_EXISTS_IN_RDNATTID: WIN32_ERROR = 8598u32;
+pub const ERROR_DS_EXISTS_IN_SUB_CLS: WIN32_ERROR = 8394u32;
+pub const ERROR_DS_FILTER_UNKNOWN: WIN32_ERROR = 8254u32;
+pub const ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS: WIN32_ERROR = 8555u32;
+pub const ERROR_DS_FLAT_NAME_EXISTS_IN_FOREST: WIN32_ERROR = 8635u32;
+pub const ERROR_DS_FOREST_VERSION_TOO_HIGH: WIN32_ERROR = 8563u32;
+pub const ERROR_DS_FOREST_VERSION_TOO_LOW: WIN32_ERROR = 8565u32;
+pub const ERROR_DS_GCVERIFY_ERROR: WIN32_ERROR = 8417u32;
+pub const ERROR_DS_GC_NOT_AVAILABLE: WIN32_ERROR = 8217u32;
+pub const ERROR_DS_GC_REQUIRED: WIN32_ERROR = 8547u32;
+pub const ERROR_DS_GENERIC_ERROR: WIN32_ERROR = 8341u32;
+pub const ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER: WIN32_ERROR = 8519u32;
+pub const ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER: WIN32_ERROR = 8516u32;
+pub const ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER: WIN32_ERROR = 8517u32;
+pub const ERROR_DS_GOVERNSID_MISSING: WIN32_ERROR = 8410u32;
+pub const ERROR_DS_GROUP_CONVERSION_ERROR: WIN32_ERROR = 8607u32;
+pub const ERROR_DS_HAVE_PRIMARY_MEMBERS: WIN32_ERROR = 8521u32;
+pub const ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED: WIN32_ERROR = 8429u32;
+pub const ERROR_DS_HIERARCHY_TABLE_TOO_DEEP: WIN32_ERROR = 8628u32;
+pub const ERROR_DS_HIGH_ADLDS_FFL: WIN32_ERROR = 8641u32;
+pub const ERROR_DS_HIGH_DSA_VERSION: WIN32_ERROR = 8642u32;
+pub const ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD: WIN32_ERROR = 8507u32;
+pub const ERROR_DS_ILLEGAL_MOD_OPERATION: WIN32_ERROR = 8311u32;
+pub const ERROR_DS_ILLEGAL_SUPERIOR: WIN32_ERROR = 8345u32;
+pub const ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION: WIN32_ERROR = 8492u32;
+pub const ERROR_DS_INAPPROPRIATE_AUTH: WIN32_ERROR = 8233u32;
+pub const ERROR_DS_INAPPROPRIATE_MATCHING: WIN32_ERROR = 8238u32;
+pub const ERROR_DS_INCOMPATIBLE_CONTROLS_USED: WIN32_ERROR = 8574u32;
+pub const ERROR_DS_INCOMPATIBLE_VERSION: WIN32_ERROR = 8567u32;
+pub const ERROR_DS_INCORRECT_ROLE_OWNER: WIN32_ERROR = 8210u32;
+pub const ERROR_DS_INIT_FAILURE: WIN32_ERROR = 8532u32;
+pub const ERROR_DS_INIT_FAILURE_CONSOLE: WIN32_ERROR = 8561u32;
+pub const ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE: WIN32_ERROR = 8512u32;
+pub const ERROR_DS_INSTALL_NO_SRC_SCH_VERSION: WIN32_ERROR = 8511u32;
+pub const ERROR_DS_INSTALL_SCHEMA_MISMATCH: WIN32_ERROR = 8467u32;
+pub const ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT: WIN32_ERROR = 8606u32;
+pub const ERROR_DS_INSUFF_ACCESS_RIGHTS: WIN32_ERROR = 8344u32;
+pub const ERROR_DS_INTERNAL_FAILURE: WIN32_ERROR = 8430u32;
+pub const ERROR_DS_INVALID_ATTRIBUTE_SYNTAX: WIN32_ERROR = 8203u32;
+pub const ERROR_DS_INVALID_DMD: WIN32_ERROR = 8360u32;
+pub const ERROR_DS_INVALID_DN_SYNTAX: WIN32_ERROR = 8242u32;
+pub const ERROR_DS_INVALID_GROUP_TYPE: WIN32_ERROR = 8513u32;
+pub const ERROR_DS_INVALID_LDAP_DISPLAY_NAME: WIN32_ERROR = 8479u32;
+pub const ERROR_DS_INVALID_NAME_FOR_SPN: WIN32_ERROR = 8554u32;
+pub const ERROR_DS_INVALID_ROLE_OWNER: WIN32_ERROR = 8366u32;
+pub const ERROR_DS_INVALID_SCRIPT: WIN32_ERROR = 8600u32;
+pub const ERROR_DS_INVALID_SEARCH_FLAG: WIN32_ERROR = 8500u32;
+pub const ERROR_DS_INVALID_SEARCH_FLAG_SUBTREE: WIN32_ERROR = 8626u32;
+pub const ERROR_DS_INVALID_SEARCH_FLAG_TUPLE: WIN32_ERROR = 8627u32;
+pub const ERROR_DS_IS_LEAF: WIN32_ERROR = 8243u32;
+pub const ERROR_DS_KEY_NOT_UNIQUE: WIN32_ERROR = 8527u32;
+pub const ERROR_DS_LDAP_SEND_QUEUE_FULL: WIN32_ERROR = 8616u32;
+pub const ERROR_DS_LINK_ID_NOT_AVAILABLE: WIN32_ERROR = 8577u32;
+pub const ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER: WIN32_ERROR = 8520u32;
+pub const ERROR_DS_LOCAL_ERROR: WIN32_ERROR = 8251u32;
+pub const ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY: WIN32_ERROR = 8548u32;
+pub const ERROR_DS_LOOP_DETECT: WIN32_ERROR = 8246u32;
+pub const ERROR_DS_LOW_ADLDS_FFL: WIN32_ERROR = 8643u32;
+pub const ERROR_DS_LOW_DSA_VERSION: WIN32_ERROR = 8568u32;
+pub const ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4: WIN32_ERROR = 8572u32;
+pub const ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED: WIN32_ERROR = 8557u32;
+pub const ERROR_DS_MAPI_ID_NOT_AVAILABLE: WIN32_ERROR = 8632u32;
+pub const ERROR_DS_MASTERDSA_REQUIRED: WIN32_ERROR = 8314u32;
+pub const ERROR_DS_MAX_OBJ_SIZE_EXCEEDED: WIN32_ERROR = 8304u32;
+pub const ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY: WIN32_ERROR = 8201u32;
+pub const ERROR_DS_MISSING_EXPECTED_ATT: WIN32_ERROR = 8411u32;
+pub const ERROR_DS_MISSING_FOREST_TRUST: WIN32_ERROR = 8649u32;
+pub const ERROR_DS_MISSING_FSMO_SETTINGS: WIN32_ERROR = 8434u32;
+pub const ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER: WIN32_ERROR = 8497u32;
+pub const ERROR_DS_MISSING_REQUIRED_ATT: WIN32_ERROR = 8316u32;
+pub const ERROR_DS_MISSING_SUPREF: WIN32_ERROR = 8406u32;
+pub const ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG: WIN32_ERROR = 8581u32;
+pub const ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE: WIN32_ERROR = 8579u32;
+pub const ERROR_DS_MODIFYDN_WRONG_GRANDPARENT: WIN32_ERROR = 8582u32;
+pub const ERROR_DS_MUST_BE_RUN_ON_DST_DC: WIN32_ERROR = 8558u32;
+pub const ERROR_DS_NAME_ERROR_DOMAIN_ONLY: WIN32_ERROR = 8473u32;
+pub const ERROR_DS_NAME_ERROR_NOT_FOUND: WIN32_ERROR = 8470u32;
+pub const ERROR_DS_NAME_ERROR_NOT_UNIQUE: WIN32_ERROR = 8471u32;
+pub const ERROR_DS_NAME_ERROR_NO_MAPPING: WIN32_ERROR = 8472u32;
+pub const ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING: WIN32_ERROR = 8474u32;
+pub const ERROR_DS_NAME_ERROR_RESOLVING: WIN32_ERROR = 8469u32;
+pub const ERROR_DS_NAME_ERROR_TRUST_REFERRAL: WIN32_ERROR = 8583u32;
+pub const ERROR_DS_NAME_NOT_UNIQUE: WIN32_ERROR = 8571u32;
+pub const ERROR_DS_NAME_REFERENCE_INVALID: WIN32_ERROR = 8373u32;
+pub const ERROR_DS_NAME_TOO_LONG: WIN32_ERROR = 8348u32;
+pub const ERROR_DS_NAME_TOO_MANY_PARTS: WIN32_ERROR = 8347u32;
+pub const ERROR_DS_NAME_TYPE_UNKNOWN: WIN32_ERROR = 8351u32;
+pub const ERROR_DS_NAME_UNPARSEABLE: WIN32_ERROR = 8350u32;
+pub const ERROR_DS_NAME_VALUE_TOO_LONG: WIN32_ERROR = 8349u32;
+pub const ERROR_DS_NAMING_MASTER_GC: WIN32_ERROR = 8523u32;
+pub const ERROR_DS_NAMING_VIOLATION: WIN32_ERROR = 8247u32;
+pub const ERROR_DS_NCNAME_MISSING_CR_REF: WIN32_ERROR = 8412u32;
+pub const ERROR_DS_NCNAME_MUST_BE_NC: WIN32_ERROR = 8357u32;
+pub const ERROR_DS_NC_MUST_HAVE_NC_PARENT: WIN32_ERROR = 8494u32;
+pub const ERROR_DS_NC_STILL_HAS_DSAS: WIN32_ERROR = 8546u32;
+pub const ERROR_DS_NONEXISTENT_MAY_HAVE: WIN32_ERROR = 8387u32;
+pub const ERROR_DS_NONEXISTENT_MUST_HAVE: WIN32_ERROR = 8388u32;
+pub const ERROR_DS_NONEXISTENT_POSS_SUP: WIN32_ERROR = 8390u32;
+pub const ERROR_DS_NONSAFE_SCHEMA_CHANGE: WIN32_ERROR = 8508u32;
+pub const ERROR_DS_NON_ASQ_SEARCH: WIN32_ERROR = 8624u32;
+pub const ERROR_DS_NON_BASE_SEARCH: WIN32_ERROR = 8480u32;
+pub const ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX: WIN32_ERROR = 8377u32;
+pub const ERROR_DS_NOT_AN_OBJECT: WIN32_ERROR = 8352u32;
+pub const ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC: WIN32_ERROR = 8487u32;
+pub const ERROR_DS_NOT_CLOSEST: WIN32_ERROR = 8588u32;
+pub const ERROR_DS_NOT_INSTALLED: WIN32_ERROR = 8200u32;
+pub const ERROR_DS_NOT_ON_BACKLINK: WIN32_ERROR = 8362u32;
+pub const ERROR_DS_NOT_SUPPORTED: WIN32_ERROR = 8256u32;
+pub const ERROR_DS_NOT_SUPPORTED_SORT_ORDER: WIN32_ERROR = 8570u32;
+pub const ERROR_DS_NO_ATTRIBUTE_OR_VALUE: WIN32_ERROR = 8202u32;
+pub const ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN: WIN32_ERROR = 8569u32;
+pub const ERROR_DS_NO_CHAINED_EVAL: WIN32_ERROR = 8328u32;
+pub const ERROR_DS_NO_CHAINING: WIN32_ERROR = 8327u32;
+pub const ERROR_DS_NO_CHECKPOINT_WITH_PDC: WIN32_ERROR = 8551u32;
+pub const ERROR_DS_NO_CROSSREF_FOR_NC: WIN32_ERROR = 8363u32;
+pub const ERROR_DS_NO_DELETED_NAME: WIN32_ERROR = 8355u32;
+pub const ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS: WIN32_ERROR = 8549u32;
+pub const ERROR_DS_NO_MORE_RIDS: WIN32_ERROR = 8209u32;
+pub const ERROR_DS_NO_MSDS_INTID: WIN32_ERROR = 8596u32;
+pub const ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN: WIN32_ERROR = 8514u32;
+pub const ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN: WIN32_ERROR = 8515u32;
+pub const ERROR_DS_NO_NTDSA_OBJECT: WIN32_ERROR = 8623u32;
+pub const ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC: WIN32_ERROR = 8580u32;
+pub const ERROR_DS_NO_PARENT_OBJECT: WIN32_ERROR = 8329u32;
+pub const ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION: WIN32_ERROR = 8533u32;
+pub const ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA: WIN32_ERROR = 8306u32;
+pub const ERROR_DS_NO_REF_DOMAIN: WIN32_ERROR = 8575u32;
+pub const ERROR_DS_NO_REQUESTED_ATTS_FOUND: WIN32_ERROR = 8308u32;
+pub const ERROR_DS_NO_RESULTS_RETURNED: WIN32_ERROR = 8257u32;
+pub const ERROR_DS_NO_RIDS_ALLOCATED: WIN32_ERROR = 8208u32;
+pub const ERROR_DS_NO_SERVER_OBJECT: WIN32_ERROR = 8622u32;
+pub const ERROR_DS_NO_SUCH_OBJECT: WIN32_ERROR = 8240u32;
+pub const ERROR_DS_NO_TREE_DELETE_ABOVE_NC: WIN32_ERROR = 8501u32;
+pub const ERROR_DS_NTDSCRIPT_PROCESS_ERROR: WIN32_ERROR = 8592u32;
+pub const ERROR_DS_NTDSCRIPT_SYNTAX_ERROR: WIN32_ERROR = 8591u32;
+pub const ERROR_DS_OBJECT_BEING_REMOVED: WIN32_ERROR = 8339u32;
+pub const ERROR_DS_OBJECT_CLASS_REQUIRED: WIN32_ERROR = 8315u32;
+pub const ERROR_DS_OBJECT_RESULTS_TOO_LARGE: WIN32_ERROR = 8248u32;
+pub const ERROR_DS_OBJ_CLASS_NOT_DEFINED: WIN32_ERROR = 8371u32;
+pub const ERROR_DS_OBJ_CLASS_NOT_SUBCLASS: WIN32_ERROR = 8372u32;
+pub const ERROR_DS_OBJ_CLASS_VIOLATION: WIN32_ERROR = 8212u32;
+pub const ERROR_DS_OBJ_GUID_EXISTS: WIN32_ERROR = 8361u32;
+pub const ERROR_DS_OBJ_NOT_FOUND: WIN32_ERROR = 8333u32;
+pub const ERROR_DS_OBJ_STRING_NAME_EXISTS: WIN32_ERROR = 8305u32;
+pub const ERROR_DS_OBJ_TOO_LARGE: WIN32_ERROR = 8312u32;
+pub const ERROR_DS_OFFSET_RANGE_ERROR: WIN32_ERROR = 8262u32;
+pub const ERROR_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS: WIN32_ERROR = 8637u32;
+pub const ERROR_DS_OID_NOT_FOUND: WIN32_ERROR = 8638u32;
+pub const ERROR_DS_OPERATIONS_ERROR: WIN32_ERROR = 8224u32;
+pub const ERROR_DS_OUT_OF_SCOPE: WIN32_ERROR = 8338u32;
+pub const ERROR_DS_OUT_OF_VERSION_STORE: WIN32_ERROR = 8573u32;
+pub const ERROR_DS_PARAM_ERROR: WIN32_ERROR = 8255u32;
+pub const ERROR_DS_PARENT_IS_AN_ALIAS: WIN32_ERROR = 8330u32;
+pub const ERROR_DS_PDC_OPERATION_IN_PROGRESS: WIN32_ERROR = 8490u32;
+pub const ERROR_DS_PER_ATTRIBUTE_AUTHZ_FAILED_DURING_ADD: WIN32_ERROR = 8652u32;
+pub const ERROR_DS_POLICY_NOT_KNOWN: WIN32_ERROR = 8618u32;
+pub const ERROR_DS_PROTOCOL_ERROR: WIN32_ERROR = 8225u32;
+pub const ERROR_DS_RANGE_CONSTRAINT: WIN32_ERROR = 8322u32;
+pub const ERROR_DS_RDN_DOESNT_MATCH_SCHEMA: WIN32_ERROR = 8307u32;
+pub const ERROR_DS_RECALCSCHEMA_FAILED: WIN32_ERROR = 8396u32;
+pub const ERROR_DS_REFERRAL: WIN32_ERROR = 8235u32;
+pub const ERROR_DS_REFERRAL_LIMIT_EXCEEDED: WIN32_ERROR = 8260u32;
+pub const ERROR_DS_REFUSING_FSMO_ROLES: WIN32_ERROR = 8433u32;
+pub const ERROR_DS_REMOTE_CROSSREF_OP_FAILED: WIN32_ERROR = 8601u32;
+pub const ERROR_DS_REPLICATOR_ONLY: WIN32_ERROR = 8370u32;
+pub const ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR: WIN32_ERROR = 8595u32;
+pub const ERROR_DS_REPL_LIFETIME_EXCEEDED: WIN32_ERROR = 8614u32;
+pub const ERROR_DS_RESERVED_LINK_ID: WIN32_ERROR = 8576u32;
+pub const ERROR_DS_RESERVED_MAPI_ID: WIN32_ERROR = 8631u32;
+pub const ERROR_DS_RIDMGR_DISABLED: WIN32_ERROR = 8263u32;
+pub const ERROR_DS_RIDMGR_INIT_ERROR: WIN32_ERROR = 8211u32;
+pub const ERROR_DS_ROLE_NOT_VERIFIED: WIN32_ERROR = 8610u32;
+pub const ERROR_DS_ROOT_CANT_BE_SUBREF: WIN32_ERROR = 8326u32;
+pub const ERROR_DS_ROOT_MUST_BE_NC: WIN32_ERROR = 8301u32;
+pub const ERROR_DS_ROOT_REQUIRES_CLASS_TOP: WIN32_ERROR = 8432u32;
+pub const ERROR_DS_SAM_INIT_FAILURE: WIN32_ERROR = 8504u32;
+pub const ERROR_DS_SAM_INIT_FAILURE_CONSOLE: WIN32_ERROR = 8562u32;
+pub const ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY: WIN32_ERROR = 8530u32;
+pub const ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD: WIN32_ERROR = 8529u32;
+pub const ERROR_DS_SCHEMA_ALLOC_FAILED: WIN32_ERROR = 8415u32;
+pub const ERROR_DS_SCHEMA_NOT_LOADED: WIN32_ERROR = 8414u32;
+pub const ERROR_DS_SCHEMA_UPDATE_DISALLOWED: WIN32_ERROR = 8509u32;
+pub const ERROR_DS_SECURITY_CHECKING_ERROR: WIN32_ERROR = 8413u32;
+pub const ERROR_DS_SECURITY_ILLEGAL_MODIFY: WIN32_ERROR = 8423u32;
+pub const ERROR_DS_SEC_DESC_INVALID: WIN32_ERROR = 8354u32;
+pub const ERROR_DS_SEC_DESC_TOO_SHORT: WIN32_ERROR = 8353u32;
+pub const ERROR_DS_SEMANTIC_ATT_TEST: WIN32_ERROR = 8383u32;
+pub const ERROR_DS_SENSITIVE_GROUP_VIOLATION: WIN32_ERROR = 8505u32;
+pub const ERROR_DS_SERVER_DOWN: WIN32_ERROR = 8250u32;
+pub const ERROR_DS_SHUTTING_DOWN: WIN32_ERROR = 8364u32;
+pub const ERROR_DS_SINGLE_USER_MODE_FAILED: WIN32_ERROR = 8590u32;
+pub const ERROR_DS_SINGLE_VALUE_CONSTRAINT: WIN32_ERROR = 8321u32;
+pub const ERROR_DS_SIZELIMIT_EXCEEDED: WIN32_ERROR = 8227u32;
+pub const ERROR_DS_SORT_CONTROL_MISSING: WIN32_ERROR = 8261u32;
+pub const ERROR_DS_SOURCE_AUDITING_NOT_ENABLED: WIN32_ERROR = 8552u32;
+pub const ERROR_DS_SOURCE_DOMAIN_IN_FOREST: WIN32_ERROR = 8534u32;
+pub const ERROR_DS_SPN_VALUE_NOT_UNIQUE_IN_FOREST: WIN32_ERROR = 8647u32;
+pub const ERROR_DS_SRC_AND_DST_NC_IDENTICAL: WIN32_ERROR = 8485u32;
+pub const ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH: WIN32_ERROR = 8540u32;
+pub const ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER: WIN32_ERROR = 8559u32;
+pub const ERROR_DS_SRC_GUID_MISMATCH: WIN32_ERROR = 8488u32;
+pub const ERROR_DS_SRC_NAME_MISMATCH: WIN32_ERROR = 8484u32;
+pub const ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER: WIN32_ERROR = 8538u32;
+pub const ERROR_DS_SRC_SID_EXISTS_IN_FOREST: WIN32_ERROR = 8539u32;
+pub const ERROR_DS_STRING_SD_CONVERSION_FAILED: WIN32_ERROR = 8522u32;
+pub const ERROR_DS_STRONG_AUTH_REQUIRED: WIN32_ERROR = 8232u32;
+pub const ERROR_DS_SUBREF_MUST_HAVE_PARENT: WIN32_ERROR = 8356u32;
+pub const ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD: WIN32_ERROR = 8376u32;
+pub const ERROR_DS_SUB_CLS_TEST_FAIL: WIN32_ERROR = 8391u32;
+pub const ERROR_DS_SYNTAX_MISMATCH: WIN32_ERROR = 8384u32;
+pub const ERROR_DS_THREAD_LIMIT_EXCEEDED: WIN32_ERROR = 8587u32;
+pub const ERROR_DS_TIMELIMIT_EXCEEDED: WIN32_ERROR = 8226u32;
+pub const ERROR_DS_TREE_DELETE_NOT_FINISHED: WIN32_ERROR = 8397u32;
+pub const ERROR_DS_UNABLE_TO_SURRENDER_ROLES: WIN32_ERROR = 8435u32;
+pub const ERROR_DS_UNAVAILABLE: WIN32_ERROR = 8207u32;
+pub const ERROR_DS_UNAVAILABLE_CRIT_EXTENSION: WIN32_ERROR = 8236u32;
+pub const ERROR_DS_UNDELETE_SAM_VALIDATION_FAILED: WIN32_ERROR = 8645u32;
+pub const ERROR_DS_UNICODEPWD_NOT_IN_QUOTES: WIN32_ERROR = 8556u32;
+pub const ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER: WIN32_ERROR = 8518u32;
+pub const ERROR_DS_UNKNOWN_ERROR: WIN32_ERROR = 8431u32;
+pub const ERROR_DS_UNKNOWN_OPERATION: WIN32_ERROR = 8365u32;
+pub const ERROR_DS_UNWILLING_TO_PERFORM: WIN32_ERROR = 8245u32;
+pub const ERROR_DS_UPN_VALUE_NOT_UNIQUE_IN_FOREST: WIN32_ERROR = 8648u32;
+pub const ERROR_DS_USER_BUFFER_TO_SMALL: WIN32_ERROR = 8309u32;
+pub const ERROR_DS_VALUE_KEY_NOT_UNIQUE: WIN32_ERROR = 8650u32;
+pub const ERROR_DS_VERSION_CHECK_FAILURE: WIN32_ERROR = 643u32;
+pub const ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL: WIN32_ERROR = 8611u32;
+pub const ERROR_DS_WRONG_LINKED_ATT_SYNTAX: WIN32_ERROR = 8528u32;
+pub const ERROR_DS_WRONG_OM_OBJ_CLASS: WIN32_ERROR = 8476u32;
+pub const ERROR_DUPLICATE_PRIVILEGES: WIN32_ERROR = 311u32;
+pub const ERROR_DUPLICATE_SERVICE_NAME: WIN32_ERROR = 1078u32;
+pub const ERROR_DUP_DOMAINNAME: WIN32_ERROR = 1221u32;
+pub const ERROR_DUP_NAME: WIN32_ERROR = 52u32;
+pub const ERROR_DYNAMIC_CODE_BLOCKED: WIN32_ERROR = 1655u32;
+pub const ERROR_DYNLINK_FROM_INVALID_RING: WIN32_ERROR = 196u32;
+pub const ERROR_EAS_DIDNT_FIT: WIN32_ERROR = 275u32;
+pub const ERROR_EAS_NOT_SUPPORTED: WIN32_ERROR = 282u32;
+pub const ERROR_EA_ACCESS_DENIED: WIN32_ERROR = 994u32;
+pub const ERROR_EA_FILE_CORRUPT: WIN32_ERROR = 276u32;
+pub const ERROR_EA_LIST_INCONSISTENT: WIN32_ERROR = 255u32;
+pub const ERROR_EA_TABLE_FULL: WIN32_ERROR = 277u32;
+pub const ERROR_EDP_DPL_POLICY_CANT_BE_SATISFIED: WIN32_ERROR = 357u32;
+pub const ERROR_EDP_POLICY_DENIES_OPERATION: WIN32_ERROR = 356u32;
+pub const ERROR_EFS_ALG_BLOB_TOO_BIG: WIN32_ERROR = 6013u32;
+pub const ERROR_EFS_DISABLED: WIN32_ERROR = 6015u32;
+pub const ERROR_EFS_SERVER_NOT_TRUSTED: WIN32_ERROR = 6011u32;
+pub const ERROR_EFS_VERSION_NOT_SUPPORT: WIN32_ERROR = 6016u32;
+pub const ERROR_ELEVATION_REQUIRED: WIN32_ERROR = 740u32;
+pub const ERROR_ENCLAVE_FAILURE: WIN32_ERROR = 349u32;
+pub const ERROR_ENCLAVE_NOT_TERMINATED: WIN32_ERROR = 814u32;
+pub const ERROR_ENCLAVE_VIOLATION: WIN32_ERROR = 815u32;
+pub const ERROR_ENCRYPTED_FILE_NOT_SUPPORTED: WIN32_ERROR = 489u32;
+pub const ERROR_ENCRYPTED_IO_NOT_POSSIBLE: WIN32_ERROR = 808u32;
+pub const ERROR_ENCRYPTING_METADATA_DISALLOWED: WIN32_ERROR = 431u32;
+pub const ERROR_ENCRYPTION_DISABLED: WIN32_ERROR = 430u32;
+pub const ERROR_ENCRYPTION_FAILED: WIN32_ERROR = 6000u32;
+pub const ERROR_ENCRYPTION_POLICY_DENIES_OPERATION: WIN32_ERROR = 6022u32;
+pub const ERROR_END_OF_MEDIA: WIN32_ERROR = 1100u32;
+pub const ERROR_ENVVAR_NOT_FOUND: WIN32_ERROR = 203u32;
+pub const ERROR_EOM_OVERFLOW: WIN32_ERROR = 1129u32;
+pub const ERROR_ERRORS_ENCOUNTERED: WIN32_ERROR = 774u32;
+pub const ERROR_EVALUATION_EXPIRATION: WIN32_ERROR = 622u32;
+pub const ERROR_EVENTLOG_CANT_START: WIN32_ERROR = 1501u32;
+pub const ERROR_EVENTLOG_FILE_CHANGED: WIN32_ERROR = 1503u32;
+pub const ERROR_EVENTLOG_FILE_CORRUPT: WIN32_ERROR = 1500u32;
+pub const ERROR_EVENT_DONE: WIN32_ERROR = 710u32;
+pub const ERROR_EVENT_PENDING: WIN32_ERROR = 711u32;
+pub const ERROR_EXCEPTION_IN_SERVICE: WIN32_ERROR = 1064u32;
+pub const ERROR_EXCL_SEM_ALREADY_OWNED: WIN32_ERROR = 101u32;
+pub const ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY: WIN32_ERROR = 217u32;
+pub const ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY: WIN32_ERROR = 218u32;
+pub const ERROR_EXE_MACHINE_TYPE_MISMATCH: WIN32_ERROR = 216u32;
+pub const ERROR_EXE_MARKED_INVALID: WIN32_ERROR = 192u32;
+pub const ERROR_EXTENDED_ERROR: WIN32_ERROR = 1208u32;
+pub const ERROR_EXTERNAL_BACKING_PROVIDER_UNKNOWN: WIN32_ERROR = 343u32;
+pub const ERROR_EXTERNAL_SYSKEY_NOT_SUPPORTED: WIN32_ERROR = 399u32;
+pub const ERROR_EXTRANEOUS_INFORMATION: WIN32_ERROR = 677u32;
+pub const ERROR_FAILED_DRIVER_ENTRY: WIN32_ERROR = 647u32;
+pub const ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: WIN32_ERROR = 1063u32;
+pub const ERROR_FAIL_FAST_EXCEPTION: WIN32_ERROR = 1653u32;
+pub const ERROR_FAIL_I24: WIN32_ERROR = 83u32;
+pub const ERROR_FAIL_NOACTION_REBOOT: WIN32_ERROR = 350u32;
+pub const ERROR_FAIL_RESTART: WIN32_ERROR = 352u32;
+pub const ERROR_FAIL_SHUTDOWN: WIN32_ERROR = 351u32;
+pub const ERROR_FATAL_APP_EXIT: WIN32_ERROR = 713u32;
+pub const ERROR_FILEMARK_DETECTED: WIN32_ERROR = 1101u32;
+pub const ERROR_FILENAME_EXCED_RANGE: WIN32_ERROR = 206u32;
+pub const ERROR_FILE_CHECKED_OUT: WIN32_ERROR = 220u32;
+pub const ERROR_FILE_CORRUPT: WIN32_ERROR = 1392u32;
+pub const ERROR_FILE_ENCRYPTED: WIN32_ERROR = 6002u32;
+pub const ERROR_FILE_EXISTS: WIN32_ERROR = 80u32;
+pub const ERROR_FILE_HANDLE_REVOKED: WIN32_ERROR = 806u32;
+pub const ERROR_FILE_INVALID: WIN32_ERROR = 1006u32;
+pub const ERROR_FILE_LEVEL_TRIM_NOT_SUPPORTED: WIN32_ERROR = 326u32;
+pub const ERROR_FILE_METADATA_OPTIMIZATION_IN_PROGRESS: WIN32_ERROR = 809u32;
+pub const ERROR_FILE_NOT_ENCRYPTED: WIN32_ERROR = 6007u32;
+pub const ERROR_FILE_NOT_FOUND: WIN32_ERROR = 2u32;
+pub const ERROR_FILE_NOT_SUPPORTED: WIN32_ERROR = 425u32;
+pub const ERROR_FILE_OFFLINE: WIN32_ERROR = 4350u32;
+pub const ERROR_FILE_PROTECTED_UNDER_DPL: WIN32_ERROR = 406u32;
+pub const ERROR_FILE_READ_ONLY: WIN32_ERROR = 6009u32;
+pub const ERROR_FILE_SNAP_INVALID_PARAMETER: WIN32_ERROR = 440u32;
+pub const ERROR_FILE_SNAP_IN_PROGRESS: WIN32_ERROR = 435u32;
+pub const ERROR_FILE_SNAP_IO_NOT_COORDINATED: WIN32_ERROR = 438u32;
+pub const ERROR_FILE_SNAP_MODIFY_NOT_SUPPORTED: WIN32_ERROR = 437u32;
+pub const ERROR_FILE_SNAP_UNEXPECTED_ERROR: WIN32_ERROR = 439u32;
+pub const ERROR_FILE_SNAP_USER_SECTION_NOT_SUPPORTED: WIN32_ERROR = 436u32;
+pub const ERROR_FILE_SYSTEM_LIMITATION: WIN32_ERROR = 665u32;
+pub const ERROR_FILE_SYSTEM_VIRTUALIZATION_BUSY: WIN32_ERROR = 371u32;
+pub const ERROR_FILE_SYSTEM_VIRTUALIZATION_INVALID_OPERATION: WIN32_ERROR = 385u32;
+pub const ERROR_FILE_SYSTEM_VIRTUALIZATION_METADATA_CORRUPT: WIN32_ERROR = 370u32;
+pub const ERROR_FILE_SYSTEM_VIRTUALIZATION_PROVIDER_UNKNOWN: WIN32_ERROR = 372u32;
+pub const ERROR_FILE_SYSTEM_VIRTUALIZATION_UNAVAILABLE: WIN32_ERROR = 369u32;
+pub const ERROR_FILE_TOO_LARGE: WIN32_ERROR = 223u32;
+pub const ERROR_FIRMWARE_UPDATED: WIN32_ERROR = 728u32;
+pub const ERROR_FLOAT_MULTIPLE_FAULTS: WIN32_ERROR = 630u32;
+pub const ERROR_FLOAT_MULTIPLE_TRAPS: WIN32_ERROR = 631u32;
+pub const ERROR_FLOPPY_BAD_REGISTERS: WIN32_ERROR = 1125u32;
+pub const ERROR_FLOPPY_ID_MARK_NOT_FOUND: WIN32_ERROR = 1122u32;
+pub const ERROR_FLOPPY_UNKNOWN_ERROR: WIN32_ERROR = 1124u32;
+pub const ERROR_FLOPPY_VOLUME: WIN32_ERROR = 584u32;
+pub const ERROR_FLOPPY_WRONG_CYLINDER: WIN32_ERROR = 1123u32;
+pub const ERROR_FORMS_AUTH_REQUIRED: WIN32_ERROR = 224u32;
+pub const ERROR_FOUND_OUT_OF_SCOPE: WIN32_ERROR = 601u32;
+pub const ERROR_FSFILTER_OP_COMPLETED_SUCCESSFULLY: WIN32_ERROR = 762u32;
+pub const ERROR_FS_DRIVER_REQUIRED: WIN32_ERROR = 588u32;
+pub const ERROR_FS_METADATA_INCONSISTENT: WIN32_ERROR = 510u32;
+pub const ERROR_FT_DI_SCAN_REQUIRED: WIN32_ERROR = 339u32;
+pub const ERROR_FT_READ_FAILURE: WIN32_ERROR = 415u32;
+pub const ERROR_FT_READ_FROM_COPY_FAILURE: WIN32_ERROR = 818u32;
+pub const ERROR_FT_READ_RECOVERY_FROM_BACKUP: WIN32_ERROR = 704u32;
+pub const ERROR_FT_WRITE_FAILURE: WIN32_ERROR = 338u32;
+pub const ERROR_FT_WRITE_RECOVERY: WIN32_ERROR = 705u32;
+pub const ERROR_FULLSCREEN_MODE: WIN32_ERROR = 1007u32;
+pub const ERROR_FUNCTION_FAILED: WIN32_ERROR = 1627u32;
+pub const ERROR_FUNCTION_NOT_CALLED: WIN32_ERROR = 1626u32;
+pub const ERROR_GDI_HANDLE_LEAK: WIN32_ERROR = 373u32;
+pub const ERROR_GENERIC_NOT_MAPPED: WIN32_ERROR = 1360u32;
+pub const ERROR_GEN_FAILURE: WIN32_ERROR = 31u32;
+pub const ERROR_GLOBAL_ONLY_HOOK: WIN32_ERROR = 1429u32;
+pub const ERROR_GRACEFUL_DISCONNECT: WIN32_ERROR = 1226u32;
+pub const ERROR_GROUP_EXISTS: WIN32_ERROR = 1318u32;
+pub const ERROR_GUID_SUBSTITUTION_MADE: WIN32_ERROR = 680u32;
+pub const ERROR_HANDLES_CLOSED: WIN32_ERROR = 676u32;
+pub const ERROR_HANDLE_DISK_FULL: WIN32_ERROR = 39u32;
+pub const ERROR_HANDLE_EOF: WIN32_ERROR = 38u32;
+pub const ERROR_HANDLE_REVOKED: WIN32_ERROR = 811u32;
+pub const ERROR_HAS_SYSTEM_CRITICAL_FILES: WIN32_ERROR = 488u32;
+pub const ERROR_HIBERNATED: WIN32_ERROR = 726u32;
+pub const ERROR_HIBERNATION_FAILURE: WIN32_ERROR = 656u32;
+pub const ERROR_HOOK_NEEDS_HMOD: WIN32_ERROR = 1428u32;
+pub const ERROR_HOOK_NOT_INSTALLED: WIN32_ERROR = 1431u32;
+pub const ERROR_HOOK_TYPE_NOT_ALLOWED: WIN32_ERROR = 1458u32;
+pub const ERROR_HOST_DOWN: WIN32_ERROR = 1256u32;
+pub const ERROR_HOST_UNREACHABLE: WIN32_ERROR = 1232u32;
+pub const ERROR_HOTKEY_ALREADY_REGISTERED: WIN32_ERROR = 1409u32;
+pub const ERROR_HOTKEY_NOT_REGISTERED: WIN32_ERROR = 1419u32;
+pub const ERROR_HWNDS_HAVE_DIFF_PARENT: WIN32_ERROR = 1441u32;
+pub const ERROR_ILLEGAL_CHARACTER: WIN32_ERROR = 582u32;
+pub const ERROR_ILLEGAL_DLL_RELOCATION: WIN32_ERROR = 623u32;
+pub const ERROR_ILLEGAL_ELEMENT_ADDRESS: WIN32_ERROR = 1162u32;
+pub const ERROR_ILLEGAL_FLOAT_CONTEXT: WIN32_ERROR = 579u32;
+pub const ERROR_ILL_FORMED_PASSWORD: WIN32_ERROR = 1324u32;
+pub const ERROR_IMAGE_AT_DIFFERENT_BASE: WIN32_ERROR = 807u32;
+pub const ERROR_IMAGE_MACHINE_TYPE_MISMATCH: WIN32_ERROR = 706u32;
+pub const ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE: WIN32_ERROR = 720u32;
+pub const ERROR_IMAGE_NOT_AT_BASE: WIN32_ERROR = 700u32;
+pub const ERROR_IMAGE_SUBSYSTEM_NOT_PRESENT: WIN32_ERROR = 308u32;
+pub const ERROR_IMPLEMENTATION_LIMIT: WIN32_ERROR = 1292u32;
+pub const ERROR_INCOMPATIBLE_SERVICE_PRIVILEGE: WIN32_ERROR = 1297u32;
+pub const ERROR_INCOMPATIBLE_SERVICE_SID_TYPE: WIN32_ERROR = 1290u32;
+pub const ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING: WIN32_ERROR = 304u32;
+pub const ERROR_INCORRECT_ACCOUNT_TYPE: WIN32_ERROR = 8646u32;
+pub const ERROR_INCORRECT_ADDRESS: WIN32_ERROR = 1241u32;
+pub const ERROR_INCORRECT_SIZE: WIN32_ERROR = 1462u32;
+pub const ERROR_INDEX_ABSENT: WIN32_ERROR = 1611u32;
+pub const ERROR_INDEX_OUT_OF_BOUNDS: WIN32_ERROR = 474u32;
+pub const ERROR_INFLOOP_IN_RELOC_CHAIN: WIN32_ERROR = 202u32;
+pub const ERROR_INSTALL_ALREADY_RUNNING: WIN32_ERROR = 1618u32;
+pub const ERROR_INSTALL_FAILURE: WIN32_ERROR = 1603u32;
+pub const ERROR_INSTALL_LANGUAGE_UNSUPPORTED: WIN32_ERROR = 1623u32;
+pub const ERROR_INSTALL_LOG_FAILURE: WIN32_ERROR = 1622u32;
+pub const ERROR_INSTALL_NOTUSED: WIN32_ERROR = 1634u32;
+pub const ERROR_INSTALL_PACKAGE_INVALID: WIN32_ERROR = 1620u32;
+pub const ERROR_INSTALL_PACKAGE_OPEN_FAILED: WIN32_ERROR = 1619u32;
+pub const ERROR_INSTALL_PACKAGE_REJECTED: WIN32_ERROR = 1625u32;
+pub const ERROR_INSTALL_PACKAGE_VERSION: WIN32_ERROR = 1613u32;
+pub const ERROR_INSTALL_PLATFORM_UNSUPPORTED: WIN32_ERROR = 1633u32;
+pub const ERROR_INSTALL_REJECTED: WIN32_ERROR = 1654u32;
+pub const ERROR_INSTALL_REMOTE_DISALLOWED: WIN32_ERROR = 1640u32;
+pub const ERROR_INSTALL_REMOTE_PROHIBITED: WIN32_ERROR = 1645u32;
+pub const ERROR_INSTALL_SERVICE_FAILURE: WIN32_ERROR = 1601u32;
+pub const ERROR_INSTALL_SERVICE_SAFEBOOT: WIN32_ERROR = 1652u32;
+pub const ERROR_INSTALL_SOURCE_ABSENT: WIN32_ERROR = 1612u32;
+pub const ERROR_INSTALL_SUSPEND: WIN32_ERROR = 1604u32;
+pub const ERROR_INSTALL_TEMP_UNWRITABLE: WIN32_ERROR = 1632u32;
+pub const ERROR_INSTALL_TRANSFORM_FAILURE: WIN32_ERROR = 1624u32;
+pub const ERROR_INSTALL_TRANSFORM_REJECTED: WIN32_ERROR = 1644u32;
+pub const ERROR_INSTALL_UI_FAILURE: WIN32_ERROR = 1621u32;
+pub const ERROR_INSTALL_USEREXIT: WIN32_ERROR = 1602u32;
+pub const ERROR_INSTRUCTION_MISALIGNMENT: WIN32_ERROR = 549u32;
+pub const ERROR_INSUFFICIENT_BUFFER: WIN32_ERROR = 122u32;
+pub const ERROR_INSUFFICIENT_LOGON_INFO: WIN32_ERROR = 608u32;
+pub const ERROR_INSUFFICIENT_POWER: WIN32_ERROR = 639u32;
+pub const ERROR_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE: WIN32_ERROR = 781u32;
+pub const ERROR_INSUFFICIENT_VIRTUAL_ADDR_RESOURCES: WIN32_ERROR = 473u32;
+pub const ERROR_INTERMIXED_KERNEL_EA_OPERATION: WIN32_ERROR = 324u32;
+pub const ERROR_INTERNAL_DB_CORRUPTION: WIN32_ERROR = 1358u32;
+pub const ERROR_INTERNAL_DB_ERROR: WIN32_ERROR = 1383u32;
+pub const ERROR_INTERNAL_ERROR: WIN32_ERROR = 1359u32;
+pub const ERROR_INTERRUPT_STILL_CONNECTED: WIN32_ERROR = 764u32;
+pub const ERROR_INTERRUPT_VECTOR_ALREADY_CONNECTED: WIN32_ERROR = 763u32;
+pub const ERROR_INVALID_ACCEL_HANDLE: WIN32_ERROR = 1403u32;
+pub const ERROR_INVALID_ACCESS: WIN32_ERROR = 12u32;
+pub const ERROR_INVALID_ACCOUNT_NAME: WIN32_ERROR = 1315u32;
+pub const ERROR_INVALID_ACE_CONDITION: WIN32_ERROR = 805u32;
+pub const ERROR_INVALID_ACL: WIN32_ERROR = 1336u32;
+pub const ERROR_INVALID_ADDRESS: WIN32_ERROR = 487u32;
+pub const ERROR_INVALID_AT_INTERRUPT_TIME: WIN32_ERROR = 104u32;
+pub const ERROR_INVALID_BLOCK: WIN32_ERROR = 9u32;
+pub const ERROR_INVALID_BLOCK_LENGTH: WIN32_ERROR = 1106u32;
+pub const ERROR_INVALID_CAP: WIN32_ERROR = 320u32;
+pub const ERROR_INVALID_CATEGORY: WIN32_ERROR = 117u32;
+pub const ERROR_INVALID_COMBOBOX_MESSAGE: WIN32_ERROR = 1422u32;
+pub const ERROR_INVALID_COMMAND_LINE: WIN32_ERROR = 1639u32;
+pub const ERROR_INVALID_COMPUTERNAME: WIN32_ERROR = 1210u32;
+pub const ERROR_INVALID_CRUNTIME_PARAMETER: WIN32_ERROR = 1288u32;
+pub const ERROR_INVALID_CURSOR_HANDLE: WIN32_ERROR = 1402u32;
+pub const ERROR_INVALID_DATA: WIN32_ERROR = 13u32;
+pub const ERROR_INVALID_DATATYPE: WIN32_ERROR = 1804u32;
+pub const ERROR_INVALID_DEVICE_OBJECT_PARAMETER: WIN32_ERROR = 650u32;
+pub const ERROR_INVALID_DLL: WIN32_ERROR = 1154u32;
+pub const ERROR_INVALID_DOMAINNAME: WIN32_ERROR = 1212u32;
+pub const ERROR_INVALID_DOMAIN_ROLE: WIN32_ERROR = 1354u32;
+pub const ERROR_INVALID_DOMAIN_STATE: WIN32_ERROR = 1353u32;
+pub const ERROR_INVALID_DRIVE: WIN32_ERROR = 15u32;
+pub const ERROR_INVALID_DWP_HANDLE: WIN32_ERROR = 1405u32;
+pub const ERROR_INVALID_EA_HANDLE: WIN32_ERROR = 278u32;
+pub const ERROR_INVALID_EA_NAME: WIN32_ERROR = 254u32;
+pub const ERROR_INVALID_EDIT_HEIGHT: WIN32_ERROR = 1424u32;
+pub const ERROR_INVALID_ENVIRONMENT: WIN32_ERROR = 1805u32;
+pub const ERROR_INVALID_EVENTNAME: WIN32_ERROR = 1211u32;
+pub const ERROR_INVALID_EVENT_COUNT: WIN32_ERROR = 151u32;
+pub const ERROR_INVALID_EXCEPTION_HANDLER: WIN32_ERROR = 310u32;
+pub const ERROR_INVALID_EXE_SIGNATURE: WIN32_ERROR = 191u32;
+pub const ERROR_INVALID_FIELD: WIN32_ERROR = 1616u32;
+pub const ERROR_INVALID_FIELD_IN_PARAMETER_LIST: WIN32_ERROR = 328u32;
+pub const ERROR_INVALID_FILTER_PROC: WIN32_ERROR = 1427u32;
+pub const ERROR_INVALID_FLAGS: WIN32_ERROR = 1004u32;
+pub const ERROR_INVALID_FLAG_NUMBER: WIN32_ERROR = 186u32;
+pub const ERROR_INVALID_FORM_NAME: WIN32_ERROR = 1902u32;
+pub const ERROR_INVALID_FORM_SIZE: WIN32_ERROR = 1903u32;
+pub const ERROR_INVALID_FUNCTION: WIN32_ERROR = 1u32;
+pub const ERROR_INVALID_GROUPNAME: WIN32_ERROR = 1209u32;
+pub const ERROR_INVALID_GROUP_ATTRIBUTES: WIN32_ERROR = 1345u32;
+pub const ERROR_INVALID_GW_COMMAND: WIN32_ERROR = 1443u32;
+pub const ERROR_INVALID_HANDLE: WIN32_ERROR = 6u32;
+pub const ERROR_INVALID_HANDLE_STATE: WIN32_ERROR = 1609u32;
+pub const ERROR_INVALID_HOOK_FILTER: WIN32_ERROR = 1426u32;
+pub const ERROR_INVALID_HOOK_HANDLE: WIN32_ERROR = 1404u32;
+pub const ERROR_INVALID_HW_PROFILE: WIN32_ERROR = 619u32;
+pub const ERROR_INVALID_ICON_HANDLE: WIN32_ERROR = 1414u32;
+pub const ERROR_INVALID_ID_AUTHORITY: WIN32_ERROR = 1343u32;
+pub const ERROR_INVALID_IMAGE_HASH: WIN32_ERROR = 577u32;
+pub const ERROR_INVALID_IMPORT_OF_NON_DLL: WIN32_ERROR = 1276u32;
+pub const ERROR_INVALID_INDEX: WIN32_ERROR = 1413u32;
+pub const ERROR_INVALID_KERNEL_INFO_VERSION: WIN32_ERROR = 340u32;
+pub const ERROR_INVALID_KEYBOARD_HANDLE: WIN32_ERROR = 1457u32;
+pub const ERROR_INVALID_LABEL: WIN32_ERROR = 1299u32;
+pub const ERROR_INVALID_LB_MESSAGE: WIN32_ERROR = 1432u32;
+pub const ERROR_INVALID_LDT_DESCRIPTOR: WIN32_ERROR = 564u32;
+pub const ERROR_INVALID_LDT_OFFSET: WIN32_ERROR = 563u32;
+pub const ERROR_INVALID_LDT_SIZE: WIN32_ERROR = 561u32;
+pub const ERROR_INVALID_LEVEL: WIN32_ERROR = 124u32;
+pub const ERROR_INVALID_LIST_FORMAT: WIN32_ERROR = 153u32;
+pub const ERROR_INVALID_LOCK_RANGE: WIN32_ERROR = 307u32;
+pub const ERROR_INVALID_LOGON_HOURS: WIN32_ERROR = 1328u32;
+pub const ERROR_INVALID_LOGON_TYPE: WIN32_ERROR = 1367u32;
+pub const ERROR_INVALID_MEMBER: WIN32_ERROR = 1388u32;
+pub const ERROR_INVALID_MENU_HANDLE: WIN32_ERROR = 1401u32;
+pub const ERROR_INVALID_MESSAGE: WIN32_ERROR = 1002u32;
+pub const ERROR_INVALID_MESSAGEDEST: WIN32_ERROR = 1218u32;
+pub const ERROR_INVALID_MESSAGENAME: WIN32_ERROR = 1217u32;
+pub const ERROR_INVALID_MINALLOCSIZE: WIN32_ERROR = 195u32;
+pub const ERROR_INVALID_MODULETYPE: WIN32_ERROR = 190u32;
+pub const ERROR_INVALID_MONITOR_HANDLE: WIN32_ERROR = 1461u32;
+pub const ERROR_INVALID_MSGBOX_STYLE: WIN32_ERROR = 1438u32;
+pub const ERROR_INVALID_NAME: WIN32_ERROR = 123u32;
+pub const ERROR_INVALID_NETNAME: WIN32_ERROR = 1214u32;
+pub const ERROR_INVALID_OPLOCK_PROTOCOL: WIN32_ERROR = 301u32;
+pub const ERROR_INVALID_ORDINAL: WIN32_ERROR = 182u32;
+pub const ERROR_INVALID_OWNER: WIN32_ERROR = 1307u32;
+pub const ERROR_INVALID_PACKAGE_SID_LENGTH: WIN32_ERROR = 4253u32;
+pub const ERROR_INVALID_PARAMETER: WIN32_ERROR = 87u32;
+pub const ERROR_INVALID_PASSWORD: WIN32_ERROR = 86u32;
+pub const ERROR_INVALID_PASSWORDNAME: WIN32_ERROR = 1216u32;
+pub const ERROR_INVALID_PATCH_XML: WIN32_ERROR = 1650u32;
+pub const ERROR_INVALID_PEP_INFO_VERSION: WIN32_ERROR = 341u32;
+pub const ERROR_INVALID_PLUGPLAY_DEVICE_PATH: WIN32_ERROR = 620u32;
+pub const ERROR_INVALID_PORT_ATTRIBUTES: WIN32_ERROR = 545u32;
+pub const ERROR_INVALID_PRIMARY_GROUP: WIN32_ERROR = 1308u32;
+pub const ERROR_INVALID_PRINTER_COMMAND: WIN32_ERROR = 1803u32;
+pub const ERROR_INVALID_PRINTER_NAME: WIN32_ERROR = 1801u32;
+pub const ERROR_INVALID_PRINTER_STATE: WIN32_ERROR = 1906u32;
+pub const ERROR_INVALID_PRIORITY: WIN32_ERROR = 1800u32;
+pub const ERROR_INVALID_QUOTA_LOWER: WIN32_ERROR = 547u32;
+pub const ERROR_INVALID_REPARSE_DATA: WIN32_ERROR = 4392u32;
+pub const ERROR_INVALID_SCROLLBAR_RANGE: WIN32_ERROR = 1448u32;
+pub const ERROR_INVALID_SECURITY_DESCR: WIN32_ERROR = 1338u32;
+pub const ERROR_INVALID_SEGDPL: WIN32_ERROR = 198u32;
+pub const ERROR_INVALID_SEGMENT_NUMBER: WIN32_ERROR = 180u32;
+pub const ERROR_INVALID_SEPARATOR_FILE: WIN32_ERROR = 1799u32;
+pub const ERROR_INVALID_SERVER_STATE: WIN32_ERROR = 1352u32;
+pub const ERROR_INVALID_SERVICENAME: WIN32_ERROR = 1213u32;
+pub const ERROR_INVALID_SERVICE_ACCOUNT: WIN32_ERROR = 1057u32;
+pub const ERROR_INVALID_SERVICE_CONTROL: WIN32_ERROR = 1052u32;
+pub const ERROR_INVALID_SERVICE_LOCK: WIN32_ERROR = 1071u32;
+pub const ERROR_INVALID_SHARENAME: WIN32_ERROR = 1215u32;
+pub const ERROR_INVALID_SHOWWIN_COMMAND: WIN32_ERROR = 1449u32;
+pub const ERROR_INVALID_SID: WIN32_ERROR = 1337u32;
+pub const ERROR_INVALID_SIGNAL_NUMBER: WIN32_ERROR = 209u32;
+pub const ERROR_INVALID_SPI_VALUE: WIN32_ERROR = 1439u32;
+pub const ERROR_INVALID_STACKSEG: WIN32_ERROR = 189u32;
+pub const ERROR_INVALID_STARTING_CODESEG: WIN32_ERROR = 188u32;
+pub const ERROR_INVALID_SUB_AUTHORITY: WIN32_ERROR = 1335u32;
+pub const ERROR_INVALID_TABLE: WIN32_ERROR = 1628u32;
+pub const ERROR_INVALID_TARGET_HANDLE: WIN32_ERROR = 114u32;
+pub const ERROR_INVALID_TASK_INDEX: WIN32_ERROR = 1551u32;
+pub const ERROR_INVALID_TASK_NAME: WIN32_ERROR = 1550u32;
+pub const ERROR_INVALID_THREAD_ID: WIN32_ERROR = 1444u32;
+pub const ERROR_INVALID_TIME: WIN32_ERROR = 1901u32;
+pub const ERROR_INVALID_TOKEN: WIN32_ERROR = 315u32;
+pub const ERROR_INVALID_UNWIND_TARGET: WIN32_ERROR = 544u32;
+pub const ERROR_INVALID_USER_BUFFER: WIN32_ERROR = 1784u32;
+pub const ERROR_INVALID_USER_PRINCIPAL_NAME: WIN32_ERROR = 8636u32;
+pub const ERROR_INVALID_VARIANT: WIN32_ERROR = 604u32;
+pub const ERROR_INVALID_VERIFY_SWITCH: WIN32_ERROR = 118u32;
+pub const ERROR_INVALID_WINDOW_HANDLE: WIN32_ERROR = 1400u32;
+pub const ERROR_INVALID_WORKSTATION: WIN32_ERROR = 1329u32;
+pub const ERROR_IOPL_NOT_ENABLED: WIN32_ERROR = 197u32;
+pub const ERROR_IO_DEVICE: WIN32_ERROR = 1117u32;
+pub const ERROR_IO_INCOMPLETE: WIN32_ERROR = 996u32;
+pub const ERROR_IO_PENDING: WIN32_ERROR = 997u32;
+pub const ERROR_IO_PRIVILEGE_FAILED: WIN32_ERROR = 571u32;
+pub const ERROR_IO_REISSUE_AS_CACHED: WIN32_ERROR = 3950u32;
+pub const ERROR_IPSEC_IKE_TIMED_OUT: WIN32_ERROR = 13805u32;
+pub const ERROR_IP_ADDRESS_CONFLICT1: WIN32_ERROR = 611u32;
+pub const ERROR_IP_ADDRESS_CONFLICT2: WIN32_ERROR = 612u32;
+pub const ERROR_IRQ_BUSY: WIN32_ERROR = 1119u32;
+pub const ERROR_IS_JOINED: WIN32_ERROR = 134u32;
+pub const ERROR_IS_JOIN_PATH: WIN32_ERROR = 147u32;
+pub const ERROR_IS_JOIN_TARGET: WIN32_ERROR = 133u32;
+pub const ERROR_IS_SUBSTED: WIN32_ERROR = 135u32;
+pub const ERROR_IS_SUBST_PATH: WIN32_ERROR = 146u32;
+pub const ERROR_IS_SUBST_TARGET: WIN32_ERROR = 149u32;
+pub const ERROR_ITERATED_DATA_EXCEEDS_64k: WIN32_ERROR = 194u32;
+pub const ERROR_JOB_NO_CONTAINER: WIN32_ERROR = 1505u32;
+pub const ERROR_JOIN_TO_JOIN: WIN32_ERROR = 138u32;
+pub const ERROR_JOIN_TO_SUBST: WIN32_ERROR = 140u32;
+pub const ERROR_JOURNAL_DELETE_IN_PROGRESS: WIN32_ERROR = 1178u32;
+pub const ERROR_JOURNAL_ENTRY_DELETED: WIN32_ERROR = 1181u32;
+pub const ERROR_JOURNAL_HOOK_SET: WIN32_ERROR = 1430u32;
+pub const ERROR_JOURNAL_NOT_ACTIVE: WIN32_ERROR = 1179u32;
+pub const ERROR_KERNEL_APC: WIN32_ERROR = 738u32;
+pub const ERROR_KEY_DELETED: WIN32_ERROR = 1018u32;
+pub const ERROR_KEY_HAS_CHILDREN: WIN32_ERROR = 1020u32;
+pub const ERROR_KM_DRIVER_BLOCKED: WIN32_ERROR = 1930u32;
+pub const ERROR_LABEL_TOO_LONG: WIN32_ERROR = 154u32;
+pub const ERROR_LAST_ADMIN: WIN32_ERROR = 1322u32;
+pub const ERROR_LB_WITHOUT_TABSTOPS: WIN32_ERROR = 1434u32;
+pub const ERROR_LICENSE_QUOTA_EXCEEDED: WIN32_ERROR = 1395u32;
+pub const ERROR_LINUX_SUBSYSTEM_NOT_PRESENT: WIN32_ERROR = 414u32;
+pub const ERROR_LINUX_SUBSYSTEM_UPDATE_REQUIRED: WIN32_ERROR = 444u32;
+pub const ERROR_LISTBOX_ID_NOT_FOUND: WIN32_ERROR = 1416u32;
+pub const ERROR_LM_CROSS_ENCRYPTION_REQUIRED: WIN32_ERROR = 1390u32;
+pub const ERROR_LOCAL_POLICY_MODIFICATION_NOT_SUPPORTED: WIN32_ERROR = 8653u32;
+pub const ERROR_LOCAL_USER_SESSION_KEY: WIN32_ERROR = 1303u32;
+pub const ERROR_LOCKED: WIN32_ERROR = 212u32;
+pub const ERROR_LOCK_FAILED: WIN32_ERROR = 167u32;
+pub const ERROR_LOCK_VIOLATION: WIN32_ERROR = 33u32;
+pub const ERROR_LOGIN_TIME_RESTRICTION: WIN32_ERROR = 1239u32;
+pub const ERROR_LOGIN_WKSTA_RESTRICTION: WIN32_ERROR = 1240u32;
+pub const ERROR_LOGON_FAILURE: WIN32_ERROR = 1326u32;
+pub const ERROR_LOGON_NOT_GRANTED: WIN32_ERROR = 1380u32;
+pub const ERROR_LOGON_SERVER_CONFLICT: WIN32_ERROR = 568u32;
+pub const ERROR_LOGON_SESSION_COLLISION: WIN32_ERROR = 1366u32;
+pub const ERROR_LOGON_SESSION_EXISTS: WIN32_ERROR = 1363u32;
+pub const ERROR_LOGON_TYPE_NOT_GRANTED: WIN32_ERROR = 1385u32;
+pub const ERROR_LOG_FILE_FULL: WIN32_ERROR = 1502u32;
+pub const ERROR_LOG_HARD_ERROR: WIN32_ERROR = 718u32;
+pub const ERROR_LONGJUMP: WIN32_ERROR = 682u32;
+pub const ERROR_LOST_MODE_LOGON_RESTRICTION: WIN32_ERROR = 1939u32;
+pub const ERROR_LOST_WRITEBEHIND_DATA: WIN32_ERROR = 596u32;
+pub const ERROR_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR: WIN32_ERROR = 790u32;
+pub const ERROR_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED: WIN32_ERROR = 788u32;
+pub const ERROR_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR: WIN32_ERROR = 789u32;
+pub const ERROR_LUIDS_EXHAUSTED: WIN32_ERROR = 1334u32;
+pub const ERROR_MACHINE_LOCKED: WIN32_ERROR = 1271u32;
+pub const ERROR_MAGAZINE_NOT_PRESENT: WIN32_ERROR = 1163u32;
+pub const ERROR_MAPPED_ALIGNMENT: WIN32_ERROR = 1132u32;
+pub const ERROR_MARKED_TO_DISALLOW_WRITES: WIN32_ERROR = 348u32;
+pub const ERROR_MARSHALL_OVERFLOW: WIN32_ERROR = 603u32;
+pub const ERROR_MAX_SESSIONS_REACHED: WIN32_ERROR = 353u32;
+pub const ERROR_MAX_THRDS_REACHED: WIN32_ERROR = 164u32;
+pub const ERROR_MCA_EXCEPTION: WIN32_ERROR = 784u32;
+pub const ERROR_MCA_OCCURED: WIN32_ERROR = 651u32;
+pub const ERROR_MEDIA_CHANGED: WIN32_ERROR = 1110u32;
+pub const ERROR_MEDIA_CHECK: WIN32_ERROR = 679u32;
+pub const ERROR_MEMBERS_PRIMARY_GROUP: WIN32_ERROR = 1374u32;
+pub const ERROR_MEMBER_IN_ALIAS: WIN32_ERROR = 1378u32;
+pub const ERROR_MEMBER_IN_GROUP: WIN32_ERROR = 1320u32;
+pub const ERROR_MEMBER_NOT_IN_ALIAS: WIN32_ERROR = 1377u32;
+pub const ERROR_MEMBER_NOT_IN_GROUP: WIN32_ERROR = 1321u32;
+pub const ERROR_MEMORY_HARDWARE: WIN32_ERROR = 779u32;
+pub const ERROR_MENU_ITEM_NOT_FOUND: WIN32_ERROR = 1456u32;
+pub const ERROR_MESSAGE_SYNC_ONLY: WIN32_ERROR = 1159u32;
+pub const ERROR_META_EXPANSION_TOO_LONG: WIN32_ERROR = 208u32;
+pub const ERROR_MISSING_SYSTEMFILE: WIN32_ERROR = 573u32;
+pub const ERROR_MOD_NOT_FOUND: WIN32_ERROR = 126u32;
+pub const ERROR_MORE_DATA: WIN32_ERROR = 234u32;
+pub const ERROR_MORE_WRITES: WIN32_ERROR = 1120u32;
+pub const ERROR_MOUNT_POINT_NOT_RESOLVED: WIN32_ERROR = 649u32;
+pub const ERROR_MP_PROCESSOR_MISMATCH: WIN32_ERROR = 725u32;
+pub const ERROR_MR_MID_NOT_FOUND: WIN32_ERROR = 317u32;
+pub const ERROR_MULTIPLE_FAULT_VIOLATION: WIN32_ERROR = 640u32;
+pub const ERROR_MUTANT_LIMIT_EXCEEDED: WIN32_ERROR = 587u32;
+pub const ERROR_MUTUAL_AUTH_FAILED: WIN32_ERROR = 1397u32;
+pub const ERROR_NEGATIVE_SEEK: WIN32_ERROR = 131u32;
+pub const ERROR_NESTING_NOT_ALLOWED: WIN32_ERROR = 215u32;
+pub const ERROR_NETLOGON_NOT_STARTED: WIN32_ERROR = 1792u32;
+pub const ERROR_NETNAME_DELETED: WIN32_ERROR = 64u32;
+pub const ERROR_NETWORK_ACCESS_DENIED: WIN32_ERROR = 65u32;
+pub const ERROR_NETWORK_ACCESS_DENIED_EDP: WIN32_ERROR = 354u32;
+pub const ERROR_NETWORK_BUSY: WIN32_ERROR = 54u32;
+pub const ERROR_NETWORK_UNREACHABLE: WIN32_ERROR = 1231u32;
+pub const ERROR_NET_OPEN_FAILED: WIN32_ERROR = 570u32;
+pub const ERROR_NET_WRITE_FAULT: WIN32_ERROR = 88u32;
+pub const ERROR_NOACCESS: WIN32_ERROR = 998u32;
+pub const ERROR_NOINTERFACE: WIN32_ERROR = 632u32;
+pub const ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT: WIN32_ERROR = 1807u32;
+pub const ERROR_NOLOGON_SERVER_TRUST_ACCOUNT: WIN32_ERROR = 1809u32;
+pub const ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT: WIN32_ERROR = 1808u32;
+pub const ERROR_NONE_MAPPED: WIN32_ERROR = 1332u32;
+pub const ERROR_NONPAGED_SYSTEM_RESOURCES: WIN32_ERROR = 1451u32;
+pub const ERROR_NON_ACCOUNT_SID: WIN32_ERROR = 1257u32;
+pub const ERROR_NON_DOMAIN_SID: WIN32_ERROR = 1258u32;
+pub const ERROR_NON_MDICHILD_WINDOW: WIN32_ERROR = 1445u32;
+pub const ERROR_NOTHING_TO_TERMINATE: WIN32_ERROR = 758u32;
+pub const ERROR_NOTIFICATION_GUID_ALREADY_DEFINED: WIN32_ERROR = 309u32;
+pub const ERROR_NOTIFY_CLEANUP: WIN32_ERROR = 745u32;
+pub const ERROR_NOTIFY_ENUM_DIR: WIN32_ERROR = 1022u32;
+pub const ERROR_NOT_ALLOWED_ON_SYSTEM_FILE: WIN32_ERROR = 313u32;
+pub const ERROR_NOT_ALL_ASSIGNED: WIN32_ERROR = 1300u32;
+pub const ERROR_NOT_APPCONTAINER: WIN32_ERROR = 4250u32;
+pub const ERROR_NOT_AUTHENTICATED: WIN32_ERROR = 1244u32;
+pub const ERROR_NOT_A_CLOUD_FILE: WIN32_ERROR = 376u32;
+pub const ERROR_NOT_A_CLOUD_SYNC_ROOT: WIN32_ERROR = 405u32;
+pub const ERROR_NOT_A_DAX_VOLUME: WIN32_ERROR = 420u32;
+pub const ERROR_NOT_A_REPARSE_POINT: WIN32_ERROR = 4390u32;
+pub const ERROR_NOT_CAPABLE: WIN32_ERROR = 775u32;
+pub const ERROR_NOT_CHILD_WINDOW: WIN32_ERROR = 1442u32;
+pub const ERROR_NOT_CONNECTED: WIN32_ERROR = 2250u32;
+pub const ERROR_NOT_CONTAINER: WIN32_ERROR = 1207u32;
+pub const ERROR_NOT_DAX_MAPPABLE: WIN32_ERROR = 421u32;
+pub const ERROR_NOT_DOS_DISK: WIN32_ERROR = 26u32;
+pub const ERROR_NOT_ENOUGH_MEMORY: WIN32_ERROR = 8u32;
+pub const ERROR_NOT_ENOUGH_QUOTA: WIN32_ERROR = 1816u32;
+pub const ERROR_NOT_ENOUGH_SERVER_MEMORY: WIN32_ERROR = 1130u32;
+pub const ERROR_NOT_EXPORT_FORMAT: WIN32_ERROR = 6008u32;
+pub const ERROR_NOT_FOUND: WIN32_ERROR = 1168u32;
+pub const ERROR_NOT_GUI_PROCESS: WIN32_ERROR = 1471u32;
+pub const ERROR_NOT_JOINED: WIN32_ERROR = 136u32;
+pub const ERROR_NOT_LOCKED: WIN32_ERROR = 158u32;
+pub const ERROR_NOT_LOGGED_ON: WIN32_ERROR = 1245u32;
+pub const ERROR_NOT_LOGON_PROCESS: WIN32_ERROR = 1362u32;
+pub const ERROR_NOT_OWNER: WIN32_ERROR = 288u32;
+pub const ERROR_NOT_READY: WIN32_ERROR = 21u32;
+pub const ERROR_NOT_READ_FROM_COPY: WIN32_ERROR = 337u32;
+pub const ERROR_NOT_REDUNDANT_STORAGE: WIN32_ERROR = 333u32;
+pub const ERROR_NOT_REGISTRY_FILE: WIN32_ERROR = 1017u32;
+pub const ERROR_NOT_SAFEBOOT_SERVICE: WIN32_ERROR = 1084u32;
+pub const ERROR_NOT_SAFE_MODE_DRIVER: WIN32_ERROR = 646u32;
+pub const ERROR_NOT_SAME_DEVICE: WIN32_ERROR = 17u32;
+pub const ERROR_NOT_SAME_OBJECT: WIN32_ERROR = 1656u32;
+pub const ERROR_NOT_SUBSTED: WIN32_ERROR = 137u32;
+pub const ERROR_NOT_SUPPORTED: WIN32_ERROR = 50u32;
+pub const ERROR_NOT_SUPPORTED_IN_APPCONTAINER: WIN32_ERROR = 4252u32;
+pub const ERROR_NOT_SUPPORTED_ON_DAX: WIN32_ERROR = 360u32;
+pub const ERROR_NOT_SUPPORTED_ON_SBS: WIN32_ERROR = 1254u32;
+pub const ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER: WIN32_ERROR = 8584u32;
+pub const ERROR_NOT_SUPPORTED_WITH_AUDITING: WIN32_ERROR = 499u32;
+pub const ERROR_NOT_SUPPORTED_WITH_BTT: WIN32_ERROR = 429u32;
+pub const ERROR_NOT_SUPPORTED_WITH_BYPASSIO: WIN32_ERROR = 493u32;
+pub const ERROR_NOT_SUPPORTED_WITH_CACHED_HANDLE: WIN32_ERROR = 509u32;
+pub const ERROR_NOT_SUPPORTED_WITH_COMPRESSION: WIN32_ERROR = 496u32;
+pub const ERROR_NOT_SUPPORTED_WITH_DEDUPLICATION: WIN32_ERROR = 498u32;
+pub const ERROR_NOT_SUPPORTED_WITH_ENCRYPTION: WIN32_ERROR = 495u32;
+pub const ERROR_NOT_SUPPORTED_WITH_MONITORING: WIN32_ERROR = 503u32;
+pub const ERROR_NOT_SUPPORTED_WITH_REPLICATION: WIN32_ERROR = 497u32;
+pub const ERROR_NOT_SUPPORTED_WITH_SNAPSHOT: WIN32_ERROR = 504u32;
+pub const ERROR_NOT_SUPPORTED_WITH_VIRTUALIZATION: WIN32_ERROR = 505u32;
+pub const ERROR_NOT_TINY_STREAM: WIN32_ERROR = 598u32;
+pub const ERROR_NO_ACE_CONDITION: WIN32_ERROR = 804u32;
+pub const ERROR_NO_ASSOCIATION: WIN32_ERROR = 1155u32;
+pub const ERROR_NO_BYPASSIO_DRIVER_SUPPORT: WIN32_ERROR = 494u32;
+pub const ERROR_NO_CALLBACK_ACTIVE: WIN32_ERROR = 614u32;
+pub const ERROR_NO_DATA: WIN32_ERROR = 232u32;
+pub const ERROR_NO_DATA_DETECTED: WIN32_ERROR = 1104u32;
+pub const ERROR_NO_EFS: WIN32_ERROR = 6004u32;
+pub const ERROR_NO_EVENT_PAIR: WIN32_ERROR = 580u32;
+pub const ERROR_NO_GUID_TRANSLATION: WIN32_ERROR = 560u32;
+pub const ERROR_NO_IMPERSONATION_TOKEN: WIN32_ERROR = 1309u32;
+pub const ERROR_NO_INHERITANCE: WIN32_ERROR = 1391u32;
+pub const ERROR_NO_LOGON_SERVERS: WIN32_ERROR = 1311u32;
+pub const ERROR_NO_LOG_SPACE: WIN32_ERROR = 1019u32;
+pub const ERROR_NO_MATCH: WIN32_ERROR = 1169u32;
+pub const ERROR_NO_MEDIA_IN_DRIVE: WIN32_ERROR = 1112u32;
+pub const ERROR_NO_MORE_DEVICES: WIN32_ERROR = 1248u32;
+pub const ERROR_NO_MORE_FILES: WIN32_ERROR = 18u32;
+pub const ERROR_NO_MORE_ITEMS: WIN32_ERROR = 259u32;
+pub const ERROR_NO_MORE_MATCHES: WIN32_ERROR = 626u32;
+pub const ERROR_NO_MORE_SEARCH_HANDLES: WIN32_ERROR = 113u32;
+pub const ERROR_NO_MORE_USER_HANDLES: WIN32_ERROR = 1158u32;
+pub const ERROR_NO_NETWORK: WIN32_ERROR = 1222u32;
+pub const ERROR_NO_NET_OR_BAD_PATH: WIN32_ERROR = 1203u32;
+pub const ERROR_NO_NVRAM_RESOURCES: WIN32_ERROR = 1470u32;
+pub const ERROR_NO_PAGEFILE: WIN32_ERROR = 578u32;
+pub const ERROR_NO_PHYSICALLY_ALIGNED_FREE_SPACE_FOUND: WIN32_ERROR = 408u32;
+pub const ERROR_NO_PROC_SLOTS: WIN32_ERROR = 89u32;
+pub const ERROR_NO_PROMOTION_ACTIVE: WIN32_ERROR = 8222u32;
+pub const ERROR_NO_QUOTAS_FOR_ACCOUNT: WIN32_ERROR = 1302u32;
+pub const ERROR_NO_RANGES_PROCESSED: WIN32_ERROR = 312u32;
+pub const ERROR_NO_RECOVERY_POLICY: WIN32_ERROR = 6003u32;
+pub const ERROR_NO_RECOVERY_PROGRAM: WIN32_ERROR = 1082u32;
+pub const ERROR_NO_SCROLLBARS: WIN32_ERROR = 1447u32;
+pub const ERROR_NO_SECRETS: WIN32_ERROR = 8620u32;
+pub const ERROR_NO_SECURITY_ON_OBJECT: WIN32_ERROR = 1350u32;
+pub const ERROR_NO_SHUTDOWN_IN_PROGRESS: WIN32_ERROR = 1116u32;
+pub const ERROR_NO_SIGNAL_SENT: WIN32_ERROR = 205u32;
+pub const ERROR_NO_SITENAME: WIN32_ERROR = 1919u32;
+pub const ERROR_NO_SITE_SETTINGS_OBJECT: WIN32_ERROR = 8619u32;
+pub const ERROR_NO_SPOOL_SPACE: WIN32_ERROR = 62u32;
+pub const ERROR_NO_SUCH_ALIAS: WIN32_ERROR = 1376u32;
+pub const ERROR_NO_SUCH_DEVICE: WIN32_ERROR = 433u32;
+pub const ERROR_NO_SUCH_DOMAIN: WIN32_ERROR = 1355u32;
+pub const ERROR_NO_SUCH_GROUP: WIN32_ERROR = 1319u32;
+pub const ERROR_NO_SUCH_LOGON_SESSION: WIN32_ERROR = 1312u32;
+pub const ERROR_NO_SUCH_MEMBER: WIN32_ERROR = 1387u32;
+pub const ERROR_NO_SUCH_PACKAGE: WIN32_ERROR = 1364u32;
+pub const ERROR_NO_SUCH_PRIVILEGE: WIN32_ERROR = 1313u32;
+pub const ERROR_NO_SUCH_SITE: WIN32_ERROR = 1249u32;
+pub const ERROR_NO_SUCH_USER: WIN32_ERROR = 1317u32;
+pub const ERROR_NO_SYSTEM_MENU: WIN32_ERROR = 1437u32;
+pub const ERROR_NO_SYSTEM_RESOURCES: WIN32_ERROR = 1450u32;
+pub const ERROR_NO_TASK_QUEUE: WIN32_ERROR = 427u32;
+pub const ERROR_NO_TOKEN: WIN32_ERROR = 1008u32;
+pub const ERROR_NO_TRACKING_SERVICE: WIN32_ERROR = 1172u32;
+pub const ERROR_NO_TRUST_LSA_SECRET: WIN32_ERROR = 1786u32;
+pub const ERROR_NO_TRUST_SAM_ACCOUNT: WIN32_ERROR = 1787u32;
+pub const ERROR_NO_UNICODE_TRANSLATION: WIN32_ERROR = 1113u32;
+pub const ERROR_NO_USER_KEYS: WIN32_ERROR = 6006u32;
+pub const ERROR_NO_USER_SESSION_KEY: WIN32_ERROR = 1394u32;
+pub const ERROR_NO_VOLUME_ID: WIN32_ERROR = 1173u32;
+pub const ERROR_NO_VOLUME_LABEL: WIN32_ERROR = 125u32;
+pub const ERROR_NO_WILDCARD_CHARACTERS: WIN32_ERROR = 1417u32;
+pub const ERROR_NO_WORK_DONE: WIN32_ERROR = 235u32;
+pub const ERROR_NO_WRITABLE_DC_FOUND: WIN32_ERROR = 8621u32;
+pub const ERROR_NO_YIELD_PERFORMED: WIN32_ERROR = 721u32;
+pub const ERROR_NTLM_BLOCKED: WIN32_ERROR = 1937u32;
+pub const ERROR_NT_CROSS_ENCRYPTION_REQUIRED: WIN32_ERROR = 1386u32;
+pub const ERROR_NULL_LM_PASSWORD: WIN32_ERROR = 1304u32;
+pub const ERROR_OBJECT_IS_IMMUTABLE: WIN32_ERROR = 4449u32;
+pub const ERROR_OBJECT_NAME_EXISTS: WIN32_ERROR = 698u32;
+pub const ERROR_OBJECT_NOT_EXTERNALLY_BACKED: WIN32_ERROR = 342u32;
+pub const ERROR_OFFLOAD_READ_FILE_NOT_SUPPORTED: WIN32_ERROR = 4442u32;
+pub const ERROR_OFFLOAD_READ_FLT_NOT_SUPPORTED: WIN32_ERROR = 4440u32;
+pub const ERROR_OFFLOAD_WRITE_FILE_NOT_SUPPORTED: WIN32_ERROR = 4443u32;
+pub const ERROR_OFFLOAD_WRITE_FLT_NOT_SUPPORTED: WIN32_ERROR = 4441u32;
+pub const ERROR_OFFSET_ALIGNMENT_VIOLATION: WIN32_ERROR = 327u32;
+pub const ERROR_OLD_WIN_VERSION: WIN32_ERROR = 1150u32;
+pub const ERROR_ONLY_IF_CONNECTED: WIN32_ERROR = 1251u32;
+pub const ERROR_OPEN_FAILED: WIN32_ERROR = 110u32;
+pub const ERROR_OPEN_FILES: WIN32_ERROR = 2401u32;
+pub const ERROR_OPERATION_ABORTED: WIN32_ERROR = 995u32;
+pub const ERROR_OPERATION_IN_PROGRESS: WIN32_ERROR = 329u32;
+pub const ERROR_OPLOCK_BREAK_IN_PROGRESS: WIN32_ERROR = 742u32;
+pub const ERROR_OPLOCK_HANDLE_CLOSED: WIN32_ERROR = 803u32;
+pub const ERROR_OPLOCK_NOT_GRANTED: WIN32_ERROR = 300u32;
+pub const ERROR_OPLOCK_SWITCHED_TO_NEW_HANDLE: WIN32_ERROR = 800u32;
+pub const ERROR_ORPHAN_NAME_EXHAUSTED: WIN32_ERROR = 799u32;
+pub const ERROR_OUTOFMEMORY: WIN32_ERROR = 14u32;
+pub const ERROR_OUT_OF_PAPER: WIN32_ERROR = 28u32;
+pub const ERROR_OUT_OF_STRUCTURES: WIN32_ERROR = 84u32;
+pub const ERROR_OVERRIDE_NOCHANGES: WIN32_ERROR = 1252u32;
+pub const ERROR_PAGED_SYSTEM_RESOURCES: WIN32_ERROR = 1452u32;
+pub const ERROR_PAGEFILE_CREATE_FAILED: WIN32_ERROR = 576u32;
+pub const ERROR_PAGEFILE_NOT_SUPPORTED: WIN32_ERROR = 491u32;
+pub const ERROR_PAGEFILE_QUOTA: WIN32_ERROR = 1454u32;
+pub const ERROR_PAGEFILE_QUOTA_EXCEEDED: WIN32_ERROR = 567u32;
+pub const ERROR_PAGE_FAULT_COPY_ON_WRITE: WIN32_ERROR = 749u32;
+pub const ERROR_PAGE_FAULT_DEMAND_ZERO: WIN32_ERROR = 748u32;
+pub const ERROR_PAGE_FAULT_GUARD_PAGE: WIN32_ERROR = 750u32;
+pub const ERROR_PAGE_FAULT_PAGING_FILE: WIN32_ERROR = 751u32;
+pub const ERROR_PAGE_FAULT_TRANSITION: WIN32_ERROR = 747u32;
+pub const ERROR_PARAMETER_QUOTA_EXCEEDED: WIN32_ERROR = 1283u32;
+pub const ERROR_PARTIAL_COPY: WIN32_ERROR = 299u32;
+pub const ERROR_PARTITION_FAILURE: WIN32_ERROR = 1105u32;
+pub const ERROR_PARTITION_TERMINATING: WIN32_ERROR = 1184u32;
+pub const ERROR_PASSWORD_CHANGE_REQUIRED: WIN32_ERROR = 1938u32;
+pub const ERROR_PASSWORD_EXPIRED: WIN32_ERROR = 1330u32;
+pub const ERROR_PASSWORD_MUST_CHANGE: WIN32_ERROR = 1907u32;
+pub const ERROR_PASSWORD_RESTRICTION: WIN32_ERROR = 1325u32;
+pub const ERROR_PATCH_MANAGED_ADVERTISED_PRODUCT: WIN32_ERROR = 1651u32;
+pub const ERROR_PATCH_NO_SEQUENCE: WIN32_ERROR = 1648u32;
+pub const ERROR_PATCH_PACKAGE_INVALID: WIN32_ERROR = 1636u32;
+pub const ERROR_PATCH_PACKAGE_OPEN_FAILED: WIN32_ERROR = 1635u32;
+pub const ERROR_PATCH_PACKAGE_REJECTED: WIN32_ERROR = 1643u32;
+pub const ERROR_PATCH_PACKAGE_UNSUPPORTED: WIN32_ERROR = 1637u32;
+pub const ERROR_PATCH_REMOVAL_DISALLOWED: WIN32_ERROR = 1649u32;
+pub const ERROR_PATCH_REMOVAL_UNSUPPORTED: WIN32_ERROR = 1646u32;
+pub const ERROR_PATCH_TARGET_NOT_FOUND: WIN32_ERROR = 1642u32;
+pub const ERROR_PATH_BUSY: WIN32_ERROR = 148u32;
+pub const ERROR_PATH_NOT_FOUND: WIN32_ERROR = 3u32;
+pub const ERROR_PER_USER_TRUST_QUOTA_EXCEEDED: WIN32_ERROR = 1932u32;
+pub const ERROR_PIPE_BUSY: WIN32_ERROR = 231u32;
+pub const ERROR_PIPE_CONNECTED: WIN32_ERROR = 535u32;
+pub const ERROR_PIPE_LISTENING: WIN32_ERROR = 536u32;
+pub const ERROR_PIPE_LOCAL: WIN32_ERROR = 229u32;
+pub const ERROR_PIPE_NOT_CONNECTED: WIN32_ERROR = 233u32;
+pub const ERROR_PKINIT_FAILURE: WIN32_ERROR = 1263u32;
+pub const ERROR_PLUGPLAY_QUERY_VETOED: WIN32_ERROR = 683u32;
+pub const ERROR_PNP_BAD_MPS_TABLE: WIN32_ERROR = 671u32;
+pub const ERROR_PNP_INVALID_ID: WIN32_ERROR = 674u32;
+pub const ERROR_PNP_IRQ_TRANSLATION_FAILED: WIN32_ERROR = 673u32;
+pub const ERROR_PNP_QUERY_REMOVE_DEVICE_TIMEOUT: WIN32_ERROR = 480u32;
+pub const ERROR_PNP_QUERY_REMOVE_RELATED_DEVICE_TIMEOUT: WIN32_ERROR = 481u32;
+pub const ERROR_PNP_QUERY_REMOVE_UNRELATED_DEVICE_TIMEOUT: WIN32_ERROR = 482u32;
+pub const ERROR_PNP_REBOOT_REQUIRED: WIN32_ERROR = 638u32;
+pub const ERROR_PNP_RESTART_ENUMERATION: WIN32_ERROR = 636u32;
+pub const ERROR_PNP_TRANSLATION_FAILED: WIN32_ERROR = 672u32;
+pub const ERROR_POINT_NOT_FOUND: WIN32_ERROR = 1171u32;
+pub const ERROR_POLICY_OBJECT_NOT_FOUND: WIN32_ERROR = 8219u32;
+pub const ERROR_POLICY_ONLY_IN_DS: WIN32_ERROR = 8220u32;
+pub const ERROR_POPUP_ALREADY_ACTIVE: WIN32_ERROR = 1446u32;
+pub const ERROR_PORT_MESSAGE_TOO_LONG: WIN32_ERROR = 546u32;
+pub const ERROR_PORT_NOT_SET: WIN32_ERROR = 642u32;
+pub const ERROR_PORT_UNREACHABLE: WIN32_ERROR = 1234u32;
+pub const ERROR_POSSIBLE_DEADLOCK: WIN32_ERROR = 1131u32;
+pub const ERROR_POTENTIAL_FILE_FOUND: WIN32_ERROR = 1180u32;
+pub const ERROR_PREDEFINED_HANDLE: WIN32_ERROR = 714u32;
+pub const ERROR_PRIMARY_TRANSPORT_CONNECT_FAILED: WIN32_ERROR = 746u32;
+pub const ERROR_PRINTER_ALREADY_EXISTS: WIN32_ERROR = 1802u32;
+pub const ERROR_PRINTER_DELETED: WIN32_ERROR = 1905u32;
+pub const ERROR_PRINTER_DRIVER_ALREADY_INSTALLED: WIN32_ERROR = 1795u32;
+pub const ERROR_PRINTQ_FULL: WIN32_ERROR = 61u32;
+pub const ERROR_PRINT_CANCELLED: WIN32_ERROR = 63u32;
+pub const ERROR_PRIVATE_DIALOG_INDEX: WIN32_ERROR = 1415u32;
+pub const ERROR_PRIVILEGE_NOT_HELD: WIN32_ERROR = 1314u32;
+pub const ERROR_PROCESS_ABORTED: WIN32_ERROR = 1067u32;
+pub const ERROR_PROCESS_IN_JOB: WIN32_ERROR = 760u32;
+pub const ERROR_PROCESS_IS_PROTECTED: WIN32_ERROR = 1293u32;
+pub const ERROR_PROCESS_MODE_ALREADY_BACKGROUND: WIN32_ERROR = 402u32;
+pub const ERROR_PROCESS_MODE_NOT_BACKGROUND: WIN32_ERROR = 403u32;
+pub const ERROR_PROCESS_NOT_IN_JOB: WIN32_ERROR = 759u32;
+pub const ERROR_PROC_NOT_FOUND: WIN32_ERROR = 127u32;
+pub const ERROR_PRODUCT_UNINSTALLED: WIN32_ERROR = 1614u32;
+pub const ERROR_PRODUCT_VERSION: WIN32_ERROR = 1638u32;
+pub const ERROR_PROFILING_AT_LIMIT: WIN32_ERROR = 553u32;
+pub const ERROR_PROFILING_NOT_STARTED: WIN32_ERROR = 550u32;
+pub const ERROR_PROFILING_NOT_STOPPED: WIN32_ERROR = 551u32;
+pub const ERROR_PROMOTION_ACTIVE: WIN32_ERROR = 8221u32;
+pub const ERROR_PROTOCOL_UNREACHABLE: WIN32_ERROR = 1233u32;
+pub const ERROR_PWD_HISTORY_CONFLICT: WIN32_ERROR = 617u32;
+pub const ERROR_PWD_TOO_LONG: WIN32_ERROR = 657u32;
+pub const ERROR_PWD_TOO_RECENT: WIN32_ERROR = 616u32;
+pub const ERROR_PWD_TOO_SHORT: WIN32_ERROR = 615u32;
+pub const ERROR_QUOTA_ACTIVITY: WIN32_ERROR = 810u32;
+pub const ERROR_QUOTA_LIST_INCONSISTENT: WIN32_ERROR = 621u32;
+pub const ERROR_RANGE_LIST_CONFLICT: WIN32_ERROR = 627u32;
+pub const ERROR_RANGE_NOT_FOUND: WIN32_ERROR = 644u32;
+pub const ERROR_READ_FAULT: WIN32_ERROR = 30u32;
+pub const ERROR_RECEIVE_EXPEDITED: WIN32_ERROR = 708u32;
+pub const ERROR_RECEIVE_PARTIAL: WIN32_ERROR = 707u32;
+pub const ERROR_RECEIVE_PARTIAL_EXPEDITED: WIN32_ERROR = 709u32;
+pub const ERROR_RECOVERY_FAILURE: WIN32_ERROR = 1279u32;
+pub const ERROR_REDIRECTOR_HAS_OPEN_HANDLES: WIN32_ERROR = 1794u32;
+pub const ERROR_REDIR_PAUSED: WIN32_ERROR = 72u32;
+pub const ERROR_REGISTRY_CORRUPT: WIN32_ERROR = 1015u32;
+pub const ERROR_REGISTRY_HIVE_RECOVERED: WIN32_ERROR = 685u32;
+pub const ERROR_REGISTRY_IO_FAILED: WIN32_ERROR = 1016u32;
+pub const ERROR_REGISTRY_QUOTA_LIMIT: WIN32_ERROR = 613u32;
+pub const ERROR_REGISTRY_RECOVERED: WIN32_ERROR = 1014u32;
+pub const ERROR_REG_NAT_CONSUMPTION: WIN32_ERROR = 1261u32;
+pub const ERROR_RELOC_CHAIN_XEEDS_SEGLIM: WIN32_ERROR = 201u32;
+pub const ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED: WIN32_ERROR = 1936u32;
+pub const ERROR_REMOTE_SESSION_LIMIT_EXCEEDED: WIN32_ERROR = 1220u32;
+pub const ERROR_REMOTE_STORAGE_MEDIA_ERROR: WIN32_ERROR = 4352u32;
+pub const ERROR_REMOTE_STORAGE_NOT_ACTIVE: WIN32_ERROR = 4351u32;
+pub const ERROR_REM_NOT_LIST: WIN32_ERROR = 51u32;
+pub const ERROR_REPARSE: WIN32_ERROR = 741u32;
+pub const ERROR_REPARSE_ATTRIBUTE_CONFLICT: WIN32_ERROR = 4391u32;
+pub const ERROR_REPARSE_OBJECT: WIN32_ERROR = 755u32;
+pub const ERROR_REPARSE_POINT_ENCOUNTERED: WIN32_ERROR = 4395u32;
+pub const ERROR_REPARSE_TAG_INVALID: WIN32_ERROR = 4393u32;
+pub const ERROR_REPARSE_TAG_MISMATCH: WIN32_ERROR = 4394u32;
+pub const ERROR_REPLY_MESSAGE_MISMATCH: WIN32_ERROR = 595u32;
+pub const ERROR_REQUEST_ABORTED: WIN32_ERROR = 1235u32;
+pub const ERROR_REQUEST_OUT_OF_SEQUENCE: WIN32_ERROR = 776u32;
+pub const ERROR_REQUEST_PAUSED: WIN32_ERROR = 3050u32;
+pub const ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION: WIN32_ERROR = 1459u32;
+pub const ERROR_REQ_NOT_ACCEP: WIN32_ERROR = 71u32;
+pub const ERROR_RESIDENT_FILE_NOT_SUPPORTED: WIN32_ERROR = 334u32;
+pub const ERROR_RESOURCE_CALL_TIMED_OUT: WIN32_ERROR = 5910u32;
+pub const ERROR_RESOURCE_DATA_NOT_FOUND: WIN32_ERROR = 1812u32;
+pub const ERROR_RESOURCE_LANG_NOT_FOUND: WIN32_ERROR = 1815u32;
+pub const ERROR_RESOURCE_NAME_NOT_FOUND: WIN32_ERROR = 1814u32;
+pub const ERROR_RESOURCE_REQUIREMENTS_CHANGED: WIN32_ERROR = 756u32;
+pub const ERROR_RESOURCE_TYPE_NOT_FOUND: WIN32_ERROR = 1813u32;
+pub const ERROR_RESTART_APPLICATION: WIN32_ERROR = 1467u32;
+pub const ERROR_RESUME_HIBERNATION: WIN32_ERROR = 727u32;
+pub const ERROR_RETRY: WIN32_ERROR = 1237u32;
+pub const ERROR_RETURN_ADDRESS_HIJACK_ATTEMPT: WIN32_ERROR = 1662u32;
+pub const ERROR_REVISION_MISMATCH: WIN32_ERROR = 1306u32;
+pub const ERROR_RING2SEG_MUST_BE_MOVABLE: WIN32_ERROR = 200u32;
+pub const ERROR_RING2_STACK_IN_USE: WIN32_ERROR = 207u32;
+pub const ERROR_RMODE_APP: WIN32_ERROR = 1153u32;
+pub const ERROR_ROWSNOTRELEASED: WIN32_ERROR = 772u32;
+pub const ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT: WIN32_ERROR = 15403u32;
+pub const ERROR_RUNLEVEL_SWITCH_TIMEOUT: WIN32_ERROR = 15402u32;
+pub const ERROR_RWRAW_ENCRYPTED_FILE_NOT_ENCRYPTED: WIN32_ERROR = 410u32;
+pub const ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILEOFFSET: WIN32_ERROR = 411u32;
+pub const ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILERANGE: WIN32_ERROR = 412u32;
+pub const ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_PARAMETER: WIN32_ERROR = 413u32;
+pub const ERROR_RXACT_COMMITTED: WIN32_ERROR = 744u32;
+pub const ERROR_RXACT_COMMIT_FAILURE: WIN32_ERROR = 1370u32;
+pub const ERROR_RXACT_COMMIT_NECESSARY: WIN32_ERROR = 678u32;
+pub const ERROR_RXACT_INVALID_STATE: WIN32_ERROR = 1369u32;
+pub const ERROR_RXACT_STATE_CREATED: WIN32_ERROR = 701u32;
+pub const ERROR_SAME_DRIVE: WIN32_ERROR = 143u32;
+pub const ERROR_SAM_INIT_FAILURE: WIN32_ERROR = 8541u32;
+pub const ERROR_SCOPE_NOT_FOUND: WIN32_ERROR = 318u32;
+pub const ERROR_SCREEN_ALREADY_LOCKED: WIN32_ERROR = 1440u32;
+pub const ERROR_SCRUB_DATA_DISABLED: WIN32_ERROR = 332u32;
+pub const ERROR_SECRET_TOO_LONG: WIN32_ERROR = 1382u32;
+pub const ERROR_SECTION_DIRECT_MAP_ONLY: WIN32_ERROR = 819u32;
+pub const ERROR_SECTOR_NOT_FOUND: WIN32_ERROR = 27u32;
+pub const ERROR_SECURITY_DENIES_OPERATION: WIN32_ERROR = 447u32;
+pub const ERROR_SECURITY_STREAM_IS_INCONSISTENT: WIN32_ERROR = 306u32;
+pub const ERROR_SEEK: WIN32_ERROR = 25u32;
+pub const ERROR_SEEK_ON_DEVICE: WIN32_ERROR = 132u32;
+pub const ERROR_SEGMENT_NOTIFICATION: WIN32_ERROR = 702u32;
+pub const ERROR_SEM_IS_SET: WIN32_ERROR = 102u32;
+pub const ERROR_SEM_NOT_FOUND: WIN32_ERROR = 187u32;
+pub const ERROR_SEM_OWNER_DIED: WIN32_ERROR = 105u32;
+pub const ERROR_SEM_TIMEOUT: WIN32_ERROR = 121u32;
+pub const ERROR_SEM_USER_LIMIT: WIN32_ERROR = 106u32;
+pub const ERROR_SERIAL_NO_DEVICE: WIN32_ERROR = 1118u32;
+pub const ERROR_SERVER_DISABLED: WIN32_ERROR = 1341u32;
+pub const ERROR_SERVER_HAS_OPEN_HANDLES: WIN32_ERROR = 1811u32;
+pub const ERROR_SERVER_NOT_DISABLED: WIN32_ERROR = 1342u32;
+pub const ERROR_SERVER_SHUTDOWN_IN_PROGRESS: WIN32_ERROR = 1255u32;
+pub const ERROR_SERVER_SID_MISMATCH: WIN32_ERROR = 628u32;
+pub const ERROR_SERVER_TRANSPORT_CONFLICT: WIN32_ERROR = 816u32;
+pub const ERROR_SERVICE_ALREADY_RUNNING: WIN32_ERROR = 1056u32;
+pub const ERROR_SERVICE_CANNOT_ACCEPT_CTRL: WIN32_ERROR = 1061u32;
+pub const ERROR_SERVICE_DATABASE_LOCKED: WIN32_ERROR = 1055u32;
+pub const ERROR_SERVICE_DEPENDENCY_DELETED: WIN32_ERROR = 1075u32;
+pub const ERROR_SERVICE_DEPENDENCY_FAIL: WIN32_ERROR = 1068u32;
+pub const ERROR_SERVICE_DISABLED: WIN32_ERROR = 1058u32;
+pub const ERROR_SERVICE_DOES_NOT_EXIST: WIN32_ERROR = 1060u32;
+pub const ERROR_SERVICE_EXISTS: WIN32_ERROR = 1073u32;
+pub const ERROR_SERVICE_LOGON_FAILED: WIN32_ERROR = 1069u32;
+pub const ERROR_SERVICE_MARKED_FOR_DELETE: WIN32_ERROR = 1072u32;
+pub const ERROR_SERVICE_NEVER_STARTED: WIN32_ERROR = 1077u32;
+pub const ERROR_SERVICE_NOTIFICATION: WIN32_ERROR = 716u32;
+pub const ERROR_SERVICE_NOTIFY_CLIENT_LAGGING: WIN32_ERROR = 1294u32;
+pub const ERROR_SERVICE_NOT_ACTIVE: WIN32_ERROR = 1062u32;
+pub const ERROR_SERVICE_NOT_FOUND: WIN32_ERROR = 1243u32;
+pub const ERROR_SERVICE_NOT_IN_EXE: WIN32_ERROR = 1083u32;
+pub const ERROR_SERVICE_NO_THREAD: WIN32_ERROR = 1054u32;
+pub const ERROR_SERVICE_REQUEST_TIMEOUT: WIN32_ERROR = 1053u32;
+pub const ERROR_SERVICE_SPECIFIC_ERROR: WIN32_ERROR = 1066u32;
+pub const ERROR_SERVICE_START_HANG: WIN32_ERROR = 1070u32;
+pub const ERROR_SESSION_CREDENTIAL_CONFLICT: WIN32_ERROR = 1219u32;
+pub const ERROR_SESSION_KEY_TOO_SHORT: WIN32_ERROR = 501u32;
+pub const ERROR_SETCOUNT_ON_BAD_LB: WIN32_ERROR = 1433u32;
+pub const ERROR_SETMARK_DETECTED: WIN32_ERROR = 1103u32;
+pub const ERROR_SET_CONTEXT_DENIED: WIN32_ERROR = 1660u32;
+pub const ERROR_SET_NOT_FOUND: WIN32_ERROR = 1170u32;
+pub const ERROR_SET_POWER_STATE_FAILED: WIN32_ERROR = 1141u32;
+pub const ERROR_SET_POWER_STATE_VETOED: WIN32_ERROR = 1140u32;
+pub const ERROR_SHARED_POLICY: WIN32_ERROR = 8218u32;
+pub const ERROR_SHARING_BUFFER_EXCEEDED: WIN32_ERROR = 36u32;
+pub const ERROR_SHARING_PAUSED: WIN32_ERROR = 70u32;
+pub const ERROR_SHARING_VIOLATION: WIN32_ERROR = 32u32;
+pub const ERROR_SHORT_NAMES_NOT_ENABLED_ON_VOLUME: WIN32_ERROR = 305u32;
+pub const ERROR_SHUTDOWN_DISKS_NOT_IN_MAINTENANCE_MODE: WIN32_ERROR = 1192u32;
+pub const ERROR_SHUTDOWN_IN_PROGRESS: WIN32_ERROR = 1115u32;
+pub const ERROR_SHUTDOWN_IS_SCHEDULED: WIN32_ERROR = 1190u32;
+pub const ERROR_SHUTDOWN_USERS_LOGGED_ON: WIN32_ERROR = 1191u32;
+pub const ERROR_SIGNAL_PENDING: WIN32_ERROR = 162u32;
+pub const ERROR_SIGNAL_REFUSED: WIN32_ERROR = 156u32;
+pub const ERROR_SINGLE_INSTANCE_APP: WIN32_ERROR = 1152u32;
+pub const ERROR_SMARTCARD_SUBSYSTEM_FAILURE: WIN32_ERROR = 1264u32;
+pub const ERROR_SMB1_NOT_AVAILABLE: WIN32_ERROR = 384u32;
+pub const ERROR_SMB_GUEST_LOGON_BLOCKED: WIN32_ERROR = 1272u32;
+pub const ERROR_SMR_GARBAGE_COLLECTION_REQUIRED: WIN32_ERROR = 4445u32;
+pub const ERROR_SOME_NOT_MAPPED: WIN32_ERROR = 1301u32;
+pub const ERROR_SOURCE_ELEMENT_EMPTY: WIN32_ERROR = 1160u32;
+pub const ERROR_SPARSE_FILE_NOT_SUPPORTED: WIN32_ERROR = 490u32;
+pub const ERROR_SPECIAL_ACCOUNT: WIN32_ERROR = 1371u32;
+pub const ERROR_SPECIAL_GROUP: WIN32_ERROR = 1372u32;
+pub const ERROR_SPECIAL_USER: WIN32_ERROR = 1373u32;
+pub const ERROR_SRC_SRV_DLL_LOAD_FAILED: WIN32_ERROR = 428u32;
+pub const ERROR_STACK_BUFFER_OVERRUN: WIN32_ERROR = 1282u32;
+pub const ERROR_STACK_OVERFLOW: WIN32_ERROR = 1001u32;
+pub const ERROR_STACK_OVERFLOW_READ: WIN32_ERROR = 599u32;
+pub const ERROR_STOPPED_ON_SYMLINK: WIN32_ERROR = 681u32;
+pub const ERROR_STORAGE_LOST_DATA_PERSISTENCE: WIN32_ERROR = 368u32;
+pub const ERROR_STORAGE_RESERVE_ALREADY_EXISTS: WIN32_ERROR = 418u32;
+pub const ERROR_STORAGE_RESERVE_DOES_NOT_EXIST: WIN32_ERROR = 417u32;
+pub const ERROR_STORAGE_RESERVE_ID_INVALID: WIN32_ERROR = 416u32;
+pub const ERROR_STORAGE_RESERVE_NOT_EMPTY: WIN32_ERROR = 419u32;
+pub const ERROR_STORAGE_STACK_ACCESS_DENIED: WIN32_ERROR = 472u32;
+pub const ERROR_STORAGE_TOPOLOGY_ID_MISMATCH: WIN32_ERROR = 345u32;
+pub const ERROR_STRICT_CFG_VIOLATION: WIN32_ERROR = 1657u32;
+pub const ERROR_SUBST_TO_JOIN: WIN32_ERROR = 141u32;
+pub const ERROR_SUBST_TO_SUBST: WIN32_ERROR = 139u32;
+pub const ERROR_SUCCESS: WIN32_ERROR = 0u32;
+pub const ERROR_SUCCESS_REBOOT_INITIATED: WIN32_ERROR = 1641u32;
+pub const ERROR_SWAPERROR: WIN32_ERROR = 999u32;
+pub const ERROR_SYMLINK_CLASS_DISABLED: WIN32_ERROR = 1463u32;
+pub const ERROR_SYMLINK_NOT_SUPPORTED: WIN32_ERROR = 1464u32;
+pub const ERROR_SYNCHRONIZATION_REQUIRED: WIN32_ERROR = 569u32;
+pub const ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED: WIN32_ERROR = 1274u32;
+pub const ERROR_SYSTEM_HIVE_TOO_LARGE: WIN32_ERROR = 653u32;
+pub const ERROR_SYSTEM_IMAGE_BAD_SIGNATURE: WIN32_ERROR = 637u32;
+pub const ERROR_SYSTEM_POWERSTATE_COMPLEX_TRANSITION: WIN32_ERROR = 783u32;
+pub const ERROR_SYSTEM_POWERSTATE_TRANSITION: WIN32_ERROR = 782u32;
+pub const ERROR_SYSTEM_PROCESS_TERMINATED: WIN32_ERROR = 591u32;
+pub const ERROR_SYSTEM_SHUTDOWN: WIN32_ERROR = 641u32;
+pub const ERROR_SYSTEM_TRACE: WIN32_ERROR = 150u32;
+pub const ERROR_THREAD_1_INACTIVE: WIN32_ERROR = 210u32;
+pub const ERROR_THREAD_ALREADY_IN_TASK: WIN32_ERROR = 1552u32;
+pub const ERROR_THREAD_MODE_ALREADY_BACKGROUND: WIN32_ERROR = 400u32;
+pub const ERROR_THREAD_MODE_NOT_BACKGROUND: WIN32_ERROR = 401u32;
+pub const ERROR_THREAD_NOT_IN_PROCESS: WIN32_ERROR = 566u32;
+pub const ERROR_THREAD_WAS_SUSPENDED: WIN32_ERROR = 699u32;
+pub const ERROR_TIMEOUT: WIN32_ERROR = 1460u32;
+pub const ERROR_TIMER_NOT_CANCELED: WIN32_ERROR = 541u32;
+pub const ERROR_TIMER_RESOLUTION_NOT_SET: WIN32_ERROR = 607u32;
+pub const ERROR_TIMER_RESUME_IGNORED: WIN32_ERROR = 722u32;
+pub const ERROR_TIME_SENSITIVE_THREAD: WIN32_ERROR = 422u32;
+pub const ERROR_TIME_SKEW: WIN32_ERROR = 1398u32;
+pub const ERROR_TLW_WITH_WSCHILD: WIN32_ERROR = 1406u32;
+pub const ERROR_TOKEN_ALREADY_IN_USE: WIN32_ERROR = 1375u32;
+pub const ERROR_TOO_MANY_CMDS: WIN32_ERROR = 56u32;
+pub const ERROR_TOO_MANY_CONTEXT_IDS: WIN32_ERROR = 1384u32;
+pub const ERROR_TOO_MANY_DESCRIPTORS: WIN32_ERROR = 331u32;
+pub const ERROR_TOO_MANY_LINKS: WIN32_ERROR = 1142u32;
+pub const ERROR_TOO_MANY_LUIDS_REQUESTED: WIN32_ERROR = 1333u32;
+pub const ERROR_TOO_MANY_MODULES: WIN32_ERROR = 214u32;
+pub const ERROR_TOO_MANY_MUXWAITERS: WIN32_ERROR = 152u32;
+pub const ERROR_TOO_MANY_NAMES: WIN32_ERROR = 68u32;
+pub const ERROR_TOO_MANY_OPEN_FILES: WIN32_ERROR = 4u32;
+pub const ERROR_TOO_MANY_POSTS: WIN32_ERROR = 298u32;
+pub const ERROR_TOO_MANY_SECRETS: WIN32_ERROR = 1381u32;
+pub const ERROR_TOO_MANY_SEMAPHORES: WIN32_ERROR = 100u32;
+pub const ERROR_TOO_MANY_SEM_REQUESTS: WIN32_ERROR = 103u32;
+pub const ERROR_TOO_MANY_SESS: WIN32_ERROR = 69u32;
+pub const ERROR_TOO_MANY_SIDS: WIN32_ERROR = 1389u32;
+pub const ERROR_TOO_MANY_TCBS: WIN32_ERROR = 155u32;
+pub const ERROR_TOO_MANY_THREADS: WIN32_ERROR = 565u32;
+pub const ERROR_TRANSLATION_COMPLETE: WIN32_ERROR = 757u32;
+pub const ERROR_TRUSTED_DOMAIN_FAILURE: WIN32_ERROR = 1788u32;
+pub const ERROR_TRUSTED_RELATIONSHIP_FAILURE: WIN32_ERROR = 1789u32;
+pub const ERROR_TRUST_FAILURE: WIN32_ERROR = 1790u32;
+pub const ERROR_UNABLE_TO_LOCK_MEDIA: WIN32_ERROR = 1108u32;
+pub const ERROR_UNABLE_TO_MOVE_REPLACEMENT: WIN32_ERROR = 1176u32;
+pub const ERROR_UNABLE_TO_MOVE_REPLACEMENT_2: WIN32_ERROR = 1177u32;
+pub const ERROR_UNABLE_TO_REMOVE_REPLACED: WIN32_ERROR = 1175u32;
+pub const ERROR_UNABLE_TO_UNLOAD_MEDIA: WIN32_ERROR = 1109u32;
+pub const ERROR_UNDEFINED_CHARACTER: WIN32_ERROR = 583u32;
+pub const ERROR_UNDEFINED_SCOPE: WIN32_ERROR = 319u32;
+pub const ERROR_UNEXPECTED_MM_CREATE_ERR: WIN32_ERROR = 556u32;
+pub const ERROR_UNEXPECTED_MM_EXTEND_ERR: WIN32_ERROR = 558u32;
+pub const ERROR_UNEXPECTED_MM_MAP_ERROR: WIN32_ERROR = 557u32;
+pub const ERROR_UNEXPECTED_NTCACHEMANAGER_ERROR: WIN32_ERROR = 443u32;
+pub const ERROR_UNEXP_NET_ERR: WIN32_ERROR = 59u32;
+pub const ERROR_UNHANDLED_EXCEPTION: WIN32_ERROR = 574u32;
+pub const ERROR_UNIDENTIFIED_ERROR: WIN32_ERROR = 1287u32;
+pub const ERROR_UNKNOWN_COMPONENT: WIN32_ERROR = 1607u32;
+pub const ERROR_UNKNOWN_FEATURE: WIN32_ERROR = 1606u32;
+pub const ERROR_UNKNOWN_PATCH: WIN32_ERROR = 1647u32;
+pub const ERROR_UNKNOWN_PORT: WIN32_ERROR = 1796u32;
+pub const ERROR_UNKNOWN_PRINTER_DRIVER: WIN32_ERROR = 1797u32;
+pub const ERROR_UNKNOWN_PRINTPROCESSOR: WIN32_ERROR = 1798u32;
+pub const ERROR_UNKNOWN_PRODUCT: WIN32_ERROR = 1605u32;
+pub const ERROR_UNKNOWN_PROPERTY: WIN32_ERROR = 1608u32;
+pub const ERROR_UNKNOWN_REVISION: WIN32_ERROR = 1305u32;
+pub const ERROR_UNRECOGNIZED_MEDIA: WIN32_ERROR = 1785u32;
+pub const ERROR_UNRECOGNIZED_VOLUME: WIN32_ERROR = 1005u32;
+pub const ERROR_UNSATISFIED_DEPENDENCIES: WIN32_ERROR = 441u32;
+pub const ERROR_UNSUPPORTED_COMPRESSION: WIN32_ERROR = 618u32;
+pub const ERROR_UNSUPPORTED_TYPE: WIN32_ERROR = 1630u32;
+pub const ERROR_UNTRUSTED_MOUNT_POINT: WIN32_ERROR = 448u32;
+pub const ERROR_UNWIND: WIN32_ERROR = 542u32;
+pub const ERROR_UNWIND_CONSOLIDATE: WIN32_ERROR = 684u32;
+pub const ERROR_USER_APC: WIN32_ERROR = 737u32;
+pub const ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED: WIN32_ERROR = 1934u32;
+pub const ERROR_USER_EXISTS: WIN32_ERROR = 1316u32;
+pub const ERROR_USER_MAPPED_FILE: WIN32_ERROR = 1224u32;
+pub const ERROR_USER_PROFILE_LOAD: WIN32_ERROR = 500u32;
+pub const ERROR_VALIDATE_CONTINUE: WIN32_ERROR = 625u32;
+pub const ERROR_VC_DISCONNECTED: WIN32_ERROR = 240u32;
+pub const ERROR_VDM_DISALLOWED: WIN32_ERROR = 1286u32;
+pub const ERROR_VDM_HARD_ERROR: WIN32_ERROR = 593u32;
+pub const ERROR_VERIFIER_STOP: WIN32_ERROR = 537u32;
+pub const ERROR_VERSION_PARSE_ERROR: WIN32_ERROR = 777u32;
+pub const ERROR_VIRUS_DELETED: WIN32_ERROR = 226u32;
+pub const ERROR_VIRUS_INFECTED: WIN32_ERROR = 225u32;
+pub const ERROR_VOLSNAP_HIBERNATE_READY: WIN32_ERROR = 761u32;
+pub const ERROR_VOLSNAP_PREPARE_HIBERNATE: WIN32_ERROR = 655u32;
+pub const ERROR_VOLUME_MOUNTED: WIN32_ERROR = 743u32;
+pub const ERROR_VOLUME_NOT_CLUSTER_ALIGNED: WIN32_ERROR = 407u32;
+pub const ERROR_VOLUME_NOT_SIS_ENABLED: WIN32_ERROR = 4500u32;
+pub const ERROR_VOLUME_NOT_SUPPORTED: WIN32_ERROR = 492u32;
+pub const ERROR_VOLUME_NOT_SUPPORT_EFS: WIN32_ERROR = 6014u32;
+pub const ERROR_VOLUME_WRITE_ACCESS_DENIED: WIN32_ERROR = 508u32;
+pub const ERROR_WAIT_1: WIN32_ERROR = 731u32;
+pub const ERROR_WAIT_2: WIN32_ERROR = 732u32;
+pub const ERROR_WAIT_3: WIN32_ERROR = 733u32;
+pub const ERROR_WAIT_63: WIN32_ERROR = 734u32;
+pub const ERROR_WAIT_FOR_OPLOCK: WIN32_ERROR = 765u32;
+pub const ERROR_WAIT_NO_CHILDREN: WIN32_ERROR = 128u32;
+pub const ERROR_WAKE_SYSTEM: WIN32_ERROR = 730u32;
+pub const ERROR_WAKE_SYSTEM_DEBUGGER: WIN32_ERROR = 675u32;
+pub const ERROR_WAS_LOCKED: WIN32_ERROR = 717u32;
+pub const ERROR_WAS_UNLOCKED: WIN32_ERROR = 715u32;
+pub const ERROR_WEAK_WHFBKEY_BLOCKED: WIN32_ERROR = 8651u32;
+pub const ERROR_WINDOW_NOT_COMBOBOX: WIN32_ERROR = 1423u32;
+pub const ERROR_WINDOW_NOT_DIALOG: WIN32_ERROR = 1420u32;
+pub const ERROR_WINDOW_OF_OTHER_THREAD: WIN32_ERROR = 1408u32;
+pub const ERROR_WIP_ENCRYPTION_FAILED: WIN32_ERROR = 6023u32;
+pub const ERROR_WOF_FILE_RESOURCE_TABLE_CORRUPT: WIN32_ERROR = 4448u32;
+pub const ERROR_WOF_WIM_HEADER_CORRUPT: WIN32_ERROR = 4446u32;
+pub const ERROR_WOF_WIM_RESOURCE_TABLE_CORRUPT: WIN32_ERROR = 4447u32;
+pub const ERROR_WORKING_SET_QUOTA: WIN32_ERROR = 1453u32;
+pub const ERROR_WOW_ASSERTION: WIN32_ERROR = 670u32;
+pub const ERROR_WRITE_FAULT: WIN32_ERROR = 29u32;
+pub const ERROR_WRITE_PROTECT: WIN32_ERROR = 19u32;
+pub const ERROR_WRONG_COMPARTMENT: WIN32_ERROR = 1468u32;
+pub const ERROR_WRONG_DISK: WIN32_ERROR = 34u32;
+pub const ERROR_WRONG_EFS: WIN32_ERROR = 6005u32;
+pub const ERROR_WRONG_PASSWORD: WIN32_ERROR = 1323u32;
+pub const ERROR_WRONG_TARGET_NAME: WIN32_ERROR = 1396u32;
+pub const ERROR_WX86_ERROR: WIN32_ERROR = 540u32;
+pub const ERROR_WX86_WARNING: WIN32_ERROR = 539u32;
+pub const ERROR_XMLDSIG_ERROR: WIN32_ERROR = 1466u32;
+pub const ERROR_XML_PARSE_ERROR: WIN32_ERROR = 1465u32;
+pub type EXCEPTION_DISPOSITION = i32;
+pub const EXCEPTION_MAXIMUM_PARAMETERS: u32 = 15u32;
+#[repr(C)]
+pub struct EXCEPTION_POINTERS {
+ pub ExceptionRecord: *mut EXCEPTION_RECORD,
+ pub ContextRecord: *mut CONTEXT,
+}
+impl ::core::marker::Copy for EXCEPTION_POINTERS {}
+impl ::core::clone::Clone for EXCEPTION_POINTERS {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub struct EXCEPTION_RECORD {
+ pub ExceptionCode: NTSTATUS,
+ pub ExceptionFlags: u32,
+ pub ExceptionRecord: *mut EXCEPTION_RECORD,
+ pub ExceptionAddress: *mut ::core::ffi::c_void,
+ pub NumberParameters: u32,
+ pub ExceptionInformation: [usize; 15],
+}
+impl ::core::marker::Copy for EXCEPTION_RECORD {}
+impl ::core::clone::Clone for EXCEPTION_RECORD {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const EXCEPTION_STACK_OVERFLOW: NTSTATUS = -1073741571i32;
+pub const EXTENDED_STARTUPINFO_PRESENT: PROCESS_CREATION_FLAGS = 524288u32;
+pub const E_NOTIMPL: HRESULT = -2147467263i32;
+pub const ExceptionCollidedUnwind: EXCEPTION_DISPOSITION = 3i32;
+pub const ExceptionContinueExecution: EXCEPTION_DISPOSITION = 0i32;
+pub const ExceptionContinueSearch: EXCEPTION_DISPOSITION = 1i32;
+pub const ExceptionNestedException: EXCEPTION_DISPOSITION = 2i32;
+pub type FACILITY_CODE = u32;
+pub const FACILITY_NT_BIT: FACILITY_CODE = 268435456u32;
+pub const FALSE: BOOL = 0i32;
+pub type FARPROC = ::core::option::Option<unsafe extern "system" fn() -> isize>;
+#[repr(C)]
+pub struct FD_SET {
+ pub fd_count: u32,
+ pub fd_array: [SOCKET; 64],
+}
+impl ::core::marker::Copy for FD_SET {}
+impl ::core::clone::Clone for FD_SET {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub struct FILETIME {
+ pub dwLowDateTime: u32,
+ pub dwHighDateTime: u32,
+}
+impl ::core::marker::Copy for FILETIME {}
+impl ::core::clone::Clone for FILETIME {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub type FILE_ACCESS_RIGHTS = u32;
+pub const FILE_ADD_FILE: FILE_ACCESS_RIGHTS = 2u32;
+pub const FILE_ADD_SUBDIRECTORY: FILE_ACCESS_RIGHTS = 4u32;
+pub const FILE_ALL_ACCESS: FILE_ACCESS_RIGHTS = 2032127u32;
+pub const FILE_APPEND_DATA: FILE_ACCESS_RIGHTS = 4u32;
+pub const FILE_ATTRIBUTE_ARCHIVE: FILE_FLAGS_AND_ATTRIBUTES = 32u32;
+pub const FILE_ATTRIBUTE_COMPRESSED: FILE_FLAGS_AND_ATTRIBUTES = 2048u32;
+pub const FILE_ATTRIBUTE_DEVICE: FILE_FLAGS_AND_ATTRIBUTES = 64u32;
+pub const FILE_ATTRIBUTE_DIRECTORY: FILE_FLAGS_AND_ATTRIBUTES = 16u32;
+pub const FILE_ATTRIBUTE_EA: FILE_FLAGS_AND_ATTRIBUTES = 262144u32;
+pub const FILE_ATTRIBUTE_ENCRYPTED: FILE_FLAGS_AND_ATTRIBUTES = 16384u32;
+pub const FILE_ATTRIBUTE_HIDDEN: FILE_FLAGS_AND_ATTRIBUTES = 2u32;
+pub const FILE_ATTRIBUTE_INTEGRITY_STREAM: FILE_FLAGS_AND_ATTRIBUTES = 32768u32;
+pub const FILE_ATTRIBUTE_NORMAL: FILE_FLAGS_AND_ATTRIBUTES = 128u32;
+pub const FILE_ATTRIBUTE_NOT_CONTENT_INDEXED: FILE_FLAGS_AND_ATTRIBUTES = 8192u32;
+pub const FILE_ATTRIBUTE_NO_SCRUB_DATA: FILE_FLAGS_AND_ATTRIBUTES = 131072u32;
+pub const FILE_ATTRIBUTE_OFFLINE: FILE_FLAGS_AND_ATTRIBUTES = 4096u32;
+pub const FILE_ATTRIBUTE_PINNED: FILE_FLAGS_AND_ATTRIBUTES = 524288u32;
+pub const FILE_ATTRIBUTE_READONLY: FILE_FLAGS_AND_ATTRIBUTES = 1u32;
+pub const FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS: FILE_FLAGS_AND_ATTRIBUTES = 4194304u32;
+pub const FILE_ATTRIBUTE_RECALL_ON_OPEN: FILE_FLAGS_AND_ATTRIBUTES = 262144u32;
+pub const FILE_ATTRIBUTE_REPARSE_POINT: FILE_FLAGS_AND_ATTRIBUTES = 1024u32;
+pub const FILE_ATTRIBUTE_SPARSE_FILE: FILE_FLAGS_AND_ATTRIBUTES = 512u32;
+pub const FILE_ATTRIBUTE_SYSTEM: FILE_FLAGS_AND_ATTRIBUTES = 4u32;
+#[repr(C)]
+pub struct FILE_ATTRIBUTE_TAG_INFO {
+ pub FileAttributes: u32,
+ pub ReparseTag: u32,
+}
+impl ::core::marker::Copy for FILE_ATTRIBUTE_TAG_INFO {}
+impl ::core::clone::Clone for FILE_ATTRIBUTE_TAG_INFO {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const FILE_ATTRIBUTE_TEMPORARY: FILE_FLAGS_AND_ATTRIBUTES = 256u32;
+pub const FILE_ATTRIBUTE_UNPINNED: FILE_FLAGS_AND_ATTRIBUTES = 1048576u32;
+pub const FILE_ATTRIBUTE_VIRTUAL: FILE_FLAGS_AND_ATTRIBUTES = 65536u32;
+#[repr(C)]
+pub struct FILE_BASIC_INFO {
+ pub CreationTime: i64,
+ pub LastAccessTime: i64,
+ pub LastWriteTime: i64,
+ pub ChangeTime: i64,
+ pub FileAttributes: u32,
+}
+impl ::core::marker::Copy for FILE_BASIC_INFO {}
+impl ::core::clone::Clone for FILE_BASIC_INFO {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const FILE_BEGIN: SET_FILE_POINTER_MOVE_METHOD = 0u32;
+pub const FILE_COMPLETE_IF_OPLOCKED: NTCREATEFILE_CREATE_OPTIONS = 256u32;
+pub const FILE_CONTAINS_EXTENDED_CREATE_INFORMATION: NTCREATEFILE_CREATE_OPTIONS = 268435456u32;
+pub const FILE_CREATE: NTCREATEFILE_CREATE_DISPOSITION = 2u32;
+pub const FILE_CREATE_PIPE_INSTANCE: FILE_ACCESS_RIGHTS = 4u32;
+pub const FILE_CREATE_TREE_CONNECTION: NTCREATEFILE_CREATE_OPTIONS = 128u32;
+pub type FILE_CREATION_DISPOSITION = u32;
+pub const FILE_CURRENT: SET_FILE_POINTER_MOVE_METHOD = 1u32;
+pub const FILE_DELETE_CHILD: FILE_ACCESS_RIGHTS = 64u32;
+pub const FILE_DELETE_ON_CLOSE: NTCREATEFILE_CREATE_OPTIONS = 4096u32;
+pub const FILE_DIRECTORY_FILE: NTCREATEFILE_CREATE_OPTIONS = 1u32;
+pub const FILE_DISALLOW_EXCLUSIVE: NTCREATEFILE_CREATE_OPTIONS = 131072u32;
+pub const FILE_DISPOSITION_FLAG_DELETE: FILE_DISPOSITION_INFO_EX_FLAGS = 1u32;
+pub const FILE_DISPOSITION_FLAG_DO_NOT_DELETE: FILE_DISPOSITION_INFO_EX_FLAGS = 0u32;
+pub const FILE_DISPOSITION_FLAG_FORCE_IMAGE_SECTION_CHECK: FILE_DISPOSITION_INFO_EX_FLAGS = 4u32;
+pub const FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE: FILE_DISPOSITION_INFO_EX_FLAGS = 16u32;
+pub const FILE_DISPOSITION_FLAG_ON_CLOSE: FILE_DISPOSITION_INFO_EX_FLAGS = 8u32;
+pub const FILE_DISPOSITION_FLAG_POSIX_SEMANTICS: FILE_DISPOSITION_INFO_EX_FLAGS = 2u32;
+#[repr(C)]
+pub struct FILE_DISPOSITION_INFO {
+ pub DeleteFile: BOOLEAN,
+}
+impl ::core::marker::Copy for FILE_DISPOSITION_INFO {}
+impl ::core::clone::Clone for FILE_DISPOSITION_INFO {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub struct FILE_DISPOSITION_INFO_EX {
+ pub Flags: FILE_DISPOSITION_INFO_EX_FLAGS,
+}
+impl ::core::marker::Copy for FILE_DISPOSITION_INFO_EX {}
+impl ::core::clone::Clone for FILE_DISPOSITION_INFO_EX {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub type FILE_DISPOSITION_INFO_EX_FLAGS = u32;
+pub const FILE_END: SET_FILE_POINTER_MOVE_METHOD = 2u32;
+#[repr(C)]
+pub struct FILE_END_OF_FILE_INFO {
+ pub EndOfFile: i64,
+}
+impl ::core::marker::Copy for FILE_END_OF_FILE_INFO {}
+impl ::core::clone::Clone for FILE_END_OF_FILE_INFO {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const FILE_EXECUTE: FILE_ACCESS_RIGHTS = 32u32;
+pub type FILE_FLAGS_AND_ATTRIBUTES = u32;
+pub const FILE_FLAG_BACKUP_SEMANTICS: FILE_FLAGS_AND_ATTRIBUTES = 33554432u32;
+pub const FILE_FLAG_DELETE_ON_CLOSE: FILE_FLAGS_AND_ATTRIBUTES = 67108864u32;
+pub const FILE_FLAG_FIRST_PIPE_INSTANCE: FILE_FLAGS_AND_ATTRIBUTES = 524288u32;
+pub const FILE_FLAG_NO_BUFFERING: FILE_FLAGS_AND_ATTRIBUTES = 536870912u32;
+pub const FILE_FLAG_OPEN_NO_RECALL: FILE_FLAGS_AND_ATTRIBUTES = 1048576u32;
+pub const FILE_FLAG_OPEN_REPARSE_POINT: FILE_FLAGS_AND_ATTRIBUTES = 2097152u32;
+pub const FILE_FLAG_OVERLAPPED: FILE_FLAGS_AND_ATTRIBUTES = 1073741824u32;
+pub const FILE_FLAG_POSIX_SEMANTICS: FILE_FLAGS_AND_ATTRIBUTES = 16777216u32;
+pub const FILE_FLAG_RANDOM_ACCESS: FILE_FLAGS_AND_ATTRIBUTES = 268435456u32;
+pub const FILE_FLAG_SEQUENTIAL_SCAN: FILE_FLAGS_AND_ATTRIBUTES = 134217728u32;
+pub const FILE_FLAG_SESSION_AWARE: FILE_FLAGS_AND_ATTRIBUTES = 8388608u32;
+pub const FILE_FLAG_WRITE_THROUGH: FILE_FLAGS_AND_ATTRIBUTES = 2147483648u32;
+pub const FILE_GENERIC_EXECUTE: FILE_ACCESS_RIGHTS = 1179808u32;
+pub const FILE_GENERIC_READ: FILE_ACCESS_RIGHTS = 1179785u32;
+pub const FILE_GENERIC_WRITE: FILE_ACCESS_RIGHTS = 1179926u32;
+#[repr(C)]
+pub struct FILE_ID_BOTH_DIR_INFO {
+ pub NextEntryOffset: u32,
+ pub FileIndex: u32,
+ pub CreationTime: i64,
+ pub LastAccessTime: i64,
+ pub LastWriteTime: i64,
+ pub ChangeTime: i64,
+ pub EndOfFile: i64,
+ pub AllocationSize: i64,
+ pub FileAttributes: u32,
+ pub FileNameLength: u32,
+ pub EaSize: u32,
+ pub ShortNameLength: i8,
+ pub ShortName: [u16; 12],
+ pub FileId: i64,
+ pub FileName: [u16; 1],
+}
+impl ::core::marker::Copy for FILE_ID_BOTH_DIR_INFO {}
+impl ::core::clone::Clone for FILE_ID_BOTH_DIR_INFO {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub type FILE_INFO_BY_HANDLE_CLASS = i32;
+pub const FILE_LIST_DIRECTORY: FILE_ACCESS_RIGHTS = 1u32;
+pub const FILE_NAME_NORMALIZED: GETFINALPATHNAMEBYHANDLE_FLAGS = 0u32;
+pub const FILE_NAME_OPENED: GETFINALPATHNAMEBYHANDLE_FLAGS = 8u32;
+pub const FILE_NON_DIRECTORY_FILE: NTCREATEFILE_CREATE_OPTIONS = 64u32;
+pub const FILE_NO_COMPRESSION: NTCREATEFILE_CREATE_OPTIONS = 32768u32;
+pub const FILE_NO_EA_KNOWLEDGE: NTCREATEFILE_CREATE_OPTIONS = 512u32;
+pub const FILE_NO_INTERMEDIATE_BUFFERING: NTCREATEFILE_CREATE_OPTIONS = 8u32;
+pub const FILE_OPEN: NTCREATEFILE_CREATE_DISPOSITION = 1u32;
+pub const FILE_OPEN_BY_FILE_ID: NTCREATEFILE_CREATE_OPTIONS = 8192u32;
+pub const FILE_OPEN_FOR_BACKUP_INTENT: NTCREATEFILE_CREATE_OPTIONS = 16384u32;
+pub const FILE_OPEN_FOR_FREE_SPACE_QUERY: NTCREATEFILE_CREATE_OPTIONS = 8388608u32;
+pub const FILE_OPEN_IF: NTCREATEFILE_CREATE_DISPOSITION = 3u32;
+pub const FILE_OPEN_NO_RECALL: NTCREATEFILE_CREATE_OPTIONS = 4194304u32;
+pub const FILE_OPEN_REPARSE_POINT: NTCREATEFILE_CREATE_OPTIONS = 2097152u32;
+pub const FILE_OPEN_REQUIRING_OPLOCK: NTCREATEFILE_CREATE_OPTIONS = 65536u32;
+pub const FILE_OVERWRITE: NTCREATEFILE_CREATE_DISPOSITION = 4u32;
+pub const FILE_OVERWRITE_IF: NTCREATEFILE_CREATE_DISPOSITION = 5u32;
+pub const FILE_RANDOM_ACCESS: NTCREATEFILE_CREATE_OPTIONS = 2048u32;
+pub const FILE_READ_ATTRIBUTES: FILE_ACCESS_RIGHTS = 128u32;
+pub const FILE_READ_DATA: FILE_ACCESS_RIGHTS = 1u32;
+pub const FILE_READ_EA: FILE_ACCESS_RIGHTS = 8u32;
+pub const FILE_RESERVE_OPFILTER: NTCREATEFILE_CREATE_OPTIONS = 1048576u32;
+pub const FILE_SEQUENTIAL_ONLY: NTCREATEFILE_CREATE_OPTIONS = 4u32;
+pub const FILE_SESSION_AWARE: NTCREATEFILE_CREATE_OPTIONS = 262144u32;
+pub const FILE_SHARE_DELETE: FILE_SHARE_MODE = 4u32;
+pub type FILE_SHARE_MODE = u32;
+pub const FILE_SHARE_NONE: FILE_SHARE_MODE = 0u32;
+pub const FILE_SHARE_READ: FILE_SHARE_MODE = 1u32;
+pub const FILE_SHARE_WRITE: FILE_SHARE_MODE = 2u32;
+#[repr(C)]
+pub struct FILE_STANDARD_INFO {
+ pub AllocationSize: i64,
+ pub EndOfFile: i64,
+ pub NumberOfLinks: u32,
+ pub DeletePending: BOOLEAN,
+ pub Directory: BOOLEAN,
+}
+impl ::core::marker::Copy for FILE_STANDARD_INFO {}
+impl ::core::clone::Clone for FILE_STANDARD_INFO {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const FILE_SUPERSEDE: NTCREATEFILE_CREATE_DISPOSITION = 0u32;
+pub const FILE_SYNCHRONOUS_IO_ALERT: NTCREATEFILE_CREATE_OPTIONS = 16u32;
+pub const FILE_SYNCHRONOUS_IO_NONALERT: NTCREATEFILE_CREATE_OPTIONS = 32u32;
+pub const FILE_TRAVERSE: FILE_ACCESS_RIGHTS = 32u32;
+pub type FILE_TYPE = u32;
+pub const FILE_TYPE_CHAR: FILE_TYPE = 2u32;
+pub const FILE_TYPE_DISK: FILE_TYPE = 1u32;
+pub const FILE_TYPE_PIPE: FILE_TYPE = 3u32;
+pub const FILE_TYPE_REMOTE: FILE_TYPE = 32768u32;
+pub const FILE_TYPE_UNKNOWN: FILE_TYPE = 0u32;
+pub const FILE_WRITE_ATTRIBUTES: FILE_ACCESS_RIGHTS = 256u32;
+pub const FILE_WRITE_DATA: FILE_ACCESS_RIGHTS = 2u32;
+pub const FILE_WRITE_EA: FILE_ACCESS_RIGHTS = 16u32;
+pub const FILE_WRITE_THROUGH: NTCREATEFILE_CREATE_OPTIONS = 2u32;
+pub const FIONBIO: i32 = -2147195266i32;
+#[repr(C)]
+#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+pub struct FLOATING_SAVE_AREA {
+ pub ControlWord: u32,
+ pub StatusWord: u32,
+ pub TagWord: u32,
+ pub ErrorOffset: u32,
+ pub ErrorSelector: u32,
+ pub DataOffset: u32,
+ pub DataSelector: u32,
+ pub RegisterArea: [u8; 80],
+ pub Cr0NpxState: u32,
+}
+#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+impl ::core::marker::Copy for FLOATING_SAVE_AREA {}
+#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+impl ::core::clone::Clone for FLOATING_SAVE_AREA {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+#[cfg(target_arch = "x86")]
+pub struct FLOATING_SAVE_AREA {
+ pub ControlWord: u32,
+ pub StatusWord: u32,
+ pub TagWord: u32,
+ pub ErrorOffset: u32,
+ pub ErrorSelector: u32,
+ pub DataOffset: u32,
+ pub DataSelector: u32,
+ pub RegisterArea: [u8; 80],
+ pub Spare0: u32,
+}
+#[cfg(target_arch = "x86")]
+impl ::core::marker::Copy for FLOATING_SAVE_AREA {}
+#[cfg(target_arch = "x86")]
+impl ::core::clone::Clone for FLOATING_SAVE_AREA {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const FORMAT_MESSAGE_ALLOCATE_BUFFER: FORMAT_MESSAGE_OPTIONS = 256u32;
+pub const FORMAT_MESSAGE_ARGUMENT_ARRAY: FORMAT_MESSAGE_OPTIONS = 8192u32;
+pub const FORMAT_MESSAGE_FROM_HMODULE: FORMAT_MESSAGE_OPTIONS = 2048u32;
+pub const FORMAT_MESSAGE_FROM_STRING: FORMAT_MESSAGE_OPTIONS = 1024u32;
+pub const FORMAT_MESSAGE_FROM_SYSTEM: FORMAT_MESSAGE_OPTIONS = 4096u32;
+pub const FORMAT_MESSAGE_IGNORE_INSERTS: FORMAT_MESSAGE_OPTIONS = 512u32;
+pub type FORMAT_MESSAGE_OPTIONS = u32;
+pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: i32 = 8014i32;
+pub const FSCTL_GET_REPARSE_POINT: u32 = 589992u32;
+pub const FSCTL_SET_REPARSE_POINT: u32 = 589988u32;
+pub const FileAlignmentInfo: FILE_INFO_BY_HANDLE_CLASS = 17i32;
+pub const FileAllocationInfo: FILE_INFO_BY_HANDLE_CLASS = 5i32;
+pub const FileAttributeTagInfo: FILE_INFO_BY_HANDLE_CLASS = 9i32;
+pub const FileBasicInfo: FILE_INFO_BY_HANDLE_CLASS = 0i32;
+pub const FileCaseSensitiveInfo: FILE_INFO_BY_HANDLE_CLASS = 23i32;
+pub const FileCompressionInfo: FILE_INFO_BY_HANDLE_CLASS = 8i32;
+pub const FileDispositionInfo: FILE_INFO_BY_HANDLE_CLASS = 4i32;
+pub const FileDispositionInfoEx: FILE_INFO_BY_HANDLE_CLASS = 21i32;
+pub const FileEndOfFileInfo: FILE_INFO_BY_HANDLE_CLASS = 6i32;
+pub const FileFullDirectoryInfo: FILE_INFO_BY_HANDLE_CLASS = 14i32;
+pub const FileFullDirectoryRestartInfo: FILE_INFO_BY_HANDLE_CLASS = 15i32;
+pub const FileIdBothDirectoryInfo: FILE_INFO_BY_HANDLE_CLASS = 10i32;
+pub const FileIdBothDirectoryRestartInfo: FILE_INFO_BY_HANDLE_CLASS = 11i32;
+pub const FileIdExtdDirectoryInfo: FILE_INFO_BY_HANDLE_CLASS = 19i32;
+pub const FileIdExtdDirectoryRestartInfo: FILE_INFO_BY_HANDLE_CLASS = 20i32;
+pub const FileIdInfo: FILE_INFO_BY_HANDLE_CLASS = 18i32;
+pub const FileIoPriorityHintInfo: FILE_INFO_BY_HANDLE_CLASS = 12i32;
+pub const FileNameInfo: FILE_INFO_BY_HANDLE_CLASS = 2i32;
+pub const FileNormalizedNameInfo: FILE_INFO_BY_HANDLE_CLASS = 24i32;
+pub const FileRemoteProtocolInfo: FILE_INFO_BY_HANDLE_CLASS = 13i32;
+pub const FileRenameInfo: FILE_INFO_BY_HANDLE_CLASS = 3i32;
+pub const FileRenameInfoEx: FILE_INFO_BY_HANDLE_CLASS = 22i32;
+pub const FileStandardInfo: FILE_INFO_BY_HANDLE_CLASS = 1i32;
+pub const FileStorageInfo: FILE_INFO_BY_HANDLE_CLASS = 16i32;
+pub const FileStreamInfo: FILE_INFO_BY_HANDLE_CLASS = 7i32;
+pub type FindFileHandle = *mut ::core::ffi::c_void;
+pub type GENERIC_ACCESS_RIGHTS = u32;
+pub const GENERIC_ALL: GENERIC_ACCESS_RIGHTS = 268435456u32;
+pub const GENERIC_EXECUTE: GENERIC_ACCESS_RIGHTS = 536870912u32;
+pub const GENERIC_READ: GENERIC_ACCESS_RIGHTS = 2147483648u32;
+pub const GENERIC_WRITE: GENERIC_ACCESS_RIGHTS = 1073741824u32;
+pub type GETFINALPATHNAMEBYHANDLE_FLAGS = u32;
+#[repr(C)]
+pub struct GUID {
+ pub data1: u32,
+ pub data2: u16,
+ pub data3: u16,
+ pub data4: [u8; 8],
+}
+impl GUID {
+ pub const fn from_u128(uuid: u128) -> Self {
+ Self {
+ data1: (uuid >> 96) as u32,
+ data2: (uuid >> 80 & 0xffff) as u16,
+ data3: (uuid >> 64 & 0xffff) as u16,
+ data4: (uuid as u64).to_be_bytes(),
+ }
+ }
+}
+impl ::core::marker::Copy for GUID {}
+impl ::core::clone::Clone for GUID {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub type HANDLE = *mut ::core::ffi::c_void;
+pub type HANDLE_FLAGS = u32;
+pub const HANDLE_FLAG_INHERIT: HANDLE_FLAGS = 1u32;
+pub const HANDLE_FLAG_PROTECT_FROM_CLOSE: HANDLE_FLAGS = 2u32;
+pub const HIGH_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 128u32;
+pub type HMODULE = *mut ::core::ffi::c_void;
+pub type HRESULT = i32;
+pub const IDLE_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 64u32;
+#[repr(C)]
+pub struct IN6_ADDR {
+ pub u: IN6_ADDR_0,
+}
+impl ::core::marker::Copy for IN6_ADDR {}
+impl ::core::clone::Clone for IN6_ADDR {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub union IN6_ADDR_0 {
+ pub Byte: [u8; 16],
+ pub Word: [u16; 8],
+}
+impl ::core::marker::Copy for IN6_ADDR_0 {}
+impl ::core::clone::Clone for IN6_ADDR_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const INFINITE: u32 = 4294967295u32;
+pub const INHERIT_CALLER_PRIORITY: PROCESS_CREATION_FLAGS = 131072u32;
+pub const INHERIT_PARENT_AFFINITY: PROCESS_CREATION_FLAGS = 65536u32;
+pub const INIT_ONCE_INIT_FAILED: u32 = 4u32;
+pub const INVALID_FILE_ATTRIBUTES: u32 = 4294967295u32;
+pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::invalid_mut(-1i32 as _);
+pub const INVALID_SOCKET: SOCKET = -1i32 as _;
+#[repr(C)]
+pub struct IN_ADDR {
+ pub S_un: IN_ADDR_0,
+}
+impl ::core::marker::Copy for IN_ADDR {}
+impl ::core::clone::Clone for IN_ADDR {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub union IN_ADDR_0 {
+ pub S_un_b: IN_ADDR_0_0,
+ pub S_un_w: IN_ADDR_0_1,
+ pub S_addr: u32,
+}
+impl ::core::marker::Copy for IN_ADDR_0 {}
+impl ::core::clone::Clone for IN_ADDR_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub struct IN_ADDR_0_0 {
+ pub s_b1: u8,
+ pub s_b2: u8,
+ pub s_b3: u8,
+ pub s_b4: u8,
+}
+impl ::core::marker::Copy for IN_ADDR_0_0 {}
+impl ::core::clone::Clone for IN_ADDR_0_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub struct IN_ADDR_0_1 {
+ pub s_w1: u16,
+ pub s_w2: u16,
+}
+impl ::core::marker::Copy for IN_ADDR_0_1 {}
+impl ::core::clone::Clone for IN_ADDR_0_1 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const IO_REPARSE_TAG_MOUNT_POINT: u32 = 2684354563u32;
+pub const IO_REPARSE_TAG_SYMLINK: u32 = 2684354572u32;
+#[repr(C)]
+pub struct IO_STATUS_BLOCK {
+ pub Anonymous: IO_STATUS_BLOCK_0,
+ pub Information: usize,
+}
+impl ::core::marker::Copy for IO_STATUS_BLOCK {}
+impl ::core::clone::Clone for IO_STATUS_BLOCK {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub union IO_STATUS_BLOCK_0 {
+ pub Status: NTSTATUS,
+ pub Pointer: *mut ::core::ffi::c_void,
+}
+impl ::core::marker::Copy for IO_STATUS_BLOCK_0 {}
+impl ::core::clone::Clone for IO_STATUS_BLOCK_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub type IPPROTO = i32;
+pub const IPPROTO_AH: IPPROTO = 51i32;
+pub const IPPROTO_CBT: IPPROTO = 7i32;
+pub const IPPROTO_DSTOPTS: IPPROTO = 60i32;
+pub const IPPROTO_EGP: IPPROTO = 8i32;
+pub const IPPROTO_ESP: IPPROTO = 50i32;
+pub const IPPROTO_FRAGMENT: IPPROTO = 44i32;
+pub const IPPROTO_GGP: IPPROTO = 3i32;
+pub const IPPROTO_HOPOPTS: IPPROTO = 0i32;
+pub const IPPROTO_ICLFXBM: IPPROTO = 78i32;
+pub const IPPROTO_ICMP: IPPROTO = 1i32;
+pub const IPPROTO_ICMPV6: IPPROTO = 58i32;
+pub const IPPROTO_IDP: IPPROTO = 22i32;
+pub const IPPROTO_IGMP: IPPROTO = 2i32;
+pub const IPPROTO_IGP: IPPROTO = 9i32;
+pub const IPPROTO_IP: IPPROTO = 0i32;
+pub const IPPROTO_IPV4: IPPROTO = 4i32;
+pub const IPPROTO_IPV6: IPPROTO = 41i32;
+pub const IPPROTO_L2TP: IPPROTO = 115i32;
+pub const IPPROTO_MAX: IPPROTO = 256i32;
+pub const IPPROTO_ND: IPPROTO = 77i32;
+pub const IPPROTO_NONE: IPPROTO = 59i32;
+pub const IPPROTO_PGM: IPPROTO = 113i32;
+pub const IPPROTO_PIM: IPPROTO = 103i32;
+pub const IPPROTO_PUP: IPPROTO = 12i32;
+pub const IPPROTO_RAW: IPPROTO = 255i32;
+pub const IPPROTO_RDP: IPPROTO = 27i32;
+pub const IPPROTO_RESERVED_IPSEC: IPPROTO = 258i32;
+pub const IPPROTO_RESERVED_IPSECOFFLOAD: IPPROTO = 259i32;
+pub const IPPROTO_RESERVED_MAX: IPPROTO = 261i32;
+pub const IPPROTO_RESERVED_RAW: IPPROTO = 257i32;
+pub const IPPROTO_RESERVED_WNV: IPPROTO = 260i32;
+pub const IPPROTO_RM: IPPROTO = 113i32;
+pub const IPPROTO_ROUTING: IPPROTO = 43i32;
+pub const IPPROTO_SCTP: IPPROTO = 132i32;
+pub const IPPROTO_ST: IPPROTO = 5i32;
+pub const IPPROTO_TCP: IPPROTO = 6i32;
+pub const IPPROTO_UDP: IPPROTO = 17i32;
+pub const IPV6_ADD_MEMBERSHIP: i32 = 12i32;
+pub const IPV6_DROP_MEMBERSHIP: i32 = 13i32;
+#[repr(C)]
+pub struct IPV6_MREQ {
+ pub ipv6mr_multiaddr: IN6_ADDR,
+ pub ipv6mr_interface: u32,
+}
+impl ::core::marker::Copy for IPV6_MREQ {}
+impl ::core::clone::Clone for IPV6_MREQ {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const IPV6_MULTICAST_LOOP: i32 = 11i32;
+pub const IPV6_V6ONLY: i32 = 27i32;
+pub const IP_ADD_MEMBERSHIP: i32 = 12i32;
+pub const IP_DROP_MEMBERSHIP: i32 = 13i32;
+#[repr(C)]
+pub struct IP_MREQ {
+ pub imr_multiaddr: IN_ADDR,
+ pub imr_interface: IN_ADDR,
+}
+impl ::core::marker::Copy for IP_MREQ {}
+impl ::core::clone::Clone for IP_MREQ {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const IP_MULTICAST_LOOP: i32 = 11i32;
+pub const IP_MULTICAST_TTL: i32 = 10i32;
+pub const IP_TTL: i32 = 4i32;
+#[repr(C)]
+pub struct LINGER {
+ pub l_onoff: u16,
+ pub l_linger: u16,
+}
+impl ::core::marker::Copy for LINGER {}
+impl ::core::clone::Clone for LINGER {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub type LPOVERLAPPED_COMPLETION_ROUTINE = ::core::option::Option<
+ unsafe extern "system" fn(
+ dwerrorcode: u32,
+ dwnumberofbytestransfered: u32,
+ lpoverlapped: *mut OVERLAPPED,
+ ) -> (),
+>;
+pub type LPPROGRESS_ROUTINE = ::core::option::Option<
+ unsafe extern "system" fn(
+ totalfilesize: i64,
+ totalbytestransferred: i64,
+ streamsize: i64,
+ streambytestransferred: i64,
+ dwstreamnumber: u32,
+ dwcallbackreason: LPPROGRESS_ROUTINE_CALLBACK_REASON,
+ hsourcefile: HANDLE,
+ hdestinationfile: HANDLE,
+ lpdata: *const ::core::ffi::c_void,
+ ) -> u32,
+>;
+pub type LPPROGRESS_ROUTINE_CALLBACK_REASON = u32;
+pub type LPTHREAD_START_ROUTINE = ::core::option::Option<
+ unsafe extern "system" fn(lpthreadparameter: *mut ::core::ffi::c_void) -> u32,
+>;
+pub type LPWSAOVERLAPPED_COMPLETION_ROUTINE = ::core::option::Option<
+ unsafe extern "system" fn(
+ dwerror: u32,
+ cbtransferred: u32,
+ lpoverlapped: *mut OVERLAPPED,
+ dwflags: u32,
+ ) -> (),
+>;
+#[repr(C)]
+pub struct M128A {
+ pub Low: u64,
+ pub High: i64,
+}
+impl ::core::marker::Copy for M128A {}
+impl ::core::clone::Clone for M128A {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: u32 = 16384u32;
+pub const MAX_PATH: u32 = 260u32;
+pub const MB_COMPOSITE: MULTI_BYTE_TO_WIDE_CHAR_FLAGS = 2u32;
+pub const MB_ERR_INVALID_CHARS: MULTI_BYTE_TO_WIDE_CHAR_FLAGS = 8u32;
+pub const MB_PRECOMPOSED: MULTI_BYTE_TO_WIDE_CHAR_FLAGS = 1u32;
+pub const MB_USEGLYPHCHARS: MULTI_BYTE_TO_WIDE_CHAR_FLAGS = 4u32;
+pub const MOVEFILE_COPY_ALLOWED: MOVE_FILE_FLAGS = 2u32;
+pub const MOVEFILE_CREATE_HARDLINK: MOVE_FILE_FLAGS = 16u32;
+pub const MOVEFILE_DELAY_UNTIL_REBOOT: MOVE_FILE_FLAGS = 4u32;
+pub const MOVEFILE_FAIL_IF_NOT_TRACKABLE: MOVE_FILE_FLAGS = 32u32;
+pub const MOVEFILE_REPLACE_EXISTING: MOVE_FILE_FLAGS = 1u32;
+pub const MOVEFILE_WRITE_THROUGH: MOVE_FILE_FLAGS = 8u32;
+pub type MOVE_FILE_FLAGS = u32;
+pub const MSG_DONTROUTE: SEND_RECV_FLAGS = 4i32;
+pub const MSG_OOB: SEND_RECV_FLAGS = 1i32;
+pub const MSG_PEEK: SEND_RECV_FLAGS = 2i32;
+pub const MSG_PUSH_IMMEDIATE: SEND_RECV_FLAGS = 32i32;
+pub const MSG_WAITALL: SEND_RECV_FLAGS = 8i32;
+pub type MULTI_BYTE_TO_WIDE_CHAR_FLAGS = u32;
+pub const MaximumFileInfoByHandleClass: FILE_INFO_BY_HANDLE_CLASS = 25i32;
+pub type NAMED_PIPE_MODE = u32;
+pub const NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 32u32;
+pub const NO_ERROR: WIN32_ERROR = 0u32;
+pub type NTCREATEFILE_CREATE_DISPOSITION = u32;
+pub type NTCREATEFILE_CREATE_OPTIONS = u32;
+pub type NTSTATUS = i32;
+#[repr(C)]
+pub struct OBJECT_ATTRIBUTES {
+ pub Length: u32,
+ pub RootDirectory: HANDLE,
+ pub ObjectName: *mut UNICODE_STRING,
+ pub Attributes: u32,
+ pub SecurityDescriptor: *mut ::core::ffi::c_void,
+ pub SecurityQualityOfService: *mut ::core::ffi::c_void,
+}
+impl ::core::marker::Copy for OBJECT_ATTRIBUTES {}
+impl ::core::clone::Clone for OBJECT_ATTRIBUTES {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const OBJ_DONT_REPARSE: i32 = 4096i32;
+pub const OPEN_ALWAYS: FILE_CREATION_DISPOSITION = 4u32;
+pub const OPEN_EXISTING: FILE_CREATION_DISPOSITION = 3u32;
+#[repr(C)]
+pub struct OVERLAPPED {
+ pub Internal: usize,
+ pub InternalHigh: usize,
+ pub Anonymous: OVERLAPPED_0,
+ pub hEvent: HANDLE,
+}
+impl ::core::marker::Copy for OVERLAPPED {}
+impl ::core::clone::Clone for OVERLAPPED {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub union OVERLAPPED_0 {
+ pub Anonymous: OVERLAPPED_0_0,
+ pub Pointer: *mut ::core::ffi::c_void,
+}
+impl ::core::marker::Copy for OVERLAPPED_0 {}
+impl ::core::clone::Clone for OVERLAPPED_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub struct OVERLAPPED_0_0 {
+ pub Offset: u32,
+ pub OffsetHigh: u32,
+}
+impl ::core::marker::Copy for OVERLAPPED_0_0 {}
+impl ::core::clone::Clone for OVERLAPPED_0_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub type PCSTR = *const u8;
+pub type PCWSTR = *const u16;
+pub type PIO_APC_ROUTINE = ::core::option::Option<
+ unsafe extern "system" fn(
+ apccontext: *const ::core::ffi::c_void,
+ iostatusblock: *const IO_STATUS_BLOCK,
+ reserved: u32,
+ ) -> (),
+>;
+pub const PIPE_ACCEPT_REMOTE_CLIENTS: NAMED_PIPE_MODE = 0u32;
+pub const PIPE_ACCESS_DUPLEX: FILE_FLAGS_AND_ATTRIBUTES = 3u32;
+pub const PIPE_ACCESS_INBOUND: FILE_FLAGS_AND_ATTRIBUTES = 1u32;
+pub const PIPE_ACCESS_OUTBOUND: FILE_FLAGS_AND_ATTRIBUTES = 2u32;
+pub const PIPE_CLIENT_END: NAMED_PIPE_MODE = 0u32;
+pub const PIPE_NOWAIT: NAMED_PIPE_MODE = 1u32;
+pub const PIPE_READMODE_BYTE: NAMED_PIPE_MODE = 0u32;
+pub const PIPE_READMODE_MESSAGE: NAMED_PIPE_MODE = 2u32;
+pub const PIPE_REJECT_REMOTE_CLIENTS: NAMED_PIPE_MODE = 8u32;
+pub const PIPE_SERVER_END: NAMED_PIPE_MODE = 1u32;
+pub const PIPE_TYPE_BYTE: NAMED_PIPE_MODE = 0u32;
+pub const PIPE_TYPE_MESSAGE: NAMED_PIPE_MODE = 4u32;
+pub const PIPE_WAIT: NAMED_PIPE_MODE = 0u32;
+pub type PROCESSOR_ARCHITECTURE = u16;
+pub type PROCESS_CREATION_FLAGS = u32;
+#[repr(C)]
+pub struct PROCESS_INFORMATION {
+ pub hProcess: HANDLE,
+ pub hThread: HANDLE,
+ pub dwProcessId: u32,
+ pub dwThreadId: u32,
+}
+impl ::core::marker::Copy for PROCESS_INFORMATION {}
+impl ::core::clone::Clone for PROCESS_INFORMATION {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const PROCESS_MODE_BACKGROUND_BEGIN: PROCESS_CREATION_FLAGS = 1048576u32;
+pub const PROCESS_MODE_BACKGROUND_END: PROCESS_CREATION_FLAGS = 2097152u32;
+pub const PROFILE_KERNEL: PROCESS_CREATION_FLAGS = 536870912u32;
+pub const PROFILE_SERVER: PROCESS_CREATION_FLAGS = 1073741824u32;
+pub const PROFILE_USER: PROCESS_CREATION_FLAGS = 268435456u32;
+pub const PROGRESS_CONTINUE: u32 = 0u32;
+pub type PSTR = *mut u8;
+pub type PVECTORED_EXCEPTION_HANDLER = ::core::option::Option<
+ unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32,
+>;
+pub type PWSTR = *mut u16;
+pub const READ_CONTROL: FILE_ACCESS_RIGHTS = 131072u32;
+pub const REALTIME_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 256u32;
+#[repr(C)]
+pub struct RTL_CONDITION_VARIABLE {
+ pub Ptr: *mut ::core::ffi::c_void,
+}
+impl ::core::marker::Copy for RTL_CONDITION_VARIABLE {}
+impl ::core::clone::Clone for RTL_CONDITION_VARIABLE {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub union RTL_RUN_ONCE {
+ pub Ptr: *mut ::core::ffi::c_void,
+}
+impl ::core::marker::Copy for RTL_RUN_ONCE {}
+impl ::core::clone::Clone for RTL_RUN_ONCE {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub struct RTL_SRWLOCK {
+ pub Ptr: *mut ::core::ffi::c_void,
+}
+impl ::core::marker::Copy for RTL_SRWLOCK {}
+impl ::core::clone::Clone for RTL_SRWLOCK {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const SD_BOTH: WINSOCK_SHUTDOWN_HOW = 2i32;
+pub const SD_RECEIVE: WINSOCK_SHUTDOWN_HOW = 0i32;
+pub const SD_SEND: WINSOCK_SHUTDOWN_HOW = 1i32;
+pub const SECURITY_ANONYMOUS: FILE_FLAGS_AND_ATTRIBUTES = 0u32;
+#[repr(C)]
+pub struct SECURITY_ATTRIBUTES {
+ pub nLength: u32,
+ pub lpSecurityDescriptor: *mut ::core::ffi::c_void,
+ pub bInheritHandle: BOOL,
+}
+impl ::core::marker::Copy for SECURITY_ATTRIBUTES {}
+impl ::core::clone::Clone for SECURITY_ATTRIBUTES {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const SECURITY_CONTEXT_TRACKING: FILE_FLAGS_AND_ATTRIBUTES = 262144u32;
+pub const SECURITY_DELEGATION: FILE_FLAGS_AND_ATTRIBUTES = 196608u32;
+pub const SECURITY_EFFECTIVE_ONLY: FILE_FLAGS_AND_ATTRIBUTES = 524288u32;
+pub const SECURITY_IDENTIFICATION: FILE_FLAGS_AND_ATTRIBUTES = 65536u32;
+pub const SECURITY_IMPERSONATION: FILE_FLAGS_AND_ATTRIBUTES = 131072u32;
+pub const SECURITY_SQOS_PRESENT: FILE_FLAGS_AND_ATTRIBUTES = 1048576u32;
+pub const SECURITY_VALID_SQOS_FLAGS: FILE_FLAGS_AND_ATTRIBUTES = 2031616u32;
+pub type SEND_RECV_FLAGS = i32;
+pub type SET_FILE_POINTER_MOVE_METHOD = u32;
+#[repr(C)]
+pub struct SOCKADDR {
+ pub sa_family: ADDRESS_FAMILY,
+ pub sa_data: [u8; 14],
+}
+impl ::core::marker::Copy for SOCKADDR {}
+impl ::core::clone::Clone for SOCKADDR {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[cfg(target_pointer_width = "32")]
+pub type SOCKET = u32;
+#[cfg(target_pointer_width = "64")]
+pub type SOCKET = u64;
+pub const SOCKET_ERROR: i32 = -1i32;
+pub const SOCK_DGRAM: WINSOCK_SOCKET_TYPE = 2i32;
+pub const SOCK_RAW: WINSOCK_SOCKET_TYPE = 3i32;
+pub const SOCK_RDM: WINSOCK_SOCKET_TYPE = 4i32;
+pub const SOCK_SEQPACKET: WINSOCK_SOCKET_TYPE = 5i32;
+pub const SOCK_STREAM: WINSOCK_SOCKET_TYPE = 1i32;
+pub const SOL_SOCKET: i32 = 65535i32;
+pub const SO_BROADCAST: i32 = 32i32;
+pub const SO_ERROR: i32 = 4103i32;
+pub const SO_LINGER: i32 = 128i32;
+pub const SO_RCVTIMEO: i32 = 4102i32;
+pub const SO_SNDTIMEO: i32 = 4101i32;
+pub const SPECIFIC_RIGHTS_ALL: FILE_ACCESS_RIGHTS = 65535u32;
+pub const STACK_SIZE_PARAM_IS_A_RESERVATION: THREAD_CREATION_FLAGS = 65536u32;
+pub const STANDARD_RIGHTS_ALL: FILE_ACCESS_RIGHTS = 2031616u32;
+pub const STANDARD_RIGHTS_EXECUTE: FILE_ACCESS_RIGHTS = 131072u32;
+pub const STANDARD_RIGHTS_READ: FILE_ACCESS_RIGHTS = 131072u32;
+pub const STANDARD_RIGHTS_REQUIRED: FILE_ACCESS_RIGHTS = 983040u32;
+pub const STANDARD_RIGHTS_WRITE: FILE_ACCESS_RIGHTS = 131072u32;
+pub const STARTF_FORCEOFFFEEDBACK: STARTUPINFOW_FLAGS = 128u32;
+pub const STARTF_FORCEONFEEDBACK: STARTUPINFOW_FLAGS = 64u32;
+pub const STARTF_PREVENTPINNING: STARTUPINFOW_FLAGS = 8192u32;
+pub const STARTF_RUNFULLSCREEN: STARTUPINFOW_FLAGS = 32u32;
+pub const STARTF_TITLEISAPPID: STARTUPINFOW_FLAGS = 4096u32;
+pub const STARTF_TITLEISLINKNAME: STARTUPINFOW_FLAGS = 2048u32;
+pub const STARTF_UNTRUSTEDSOURCE: STARTUPINFOW_FLAGS = 32768u32;
+pub const STARTF_USECOUNTCHARS: STARTUPINFOW_FLAGS = 8u32;
+pub const STARTF_USEFILLATTRIBUTE: STARTUPINFOW_FLAGS = 16u32;
+pub const STARTF_USEHOTKEY: STARTUPINFOW_FLAGS = 512u32;
+pub const STARTF_USEPOSITION: STARTUPINFOW_FLAGS = 4u32;
+pub const STARTF_USESHOWWINDOW: STARTUPINFOW_FLAGS = 1u32;
+pub const STARTF_USESIZE: STARTUPINFOW_FLAGS = 2u32;
+pub const STARTF_USESTDHANDLES: STARTUPINFOW_FLAGS = 256u32;
+#[repr(C)]
+pub struct STARTUPINFOW {
+ pub cb: u32,
+ pub lpReserved: PWSTR,
+ pub lpDesktop: PWSTR,
+ pub lpTitle: PWSTR,
+ pub dwX: u32,
+ pub dwY: u32,
+ pub dwXSize: u32,
+ pub dwYSize: u32,
+ pub dwXCountChars: u32,
+ pub dwYCountChars: u32,
+ pub dwFillAttribute: u32,
+ pub dwFlags: STARTUPINFOW_FLAGS,
+ pub wShowWindow: u16,
+ pub cbReserved2: u16,
+ pub lpReserved2: *mut u8,
+ pub hStdInput: HANDLE,
+ pub hStdOutput: HANDLE,
+ pub hStdError: HANDLE,
+}
+impl ::core::marker::Copy for STARTUPINFOW {}
+impl ::core::clone::Clone for STARTUPINFOW {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub type STARTUPINFOW_FLAGS = u32;
+pub const STATUS_DELETE_PENDING: NTSTATUS = -1073741738i32;
+pub const STATUS_END_OF_FILE: NTSTATUS = -1073741807i32;
+pub const STATUS_INVALID_PARAMETER: NTSTATUS = -1073741811i32;
+pub const STATUS_PENDING: NTSTATUS = 259i32;
+pub const STATUS_SUCCESS: NTSTATUS = 0i32;
+pub const STD_ERROR_HANDLE: STD_HANDLE = 4294967284u32;
+pub type STD_HANDLE = u32;
+pub const STD_INPUT_HANDLE: STD_HANDLE = 4294967286u32;
+pub const STD_OUTPUT_HANDLE: STD_HANDLE = 4294967285u32;
+pub type SYMBOLIC_LINK_FLAGS = u32;
+pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: SYMBOLIC_LINK_FLAGS = 2u32;
+pub const SYMBOLIC_LINK_FLAG_DIRECTORY: SYMBOLIC_LINK_FLAGS = 1u32;
+pub const SYMLINK_FLAG_RELATIVE: u32 = 1u32;
+pub const SYNCHRONIZE: FILE_ACCESS_RIGHTS = 1048576u32;
+#[repr(C)]
+pub struct SYSTEM_INFO {
+ pub Anonymous: SYSTEM_INFO_0,
+ pub dwPageSize: u32,
+ pub lpMinimumApplicationAddress: *mut ::core::ffi::c_void,
+ pub lpMaximumApplicationAddress: *mut ::core::ffi::c_void,
+ pub dwActiveProcessorMask: usize,
+ pub dwNumberOfProcessors: u32,
+ pub dwProcessorType: u32,
+ pub dwAllocationGranularity: u32,
+ pub wProcessorLevel: u16,
+ pub wProcessorRevision: u16,
+}
+impl ::core::marker::Copy for SYSTEM_INFO {}
+impl ::core::clone::Clone for SYSTEM_INFO {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub union SYSTEM_INFO_0 {
+ pub dwOemId: u32,
+ pub Anonymous: SYSTEM_INFO_0_0,
+}
+impl ::core::marker::Copy for SYSTEM_INFO_0 {}
+impl ::core::clone::Clone for SYSTEM_INFO_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub struct SYSTEM_INFO_0_0 {
+ pub wProcessorArchitecture: PROCESSOR_ARCHITECTURE,
+ pub wReserved: u16,
+}
+impl ::core::marker::Copy for SYSTEM_INFO_0_0 {}
+impl ::core::clone::Clone for SYSTEM_INFO_0_0 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const TCP_NODELAY: i32 = 1i32;
+pub const THREAD_CREATE_RUN_IMMEDIATELY: THREAD_CREATION_FLAGS = 0u32;
+pub const THREAD_CREATE_SUSPENDED: THREAD_CREATION_FLAGS = 4u32;
+pub type THREAD_CREATION_FLAGS = u32;
+#[repr(C)]
+pub struct TIMEVAL {
+ pub tv_sec: i32,
+ pub tv_usec: i32,
+}
+impl ::core::marker::Copy for TIMEVAL {}
+impl ::core::clone::Clone for TIMEVAL {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const TLS_OUT_OF_INDEXES: u32 = 4294967295u32;
+pub type TOKEN_ACCESS_MASK = u32;
+pub const TOKEN_ACCESS_PSEUDO_HANDLE: TOKEN_ACCESS_MASK = 24u32;
+pub const TOKEN_ACCESS_PSEUDO_HANDLE_WIN8: TOKEN_ACCESS_MASK = 24u32;
+pub const TOKEN_ACCESS_SYSTEM_SECURITY: TOKEN_ACCESS_MASK = 16777216u32;
+pub const TOKEN_ADJUST_DEFAULT: TOKEN_ACCESS_MASK = 128u32;
+pub const TOKEN_ADJUST_GROUPS: TOKEN_ACCESS_MASK = 64u32;
+pub const TOKEN_ADJUST_PRIVILEGES: TOKEN_ACCESS_MASK = 32u32;
+pub const TOKEN_ADJUST_SESSIONID: TOKEN_ACCESS_MASK = 256u32;
+pub const TOKEN_ALL_ACCESS: TOKEN_ACCESS_MASK = 983551u32;
+pub const TOKEN_ASSIGN_PRIMARY: TOKEN_ACCESS_MASK = 1u32;
+pub const TOKEN_DELETE: TOKEN_ACCESS_MASK = 65536u32;
+pub const TOKEN_DUPLICATE: TOKEN_ACCESS_MASK = 2u32;
+pub const TOKEN_EXECUTE: TOKEN_ACCESS_MASK = 131072u32;
+pub const TOKEN_IMPERSONATE: TOKEN_ACCESS_MASK = 4u32;
+pub const TOKEN_QUERY: TOKEN_ACCESS_MASK = 8u32;
+pub const TOKEN_QUERY_SOURCE: TOKEN_ACCESS_MASK = 16u32;
+pub const TOKEN_READ: TOKEN_ACCESS_MASK = 131080u32;
+pub const TOKEN_READ_CONTROL: TOKEN_ACCESS_MASK = 131072u32;
+pub const TOKEN_TRUST_CONSTRAINT_MASK: TOKEN_ACCESS_MASK = 131096u32;
+pub const TOKEN_WRITE: TOKEN_ACCESS_MASK = 131296u32;
+pub const TOKEN_WRITE_DAC: TOKEN_ACCESS_MASK = 262144u32;
+pub const TOKEN_WRITE_OWNER: TOKEN_ACCESS_MASK = 524288u32;
+pub const TRUE: BOOL = 1i32;
+pub const TRUNCATE_EXISTING: FILE_CREATION_DISPOSITION = 5u32;
+#[repr(C)]
+pub struct UNICODE_STRING {
+ pub Length: u16,
+ pub MaximumLength: u16,
+ pub Buffer: PWSTR,
+}
+impl ::core::marker::Copy for UNICODE_STRING {}
+impl ::core::clone::Clone for UNICODE_STRING {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const VOLUME_NAME_DOS: GETFINALPATHNAMEBYHANDLE_FLAGS = 0u32;
+pub const VOLUME_NAME_GUID: GETFINALPATHNAMEBYHANDLE_FLAGS = 1u32;
+pub const VOLUME_NAME_NONE: GETFINALPATHNAMEBYHANDLE_FLAGS = 4u32;
+pub const WAIT_ABANDONED: WIN32_ERROR = 128u32;
+pub const WAIT_ABANDONED_0: WIN32_ERROR = 128u32;
+pub const WAIT_FAILED: WIN32_ERROR = 4294967295u32;
+pub const WAIT_IO_COMPLETION: WIN32_ERROR = 192u32;
+pub const WAIT_OBJECT_0: WIN32_ERROR = 0u32;
+pub const WAIT_TIMEOUT: WIN32_ERROR = 258u32;
+pub const WC_ERR_INVALID_CHARS: u32 = 128u32;
+pub type WIN32_ERROR = u32;
+#[repr(C)]
+pub struct WIN32_FIND_DATAW {
+ pub dwFileAttributes: u32,
+ pub ftCreationTime: FILETIME,
+ pub ftLastAccessTime: FILETIME,
+ pub ftLastWriteTime: FILETIME,
+ pub nFileSizeHigh: u32,
+ pub nFileSizeLow: u32,
+ pub dwReserved0: u32,
+ pub dwReserved1: u32,
+ pub cFileName: [u16; 260],
+ pub cAlternateFileName: [u16; 14],
+}
+impl ::core::marker::Copy for WIN32_FIND_DATAW {}
+impl ::core::clone::Clone for WIN32_FIND_DATAW {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub type WINSOCK_SHUTDOWN_HOW = i32;
+pub type WINSOCK_SOCKET_TYPE = i32;
+pub const WRITE_DAC: FILE_ACCESS_RIGHTS = 262144u32;
+pub const WRITE_OWNER: FILE_ACCESS_RIGHTS = 524288u32;
+pub const WSABASEERR: WSA_ERROR = 10000i32;
+#[repr(C)]
+pub struct WSABUF {
+ pub len: u32,
+ pub buf: PSTR,
+}
+impl ::core::marker::Copy for WSABUF {}
+impl ::core::clone::Clone for WSABUF {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+pub struct WSADATA {
+ pub wVersion: u16,
+ pub wHighVersion: u16,
+ pub iMaxSockets: u16,
+ pub iMaxUdpDg: u16,
+ pub lpVendorInfo: PSTR,
+ pub szDescription: [u8; 257],
+ pub szSystemStatus: [u8; 129],
+}
+#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+impl ::core::marker::Copy for WSADATA {}
+#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+impl ::core::clone::Clone for WSADATA {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+#[cfg(target_arch = "x86")]
+pub struct WSADATA {
+ pub wVersion: u16,
+ pub wHighVersion: u16,
+ pub szDescription: [u8; 257],
+ pub szSystemStatus: [u8; 129],
+ pub iMaxSockets: u16,
+ pub iMaxUdpDg: u16,
+ pub lpVendorInfo: PSTR,
+}
+#[cfg(target_arch = "x86")]
+impl ::core::marker::Copy for WSADATA {}
+#[cfg(target_arch = "x86")]
+impl ::core::clone::Clone for WSADATA {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const WSAEACCES: WSA_ERROR = 10013i32;
+pub const WSAEADDRINUSE: WSA_ERROR = 10048i32;
+pub const WSAEADDRNOTAVAIL: WSA_ERROR = 10049i32;
+pub const WSAEAFNOSUPPORT: WSA_ERROR = 10047i32;
+pub const WSAEALREADY: WSA_ERROR = 10037i32;
+pub const WSAEBADF: WSA_ERROR = 10009i32;
+pub const WSAECANCELLED: WSA_ERROR = 10103i32;
+pub const WSAECONNABORTED: WSA_ERROR = 10053i32;
+pub const WSAECONNREFUSED: WSA_ERROR = 10061i32;
+pub const WSAECONNRESET: WSA_ERROR = 10054i32;
+pub const WSAEDESTADDRREQ: WSA_ERROR = 10039i32;
+pub const WSAEDISCON: WSA_ERROR = 10101i32;
+pub const WSAEDQUOT: WSA_ERROR = 10069i32;
+pub const WSAEFAULT: WSA_ERROR = 10014i32;
+pub const WSAEHOSTDOWN: WSA_ERROR = 10064i32;
+pub const WSAEHOSTUNREACH: WSA_ERROR = 10065i32;
+pub const WSAEINPROGRESS: WSA_ERROR = 10036i32;
+pub const WSAEINTR: WSA_ERROR = 10004i32;
+pub const WSAEINVAL: WSA_ERROR = 10022i32;
+pub const WSAEINVALIDPROCTABLE: WSA_ERROR = 10104i32;
+pub const WSAEINVALIDPROVIDER: WSA_ERROR = 10105i32;
+pub const WSAEISCONN: WSA_ERROR = 10056i32;
+pub const WSAELOOP: WSA_ERROR = 10062i32;
+pub const WSAEMFILE: WSA_ERROR = 10024i32;
+pub const WSAEMSGSIZE: WSA_ERROR = 10040i32;
+pub const WSAENAMETOOLONG: WSA_ERROR = 10063i32;
+pub const WSAENETDOWN: WSA_ERROR = 10050i32;
+pub const WSAENETRESET: WSA_ERROR = 10052i32;
+pub const WSAENETUNREACH: WSA_ERROR = 10051i32;
+pub const WSAENOBUFS: WSA_ERROR = 10055i32;
+pub const WSAENOMORE: WSA_ERROR = 10102i32;
+pub const WSAENOPROTOOPT: WSA_ERROR = 10042i32;
+pub const WSAENOTCONN: WSA_ERROR = 10057i32;
+pub const WSAENOTEMPTY: WSA_ERROR = 10066i32;
+pub const WSAENOTSOCK: WSA_ERROR = 10038i32;
+pub const WSAEOPNOTSUPP: WSA_ERROR = 10045i32;
+pub const WSAEPFNOSUPPORT: WSA_ERROR = 10046i32;
+pub const WSAEPROCLIM: WSA_ERROR = 10067i32;
+pub const WSAEPROTONOSUPPORT: WSA_ERROR = 10043i32;
+pub const WSAEPROTOTYPE: WSA_ERROR = 10041i32;
+pub const WSAEPROVIDERFAILEDINIT: WSA_ERROR = 10106i32;
+pub const WSAEREFUSED: WSA_ERROR = 10112i32;
+pub const WSAEREMOTE: WSA_ERROR = 10071i32;
+pub const WSAESHUTDOWN: WSA_ERROR = 10058i32;
+pub const WSAESOCKTNOSUPPORT: WSA_ERROR = 10044i32;
+pub const WSAESTALE: WSA_ERROR = 10070i32;
+pub const WSAETIMEDOUT: WSA_ERROR = 10060i32;
+pub const WSAETOOMANYREFS: WSA_ERROR = 10059i32;
+pub const WSAEUSERS: WSA_ERROR = 10068i32;
+pub const WSAEWOULDBLOCK: WSA_ERROR = 10035i32;
+pub const WSAHOST_NOT_FOUND: WSA_ERROR = 11001i32;
+pub const WSANOTINITIALISED: WSA_ERROR = 10093i32;
+pub const WSANO_DATA: WSA_ERROR = 11004i32;
+pub const WSANO_RECOVERY: WSA_ERROR = 11003i32;
+#[repr(C)]
+pub struct WSAPROTOCOLCHAIN {
+ pub ChainLen: i32,
+ pub ChainEntries: [u32; 7],
+}
+impl ::core::marker::Copy for WSAPROTOCOLCHAIN {}
+impl ::core::clone::Clone for WSAPROTOCOLCHAIN {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+pub struct WSAPROTOCOL_INFOW {
+ pub dwServiceFlags1: u32,
+ pub dwServiceFlags2: u32,
+ pub dwServiceFlags3: u32,
+ pub dwServiceFlags4: u32,
+ pub dwProviderFlags: u32,
+ pub ProviderId: GUID,
+ pub dwCatalogEntryId: u32,
+ pub ProtocolChain: WSAPROTOCOLCHAIN,
+ pub iVersion: i32,
+ pub iAddressFamily: i32,
+ pub iMaxSockAddr: i32,
+ pub iMinSockAddr: i32,
+ pub iSocketType: i32,
+ pub iProtocol: i32,
+ pub iProtocolMaxOffset: i32,
+ pub iNetworkByteOrder: i32,
+ pub iSecurityScheme: i32,
+ pub dwMessageSize: u32,
+ pub dwProviderReserved: u32,
+ pub szProtocol: [u16; 256],
+}
+impl ::core::marker::Copy for WSAPROTOCOL_INFOW {}
+impl ::core::clone::Clone for WSAPROTOCOL_INFOW {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub const WSASERVICE_NOT_FOUND: WSA_ERROR = 10108i32;
+pub const WSASYSCALLFAILURE: WSA_ERROR = 10107i32;
+pub const WSASYSNOTREADY: WSA_ERROR = 10091i32;
+pub const WSATRY_AGAIN: WSA_ERROR = 11002i32;
+pub const WSATYPE_NOT_FOUND: WSA_ERROR = 10109i32;
+pub const WSAVERNOTSUPPORTED: WSA_ERROR = 10092i32;
+pub type WSA_ERROR = i32;
+pub const WSA_E_CANCELLED: WSA_ERROR = 10111i32;
+pub const WSA_E_NO_MORE: WSA_ERROR = 10110i32;
+pub const WSA_FLAG_NO_HANDLE_INHERIT: u32 = 128u32;
+pub const WSA_FLAG_OVERLAPPED: u32 = 1u32;
+pub const WSA_INVALID_HANDLE: WSA_ERROR = 6i32;
+pub const WSA_INVALID_PARAMETER: WSA_ERROR = 87i32;
+pub const WSA_IO_INCOMPLETE: WSA_ERROR = 996i32;
+pub const WSA_IO_PENDING: WSA_ERROR = 997i32;
+pub const WSA_IPSEC_NAME_POLICY_ERROR: WSA_ERROR = 11033i32;
+pub const WSA_NOT_ENOUGH_MEMORY: WSA_ERROR = 8i32;
+pub const WSA_OPERATION_ABORTED: WSA_ERROR = 995i32;
+pub const WSA_QOS_ADMISSION_FAILURE: WSA_ERROR = 11010i32;
+pub const WSA_QOS_BAD_OBJECT: WSA_ERROR = 11013i32;
+pub const WSA_QOS_BAD_STYLE: WSA_ERROR = 11012i32;
+pub const WSA_QOS_EFILTERCOUNT: WSA_ERROR = 11021i32;
+pub const WSA_QOS_EFILTERSTYLE: WSA_ERROR = 11019i32;
+pub const WSA_QOS_EFILTERTYPE: WSA_ERROR = 11020i32;
+pub const WSA_QOS_EFLOWCOUNT: WSA_ERROR = 11023i32;
+pub const WSA_QOS_EFLOWDESC: WSA_ERROR = 11026i32;
+pub const WSA_QOS_EFLOWSPEC: WSA_ERROR = 11017i32;
+pub const WSA_QOS_EOBJLENGTH: WSA_ERROR = 11022i32;
+pub const WSA_QOS_EPOLICYOBJ: WSA_ERROR = 11025i32;
+pub const WSA_QOS_EPROVSPECBUF: WSA_ERROR = 11018i32;
+pub const WSA_QOS_EPSFILTERSPEC: WSA_ERROR = 11028i32;
+pub const WSA_QOS_EPSFLOWSPEC: WSA_ERROR = 11027i32;
+pub const WSA_QOS_ESDMODEOBJ: WSA_ERROR = 11029i32;
+pub const WSA_QOS_ESERVICETYPE: WSA_ERROR = 11016i32;
+pub const WSA_QOS_ESHAPERATEOBJ: WSA_ERROR = 11030i32;
+pub const WSA_QOS_EUNKOWNPSOBJ: WSA_ERROR = 11024i32;
+pub const WSA_QOS_GENERIC_ERROR: WSA_ERROR = 11015i32;
+pub const WSA_QOS_NO_RECEIVERS: WSA_ERROR = 11008i32;
+pub const WSA_QOS_NO_SENDERS: WSA_ERROR = 11007i32;
+pub const WSA_QOS_POLICY_FAILURE: WSA_ERROR = 11011i32;
+pub const WSA_QOS_RECEIVERS: WSA_ERROR = 11005i32;
+pub const WSA_QOS_REQUEST_CONFIRMED: WSA_ERROR = 11009i32;
+pub const WSA_QOS_RESERVED_PETYPE: WSA_ERROR = 11031i32;
+pub const WSA_QOS_SENDERS: WSA_ERROR = 11006i32;
+pub const WSA_QOS_TRAFFIC_CTRL_ERROR: WSA_ERROR = 11014i32;
+pub const WSA_SECURE_HOST_NOT_FOUND: WSA_ERROR = 11032i32;
+pub const WSA_WAIT_EVENT_0: WSA_ERROR = 0i32;
+pub const WSA_WAIT_IO_COMPLETION: WSA_ERROR = 192i32;
+#[repr(C)]
+#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+pub struct XSAVE_FORMAT {
+ pub ControlWord: u16,
+ pub StatusWord: u16,
+ pub TagWord: u8,
+ pub Reserved1: u8,
+ pub ErrorOpcode: u16,
+ pub ErrorOffset: u32,
+ pub ErrorSelector: u16,
+ pub Reserved2: u16,
+ pub DataOffset: u32,
+ pub DataSelector: u16,
+ pub Reserved3: u16,
+ pub MxCsr: u32,
+ pub MxCsr_Mask: u32,
+ pub FloatRegisters: [M128A; 8],
+ pub XmmRegisters: [M128A; 16],
+ pub Reserved4: [u8; 96],
+}
+#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+impl ::core::marker::Copy for XSAVE_FORMAT {}
+#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+impl ::core::clone::Clone for XSAVE_FORMAT {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
+#[cfg(target_arch = "x86")]
+pub struct XSAVE_FORMAT {
+ pub ControlWord: u16,
+ pub StatusWord: u16,
+ pub TagWord: u8,
+ pub Reserved1: u8,
+ pub ErrorOpcode: u16,
+ pub ErrorOffset: u32,
+ pub ErrorSelector: u16,
+ pub Reserved2: u16,
+ pub DataOffset: u32,
+ pub DataSelector: u16,
+ pub Reserved3: u16,
+ pub MxCsr: u32,
+ pub MxCsr_Mask: u32,
+ pub FloatRegisters: [M128A; 8],
+ pub XmmRegisters: [M128A; 8],
+ pub Reserved4: [u8; 224],
+}
+#[cfg(target_arch = "x86")]
+impl ::core::marker::Copy for XSAVE_FORMAT {}
+#[cfg(target_arch = "x86")]
+impl ::core::clone::Clone for XSAVE_FORMAT {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
diff --git a/library/std/src/sys/windows/compat.rs b/library/std/src/sys/windows/compat.rs
index 7dff81ecb8d..4fe95d41116 100644
--- a/library/std/src/sys/windows/compat.rs
+++ b/library/std/src/sys/windows/compat.rs
@@ -114,17 +114,20 @@ impl Module {
/// (e.g. kernel32 and ntdll).
pub unsafe fn new(name: &CStr) -> Option<Self> {
// SAFETY: A CStr is always null terminated.
- let module = c::GetModuleHandleA(name.as_ptr());
+ let module = c::GetModuleHandleA(name.as_ptr().cast::<u8>());
NonNull::new(module).map(Self)
}
// Try to get the address of a function.
pub fn proc_address(self, name: &CStr) -> Option<NonNull<c_void>> {
- // SAFETY:
- // `self.0` will always be a valid module.
- // A CStr is always null terminated.
- let proc = unsafe { c::GetProcAddress(self.0.as_ptr(), name.as_ptr()) };
- NonNull::new(proc)
+ unsafe {
+ // SAFETY:
+ // `self.0` will always be a valid module.
+ // A CStr is always null terminated.
+ let proc = c::GetProcAddress(self.0.as_ptr(), name.as_ptr().cast::<u8>());
+ // SAFETY: `GetProcAddress` returns None on null.
+ proc.map(|p| NonNull::new_unchecked(p as *mut c_void))
+ }
}
}
@@ -199,6 +202,7 @@ macro_rules! compat_fn_optional {
)+) => (
$(
pub mod $symbol {
+ #[allow(unused_imports)]
use super::*;
use crate::ffi::c_void;
use crate::mem;
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs
index fe052c8281b..ce427766d17 100644
--- a/library/std/src/sys/windows/fs.rs
+++ b/library/std/src/sys/windows/fs.rs
@@ -89,6 +89,12 @@ pub struct FileTimes {
accessed: Option<c::FILETIME>,
modified: Option<c::FILETIME>,
}
+impl core::fmt::Debug for c::FILETIME {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let time = ((self.dwHighDateTime as u64) << 32) | self.dwLowDateTime as u64;
+ f.debug_tuple("FILETIME").field(&time).finish()
+ }
+}
#[derive(Debug)]
pub struct DirBuilder;
@@ -290,6 +296,7 @@ impl File {
ptr::null_mut(),
)
};
+ let handle = unsafe { HandleOrInvalid::from_raw_handle(handle) };
if let Ok(handle) = handle.try_into() {
Ok(File { handle: Handle::from_inner(handle) })
} else {
@@ -501,7 +508,8 @@ impl File {
}
fn readlink(&self) -> io::Result<PathBuf> {
- let mut space = Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
+ let mut space =
+ Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]);
let (_bytes, buf) = self.reparse_point(&mut space)?;
unsafe {
let (path_buffer, subst_off, subst_len, relative) = match (*buf).ReparseTag {
@@ -589,7 +597,11 @@ impl File {
));
}
cvt(unsafe {
- c::SetFileTime(self.as_handle(), None, times.accessed.as_ref(), times.modified.as_ref())
+ let accessed =
+ times.accessed.as_ref().map(|a| a as *const c::FILETIME).unwrap_or(ptr::null());
+ let modified =
+ times.modified.as_ref().map(|a| a as *const c::FILETIME).unwrap_or(ptr::null());
+ c::SetFileTime(self.as_raw_handle(), ptr::null_mut(), accessed, modified)
})?;
Ok(())
}
@@ -618,9 +630,9 @@ impl File {
/// then errors will be `ERROR_NOT_SUPPORTED` or `ERROR_INVALID_PARAMETER`.
fn posix_delete(&self) -> io::Result<()> {
let mut info = c::FILE_DISPOSITION_INFO_EX {
- Flags: c::FILE_DISPOSITION_DELETE
- | c::FILE_DISPOSITION_POSIX_SEMANTICS
- | c::FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE,
+ Flags: c::FILE_DISPOSITION_FLAG_DELETE
+ | c::FILE_DISPOSITION_FLAG_POSIX_SEMANTICS
+ | c::FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE,
};
let size = mem::size_of_val(&info);
cvt(unsafe {
@@ -791,15 +803,15 @@ fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result<
// See https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntcreatefile
unsafe {
let mut handle = ptr::null_mut();
- let mut io_status = c::IO_STATUS_BLOCK::default();
- let name_str = c::UNICODE_STRING::from_ref(name);
+ let mut io_status = c::IO_STATUS_BLOCK::PENDING;
+ let mut name_str = c::UNICODE_STRING::from_ref(name);
use crate::sync::atomic::{AtomicU32, Ordering};
// The `OBJ_DONT_REPARSE` attribute ensures that we haven't been
// tricked into following a symlink. However, it may not be available in
// earlier versions of Windows.
static ATTRIBUTES: AtomicU32 = AtomicU32::new(c::OBJ_DONT_REPARSE);
- let object = c::OBJECT_ATTRIBUTES {
- ObjectName: &name_str,
+ let mut object = c::OBJECT_ATTRIBUTES {
+ ObjectName: &mut name_str,
RootDirectory: parent.as_raw_handle(),
Attributes: ATTRIBUTES.load(Ordering::Relaxed),
..c::OBJECT_ATTRIBUTES::default()
@@ -807,7 +819,7 @@ fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result<
let status = c::NtCreateFile(
&mut handle,
access,
- &object,
+ &mut object,
&mut io_status,
crate::ptr::null_mut(),
0,
@@ -1368,7 +1380,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
_dwCallbackReason: c::DWORD,
_hSourceFile: c::HANDLE,
_hDestinationFile: c::HANDLE,
- lpData: c::LPVOID,
+ lpData: c::LPCVOID,
) -> c::DWORD {
if dwStreamNumber == 1 {
*(lpData as *mut i64) = StreamBytesTransferred;
@@ -1415,9 +1427,10 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
let f = File::open(junction, &opts)?;
let h = f.as_inner().as_raw_handle();
unsafe {
- let mut data = Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
+ let mut data =
+ Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]);
let data_ptr = data.0.as_mut_ptr();
- let data_end = data_ptr.add(c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
+ let data_end = data_ptr.add(c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize);
let db = data_ptr.cast::<c::REPARSE_MOUNTPOINT_DATA_BUFFER>();
// Zero the header to ensure it's fully initialized, including reserved parameters.
*db = mem::zeroed();
diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs
index c7677d1c13a..84c1fbde32d 100644
--- a/library/std/src/sys/windows/handle.rs
+++ b/library/std/src/sys/windows/handle.rs
@@ -144,7 +144,7 @@ impl Handle {
let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD;
let mut amt = 0;
let res = cvt(c::ReadFile(
- self.as_handle(),
+ self.as_raw_handle(),
buf.as_ptr() as c::LPVOID,
len,
&mut amt,
@@ -235,7 +235,7 @@ impl Handle {
len: usize,
offset: Option<u64>,
) -> io::Result<usize> {
- let mut io_status = c::IO_STATUS_BLOCK::default();
+ let mut io_status = c::IO_STATUS_BLOCK::PENDING;
// The length is clamped at u32::MAX.
let len = cmp::min(len, c::DWORD::MAX as usize) as c::DWORD;
@@ -283,7 +283,7 @@ impl Handle {
///
/// If `offset` is `None` then the current file position is used.
fn synchronous_write(&self, buf: &[u8], offset: Option<u64>) -> io::Result<usize> {
- let mut io_status = c::IO_STATUS_BLOCK::default();
+ let mut io_status = c::IO_STATUS_BLOCK::PENDING;
// The length is clamped at u32::MAX.
let len = cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
diff --git a/library/std/src/sys/windows/io.rs b/library/std/src/sys/windows/io.rs
index 7fdd1f702e2..fc9856caed6 100644
--- a/library/std/src/sys/windows/io.rs
+++ b/library/std/src/sys/windows/io.rs
@@ -17,10 +17,7 @@ impl<'a> IoSlice<'a> {
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
assert!(buf.len() <= c::ULONG::MAX as usize);
IoSlice {
- vec: c::WSABUF {
- len: buf.len() as c::ULONG,
- buf: buf.as_ptr() as *mut u8 as *mut c::CHAR,
- },
+ vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_ptr() as *mut u8 },
_p: PhantomData,
}
}
@@ -54,7 +51,7 @@ impl<'a> IoSliceMut<'a> {
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
assert!(buf.len() <= c::ULONG::MAX as usize);
IoSliceMut {
- vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_mut_ptr() as *mut c::CHAR },
+ vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_mut_ptr() },
_p: PhantomData,
}
}
diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs
index 8158713fa84..2404bbe2b89 100644
--- a/library/std/src/sys/windows/net.rs
+++ b/library/std/src/sys/windows/net.rs
@@ -263,7 +263,7 @@ impl Socket {
&mut nread,
&mut flags,
ptr::null_mut(),
- ptr::null_mut(),
+ None,
)
};
@@ -347,7 +347,7 @@ impl Socket {
&mut nwritten,
0,
ptr::null_mut(),
- ptr::null_mut(),
+ None,
)
};
cvt(result).map(|_| nwritten as usize)
diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs
index 0780b29584d..d07147eccc1 100644
--- a/library/std/src/sys/windows/pipe.rs
+++ b/library/std/src/sys/windows/pipe.rs
@@ -373,7 +373,7 @@ impl AnonPipe {
// Asynchronous read of the pipe.
// If successful, `callback` will be called once it completes.
- let result = io(self.inner.as_handle(), buf, len, &mut overlapped, callback);
+ let result = io(self.inner.as_handle(), buf, len, &mut overlapped, Some(callback));
if result == c::FALSE {
// We can return here because the call failed.
// After this we must not return until the I/O completes.
diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs
index 1c73b64e250..df3667c0fd7 100644
--- a/library/std/src/sys/windows/process.rs
+++ b/library/std/src/sys/windows/process.rs
@@ -308,7 +308,7 @@ impl Command {
let stderr = stderr.to_handle(c::STD_ERROR_HANDLE, &mut pipes.stderr)?;
let mut si = zeroed_startupinfo();
- si.cb = mem::size_of::<c::STARTUPINFO>() as c::DWORD;
+ si.cb = mem::size_of::<c::STARTUPINFOW>() as c::DWORD;
// If at least one of stdin, stdout or stderr are set (i.e. are non null)
// then set the `hStd` fields in `STARTUPINFO`.
@@ -332,7 +332,7 @@ impl Command {
flags,
envp,
dirp,
- &mut si,
+ &si,
&mut pi,
))
}?;
@@ -720,8 +720,8 @@ impl From<u32> for ExitCode {
}
}
-fn zeroed_startupinfo() -> c::STARTUPINFO {
- c::STARTUPINFO {
+fn zeroed_startupinfo() -> c::STARTUPINFOW {
+ c::STARTUPINFOW {
cb: 0,
lpReserved: ptr::null_mut(),
lpDesktop: ptr::null_mut(),
@@ -731,7 +731,7 @@ fn zeroed_startupinfo() -> c::STARTUPINFO {
dwXSize: 0,
dwYSize: 0,
dwXCountChars: 0,
- dwYCountCharts: 0,
+ dwYCountChars: 0,
dwFillAttribute: 0,
dwFlags: 0,
wShowWindow: 0,
diff --git a/library/std/src/sys/windows/rand.rs b/library/std/src/sys/windows/rand.rs
index cdf37cfe911..bca4e38d9f6 100644
--- a/library/std/src/sys/windows/rand.rs
+++ b/library/std/src/sys/windows/rand.rs
@@ -1,3 +1,4 @@
+use crate::ffi::c_void;
use crate::io;
use crate::mem;
use crate::ptr;
@@ -25,8 +26,9 @@ pub fn hashmap_random_keys() -> (u64, u64) {
#[inline(never)]
fn fallback_rng() -> (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) };
+ let ret = unsafe {
+ c::RtlGenRandom(&mut v as *mut _ as *mut c_void, mem::size_of_val(&v) as c::ULONG)
+ };
if ret != 0 { v } else { panic!("fallback RNG broken: {}", io::Error::last_os_error()) }
}
diff --git a/library/std/src/sys/windows/stack_overflow.rs b/library/std/src/sys/windows/stack_overflow.rs
index 18a2a36ad25..0caf0a317a4 100644
--- a/library/std/src/sys/windows/stack_overflow.rs
+++ b/library/std/src/sys/windows/stack_overflow.rs
@@ -18,7 +18,7 @@ impl Handler {
}
}
-extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> c::LONG {
+unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> c::LONG {
unsafe {
let rec = &(*(*ExceptionInfo).ExceptionRecord);
let code = rec.ExceptionCode;
@@ -34,7 +34,7 @@ extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -
}
pub unsafe fn init() {
- if c::AddVectoredExceptionHandler(0, vectored_handler).is_null() {
+ if c::AddVectoredExceptionHandler(0, Some(vectored_handler)).is_null() {
panic!("failed to install exception handler");
}
// Set the thread stack guarantee for the main thread.
diff --git a/library/std/src/sys/windows/stdio.rs b/library/std/src/sys/windows/stdio.rs
index 32c6ccffb7a..2e3e0859dc1 100644
--- a/library/std/src/sys/windows/stdio.rs
+++ b/library/std/src/sys/windows/stdio.rs
@@ -180,7 +180,7 @@ fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result<usiz
let result = c::MultiByteToWideChar(
c::CP_UTF8, // CodePage
c::MB_ERR_INVALID_CHARS, // dwFlags
- utf8.as_ptr() as c::LPCCH, // lpMultiByteStr
+ utf8.as_ptr(), // lpMultiByteStr
utf8.len() as c::c_int, // cbMultiByte
utf16.as_mut_ptr() as c::LPWSTR, // lpWideCharStr
utf16.len() as c::c_int, // cchWideChar
@@ -344,7 +344,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit<u16>]) -> io::Result<usiz
// See #38274 and https://stackoverflow.com/questions/43836040/win-api-readconsole.
const CTRL_Z: u16 = 0x1A;
const CTRL_Z_MASK: c::ULONG = 1 << CTRL_Z;
- let mut input_control = c::CONSOLE_READCONSOLE_CONTROL {
+ let input_control = c::CONSOLE_READCONSOLE_CONTROL {
nLength: crate::mem::size_of::<c::CONSOLE_READCONSOLE_CONTROL>() as c::ULONG,
nInitialChars: 0,
dwCtrlWakeupMask: CTRL_Z_MASK,
@@ -360,7 +360,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit<u16>]) -> io::Result<usiz
buf.as_mut_ptr() as c::LPVOID,
buf.len() as u32,
&mut amount,
- &mut input_control as c::PCONSOLE_READCONSOLE_CONTROL,
+ &input_control,
)
})?;
@@ -385,14 +385,14 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> {
let result = unsafe {
c::WideCharToMultiByte(
- c::CP_UTF8, // CodePage
- c::WC_ERR_INVALID_CHARS, // dwFlags
- utf16.as_ptr(), // lpWideCharStr
- utf16.len() as c::c_int, // cchWideChar
- utf8.as_mut_ptr() as c::LPSTR, // lpMultiByteStr
- utf8.len() as c::c_int, // cbMultiByte
- ptr::null(), // lpDefaultChar
- ptr::null_mut(), // lpUsedDefaultChar
+ c::CP_UTF8, // CodePage
+ c::WC_ERR_INVALID_CHARS, // dwFlags
+ utf16.as_ptr(), // lpWideCharStr
+ utf16.len() as c::c_int, // cchWideChar
+ utf8.as_mut_ptr(), // lpMultiByteStr
+ utf8.len() as c::c_int, // cbMultiByte
+ ptr::null(), // lpDefaultChar
+ ptr::null_mut(), // lpUsedDefaultChar
)
};
if result == 0 {
diff --git a/library/std/src/sys/windows/thread.rs b/library/std/src/sys/windows/thread.rs
index ed58c47e090..18cecb65681 100644
--- a/library/std/src/sys/windows/thread.rs
+++ b/library/std/src/sys/windows/thread.rs
@@ -2,6 +2,7 @@ use crate::ffi::CStr;
use crate::io;
use crate::num::NonZeroUsize;
use crate::os::windows::io::AsRawHandle;
+use crate::os::windows::io::HandleOrNull;
use crate::ptr;
use crate::sys::c;
use crate::sys::handle::Handle;
@@ -32,12 +33,12 @@ impl Thread {
let ret = c::CreateThread(
ptr::null_mut(),
stack,
- thread_start,
+ Some(thread_start),
p as *mut _,
c::STACK_SIZE_PARAM_IS_A_RESERVATION,
ptr::null_mut(),
);
-
+ let ret = HandleOrNull::from_raw_handle(ret);
return if let Ok(handle) = ret.try_into() {
Ok(Thread { handle: Handle::from_inner(handle) })
} else {
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index 3b7c31826b9..1b86d898cc7 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -18,8 +18,8 @@ use crate::fmt;
/// target platform. It is instantiated with the [`thread_local!`] macro and the
/// primary method is the [`with`] method.
///
-/// The [`with`] method yields a reference to the contained value which cannot be
-/// sent across threads or escape the given closure.
+/// The [`with`] method yields a reference to the contained value which cannot
+/// outlive the current thread or escape the given closure.
///
/// [`thread_local!`]: crate::thread_local
///
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index 6c9ce6fa0dd..b65e2572cc5 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -375,7 +375,9 @@ fn test_scoped_threads_nll() {
// this is mostly a *compilation test* for this exact function:
fn foo(x: &u8) {
thread::scope(|s| {
- s.spawn(|| drop(x));
+ s.spawn(|| match x {
+ _ => (),
+ });
});
}
// let's also run it for good measure
diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs
index bf3c81fcc98..9ce29a33df6 100644
--- a/library/std/tests/run-time-detect.rs
+++ b/library/std/tests/run-time-detect.rs
@@ -16,7 +16,6 @@ fn arm_linux() {
// tidy-alphabetical-start
println!("aes: {}", is_arm_feature_detected!("aes"));
println!("crc: {}", is_arm_feature_detected!("crc"));
- println!("crypto: {}", is_arm_feature_detected!("crypto"));
println!("neon: {}", is_arm_feature_detected!("neon"));
println!("pmull: {}", is_arm_feature_detected!("pmull"));
println!("sha2: {}", is_arm_feature_detected!("sha2"));
diff --git a/library/stdarch b/library/stdarch
-Subproject b655243782c18d3419439daa523782e0818ecf2
+Subproject 7e2cdc675b92165c5f8c4c794620252be4605e7
diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md
index 74dd22df9e0..d6924cf2cfb 100644
--- a/src/bootstrap/CHANGELOG.md
+++ b/src/bootstrap/CHANGELOG.md
@@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
from the default rust toolchain. [#78513](https://github.com/rust-lang/rust/pull/78513)
- Add options for enabling overflow checks, one for std (`overflow-checks-std`) and one for everything else (`overflow-checks`). Both default to false.
- Add llvm option `enable-warnings` to have control on llvm compilation warnings. Default to false.
+- Add `rpath` option in `target` section to support set rpath option for each target independently. [#111242](https://github.com/rust-lang/rust/pull/111242)
## [Version 2] - 2020-09-25
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index dfe6bb7f057..9420c4fec5f 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -45,6 +45,7 @@ dependencies = [
"build_helper",
"cc",
"clap",
+ "clap_complete",
"cmake",
"fd-lock",
"filetime",
@@ -57,6 +58,7 @@ dependencies = [
"once_cell",
"opener",
"pretty_assertions",
+ "semver",
"serde",
"serde_derive",
"serde_json",
@@ -120,6 +122,15 @@ dependencies = [
]
[[package]]
+name = "clap_complete"
+version = "4.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36774babb166352bb4f7b9cb16f781ffa3439d2a8f12cd31bea85a38c888fea3"
+dependencies = [
+ "clap",
+]
+
+[[package]]
name = "clap_derive"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -636,6 +647,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
+name = "semver"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
+
+[[package]]
name = "serde"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index fd5eb740630..746c8dcfce0 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -56,6 +56,8 @@ walkdir = "2"
# Dependencies needed by the build-metrics feature
sysinfo = { version = "0.26.0", optional = true }
clap = { version = "4.2.4", default-features = false, features = ["std", "usage", "help", "derive", "error-context"] }
+clap_complete = "4.2.2"
+semver = "1.0.17"
# Solaris doesn't support flock() and thus fd-lock is not option now
[target.'cfg(not(target_os = "solaris"))'.dependencies]
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 45f2975f5f5..5c37fab5470 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -838,6 +838,8 @@ impl<'a> Builder<'a> {
run::Miri,
run::CollectLicenseMetadata,
run::GenerateCopyright,
+ run::GenerateWindowsSys,
+ run::GenerateCompletions,
),
Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::Vscode),
Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std),
@@ -1622,7 +1624,7 @@ impl<'a> Builder<'a> {
// argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
// fun to pass a flag to a tool to pass a flag to pass a flag to a tool
// to change a flag in a binary?
- if self.config.rust_rpath && util::use_host_linker(target) {
+ if self.config.rpath_enabled(target) && util::use_host_linker(target) {
let rpath = if target.contains("apple") {
// Note that we need to take one extra step on macOS to also pass
// `-Wl,-instal_name,@rpath/...` to get things to work right. To
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index f4e97d7dfed..710c8b52194 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -24,6 +24,7 @@ pub use crate::flags::Subcommand;
use crate::flags::{Color, Flags, Warnings};
use crate::util::{exe, output, t};
use once_cell::sync::OnceCell;
+use semver::Version;
use serde::{Deserialize, Deserializer};
use serde_derive::Deserialize;
@@ -467,6 +468,7 @@ pub struct Target {
pub ndk: Option<PathBuf>,
pub sanitizers: Option<bool>,
pub profiler: Option<bool>,
+ pub rpath: Option<bool>,
pub crt_static: Option<bool>,
pub musl_root: Option<PathBuf>,
pub musl_libdir: Option<PathBuf>,
@@ -812,6 +814,7 @@ define_config! {
android_ndk: Option<String> = "android-ndk",
sanitizers: Option<bool> = "sanitizers",
profiler: Option<bool> = "profiler",
+ rpath: Option<bool> = "rpath",
crt_static: Option<bool> = "crt-static",
musl_root: Option<String> = "musl-root",
musl_libdir: Option<String> = "musl-libdir",
@@ -1017,6 +1020,7 @@ impl Config {
config.download_beta_toolchain();
config.out.join(config.build.triple).join("stage0/bin/rustc")
});
+
config.initial_cargo = build
.cargo
.map(|cargo| {
@@ -1318,6 +1322,7 @@ impl Config {
target.qemu_rootfs = cfg.qemu_rootfs.map(PathBuf::from);
target.sanitizers = cfg.sanitizers;
target.profiler = cfg.profiler;
+ target.rpath = cfg.rpath;
config.target_config.insert(TargetSelection::from_user(&triple), target);
}
@@ -1649,6 +1654,10 @@ impl Config {
self.target_config.values().any(|t| t.profiler == Some(true)) || self.profiler
}
+ pub fn rpath_enabled(&self, target: TargetSelection) -> bool {
+ self.target_config.get(&target).map(|t| t.rpath).flatten().unwrap_or(self.rust_rpath)
+ }
+
pub fn llvm_enabled(&self) -> bool {
self.rust_codegen_backends.contains(&INTERNER.intern_str("llvm"))
}
@@ -1673,6 +1682,42 @@ impl Config {
self.rust_codegen_backends.get(0).cloned()
}
+ pub fn check_build_rustc_version(&self) {
+ if self.dry_run() {
+ return;
+ }
+
+ // check rustc version is same or lower with 1 apart from the building one
+ let mut cmd = Command::new(&self.initial_rustc);
+ cmd.arg("--version");
+ let rustc_output = output(&mut cmd)
+ .lines()
+ .next()
+ .unwrap()
+ .split(' ')
+ .nth(1)
+ .unwrap()
+ .split('-')
+ .next()
+ .unwrap()
+ .to_owned();
+ let rustc_version = Version::parse(&rustc_output.trim()).unwrap();
+ let source_version =
+ Version::parse(&fs::read_to_string(self.src.join("src/version")).unwrap().trim())
+ .unwrap();
+ if !(source_version == rustc_version
+ || (source_version.major == rustc_version.major
+ && source_version.minor == rustc_version.minor + 1))
+ {
+ let prev_version = format!("{}.{}.x", source_version.major, source_version.minor - 1);
+ eprintln!(
+ "Unexpected rustc version: {}, we should use {}/{} to build source with {}",
+ rustc_version, prev_version, source_version, source_version
+ );
+ crate::detail_exit(1);
+ }
+ }
+
/// Returns the commit to download, or `None` if we shouldn't download CI artifacts.
fn download_ci_rustc_commit(&self, download_rustc: Option<StringOrBool>) -> Option<String> {
// If `download-rustc` is not set, default to rebuilding.
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index c79a1bf9563..6e0c0e01af8 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -3,9 +3,9 @@
//! This module implements the command-line parsing of the build system which
//! has various flags to configure how it's run.
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
-use clap::{Parser, ValueEnum};
+use clap::{CommandFactory, Parser, ValueEnum};
use crate::builder::{Builder, Kind};
use crate::config::{target_selection_list, Config, TargetSelectionList};
@@ -54,15 +54,15 @@ pub struct Flags {
/// Build directory, overrides `build.build-dir` in `config.toml`
pub build_dir: Option<PathBuf>,
- #[arg(global(true), long, value_name = "BUILD")]
+ #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "BUILD")]
/// build target of the stage0 compiler
pub build: Option<String>,
- #[arg(global(true), long, value_name = "HOST", value_parser = target_selection_list)]
+ #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "HOST", value_parser = target_selection_list)]
/// host targets to build
pub host: Option<TargetSelectionList>,
- #[arg(global(true), long, value_name = "TARGET", value_parser = target_selection_list)]
+ #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "TARGET", value_parser = target_selection_list)]
/// target targets to build
pub target: Option<TargetSelectionList>,
@@ -73,7 +73,7 @@ pub struct Flags {
/// include default paths in addition to the provided ones
pub include_default_paths: bool,
- #[arg(global(true), long)]
+ #[arg(global(true), value_hint = clap::ValueHint::Other, long)]
pub rustc_error_format: Option<String>,
#[arg(global(true), long, value_hint = clap::ValueHint::CommandString, value_name = "CMD")]
@@ -82,16 +82,16 @@ pub struct Flags {
#[arg(global(true), long)]
/// dry run; don't build anything
pub dry_run: bool,
- #[arg(global(true), long, value_name = "N")]
+ #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")]
/// stage to build (indicates compiler to use/test, e.g., stage 0 uses the
/// bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)
pub stage: Option<u32>,
- #[arg(global(true), long, value_name = "N")]
+ #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")]
/// stage(s) to keep without recompiling
/// (pass multiple times to keep e.g., both stages 0 and 1)
pub keep_stage: Vec<u32>,
- #[arg(global(true), long, value_name = "N")]
+ #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")]
/// stage(s) of the standard library to keep without recompiling
/// (pass multiple times to keep e.g., both stages 0 and 1)
pub keep_stage_std: Vec<u32>,
@@ -103,6 +103,7 @@ pub struct Flags {
global(true),
short,
long,
+ value_hint = clap::ValueHint::Other,
default_value_t = std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get),
value_name = "JOBS"
)]
@@ -117,7 +118,7 @@ pub struct Flags {
/// otherwise, use the default configured behaviour
pub warnings: Warnings,
- #[arg(global(true), long, value_name = "FORMAT")]
+ #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "FORMAT")]
/// rustc error format
pub error_format: Option<String>,
#[arg(global(true), long)]
@@ -133,13 +134,13 @@ pub struct Flags {
#[arg(global(true), long, value_name = "VALUE")]
pub llvm_skip_rebuild: Option<bool>,
/// generate PGO profile with rustc build
- #[arg(global(true), long, value_name = "PROFILE")]
+ #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
pub rust_profile_generate: Option<String>,
/// use PGO profile for rustc build
- #[arg(global(true), long, value_name = "PROFILE")]
+ #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
pub rust_profile_use: Option<String>,
/// use PGO profile for LLVM build
- #[arg(global(true), long, value_name = "PROFILE")]
+ #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
pub llvm_profile_use: Option<String>,
// LLVM doesn't support a custom location for generating profile
// information.
@@ -152,7 +153,7 @@ pub struct Flags {
#[arg(global(true), long)]
pub llvm_bolt_profile_generate: bool,
/// use BOLT profile for LLVM build
- #[arg(global(true), long, value_name = "PROFILE")]
+ #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
pub llvm_bolt_profile_use: Option<String>,
#[arg(global(true))]
/// paths for the subcommand
@@ -524,3 +525,23 @@ impl Subcommand {
}
}
}
+
+/// Returns the shell completion for a given shell, if the result differs from the current
+/// content of `path`. If `path` does not exist, always returns `Some`.
+pub fn get_completion<G: clap_complete::Generator>(shell: G, path: &Path) -> Option<String> {
+ let mut cmd = Flags::command();
+ let current = if !path.exists() {
+ String::new()
+ } else {
+ std::fs::read_to_string(path).unwrap_or_else(|_| {
+ eprintln!("couldn't read {}", path.display());
+ crate::detail_exit(1)
+ })
+ };
+ let mut buf = Vec::new();
+ clap_complete::generate(shell, &mut cmd, "x.py", &mut buf);
+ if buf == current.as_bytes() {
+ return None;
+ }
+ Some(String::from_utf8(buf).expect("completion script should be UTF-8"))
+}
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 994336977dc..3756976dee0 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -414,6 +414,7 @@ impl Build {
bootstrap_out.display()
)
}
+ config.check_build_rustc_version();
if rust_info.is_from_tarball() && config.description.is_none() {
config.description = Some("built from a source tarball".to_owned());
diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs
index cb15d9a6325..ec01f744b82 100644
--- a/src/bootstrap/run.rs
+++ b/src/bootstrap/run.rs
@@ -1,9 +1,12 @@
use std::path::PathBuf;
use std::process::Command;
+use clap_complete::shells;
+
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::config::TargetSelection;
use crate::dist::distdir;
+use crate::flags::get_completion;
use crate::test;
use crate::tool::{self, SourceType, Tool};
use crate::util::output;
@@ -253,3 +256,56 @@ impl Step for GenerateCopyright {
dest
}
}
+
+#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct GenerateWindowsSys;
+
+impl Step for GenerateWindowsSys {
+ type Output = ();
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+ run.path("src/tools/generate-windows-sys")
+ }
+
+ fn make_run(run: RunConfig<'_>) {
+ run.builder.ensure(GenerateWindowsSys);
+ }
+
+ fn run(self, builder: &Builder<'_>) {
+ let mut cmd = builder.tool_cmd(Tool::GenerateWindowsSys);
+ cmd.arg(&builder.src);
+ builder.run(&mut cmd);
+ }
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct GenerateCompletions;
+
+impl Step for GenerateCompletions {
+ type Output = ();
+
+ /// Uses `clap_complete` to generate shell completions.
+ fn run(self, builder: &Builder<'_>) {
+ // FIXME(clubby789): enable zsh when clap#4898 is fixed
+ let [bash, fish, powershell] = ["x.py.sh", "x.py.fish", "x.py.ps1"]
+ .map(|filename| builder.src.join("src/etc/completions").join(filename));
+ if let Some(comp) = get_completion(shells::Bash, &bash) {
+ std::fs::write(&bash, comp).expect("writing bash completion");
+ }
+ if let Some(comp) = get_completion(shells::Fish, &fish) {
+ std::fs::write(&fish, comp).expect("writing fish completion");
+ }
+ if let Some(comp) = get_completion(shells::PowerShell, &powershell) {
+ std::fs::write(&powershell, comp).expect("writing powershell completion");
+ }
+ }
+
+ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+ run.alias("generate-completions")
+ }
+
+ fn make_run(run: RunConfig<'_>) {
+ run.builder.ensure(GenerateCompletions);
+ }
+}
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 854b7f5bd3a..2d600704e02 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -10,6 +10,8 @@ use std::iter;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
+use clap_complete::shells;
+
use crate::builder::crate_description;
use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
use crate::cache::Interned;
@@ -613,6 +615,21 @@ impl Step for Miri {
builder.run(&mut cargo);
}
+ // Run it again for mir-opt-level 4 to catch some miscompilations.
+ if builder.config.test_args().is_empty() {
+ cargo.env("MIRIFLAGS", "-O -Zmir-opt-level=4 -Cdebug-assertions=yes");
+ // Optimizations can change backtraces
+ cargo.env("MIRI_SKIP_UI_CHECKS", "1");
+ // Optimizations can change error locations and remove UB so don't run `fail` tests.
+ cargo.args(&["tests/pass", "tests/panic"]);
+
+ let mut cargo = prepare_cargo_test(cargo, &[], &[], "miri", compiler, target, builder);
+ {
+ let _time = util::timeit(&builder);
+ builder.run(&mut cargo);
+ }
+ }
+
// # Run `cargo miri test`.
// This is just a smoke test (Miri's own CI invokes this in a bunch of different ways and ensures
// that we get the desired output), but that is sufficient to make sure that the libtest harness
@@ -644,8 +661,10 @@ impl Step for Miri {
cargo.env("RUST_BACKTRACE", "1");
let mut cargo = Command::from(cargo);
- let _time = util::timeit(&builder);
- builder.run(&mut cargo);
+ {
+ let _time = util::timeit(&builder);
+ builder.run(&mut cargo);
+ }
}
}
@@ -1121,7 +1140,24 @@ help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy`
builder.info("tidy check");
try_run(builder, &mut cmd);
- builder.ensure(ExpandYamlAnchors {});
+ builder.ensure(ExpandYamlAnchors);
+
+ builder.info("x.py completions check");
+ let [bash, fish, powershell] = ["x.py.sh", "x.py.fish", "x.py.ps1"]
+ .map(|filename| builder.src.join("src/etc/completions").join(filename));
+ if builder.config.cmd.bless() {
+ builder.ensure(crate::run::GenerateCompletions);
+ } else {
+ if crate::flags::get_completion(shells::Bash, &bash).is_some()
+ || crate::flags::get_completion(shells::Fish, &fish).is_some()
+ || crate::flags::get_completion(shells::PowerShell, &powershell).is_some()
+ {
+ eprintln!(
+ "x.py completions were changed; run `x.py run generate-completions` to update them"
+ );
+ crate::detail_exit(1);
+ }
+ }
}
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 39f6369b4d3..f13d365e375 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -301,6 +301,7 @@ bootstrap_tool!(
CollectLicenseMetadata, "src/tools/collect-license-metadata", "collect-license-metadata";
GenerateCopyright, "src/tools/generate-copyright", "generate-copyright";
SuggestTests, "src/tools/suggest-tests", "suggest-tests";
+ GenerateWindowsSys, "src/tools/generate-windows-sys", "generate-windows-sys";
);
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
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 7092c7c46f8..6b4966ddeb4 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.15.0 \ No newline at end of file
+0.16.3 \ No newline at end of file
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject 6038be9d37d7251c966b486154af621d1794d7a
+Subproject f63e578b92ff43e8cc38fcaa257b660f45c8a8c
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject 897fcf566f16bf87bf37199bdddec1801fd0053
+Subproject d9eb4c3f75435b008881062ffa77bf0d1527b37
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 1f8dc727e94ae4ef92adf70df979521a1ea1143
+Subproject 28dc0f3576b55f5e57c5d6e65cd68ba3161e9fd
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 31961fe22521a779070a44a8f30a2b00a20b621
+Subproject 8ee9528b72b927cff8fd32346db8bbd1198816f
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 2a5eb92197e9cf8fe91164dcbf4f9b88c0d7e73
+Subproject 28dbeaf5c44bc7f5111ad412e99f2d7c5cec6c9
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 48efa67191a..73343ba9df5 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -27,6 +27,7 @@
- [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
- [\*-android and \*-androideabi](platform-support/android.md)
- [\*-linux-ohos](platform-support/openharmony.md)
+ - [\*-esp-espidf](platform-support/esp-idf.md)
- [\*-unknown-fuchsia](platform-support/fuchsia.md)
- [\*-kmc-solid_\*](platform-support/kmc-solid.md)
- [loongarch\*-unknown-linux-\*](platform-support/loongarch-linux.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 75f97c1fc1e..d22e1cf7f68 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -297,7 +297,7 @@ target | std | host | notes
`riscv32gc-unknown-linux-musl` | | | RISC-V Linux (kernel 5.4, musl + RISCV32 support patches)
`riscv32im-unknown-none-elf` | * | | Bare RISC-V (RV32IM ISA)
[`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA)
-`riscv32imc-esp-espidf` | ✓ | | RISC-V ESP-IDF
+[`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF
`riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD
`riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia
`riscv64gc-unknown-linux-musl` | | | RISC-V Linux (kernel 4.20, musl 1.2.0)
diff --git a/src/doc/rustc/src/platform-support/esp-idf.md b/src/doc/rustc/src/platform-support/esp-idf.md
new file mode 100644
index 00000000000..8a4ca347e22
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/esp-idf.md
@@ -0,0 +1,41 @@
+# `*-esp-espidf`
+
+**Tier: 3**
+
+Targets for the [ESP-IDF](https://github.com/espressif/esp-idf) development framework running on RISC-V and Xtensa CPUs.
+
+## Target maintainers
+
+- Ivan Markov [@ivmarkov](https://github.com/ivmarkov)
+- Scott Mabin [@MabezDev](https://github.com/MabezDev)
+
+## Requirements
+
+The target names follow this format: `$ARCH-esp-espidf`, where `$ARCH` specifies the target processor architecture. The following targets are currently defined:
+
+| Target name | Target CPU(s) |
+|--------------------------------|-----------------------|
+| `riscv32imc-esp-espidf` | [ESP32-C3](https://www.espressif.com/en/products/socs/esp32-c3) |
+
+The minimum supported ESP-IDF version is `v4.3`, though it is recommended to use the latest stable release if possible.
+
+## Building the target
+
+The target can be built by enabling it for a `rustc` build. The `build-std` feature is required to build the standard library for ESP-IDF. `ldproxy` is also required for linking, it can be installed from crates.io.
+
+```toml
+[build]
+target = ["$ARCH-esp-espidf"]
+
+[target.$ARCH-esp-espidf]
+linker = "ldproxy"
+
+[unstable]
+build-std = ["std", "panic_abort"]
+```
+
+The `esp-idf-sys` crate will handle the compilation of ESP-IDF, including downloading the relevant toolchains for the build.
+
+## Cross-compilation toolchains and C code
+
+`esp-idf-sys` exposes the toolchain used in the compilation of ESP-IDF, see the crate [documentation for build output propagation](https://github.com/esp-rs/esp-idf-sys#conditional-compilation) for more information.
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
new file mode 100644
index 00000000000..089c03a0d64
--- /dev/null
+++ b/src/etc/completions/x.py.fish
@@ -0,0 +1,475 @@
+complete -c x.py -n "__fish_use_subcommand" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_use_subcommand" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_use_subcommand" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_use_subcommand" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_use_subcommand" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_use_subcommand" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_use_subcommand" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_use_subcommand" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_use_subcommand" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_use_subcommand" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_use_subcommand" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_use_subcommand" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_use_subcommand" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_use_subcommand" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_use_subcommand" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_use_subcommand" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_use_subcommand" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_use_subcommand" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_use_subcommand" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_use_subcommand" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_use_subcommand" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_use_subcommand" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_use_subcommand" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_use_subcommand" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_use_subcommand" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_use_subcommand" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_use_subcommand" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_use_subcommand" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_use_subcommand" -s h -l help -d 'Print help'
+complete -c x.py -n "__fish_use_subcommand" -f -a "build" -d 'Compile either the compiler or libraries'
+complete -c x.py -n "__fish_use_subcommand" -f -a "check" -d 'Compile either the compiler or libraries, using cargo check'
+complete -c x.py -n "__fish_use_subcommand" -f -a "clippy" -d 'Run Clippy (uses rustup/cargo-installed clippy binary)'
+complete -c x.py -n "__fish_use_subcommand" -f -a "fix" -d 'Run cargo fix'
+complete -c x.py -n "__fish_use_subcommand" -f -a "fmt" -d 'Run rustfmt'
+complete -c x.py -n "__fish_use_subcommand" -f -a "doc" -d 'Build documentation'
+complete -c x.py -n "__fish_use_subcommand" -f -a "test" -d 'Build and run some test suites'
+complete -c x.py -n "__fish_use_subcommand" -f -a "bench" -d 'Build and run some benchmarks'
+complete -c x.py -n "__fish_use_subcommand" -f -a "clean" -d 'Clean out build directories'
+complete -c x.py -n "__fish_use_subcommand" -f -a "dist" -d 'Duild distribution artifacts'
+complete -c x.py -n "__fish_use_subcommand" -f -a "install" -d 'Install distribution artifacts'
+complete -c x.py -n "__fish_use_subcommand" -f -a "run" -d 'Run tools contained in this repository'
+complete -c x.py -n "__fish_use_subcommand" -f -a "setup" -d 'Set up the environment for development'
+complete -c x.py -n "__fish_use_subcommand" -f -a "suggest" -d 'Suggest a subset of tests to run, based on modified files'
+complete -c x.py -n "__fish_seen_subcommand_from build" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from build" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from build" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from build" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from build" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from build" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from build" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from build" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from build" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from build" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from build" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from build" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from build" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from build" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from build" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from build" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from build" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from build" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from build" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from build" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from build" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from build" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from build" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_seen_subcommand_from check" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from check" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from check" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from check" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from check" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from check" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from check" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from check" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from check" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from check" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from check" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from check" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from check" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from check" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from check" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from check" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from check" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from check" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from check" -l all-targets -d 'Check all targets'
+complete -c x.py -n "__fish_seen_subcommand_from check" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from check" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from check" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from check" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from check" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from check" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -s A -d 'clippy lints to allow' -r
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -s D -d 'clippy lints to deny' -r
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -s W -d 'clippy lints to warn on' -r
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -s F -d 'clippy lints to forbid' -r
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l fix
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from fix" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fix" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from fix" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from fix" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l check -d 'check formatting instead of applying'
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from doc" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l open -d 'open the docs in a browser'
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l json -d 'render the documentation in JSON format in addition to the usual HTML format'
+complete -c x.py -n "__fish_seen_subcommand_from doc" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from doc" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from doc" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_seen_subcommand_from test" -l skip -d 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times' -r
+complete -c x.py -n "__fish_seen_subcommand_from test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
+complete -c x.py -n "__fish_seen_subcommand_from test" -l rustc-args -d 'extra options to pass the compiler when running tests' -r
+complete -c x.py -n "__fish_seen_subcommand_from test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
+complete -c x.py -n "__fish_seen_subcommand_from test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
+complete -c x.py -n "__fish_seen_subcommand_from test" -l run -d 'whether to execute run-* tests' -r
+complete -c x.py -n "__fish_seen_subcommand_from test" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from test" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from test" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from test" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from test" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from test" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from test" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from test" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from test" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from test" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from test" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from test" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from test" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from test" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from test" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from test" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from test" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from test" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from test" -l no-fail-fast -d 'run all tests regardless of failure'
+complete -c x.py -n "__fish_seen_subcommand_from test" -l no-doc -d 'do not run doc tests'
+complete -c x.py -n "__fish_seen_subcommand_from test" -l doc -d 'only run doc tests'
+complete -c x.py -n "__fish_seen_subcommand_from test" -l bless -d 'whether to automatically update stderr/stdout files'
+complete -c x.py -n "__fish_seen_subcommand_from test" -l force-rerun -d 'rerun tests even if the inputs are unchanged'
+complete -c x.py -n "__fish_seen_subcommand_from test" -l only-modified -d 'only run tests that result has been changed'
+complete -c x.py -n "__fish_seen_subcommand_from test" -l rustfix-coverage -d 'enable this to generate a Rustfix coverage file, which is saved in `/<build_base>/rustfix_missing_coverage.txt`'
+complete -c x.py -n "__fish_seen_subcommand_from test" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from test" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from test" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from test" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from test" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l test-args -r
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from bench" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from bench" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from bench" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from bench" -s h -l help -d 'Print help'
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from clean" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l all
+complete -c x.py -n "__fish_seen_subcommand_from clean" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from clean" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from clean" -s h -l help -d 'Print help'
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from dist" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from dist" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from dist" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from dist" -s h -l help -d 'Print help'
+complete -c x.py -n "__fish_seen_subcommand_from install" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from install" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from install" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from install" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from install" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from install" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from install" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from install" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from install" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from install" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from install" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from install" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from install" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from install" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from install" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from install" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from install" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from install" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from install" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from install" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from install" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from install" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from install" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from install" -s h -l help -d 'Print help'
+complete -c x.py -n "__fish_seen_subcommand_from run" -l args -d 'arguments for the tool' -r
+complete -c x.py -n "__fish_seen_subcommand_from run" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from run" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from run" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from run" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from run" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from run" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from run" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from run" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from run" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from run" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from run" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from run" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from run" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from run" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from run" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from run" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from run" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from run" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from run" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from run" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from run" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from run" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from run" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from run" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from setup" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from setup" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from setup" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from setup" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }"
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }"
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }"
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l run -d 'run suggested tests'
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -s h -l help -d 'Print help (see more with \'--help\')'
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
new file mode 100644
index 00000000000..fad2391e61f
--- /dev/null
+++ b/src/etc/completions/x.py.ps1
@@ -0,0 +1,607 @@
+
+using namespace System.Management.Automation
+using namespace System.Management.Automation.Language
+
+Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
+ param($wordToComplete, $commandAst, $cursorPosition)
+
+ $commandElements = $commandAst.CommandElements
+ $command = @(
+ 'x.py'
+ for ($i = 1; $i -lt $commandElements.Count; $i++) {
+ $element = $commandElements[$i]
+ if ($element -isnot [StringConstantExpressionAst] -or
+ $element.StringConstantType -ne [StringConstantType]::BareWord -or
+ $element.Value.StartsWith('-') -or
+ $element.Value -eq $wordToComplete) {
+ break
+ }
+ $element.Value
+ }) -join ';'
+
+ $completions = @(switch ($command) {
+ 'x.py' {
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
+ [CompletionResult]::new('build', 'build', [CompletionResultType]::ParameterValue, 'Compile either the compiler or libraries')
+ [CompletionResult]::new('check', 'check', [CompletionResultType]::ParameterValue, 'Compile either the compiler or libraries, using cargo check')
+ [CompletionResult]::new('clippy', 'clippy', [CompletionResultType]::ParameterValue, 'Run Clippy (uses rustup/cargo-installed clippy binary)')
+ [CompletionResult]::new('fix', 'fix', [CompletionResultType]::ParameterValue, 'Run cargo fix')
+ [CompletionResult]::new('fmt', 'fmt', [CompletionResultType]::ParameterValue, 'Run rustfmt')
+ [CompletionResult]::new('doc', 'doc', [CompletionResultType]::ParameterValue, 'Build documentation')
+ [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'Build and run some test suites')
+ [CompletionResult]::new('bench', 'bench', [CompletionResultType]::ParameterValue, 'Build and run some benchmarks')
+ [CompletionResult]::new('clean', 'clean', [CompletionResultType]::ParameterValue, 'Clean out build directories')
+ [CompletionResult]::new('dist', 'dist', [CompletionResultType]::ParameterValue, 'Duild distribution artifacts')
+ [CompletionResult]::new('install', 'install', [CompletionResultType]::ParameterValue, 'Install distribution artifacts')
+ [CompletionResult]::new('run', 'run', [CompletionResultType]::ParameterValue, 'Run tools contained in this repository')
+ [CompletionResult]::new('setup', 'setup', [CompletionResultType]::ParameterValue, 'Set up the environment for development')
+ [CompletionResult]::new('suggest', 'suggest', [CompletionResultType]::ParameterValue, 'Suggest a subset of tests to run, based on modified files')
+ break
+ }
+ 'x.py;build' {
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ break
+ }
+ 'x.py;check' {
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('--all-targets', 'all-targets', [CompletionResultType]::ParameterName, 'Check all targets')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ break
+ }
+ 'x.py;clippy' {
+ [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'clippy lints to allow')
+ [CompletionResult]::new('-D', 'D', [CompletionResultType]::ParameterName, 'clippy lints to deny')
+ [CompletionResult]::new('-W', 'W', [CompletionResultType]::ParameterName, 'clippy lints to warn on')
+ [CompletionResult]::new('-F', 'F', [CompletionResultType]::ParameterName, 'clippy lints to forbid')
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('--fix', 'fix', [CompletionResultType]::ParameterName, 'fix')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ break
+ }
+ 'x.py;fix' {
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ break
+ }
+ 'x.py;fmt' {
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('--check', 'check', [CompletionResultType]::ParameterName, 'check formatting instead of applying')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ break
+ }
+ 'x.py;doc' {
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('--open', 'open', [CompletionResultType]::ParameterName, 'open the docs in a browser')
+ [CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'render the documentation in JSON format in addition to the usual HTML format')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ break
+ }
+ 'x.py;test' {
+ [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times')
+ [CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)')
+ [CompletionResult]::new('--rustc-args', 'rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running tests')
+ [CompletionResult]::new('--compare-mode', 'compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
+ [CompletionResult]::new('--pass', 'pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
+ [CompletionResult]::new('--run', 'run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests')
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('--no-fail-fast', 'no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure')
+ [CompletionResult]::new('--no-doc', 'no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests')
+ [CompletionResult]::new('--doc', 'doc', [CompletionResultType]::ParameterName, 'only run doc tests')
+ [CompletionResult]::new('--bless', 'bless', [CompletionResultType]::ParameterName, 'whether to automatically update stderr/stdout files')
+ [CompletionResult]::new('--force-rerun', 'force-rerun', [CompletionResultType]::ParameterName, 'rerun tests even if the inputs are unchanged')
+ [CompletionResult]::new('--only-modified', 'only-modified', [CompletionResultType]::ParameterName, 'only run tests that result has been changed')
+ [CompletionResult]::new('--rustfix-coverage', 'rustfix-coverage', [CompletionResultType]::ParameterName, 'enable this to generate a Rustfix coverage file, which is saved in `/<build_base>/rustfix_missing_coverage.txt`')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ break
+ }
+ 'x.py;bench' {
+ [CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'test-args')
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
+ break
+ }
+ 'x.py;clean' {
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('--all', 'all', [CompletionResultType]::ParameterName, 'all')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
+ break
+ }
+ 'x.py;dist' {
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
+ break
+ }
+ 'x.py;install' {
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
+ break
+ }
+ 'x.py;run' {
+ [CompletionResult]::new('--args', 'args', [CompletionResultType]::ParameterName, 'arguments for the tool')
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ break
+ }
+ 'x.py;setup' {
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ break
+ }
+ 'x.py;suggest' {
+ [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+ [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+ [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+ [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+ [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+ [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+ [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+ [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+ [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+ [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+ [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+ [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+ [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+ [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+ [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+ [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+ [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+ [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+ [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+ [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+ [CompletionResult]::new('--run', 'run', [CompletionResultType]::ParameterName, 'run suggested tests')
+ [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+ [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+ [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+ [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+ [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+ [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+ [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build')
+ [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+ break
+ }
+ })
+
+ $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
+ Sort-Object -Property ListItemText
+}
diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh
new file mode 100644
index 00000000000..931cc4353b2
--- /dev/null
+++ b/src/etc/completions/x.py.sh
@@ -0,0 +1,1644 @@
+_x.py() {
+ local i cur prev opts cmd
+ COMPREPLY=()
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
+ cmd=""
+ opts=""
+
+ for i in ${COMP_WORDS[@]}
+ do
+ case "${cmd},${i}" in
+ ",$1")
+ cmd="x.py"
+ ;;
+ bootstrap,bench)
+ cmd="bootstrap__bench"
+ ;;
+ bootstrap,build)
+ cmd="bootstrap__build"
+ ;;
+ bootstrap,check)
+ cmd="bootstrap__check"
+ ;;
+ bootstrap,clean)
+ cmd="bootstrap__clean"
+ ;;
+ bootstrap,clippy)
+ cmd="bootstrap__clippy"
+ ;;
+ bootstrap,dist)
+ cmd="bootstrap__dist"
+ ;;
+ bootstrap,doc)
+ cmd="bootstrap__doc"
+ ;;
+ bootstrap,fix)
+ cmd="bootstrap__fix"
+ ;;
+ bootstrap,fmt)
+ cmd="bootstrap__fmt"
+ ;;
+ bootstrap,install)
+ cmd="bootstrap__install"
+ ;;
+ bootstrap,run)
+ cmd="bootstrap__run"
+ ;;
+ bootstrap,setup)
+ cmd="bootstrap__setup"
+ ;;
+ bootstrap,suggest)
+ cmd="bootstrap__suggest"
+ ;;
+ bootstrap,test)
+ cmd="bootstrap__test"
+ ;;
+ *)
+ ;;
+ esac
+ done
+
+ case "${cmd}" in
+ x.py)
+ opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest"
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__bench)
+ opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --test-args)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__build)
+ opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__check)
+ opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__clean)
+ opts="-v -i -j -h --all --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__clippy)
+ opts="-A -D -W -F -v -i -j -h --fix --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ -A)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ -D)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ -W)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ -F)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__dist)
+ opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__doc)
+ opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__fix)
+ opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__fmt)
+ opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__install)
+ opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__run)
+ opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --args)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__setup)
+ opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [<PROFILE>|hook|vscode|link] [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__suggest)
+ opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ x.py__test)
+ opts="-v -i -j -h --no-fail-fast --skip --test-args --rustc-args --no-doc --doc --bless --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+ if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ fi
+ case "${prev}" in
+ --skip)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --test-args)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-args)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --compare-mode)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --pass)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --run)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --config)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build-dir)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --build)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --host)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --target)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --exclude)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rustc-error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --on-fail)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --keep-stage-std)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --src)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --jobs)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ -j)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --warnings)
+ COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+ return 0
+ ;;
+ --error-format)
+ COMPREPLY=("${cur}")
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+ return 0
+ ;;
+ --llvm-skip-rebuild)
+ COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+ return 0
+ ;;
+ --rust-profile-generate)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --rust-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ --llvm-bolt-profile-use)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+ return 0
+ ;;
+ esac
+}
+
+complete -F _x.py -o bashdefault -o default x.py
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index fb32b6ef1d3..baf2b0a8585 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -556,7 +556,10 @@ where
WherePredicate::EqPredicate { lhs, rhs, bound_params } => {
match *lhs {
Type::QPath(box QPathData {
- ref assoc, ref self_type, ref trait_, ..
+ ref assoc,
+ ref self_type,
+ trait_: Some(ref trait_),
+ ..
}) => {
let ty = &*self_type;
let mut new_trait = trait_.clone();
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 951f54e9366..c852f9cca2b 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -706,7 +706,12 @@ 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(box clean::QPathData { self_type: clean::Generic(ref s), trait_, .. }),
+ ty:
+ clean::QPath(box clean::QPathData {
+ self_type: clean::Generic(ref s),
+ trait_: Some(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 23449a25c3a..59a3e631724 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -119,7 +119,39 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
});
let kind = ModuleItem(Module { items, span });
- Item::from_def_id_and_parts(doc.def_id.to_def_id(), Some(doc.name), kind, cx)
+ generate_item_with_correct_attrs(cx, kind, doc.def_id, doc.name, doc.import_id, doc.renamed)
+}
+
+fn generate_item_with_correct_attrs(
+ cx: &mut DocContext<'_>,
+ kind: ItemKind,
+ local_def_id: LocalDefId,
+ name: Symbol,
+ import_id: Option<LocalDefId>,
+ renamed: Option<Symbol>,
+) -> Item {
+ let def_id = local_def_id.to_def_id();
+ let target_attrs = inline::load_attrs(cx, def_id);
+ let attrs = if let Some(import_id) = import_id {
+ let is_inline = inline::load_attrs(cx, import_id.to_def_id())
+ .lists(sym::doc)
+ .get_word_attr(sym::inline)
+ .is_some();
+ let mut attrs = get_all_import_attributes(cx, import_id, local_def_id, is_inline);
+ add_without_unwanted_attributes(&mut attrs, target_attrs, is_inline, None);
+ attrs
+ } else {
+ // We only keep the item's attributes.
+ target_attrs.iter().map(|attr| (Cow::Borrowed(attr), None)).collect()
+ };
+
+ let cfg = attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
+ let attrs = Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false);
+
+ let name = renamed.or(Some(name));
+ let mut item = Item::from_def_id_and_attrs_and_parts(def_id, name, kind, Box::new(attrs), cfg);
+ item.inline_stmt_id = import_id.map(|local| local.to_def_id());
+ item
}
fn clean_generic_bound<'tcx>(
@@ -441,7 +473,7 @@ fn clean_projection<'tcx>(
assoc: projection_to_path_segment(ty, cx),
should_show_cast,
self_type,
- trait_,
+ trait_: Some(trait_),
}))
}
@@ -1330,7 +1362,13 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
let mut bounds: Vec<GenericBound> = Vec::new();
generics.where_predicates.retain_mut(|pred| match *pred {
WherePredicate::BoundPredicate {
- ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }),
+ ty:
+ QPath(box QPathData {
+ ref assoc,
+ ref self_type,
+ trait_: Some(ref trait_),
+ ..
+ }),
bounds: ref mut pred_bounds,
..
} => {
@@ -1492,25 +1530,30 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
assoc: clean_path_segment(p.segments.last().expect("segments were empty"), cx),
should_show_cast,
self_type,
- trait_,
+ trait_: Some(trait_),
}))
}
hir::QPath::TypeRelative(qself, segment) => {
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
- let res = match ty.kind() {
+ let self_type = clean_ty(qself, cx);
+
+ let (trait_, should_show_cast) = match ty.kind() {
ty::Alias(ty::Projection, proj) => {
- Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id)
+ let res = Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id);
+ let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx);
+ register_res(cx, trait_.res);
+ let self_def_id = res.opt_def_id();
+ let should_show_cast =
+ compute_should_show_cast(self_def_id, &trait_, &self_type);
+
+ (Some(trait_), should_show_cast)
}
+ ty::Alias(ty::Inherent, _) => (None, false),
// Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s.
ty::Error(_) => return Type::Infer,
- // Otherwise, this is an inherent associated type.
- _ => return clean_middle_ty(ty::Binder::dummy(ty), cx, None),
+ _ => bug!("clean: expected associated type, found `{ty:?}`"),
};
- let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx);
- register_res(cx, trait_.res);
- 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(Box::new(QPathData {
assoc: clean_path_segment(segment, cx),
should_show_cast,
@@ -1836,6 +1879,29 @@ pub(crate) fn clean_middle_ty<'tcx>(
clean_projection(bound_ty.rebind(*data), cx, parent_def_id)
}
+ ty::Alias(ty::Inherent, alias_ty) => {
+ let alias_ty = bound_ty.rebind(alias_ty);
+ let self_type = clean_middle_ty(alias_ty.map_bound(|ty| ty.self_ty()), cx, None);
+
+ Type::QPath(Box::new(QPathData {
+ assoc: PathSegment {
+ name: cx.tcx.associated_item(alias_ty.skip_binder().def_id).name,
+ args: GenericArgs::AngleBracketed {
+ args: substs_to_args(
+ cx,
+ alias_ty.map_bound(|ty| ty.substs.as_slice()),
+ true,
+ )
+ .into(),
+ bindings: Default::default(),
+ },
+ },
+ should_show_cast: false,
+ self_type,
+ trait_: None,
+ }))
+ }
+
ty::Param(ref p) => {
if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) {
ImplTrait(bounds)
@@ -2311,29 +2377,14 @@ fn clean_maybe_renamed_item<'tcx>(
_ => unreachable!("not yet converted"),
};
- let target_attrs = inline::load_attrs(cx, def_id);
- let attrs = if let Some(import_id) = import_id {
- let is_inline = inline::load_attrs(cx, import_id.to_def_id())
- .lists(sym::doc)
- .get_word_attr(sym::inline)
- .is_some();
- let mut attrs =
- get_all_import_attributes(cx, import_id, item.owner_id.def_id, is_inline);
- add_without_unwanted_attributes(&mut attrs, target_attrs, is_inline, None);
- attrs
- } else {
- // We only keep the item's attributes.
- target_attrs.iter().map(|attr| (Cow::Borrowed(attr), None)).collect()
- };
-
- let cfg = attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
- let attrs =
- Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false);
-
- let mut item =
- Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg);
- item.inline_stmt_id = import_id.map(|local| local.to_def_id());
- vec![item]
+ vec![generate_item_with_correct_attrs(
+ cx,
+ kind,
+ item.owner_id.def_id,
+ name,
+ import_id,
+ renamed,
+ )]
})
}
@@ -2363,14 +2414,15 @@ fn clean_impl<'tcx>(
}
let for_ = clean_ty(impl_.self_ty, cx);
- let type_alias = for_.def_id(&cx.cache).and_then(|did| match tcx.def_kind(did) {
- DefKind::TyAlias => Some(clean_middle_ty(
- ty::Binder::dummy(tcx.type_of(did).subst_identity()),
- cx,
- Some(did),
- )),
- _ => None,
- });
+ let type_alias =
+ for_.def_id(&cx.cache).and_then(|alias_def_id: DefId| match tcx.def_kind(alias_def_id) {
+ DefKind::TyAlias => Some(clean_middle_ty(
+ ty::Binder::dummy(tcx.type_of(def_id).subst_identity()),
+ cx,
+ Some(def_id.to_def_id()),
+ )),
+ _ => None,
+ });
let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| {
let kind = ImplItem(Box::new(Impl {
unsafety: impl_.unsafety,
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 7371b44465b..38664c3e359 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1660,7 +1660,7 @@ impl Type {
pub(crate) fn projection(&self) -> Option<(&Type, DefId, PathSegment)> {
if let QPath(box QPathData { self_type, trait_, assoc, .. }) = self {
- Some((self_type, trait_.def_id(), assoc.clone()))
+ Some((self_type, trait_.as_ref()?.def_id(), assoc.clone()))
} else {
None
}
@@ -1704,7 +1704,7 @@ pub(crate) struct QPathData {
pub self_type: Type,
/// FIXME: compute this field on demand.
pub should_show_cast: bool,
- pub trait_: Path,
+ pub trait_: Option<Path>,
}
/// A primitive (aka, builtin) type.
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index b802fd065fe..17aa6b38e38 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -594,9 +594,8 @@ pub(super) fn display_macro_source(
def_id: DefId,
vis: ty::Visibility<DefId>,
) -> String {
- let tts: Vec<_> = def.body.tokens.clone().into_trees().collect();
// Extract the spans of all matchers. They represent the "interface" of the macro.
- let matchers = tts.chunks(4).map(|arm| &arm[0]);
+ let matchers = def.body.tokens.chunks(4).map(|arm| &arm[0]);
if def.macro_rules {
format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(cx.tcx, matchers, ";"))
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 841abfab666..c0730e90740 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -195,7 +195,13 @@ impl Cache {
impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
if item.item_id.is_local() {
- debug!("folding {} \"{:?}\", id {:?}", item.type_(), item.name, item.item_id);
+ let is_stripped = matches!(*item.kind, clean::ItemKind::StrippedItem(..));
+ debug!(
+ "folding {} (stripped: {is_stripped:?}) \"{:?}\", id {:?}",
+ item.type_(),
+ item.name,
+ item.item_id
+ );
}
// If this is a stripped module,
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 1c6810bdaf9..d963d6092c4 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1116,14 +1116,17 @@ fn fmt_type<'cx>(
ref trait_,
should_show_cast,
}) => {
+ // FIXME(inherent_associated_types): Once we support non-ADT self-types (#106719),
+ // we need to surround them with angle brackets in some cases (e.g. `<dyn …>::P`).
+
if f.alternate() {
- if should_show_cast {
+ if let Some(trait_) = trait_ && should_show_cast {
write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))?
} else {
write!(f, "{:#}::", self_type.print(cx))?
}
} else {
- if should_show_cast {
+ if let Some(trait_) = trait_ && should_show_cast {
write!(f, "&lt;{} as {}&gt;::", self_type.print(cx), trait_.print(cx))?
} else {
write!(f, "{}::", self_type.print(cx))?
@@ -1139,15 +1142,36 @@ fn fmt_type<'cx>(
// the ugliness comes from inlining across crates where
// everything comes in as a fully resolved QPath (hard to
// look at).
- if !f.alternate() && let Ok((url, _, path)) = href(trait_.def_id(), cx) {
- write!(
- f,
- "<a class=\"associatedtype\" href=\"{url}#{shortty}.{name}\" \
- title=\"type {path}::{name}\">{name}</a>",
- shortty = ItemType::AssocType,
- name = assoc.name,
- path = join_with_double_colon(&path),
- )
+ if !f.alternate() {
+ // FIXME(inherent_associated_types): We always link to the very first associated
+ // type (in respect to source order) that bears the given name (`assoc.name`) and that is
+ // affiliated with the computed `DefId`. This is obviously incorrect when we have
+ // multiple impl blocks. Ideally, we would thread the `DefId` of the assoc ty itself
+ // through here and map it to the corresponding HTML ID that was generated by
+ // `render::Context::derive_id` when the impl blocks were rendered.
+ // There is no such mapping unfortunately.
+ // As a hack, we could badly imitate `derive_id` here by keeping *count* when looking
+ // for the assoc ty `DefId` in `tcx.associated_items(self_ty_did).in_definition_order()`
+ // considering privacy, `doc(hidden)`, etc.
+ // I don't feel like that right now :cold_sweat:.
+
+ let parent_href = match trait_ {
+ Some(trait_) => href(trait_.def_id(), cx).ok(),
+ None => self_type.def_id(cx.cache()).and_then(|did| href(did, cx).ok()),
+ };
+
+ if let Some((url, _, path)) = parent_href {
+ write!(
+ f,
+ "<a class=\"associatedtype\" href=\"{url}#{shortty}.{name}\" \
+ title=\"type {path}::{name}\">{name}</a>",
+ shortty = ItemType::AssocType,
+ name = assoc.name,
+ path = join_with_double_colon(&path),
+ )
+ } else {
+ write!(f, "{}", assoc.name)
+ }
} else {
write!(f, "{}", assoc.name)
}?;
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index e09c6480060..0a2f5f6653c 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1751,7 +1751,7 @@ fn render_impl(
if trait_.is_none() && i.inner_impl().items.is_empty() {
w.write_str(
"<div class=\"item-info\">\
- <div class=\"stab empty-impl\">This impl block contains no items.</div>
+ <div class=\"stab empty-impl\">This impl block contains no items.</div>\
</div>",
);
}
@@ -2202,7 +2202,9 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
}
clean::Type::QPath(box clean::QPathData { self_type, trait_, .. }) => {
work.push_back(self_type);
- process_path(trait_.def_id());
+ if let Some(trait_) = trait_ {
+ process_path(trait_.def_id());
+ }
}
_ => {}
}
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index b5bebb70593..b1cef20b434 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -574,7 +574,7 @@ impl FromWithTcx<clean::Type> for Type {
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),
+ trait_: trait_.map(|trait_| trait_.into_tcx(tcx)),
},
}
}
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index b6eb450d62b..5460bce21a5 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -739,6 +739,9 @@ fn main_args(at_args: &[String]) -> MainResult {
}
};
+ // Set parallel mode before error handler creation, which will create `Lock`s.
+ interface::set_thread_safe_mode(&options.unstable_opts);
+
let diag = core::new_handler(
options.error_format,
None,
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index 6b13e6c9581..10295cbd189 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -95,7 +95,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
}
if cx.tcx.is_doc_hidden(def_id.to_def_id())
- || inherits_doc_hidden(cx.tcx, def_id)
+ || inherits_doc_hidden(cx.tcx, def_id, None)
|| cx.tcx.def_span(def_id.to_def_id()).in_derive_expansion()
{
return false;
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index a688aa14863..972b0c5ec19 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -1,5 +1,6 @@
//! Strip all doc(hidden) items from the output.
+use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::sym;
use std::mem;
@@ -29,6 +30,7 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
update_retained: true,
tcx: cx.tcx,
is_in_hidden_item: false,
+ last_reexport: None,
};
stripper.fold_crate(krate)
};
@@ -49,13 +51,24 @@ struct Stripper<'a, 'tcx> {
update_retained: bool,
tcx: TyCtxt<'tcx>,
is_in_hidden_item: bool,
+ last_reexport: Option<LocalDefId>,
}
impl<'a, 'tcx> Stripper<'a, 'tcx> {
+ fn set_last_reexport_then_fold_item(&mut self, i: Item) -> Item {
+ let prev_from_reexport = self.last_reexport;
+ if i.inline_stmt_id.is_some() {
+ self.last_reexport = i.item_id.as_def_id().and_then(|def_id| def_id.as_local());
+ }
+ let ret = self.fold_item_recur(i);
+ self.last_reexport = prev_from_reexport;
+ ret
+ }
+
fn set_is_in_hidden_item_and_fold(&mut self, is_in_hidden_item: bool, i: Item) -> Item {
let prev = self.is_in_hidden_item;
self.is_in_hidden_item |= is_in_hidden_item;
- let ret = self.fold_item_recur(i);
+ let ret = self.set_last_reexport_then_fold_item(i);
self.is_in_hidden_item = prev;
ret
}
@@ -64,7 +77,7 @@ impl<'a, 'tcx> Stripper<'a, 'tcx> {
/// of `is_in_hidden_item` to `true` because the impl children inherit its visibility.
fn recurse_in_impl_or_exported_macro(&mut self, i: Item) -> Item {
let prev = mem::replace(&mut self.is_in_hidden_item, false);
- let ret = self.fold_item_recur(i);
+ let ret = self.set_last_reexport_then_fold_item(i);
self.is_in_hidden_item = prev;
ret
}
@@ -86,13 +99,20 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
if !is_impl_or_exported_macro {
is_hidden = self.is_in_hidden_item || has_doc_hidden;
if !is_hidden && i.inline_stmt_id.is_none() {
- // We don't need to check if it's coming from a reexport since the reexport itself was
- // already checked.
+ // `i.inline_stmt_id` is `Some` if the item is directly reexported. If it is, we
+ // don't need to check it, because the reexport itself was already checked.
+ //
+ // If this item is the child of a reexported module, `self.last_reexport` will be
+ // `Some` even though `i.inline_stmt_id` is `None`. Hiddenness inheritance needs to
+ // account for the possibility that an item's true parent module is hidden, but it's
+ // inlined into a visible module true. This code shouldn't be reachable if the
+ // module's reexport is itself hidden, for the same reason it doesn't need to be
+ // checked if `i.inline_stmt_id` is Some: hidden reexports are never inlined.
is_hidden = i
.item_id
.as_def_id()
.and_then(|def_id| def_id.as_local())
- .map(|def_id| inherits_doc_hidden(self.tcx, def_id))
+ .map(|def_id| inherits_doc_hidden(self.tcx, def_id, self.last_reexport))
.unwrap_or(false);
}
}
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 841c7a78b2d..8f8dc6b7090 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet};
-use rustc_hir::intravisit::{walk_item, Visitor};
+use rustc_hir::intravisit::{walk_body, walk_item, Visitor};
use rustc_hir::{Node, CRATE_HIR_ID};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::TyCtxt;
@@ -27,6 +27,8 @@ pub(crate) struct Module<'hir> {
pub(crate) where_inner: Span,
pub(crate) mods: Vec<Module<'hir>>,
pub(crate) def_id: LocalDefId,
+ pub(crate) renamed: Option<Symbol>,
+ pub(crate) import_id: Option<LocalDefId>,
/// The key is the item `ItemId` and the value is: (item, renamed, import_id).
/// We use `FxIndexMap` to keep the insert order.
pub(crate) items: FxIndexMap<
@@ -37,11 +39,19 @@ pub(crate) struct Module<'hir> {
}
impl Module<'_> {
- pub(crate) fn new(name: Symbol, def_id: LocalDefId, where_inner: Span) -> Self {
+ pub(crate) fn new(
+ name: Symbol,
+ def_id: LocalDefId,
+ where_inner: Span,
+ renamed: Option<Symbol>,
+ import_id: Option<LocalDefId>,
+ ) -> Self {
Module {
name,
def_id,
where_inner,
+ renamed,
+ import_id,
mods: Vec::new(),
items: FxIndexMap::default(),
foreigns: Vec::new(),
@@ -60,9 +70,16 @@ fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec<Symbol> {
std::iter::once(crate_name).chain(relative).collect()
}
-pub(crate) fn inherits_doc_hidden(tcx: TyCtxt<'_>, mut def_id: LocalDefId) -> bool {
+pub(crate) fn inherits_doc_hidden(
+ tcx: TyCtxt<'_>,
+ mut def_id: LocalDefId,
+ stop_at: Option<LocalDefId>,
+) -> bool {
let hir = tcx.hir();
while let Some(id) = tcx.opt_local_parent(def_id) {
+ if let Some(stop_at) = stop_at && id == stop_at {
+ return false;
+ }
def_id = id;
if tcx.is_doc_hidden(def_id.to_def_id()) {
return true;
@@ -89,6 +106,7 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> {
exact_paths: DefIdMap<Vec<Symbol>>,
modules: Vec<Module<'tcx>>,
is_importable_from_parent: bool,
+ inside_body: bool,
}
impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
@@ -100,6 +118,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
cx.tcx.crate_name(LOCAL_CRATE),
CRATE_DEF_ID,
cx.tcx.hir().root_module().spans.inner_span,
+ None,
+ None,
);
RustdocVisitor {
@@ -110,6 +130,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
exact_paths: Default::default(),
modules: vec![om],
is_importable_from_parent: true,
+ inside_body: false,
}
}
@@ -261,7 +282,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let is_private =
!self.cx.cache.effective_visibilities.is_directly_public(self.cx.tcx, ori_res_did);
- let is_hidden = inherits_doc_hidden(self.cx.tcx, res_did);
+ let is_hidden = inherits_doc_hidden(self.cx.tcx, res_did, None);
// Only inline if requested or if the item would otherwise be stripped.
if (!please_inline && !is_private && !is_hidden) || is_no_inline {
@@ -278,7 +299,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
.cache
.effective_visibilities
.is_directly_public(self.cx.tcx, item_def_id.to_def_id()) &&
- !inherits_doc_hidden(self.cx.tcx, item_def_id)
+ !inherits_doc_hidden(self.cx.tcx, item_def_id, None)
{
// The imported item is public and not `doc(hidden)` so no need to inline it.
return false;
@@ -349,6 +370,26 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
import_id: Option<LocalDefId>,
) {
debug!("visiting item {:?}", item);
+ if self.inside_body {
+ // Only impls can be "seen" outside a body. For example:
+ //
+ // ```
+ // struct Bar;
+ //
+ // fn foo() {
+ // impl Bar { fn bar() {} }
+ // }
+ // Bar::bar();
+ // ```
+ if let hir::ItemKind::Impl(impl_) = item.kind &&
+ // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
+ // them up regardless of where they're located.
+ impl_.of_trait.is_none()
+ {
+ self.add_to_current_mod(item, None, None);
+ }
+ return;
+ }
let name = renamed.unwrap_or(item.ident.name);
let tcx = self.cx.tcx;
@@ -427,7 +468,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
}
}
hir::ItemKind::Mod(ref m) => {
- self.enter_mod(item.owner_id.def_id, m, name);
+ self.enter_mod(item.owner_id.def_id, m, name, renamed, import_id);
}
hir::ItemKind::Fn(..)
| hir::ItemKind::ExternCrate(..)
@@ -436,7 +477,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
| hir::ItemKind::Union(..)
| hir::ItemKind::TyAlias(..)
| hir::ItemKind::OpaqueTy(hir::OpaqueTy {
- origin: hir::OpaqueTyOrigin::TyAlias, ..
+ origin: hir::OpaqueTyOrigin::TyAlias { .. },
+ ..
})
| hir::ItemKind::Static(..)
| hir::ItemKind::Trait(..)
@@ -480,8 +522,15 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
/// This method will create a new module and push it onto the "modules stack" then call
/// `visit_mod_contents`. Once done, it'll remove it from the "modules stack" and instead
/// add into the list of modules of the current module.
- fn enter_mod(&mut self, id: LocalDefId, m: &'tcx hir::Mod<'tcx>, name: Symbol) {
- self.modules.push(Module::new(name, id, m.spans.inner_span));
+ fn enter_mod(
+ &mut self,
+ id: LocalDefId,
+ m: &'tcx hir::Mod<'tcx>,
+ name: Symbol,
+ renamed: Option<Symbol>,
+ import_id: Option<LocalDefId>,
+ ) {
+ self.modules.push(Module::new(name, id, m.spans.inner_span, renamed, import_id));
self.visit_mod_contents(id, m);
@@ -501,19 +550,14 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
self.visit_item_inner(i, None, None);
- let new_value = if self.is_importable_from_parent {
- matches!(
+ let new_value = self.is_importable_from_parent
+ && matches!(
i.kind,
hir::ItemKind::Mod(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::Impl(..)
| hir::ItemKind::Trait(..)
- )
- } else {
- // Whatever the context, if it's an impl block, the items inside it can be used so they
- // should be visible.
- matches!(i.kind, hir::ItemKind::Impl(..))
- };
+ );
let prev = mem::replace(&mut self.is_importable_from_parent, new_value);
walk_item(self, i);
self.is_importable_from_parent = prev;
@@ -542,4 +586,10 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> {
fn visit_lifetime(&mut self, _: &hir::Lifetime) {
// Unneeded.
}
+
+ fn visit_body(&mut self, b: &'tcx hir::Body<'tcx>) {
+ let prev = mem::replace(&mut self.inside_body, true);
+ walk_body(self, b);
+ self.inside_body = prev;
+ }
}
diff --git a/src/llvm-project b/src/llvm-project
-Subproject ea6fa9c2d43aaf0f11559719eda9b54d356d541
+Subproject 533d3f338b804d54e5d0ac4fba6276af23002d9
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 3cf8ceed620..3556834071f 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use std::path::PathBuf;
/// rustdoc format-version.
-pub const FORMAT_VERSION: u32 = 24;
+pub const FORMAT_VERSION: u32 = 25;
/// 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
@@ -581,13 +581,15 @@ pub enum Type {
#[serde(rename = "type")]
type_: Box<Type>,
},
- /// `<Type as Trait>::Name` or associated types like `T::Item` where `T: Iterator`
+ /// Associated types like `<Type as Trait>::Name` and `T::Item` where
+ /// `T: Iterator` or inherent associated types like `Struct::Name`.
QualifiedPath {
name: String,
args: Box<GenericArgs>,
self_type: Box<Type>,
+ /// `None` iff this is an *inherent* associated type.
#[serde(rename = "trait")]
- trait_: Path,
+ trait_: Option<Path>,
},
}
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 569b648b5831ae8a515e90c80843a5287c3304e
+Subproject 09276c703a473ab33daaeb94917232e80eefd62
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 79d0f6f3607..04993e49287 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -132,12 +132,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::doc::NEEDLESS_DOCTEST_MAIN_INFO,
crate::doc::UNNECESSARY_SAFETY_DOC_INFO,
crate::double_parens::DOUBLE_PARENS_INFO,
- crate::drop_forget_ref::DROP_COPY_INFO,
crate::drop_forget_ref::DROP_NON_DROP_INFO,
- crate::drop_forget_ref::DROP_REF_INFO,
- crate::drop_forget_ref::FORGET_COPY_INFO,
crate::drop_forget_ref::FORGET_NON_DROP_INFO,
- crate::drop_forget_ref::FORGET_REF_INFO,
crate::drop_forget_ref::UNDROPPED_MANUALLY_DROPS_INFO,
crate::duplicate_mod::DUPLICATE_MOD_INFO,
crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 7f3f26bed7c..b27ffe73ffd 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1424,6 +1424,7 @@ fn ty_auto_deref_stability<'tcx>(
continue;
},
ty::Param(_) => TyPosition::new_deref_stable_for_result(precedence, ty),
+ ty::Alias(ty::Inherent, _) => unreachable!("inherent projection should have been normalized away above"),
ty::Alias(ty::Projection, _) if ty.has_non_region_param() => {
TyPosition::new_deref_stable_for_result(precedence, ty)
},
diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
index 11e1bcdf12d..b2f7d026cc8 100644
--- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
@@ -9,102 +9,6 @@ use rustc_span::sym;
declare_clippy_lint! {
/// ### 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
- /// ```ignore
- /// 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();
- /// ```
- #[clippy::version = "pre 1.29.0"]
- pub DROP_REF,
- correctness,
- "calls to `std::mem::drop` with a reference instead of an owned value"
-}
-
-declare_clippy_lint! {
- /// ### 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
- /// ```rust
- /// let x = Box::new(1);
- /// std::mem::forget(&x) // Should have been forget(x), x will still be dropped
- /// ```
- #[clippy::version = "pre 1.29.0"]
- pub FORGET_REF,
- correctness,
- "calls to `std::mem::forget` with a reference instead of an owned value"
-}
-
-declare_clippy_lint! {
- /// ### 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
- /// ```rust
- /// let x: i32 = 42; // i32 implements Copy
- /// std::mem::drop(x) // A copy of x is passed to the function, leaving the
- /// // original unaffected
- /// ```
- #[clippy::version = "pre 1.29.0"]
- pub DROP_COPY,
- correctness,
- "calls to `std::mem::drop` with a value that implements Copy"
-}
-
-declare_clippy_lint! {
- /// ### 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
- /// ```rust
- /// let x: i32 = 42; // i32 implements Copy
- /// std::mem::forget(x) // A copy of x is passed to the function, leaving the
- /// // original unaffected
- /// ```
- #[clippy::version = "pre 1.29.0"]
- pub FORGET_COPY,
- correctness,
- "calls to `std::mem::forget` with a value that implements Copy"
-}
-
-declare_clippy_lint! {
- /// ### What it does
/// Checks for calls to `std::mem::drop` with a value that does not implement `Drop`.
///
/// ### Why is this bad?
@@ -172,24 +76,12 @@ declare_clippy_lint! {
"use of safe `std::mem::drop` function to drop a std::mem::ManuallyDrop, which will not drop the inner value"
}
-const DROP_REF_SUMMARY: &str = "calls to `std::mem::drop` with a reference instead of an owned value. \
- Dropping a reference does nothing";
-const FORGET_REF_SUMMARY: &str = "calls to `std::mem::forget` with a reference instead of an owned value. \
- Forgetting a reference does nothing";
-const DROP_COPY_SUMMARY: &str = "calls to `std::mem::drop` with a value that implements `Copy`. \
- Dropping a copy leaves the original intact";
-const FORGET_COPY_SUMMARY: &str = "calls to `std::mem::forget` with a value that implements `Copy`. \
- Forgetting a copy leaves the original intact";
const DROP_NON_DROP_SUMMARY: &str = "call to `std::mem::drop` with a value that does not implement `Drop`. \
Dropping such a type only extends its contained lifetimes";
const FORGET_NON_DROP_SUMMARY: &str = "call to `std::mem::forget` with a value that does not implement `Drop`. \
Forgetting such a type is the same as dropping it";
declare_lint_pass!(DropForgetRef => [
- DROP_REF,
- FORGET_REF,
- DROP_COPY,
- FORGET_COPY,
DROP_NON_DROP,
FORGET_NON_DROP,
UNDROPPED_MANUALLY_DROPS
@@ -206,10 +98,11 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
let is_copy = is_copy(cx, arg_ty);
let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
let (lint, msg) = match fn_name {
- sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => (DROP_REF, DROP_REF_SUMMARY),
- sym::mem_forget if arg_ty.is_ref() => (FORGET_REF, FORGET_REF_SUMMARY),
- sym::mem_drop if is_copy && !drop_is_single_call_in_arm => (DROP_COPY, DROP_COPY_SUMMARY),
- sym::mem_forget if is_copy => (FORGET_COPY, FORGET_COPY_SUMMARY),
+ // early return for uplifted lints: drop_ref, drop_copy, forget_ref, forget_copy
+ sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return,
+ sym::mem_forget if arg_ty.is_ref() => return,
+ sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return,
+ sym::mem_forget if is_copy => return,
sym::mem_drop if is_type_lang_item(cx, arg_ty, LangItem::ManuallyDrop) => {
span_lint_and_help(
cx,
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 af121f317cd..0809837d1fd 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
@@ -289,10 +289,11 @@ fn is_pat_variant(cx: &LateContext<'_>, pat: &Pat<'_>, path: &QPath<'_>, expecte
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::Lang(expected_lang_item) => cx
+ .tcx
+ .lang_items()
+ .get(expected_lang_item)
+ .map_or(false, |expected_id| cx.tcx.parent(id) == expected_id),
Item::Diag(expected_ty, expected_variant) => {
let ty = cx.typeck_results().pat_ty(pat);
diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
index 5e81a01a461..52e22c0c630 100644
--- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
@@ -32,9 +32,13 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
("clippy::zero_width_space", "clippy::invisible_characters"),
("clippy::clone_double_ref", "suspicious_double_ref_op"),
("clippy::drop_bounds", "drop_bounds"),
+ ("clippy::drop_copy", "drop_copy"),
+ ("clippy::drop_ref", "drop_ref"),
("clippy::for_loop_over_option", "for_loops_over_fallibles"),
("clippy::for_loop_over_result", "for_loops_over_fallibles"),
("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"),
+ ("clippy::forget_copy", "forget_copy"),
+ ("clippy::forget_ref", "forget_ref"),
("clippy::into_iter_on_array", "array_into_iter"),
("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"),
("clippy::invalid_ref", "invalid_value"),
diff --git a/src/tools/clippy/tests/ui/diverging_sub_expression.stderr b/src/tools/clippy/tests/ui/diverging_sub_expression.stderr
index 9c91d935716..51a3b0d972e 100644
--- a/src/tools/clippy/tests/ui/diverging_sub_expression.stderr
+++ b/src/tools/clippy/tests/ui/diverging_sub_expression.stderr
@@ -31,18 +31,10 @@ LL | 3 => true || diverge(),
| ^^^^^^^^^
error: sub-expression diverges
- --> $DIR/diverging_sub_expression.rs:36:30
- |
-LL | _ => true || panic!("boo"),
- | ^^^^^^^^^^^^^
- |
- = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: sub-expression diverges
--> $DIR/diverging_sub_expression.rs:38:26
|
LL | _ => true || break,
| ^^^^^
-error: aborting due to 7 previous errors
+error: aborting due to 6 previous errors
diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.rs b/src/tools/clippy/tests/ui/drop_forget_copy.rs
deleted file mode 100644
index a7276dd59f4..00000000000
--- a/src/tools/clippy/tests/ui/drop_forget_copy.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-#![warn(clippy::drop_copy, clippy::forget_copy)]
-#![allow(clippy::toplevel_ref_arg, clippy::drop_ref, clippy::forget_ref, unused_mut)]
-
-use std::mem::{drop, forget};
-use std::vec::Vec;
-
-#[derive(Copy, Clone)]
-struct SomeStruct;
-
-struct AnotherStruct {
- x: u8,
- y: u8,
- z: Vec<u8>,
-}
-
-impl Clone for AnotherStruct {
- fn clone(&self) -> AnotherStruct {
- AnotherStruct {
- x: self.x,
- y: self.y,
- z: self.z.clone(),
- }
- }
-}
-
-fn main() {
- let s1 = SomeStruct {};
- let s2 = s1;
- let s3 = &s1;
- let mut s4 = s1;
- let ref s5 = s1;
-
- drop(s1);
- drop(s2);
- drop(s3);
- drop(s4);
- drop(s5);
-
- forget(s1);
- forget(s2);
- forget(s3);
- forget(s4);
- forget(s5);
-
- let a1 = AnotherStruct {
- x: 255,
- y: 0,
- z: vec![1, 2, 3],
- };
- let a2 = &a1;
- let mut a3 = a1.clone();
- let ref a4 = a1;
- let a5 = a1.clone();
-
- drop(a2);
- drop(a3);
- drop(a4);
- drop(a5);
-
- forget(a2);
- let a3 = &a1;
- forget(a3);
- forget(a4);
- let a5 = a1.clone();
- forget(a5);
-}
-
-#[allow(unused)]
-#[allow(clippy::unit_cmp)]
-fn issue9482(x: u8) {
- fn println_and<T>(t: T) -> T {
- println!("foo");
- t
- }
-
- match x {
- 0 => drop(println_and(12)), // Don't lint (copy type), we only care about side-effects
- 1 => drop(println_and(String::new())), // Don't lint (no copy type), we only care about side-effects
- 2 => {
- drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block
- },
- 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm`
- 4 => drop(2), // Lint, not a fn/method call
- _ => (),
- }
-}
diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.stderr b/src/tools/clippy/tests/ui/drop_forget_copy.stderr
deleted file mode 100644
index 90bef1c3c43..00000000000
--- a/src/tools/clippy/tests/ui/drop_forget_copy.stderr
+++ /dev/null
@@ -1,112 +0,0 @@
-error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact
- --> $DIR/drop_forget_copy.rs:33:5
- |
-LL | drop(s1);
- | ^^^^^^^^
- |
-note: argument has type `SomeStruct`
- --> $DIR/drop_forget_copy.rs:33:10
- |
-LL | drop(s1);
- | ^^
- = note: `-D clippy::drop-copy` implied by `-D warnings`
-
-error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact
- --> $DIR/drop_forget_copy.rs:34:5
- |
-LL | drop(s2);
- | ^^^^^^^^
- |
-note: argument has type `SomeStruct`
- --> $DIR/drop_forget_copy.rs:34:10
- |
-LL | drop(s2);
- | ^^
-
-error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact
- --> $DIR/drop_forget_copy.rs:36:5
- |
-LL | drop(s4);
- | ^^^^^^^^
- |
-note: argument has type `SomeStruct`
- --> $DIR/drop_forget_copy.rs:36:10
- |
-LL | drop(s4);
- | ^^
-
-error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact
- --> $DIR/drop_forget_copy.rs:39:5
- |
-LL | forget(s1);
- | ^^^^^^^^^^
- |
-note: argument has type `SomeStruct`
- --> $DIR/drop_forget_copy.rs:39:12
- |
-LL | forget(s1);
- | ^^
- = note: `-D clippy::forget-copy` implied by `-D warnings`
-
-error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact
- --> $DIR/drop_forget_copy.rs:40:5
- |
-LL | forget(s2);
- | ^^^^^^^^^^
- |
-note: argument has type `SomeStruct`
- --> $DIR/drop_forget_copy.rs:40:12
- |
-LL | forget(s2);
- | ^^
-
-error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact
- --> $DIR/drop_forget_copy.rs:42:5
- |
-LL | forget(s4);
- | ^^^^^^^^^^
- |
-note: argument has type `SomeStruct`
- --> $DIR/drop_forget_copy.rs:42:12
- |
-LL | forget(s4);
- | ^^
-
-error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact
- --> $DIR/drop_forget_copy.rs:80:13
- |
-LL | drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block
- | ^^^^^^^^^^^^^^^^^^^^^
- |
-note: argument has type `i32`
- --> $DIR/drop_forget_copy.rs:80:18
- |
-LL | drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block
- | ^^^^^^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact
- --> $DIR/drop_forget_copy.rs:82:14
- |
-LL | 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm`
- | ^^^^^^^^^^^^^^^^^^^^^
- |
-note: argument has type `i32`
- --> $DIR/drop_forget_copy.rs:82:19
- |
-LL | 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm`
- | ^^^^^^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact
- --> $DIR/drop_forget_copy.rs:83:14
- |
-LL | 4 => drop(2), // Lint, not a fn/method call
- | ^^^^^^^
- |
-note: argument has type `i32`
- --> $DIR/drop_forget_copy.rs:83:19
- |
-LL | 4 => drop(2), // Lint, not a fn/method call
- | ^
-
-error: aborting due to 9 previous errors
-
diff --git a/src/tools/clippy/tests/ui/drop_ref.stderr b/src/tools/clippy/tests/ui/drop_ref.stderr
deleted file mode 100644
index 293b9f6de83..00000000000
--- a/src/tools/clippy/tests/ui/drop_ref.stderr
+++ /dev/null
@@ -1,147 +0,0 @@
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
- --> $DIR/drop_ref.rs:11:5
- |
-LL | drop(&SomeStruct);
- | ^^^^^^^^^^^^^^^^^
- |
-note: argument has type `&SomeStruct`
- --> $DIR/drop_ref.rs:11:10
- |
-LL | drop(&SomeStruct);
- | ^^^^^^^^^^^
- = note: `-D clippy::drop-ref` implied by `-D warnings`
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
- --> $DIR/drop_ref.rs:14:5
- |
-LL | drop(&owned1);
- | ^^^^^^^^^^^^^
- |
-note: argument has type `&SomeStruct`
- --> $DIR/drop_ref.rs:14:10
- |
-LL | drop(&owned1);
- | ^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
- --> $DIR/drop_ref.rs:15:5
- |
-LL | drop(&&owned1);
- | ^^^^^^^^^^^^^^
- |
-note: argument has type `&&SomeStruct`
- --> $DIR/drop_ref.rs:15:10
- |
-LL | drop(&&owned1);
- | ^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
- --> $DIR/drop_ref.rs:16:5
- |
-LL | drop(&mut owned1);
- | ^^^^^^^^^^^^^^^^^
- |
-note: argument has type `&mut SomeStruct`
- --> $DIR/drop_ref.rs:16:10
- |
-LL | drop(&mut owned1);
- | ^^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
- --> $DIR/drop_ref.rs:20:5
- |
-LL | drop(reference1);
- | ^^^^^^^^^^^^^^^^
- |
-note: argument has type `&SomeStruct`
- --> $DIR/drop_ref.rs:20:10
- |
-LL | drop(reference1);
- | ^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
- --> $DIR/drop_ref.rs:23:5
- |
-LL | drop(reference2);
- | ^^^^^^^^^^^^^^^^
- |
-note: argument has type `&mut SomeStruct`
- --> $DIR/drop_ref.rs:23:10
- |
-LL | drop(reference2);
- | ^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
- --> $DIR/drop_ref.rs:26:5
- |
-LL | drop(reference3);
- | ^^^^^^^^^^^^^^^^
- |
-note: argument has type `&SomeStruct`
- --> $DIR/drop_ref.rs:26:10
- |
-LL | drop(reference3);
- | ^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
- --> $DIR/drop_ref.rs:31:5
- |
-LL | drop(&val);
- | ^^^^^^^^^^
- |
-note: argument has type `&T`
- --> $DIR/drop_ref.rs:31:10
- |
-LL | drop(&val);
- | ^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
- --> $DIR/drop_ref.rs:39:5
- |
-LL | std::mem::drop(&SomeStruct);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: argument has type `&SomeStruct`
- --> $DIR/drop_ref.rs:39:20
- |
-LL | std::mem::drop(&SomeStruct);
- | ^^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
- --> $DIR/drop_ref.rs:91:13
- |
-LL | drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
-note: argument has type `&i32`
- --> $DIR/drop_ref.rs:91:18
- |
-LL | drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block
- | ^^^^^^^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
- --> $DIR/drop_ref.rs:93:14
- |
-LL | 3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm`
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
-note: argument has type `&i32`
- --> $DIR/drop_ref.rs:93:19
- |
-LL | 3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm`
- | ^^^^^^^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
- --> $DIR/drop_ref.rs:94:14
- |
-LL | 4 => drop(&2), // Lint, not a fn/method call
- | ^^^^^^^^
- |
-note: argument has type `&i32`
- --> $DIR/drop_ref.rs:94:19
- |
-LL | 4 => drop(&2), // Lint, not a fn/method call
- | ^^
-
-error: aborting due to 12 previous errors
-
diff --git a/src/tools/clippy/tests/ui/forget_ref.rs b/src/tools/clippy/tests/ui/forget_ref.rs
deleted file mode 100644
index 031b415f56f..00000000000
--- a/src/tools/clippy/tests/ui/forget_ref.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-#![warn(clippy::forget_ref)]
-#![allow(clippy::toplevel_ref_arg)]
-#![allow(clippy::unnecessary_wraps, clippy::forget_non_drop)]
-#![allow(clippy::borrow_deref_ref)]
-
-use std::mem::forget;
-
-struct SomeStruct;
-
-fn main() {
- forget(&SomeStruct);
-
- let mut owned = SomeStruct;
- forget(&owned);
- forget(&&owned);
- forget(&mut owned);
- forget(owned); //OK
-
- let reference1 = &SomeStruct;
- forget(&*reference1);
-
- let reference2 = &mut SomeStruct;
- forget(reference2);
-
- let ref reference3 = SomeStruct;
- forget(reference3);
-}
-
-#[allow(dead_code)]
-fn test_generic_fn_forget<T>(val: T) {
- forget(&val);
- forget(val); //OK
-}
-
-#[allow(dead_code)]
-fn test_similarly_named_function() {
- fn forget<T>(_val: T) {}
- forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name
- std::mem::forget(&SomeStruct);
-}
-
-#[derive(Copy, Clone)]
-pub struct Error;
-fn produce_half_owl_error() -> Result<(), Error> {
- Ok(())
-}
-
-fn produce_half_owl_ok() -> Result<bool, ()> {
- Ok(true)
-}
diff --git a/src/tools/clippy/tests/ui/forget_ref.stderr b/src/tools/clippy/tests/ui/forget_ref.stderr
deleted file mode 100644
index 011cdefc665..00000000000
--- a/src/tools/clippy/tests/ui/forget_ref.stderr
+++ /dev/null
@@ -1,111 +0,0 @@
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
- --> $DIR/forget_ref.rs:11:5
- |
-LL | forget(&SomeStruct);
- | ^^^^^^^^^^^^^^^^^^^
- |
-note: argument has type `&SomeStruct`
- --> $DIR/forget_ref.rs:11:12
- |
-LL | forget(&SomeStruct);
- | ^^^^^^^^^^^
- = note: `-D clippy::forget-ref` implied by `-D warnings`
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
- --> $DIR/forget_ref.rs:14:5
- |
-LL | forget(&owned);
- | ^^^^^^^^^^^^^^
- |
-note: argument has type `&SomeStruct`
- --> $DIR/forget_ref.rs:14:12
- |
-LL | forget(&owned);
- | ^^^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
- --> $DIR/forget_ref.rs:15:5
- |
-LL | forget(&&owned);
- | ^^^^^^^^^^^^^^^
- |
-note: argument has type `&&SomeStruct`
- --> $DIR/forget_ref.rs:15:12
- |
-LL | forget(&&owned);
- | ^^^^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
- --> $DIR/forget_ref.rs:16:5
- |
-LL | forget(&mut owned);
- | ^^^^^^^^^^^^^^^^^^
- |
-note: argument has type `&mut SomeStruct`
- --> $DIR/forget_ref.rs:16:12
- |
-LL | forget(&mut owned);
- | ^^^^^^^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
- --> $DIR/forget_ref.rs:20:5
- |
-LL | forget(&*reference1);
- | ^^^^^^^^^^^^^^^^^^^^
- |
-note: argument has type `&SomeStruct`
- --> $DIR/forget_ref.rs:20:12
- |
-LL | forget(&*reference1);
- | ^^^^^^^^^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
- --> $DIR/forget_ref.rs:23:5
- |
-LL | forget(reference2);
- | ^^^^^^^^^^^^^^^^^^
- |
-note: argument has type `&mut SomeStruct`
- --> $DIR/forget_ref.rs:23:12
- |
-LL | forget(reference2);
- | ^^^^^^^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
- --> $DIR/forget_ref.rs:26:5
- |
-LL | forget(reference3);
- | ^^^^^^^^^^^^^^^^^^
- |
-note: argument has type `&SomeStruct`
- --> $DIR/forget_ref.rs:26:12
- |
-LL | forget(reference3);
- | ^^^^^^^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
- --> $DIR/forget_ref.rs:31:5
- |
-LL | forget(&val);
- | ^^^^^^^^^^^^
- |
-note: argument has type `&T`
- --> $DIR/forget_ref.rs:31:12
- |
-LL | forget(&val);
- | ^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
- --> $DIR/forget_ref.rs:39:5
- |
-LL | std::mem::forget(&SomeStruct);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: argument has type `&SomeStruct`
- --> $DIR/forget_ref.rs:39:22
- |
-LL | std::mem::forget(&SomeStruct);
- | ^^^^^^^^^^^
-
-error: aborting due to 9 previous errors
-
diff --git a/src/tools/clippy/tests/ui/mem_forget.rs b/src/tools/clippy/tests/ui/mem_forget.rs
index e5b35c098a2..5137448a6d4 100644
--- a/src/tools/clippy/tests/ui/mem_forget.rs
+++ b/src/tools/clippy/tests/ui/mem_forget.rs
@@ -5,7 +5,7 @@ use std::mem as memstuff;
use std::mem::forget as forgetSomething;
#[warn(clippy::mem_forget)]
-#[allow(clippy::forget_copy)]
+#[allow(forget_copy)]
fn main() {
let five: i32 = 5;
forgetSomething(five);
diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
index 73ef35c8c36..f28153e56b0 100644
--- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
+++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
@@ -2,7 +2,7 @@
#![allow(unused)]
#![allow(deref_nullptr)]
#![allow(clippy::unnecessary_operation)]
-#![allow(clippy::drop_copy)]
+#![allow(drop_copy)]
#![warn(clippy::multiple_unsafe_ops_per_block)]
extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index 42a59f6d43d..9036f892612 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -29,7 +29,11 @@
#![allow(clippy::invisible_characters)]
#![allow(suspicious_double_ref_op)]
#![allow(drop_bounds)]
+#![allow(drop_copy)]
+#![allow(drop_ref)]
#![allow(for_loops_over_fallibles)]
+#![allow(forget_copy)]
+#![allow(forget_ref)]
#![allow(array_into_iter)]
#![allow(invalid_atomic_ordering)]
#![allow(invalid_value)]
@@ -71,9 +75,13 @@
#![warn(clippy::invisible_characters)]
#![warn(suspicious_double_ref_op)]
#![warn(drop_bounds)]
+#![warn(drop_copy)]
+#![warn(drop_ref)]
#![warn(for_loops_over_fallibles)]
#![warn(for_loops_over_fallibles)]
#![warn(for_loops_over_fallibles)]
+#![warn(forget_copy)]
+#![warn(forget_ref)]
#![warn(array_into_iter)]
#![warn(invalid_atomic_ordering)]
#![warn(invalid_value)]
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index 4d173e8cbbf..43cabe810f3 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -29,7 +29,11 @@
#![allow(clippy::invisible_characters)]
#![allow(suspicious_double_ref_op)]
#![allow(drop_bounds)]
+#![allow(drop_copy)]
+#![allow(drop_ref)]
#![allow(for_loops_over_fallibles)]
+#![allow(forget_copy)]
+#![allow(forget_ref)]
#![allow(array_into_iter)]
#![allow(invalid_atomic_ordering)]
#![allow(invalid_value)]
@@ -71,9 +75,13 @@
#![warn(clippy::zero_width_space)]
#![warn(clippy::clone_double_ref)]
#![warn(clippy::drop_bounds)]
+#![warn(clippy::drop_copy)]
+#![warn(clippy::drop_ref)]
#![warn(clippy::for_loop_over_option)]
#![warn(clippy::for_loop_over_result)]
#![warn(clippy::for_loops_over_fallibles)]
+#![warn(clippy::forget_copy)]
+#![warn(clippy::forget_ref)]
#![warn(clippy::into_iter_on_array)]
#![warn(clippy::invalid_atomic_ordering)]
#![warn(clippy::invalid_ref)]
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index 0da4ed7520c..1ad7cf412c8 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -1,5 +1,5 @@
error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range`
- --> $DIR/rename.rs:44:9
+ --> $DIR/rename.rs:48:9
|
LL | #![warn(clippy::almost_complete_letter_range)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range`
@@ -7,256 +7,280 @@ LL | #![warn(clippy::almost_complete_letter_range)]
= note: `-D renamed-and-removed-lints` implied by `-D warnings`
error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`
- --> $DIR/rename.rs:45:9
+ --> $DIR/rename.rs:49:9
|
LL | #![warn(clippy::blacklisted_name)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names`
error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions`
- --> $DIR/rename.rs:46:9
+ --> $DIR/rename.rs:50:9
|
LL | #![warn(clippy::block_in_if_condition_expr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions`
- --> $DIR/rename.rs:47:9
+ --> $DIR/rename.rs:51: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:48:9
+ --> $DIR/rename.rs:52: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:49:9
+ --> $DIR/rename.rs:53: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:50:9
+ --> $DIR/rename.rs:54:9
|
LL | #![warn(clippy::cyclomatic_complexity)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq`
- --> $DIR/rename.rs:51:9
+ --> $DIR/rename.rs:55:9
|
LL | #![warn(clippy::derive_hash_xor_eq)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq`
error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
- --> $DIR/rename.rs:52:9
+ --> $DIR/rename.rs:56: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:53:9
+ --> $DIR/rename.rs:57: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:54:9
+ --> $DIR/rename.rs:58:9
|
LL | #![warn(clippy::eval_order_dependence)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`
error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
- --> $DIR/rename.rs:55:9
+ --> $DIR/rename.rs:59: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:56:9
+ --> $DIR/rename.rs:60: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:57:9
+ --> $DIR/rename.rs:61: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:58:9
+ --> $DIR/rename.rs:62: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:59:9
+ --> $DIR/rename.rs:63: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:60:9
+ --> $DIR/rename.rs:64: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:61:9
+ --> $DIR/rename.rs:65: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:62:9
+ --> $DIR/rename.rs:66: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:63:9
+ --> $DIR/rename.rs:67: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:64:9
+ --> $DIR/rename.rs:68: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:65:9
+ --> $DIR/rename.rs:69: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:66:9
+ --> $DIR/rename.rs:70: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:67:9
+ --> $DIR/rename.rs:71: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:68:9
+ --> $DIR/rename.rs:72: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:69:9
+ --> $DIR/rename.rs:73: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:70:9
+ --> $DIR/rename.rs:74: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:71:9
+ --> $DIR/rename.rs:75:9
|
LL | #![warn(clippy::zero_width_space)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op`
- --> $DIR/rename.rs:72:9
+ --> $DIR/rename.rs:76:9
|
LL | #![warn(clippy::clone_double_ref)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op`
error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
- --> $DIR/rename.rs:73:9
+ --> $DIR/rename.rs:77:9
|
LL | #![warn(clippy::drop_bounds)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
+error: lint `clippy::drop_copy` has been renamed to `drop_copy`
+ --> $DIR/rename.rs:78:9
+ |
+LL | #![warn(clippy::drop_copy)]
+ | ^^^^^^^^^^^^^^^^^ help: use the new name: `drop_copy`
+
+error: lint `clippy::drop_ref` has been renamed to `drop_ref`
+ --> $DIR/rename.rs:79:9
+ |
+LL | #![warn(clippy::drop_ref)]
+ | ^^^^^^^^^^^^^^^^ help: use the new name: `drop_ref`
+
error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
- --> $DIR/rename.rs:74:9
+ --> $DIR/rename.rs:80:9
|
LL | #![warn(clippy::for_loop_over_option)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles`
- --> $DIR/rename.rs:75:9
+ --> $DIR/rename.rs:81:9
|
LL | #![warn(clippy::for_loop_over_result)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`
- --> $DIR/rename.rs:76:9
+ --> $DIR/rename.rs:82:9
|
LL | #![warn(clippy::for_loops_over_fallibles)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
+error: lint `clippy::forget_copy` has been renamed to `forget_copy`
+ --> $DIR/rename.rs:83:9
+ |
+LL | #![warn(clippy::forget_copy)]
+ | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forget_copy`
+
+error: lint `clippy::forget_ref` has been renamed to `forget_ref`
+ --> $DIR/rename.rs:84:9
+ |
+LL | #![warn(clippy::forget_ref)]
+ | ^^^^^^^^^^^^^^^^^^ help: use the new name: `forget_ref`
+
error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
- --> $DIR/rename.rs:77:9
+ --> $DIR/rename.rs:85: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:78:9
+ --> $DIR/rename.rs:86: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:79:9
+ --> $DIR/rename.rs:87:9
|
LL | #![warn(clippy::invalid_ref)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
- --> $DIR/rename.rs:80:9
+ --> $DIR/rename.rs:88:9
|
LL | #![warn(clippy::let_underscore_drop)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
- --> $DIR/rename.rs:81:9
+ --> $DIR/rename.rs:89: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:82:9
+ --> $DIR/rename.rs:90:9
|
LL | #![warn(clippy::panic_params)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
- --> $DIR/rename.rs:83:9
+ --> $DIR/rename.rs:91:9
|
LL | #![warn(clippy::positional_named_format_parameters)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
- --> $DIR/rename.rs:84:9
+ --> $DIR/rename.rs:92: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:85:9
+ --> $DIR/rename.rs:93: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:86:9
+ --> $DIR/rename.rs:94:9
|
LL | #![warn(clippy::unused_label)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
-error: aborting due to 43 previous errors
+error: aborting due to 47 previous errors
diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed
index 0c269d650c8..49c0e4dc7eb 100644
--- a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed
+++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed
@@ -10,7 +10,7 @@
#[warn(clippy::unnecessary_cast)]
#[warn(clippy::useless_transmute)]
// Shouldn't suggest rustc lint name(`dead_code`)
-#[warn(clippy::drop_copy)]
+#[warn(clippy::eq_op)]
// Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`)
#[warn(clippy::unused_self)]
// Shouldn't suggest renamed clippy lint name(`const_static_lifetime`)
diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
index 421bf5ffa9a..584c428932f 100644
--- a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
+++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
@@ -34,7 +34,7 @@ error: unknown lint: `clippy::dead_cod`
--> $DIR/unknown_clippy_lints.rs:13:8
|
LL | #[warn(clippy::dead_cod)]
- | ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::drop_copy`
+ | ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::eq_op`
error: unknown lint: `clippy::unused_colle`
--> $DIR/unknown_clippy_lints.rs:15:8
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 85fd6523c82..0d42504c7f4 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -28,7 +28,7 @@ libc = "0.2"
miow = "0.5"
[target.'cfg(windows)'.dependencies.windows]
-version = "0.46.0"
+version = "0.48.0"
features = [
"Win32_Foundation",
"Win32_System_Diagnostics_Debug",
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 9059a145b43..ba68b5ee9d5 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -428,7 +428,6 @@ impl TargetCfgs {
))
.unwrap();
- let mut current = None;
let mut all_targets = HashSet::new();
let mut all_archs = HashSet::new();
let mut all_oses = HashSet::new();
@@ -449,14 +448,11 @@ impl TargetCfgs {
}
all_pointer_widths.insert(format!("{}bit", cfg.pointer_width));
- if target == config.target {
- current = Some(cfg);
- }
all_targets.insert(target.into());
}
Self {
- current: current.expect("current target not found"),
+ current: Self::get_current_target_config(config),
all_targets,
all_archs,
all_oses,
@@ -467,6 +463,89 @@ impl TargetCfgs {
all_pointer_widths,
}
}
+
+ fn get_current_target_config(config: &Config) -> TargetCfg {
+ 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;
+ let mut panic = None;
+
+ for config in
+ rustc_output(config, &["--print=cfg", "--target", &config.target]).trim().lines()
+ {
+ let (name, value) = config
+ .split_once("=\"")
+ .map(|(name, value)| {
+ (
+ name,
+ Some(
+ value
+ .strip_suffix("\"")
+ .expect("key-value pair should be properly quoted"),
+ ),
+ )
+ })
+ .unwrap_or_else(|| (config, None));
+
+ match name {
+ "target_arch" => {
+ arch = Some(value.expect("target_arch should be a key-value pair").to_string());
+ }
+ "target_os" => {
+ os = Some(value.expect("target_os sould be a key-value pair").to_string());
+ }
+ "target_env" => {
+ env = Some(value.expect("target_env should be a key-value pair").to_string());
+ }
+ "target_abi" => {
+ abi = Some(value.expect("target_abi should be a key-value pair").to_string());
+ }
+ "target_family" => {
+ families
+ .push(value.expect("target_family should be a key-value pair").to_string());
+ }
+ "target_pointer_width" => {
+ pointer_width = Some(
+ value
+ .expect("target_pointer_width should be a key-value pair")
+ .parse::<u32>()
+ .expect("target_pointer_width should be a valid u32"),
+ );
+ }
+ "target_endian" => {
+ endian = Some(match value.expect("target_endian should be a key-value pair") {
+ "big" => Endian::Big,
+ "little" => Endian::Little,
+ _ => panic!("target_endian should be either 'big' or 'little'"),
+ });
+ }
+ "panic" => {
+ panic = Some(match value.expect("panic should be a key-value pair") {
+ "abort" => PanicStrategy::Abort,
+ "unwind" => PanicStrategy::Unwind,
+ _ => panic!("panic should be either 'abort' or 'unwind'"),
+ });
+ }
+ _ => (),
+ }
+ }
+
+ TargetCfg {
+ arch: arch.expect("target configuration should specify target_arch"),
+ os: os.expect("target configuration should specify target_os"),
+ env: env.expect("target configuration should specify target_env"),
+ abi: abi.expect("target configuration should specify target_abi"),
+ families,
+ pointer_width: pointer_width
+ .expect("target configuration should specify target_pointer_width"),
+ endian: endian.expect("target configuration should specify target_endian"),
+ panic: panic.expect("target configuration should specify panic"),
+ }
+ }
}
#[derive(Clone, Debug, serde::Deserialize)]
diff --git a/src/tools/generate-windows-sys/Cargo.toml b/src/tools/generate-windows-sys/Cargo.toml
new file mode 100644
index 00000000000..23e88844bd0
--- /dev/null
+++ b/src/tools/generate-windows-sys/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "generate-windows-sys"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies.windows-bindgen]
+version = "0.49"
diff --git a/src/tools/generate-windows-sys/src/main.rs b/src/tools/generate-windows-sys/src/main.rs
new file mode 100644
index 00000000000..91d981462e8
--- /dev/null
+++ b/src/tools/generate-windows-sys/src/main.rs
@@ -0,0 +1,37 @@
+use std::fs;
+use std::io::{self, Write};
+use std::path::PathBuf;
+
+/// This is printed to the file before the rest of the contents.
+const PRELUDE: &str = r#"// This file is autogenerated.
+//
+// To add bindings, edit windows_sys.lst then use `./x run generate-windows-sys` to
+// regenerate the bindings.
+//
+// ignore-tidy-filelength
+"#;
+
+fn main() -> io::Result<()> {
+ let mut path: PathBuf =
+ std::env::args_os().nth(1).expect("a path to the rust repository is required").into();
+ path.push("library/std/src/sys/windows/c/windows_sys.lst");
+
+ // Load the list of APIs
+ let buffer = fs::read_to_string(&path)?;
+ let names: Vec<&str> = buffer
+ .lines()
+ .filter_map(|line| {
+ let line = line.trim();
+ if line.is_empty() || line.starts_with("//") { None } else { Some(line) }
+ })
+ .collect();
+
+ // Write the bindings to windows-sys.rs
+ let bindings = windows_bindgen::standalone_std(&names);
+ path.set_extension("rs");
+ let mut f = std::fs::File::create(&path)?;
+ f.write_all(PRELUDE.as_bytes())?;
+ f.write_all(bindings.as_bytes())?;
+
+ Ok(())
+}
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
index a1f675a3b40..bf8a64acf08 100644
--- a/src/tools/jsondoclint/src/validator.rs
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -273,7 +273,9 @@ impl<'a> Validator<'a> {
Type::QualifiedPath { name: _, args, self_type, trait_ } => {
self.check_generic_args(&**args);
self.check_type(&**self_type);
- self.check_path(trait_, PathKind::Trait);
+ if let Some(trait_) = trait_ {
+ self.check_path(trait_, PathKind::Trait);
+ }
}
}
}
diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs
index 4170c32f1fe..c8a370085a0 100644
--- a/src/tools/linkchecker/main.rs
+++ b/src/tools/linkchecker/main.rs
@@ -139,18 +139,18 @@ enum FileEntry {
type Cache = HashMap<String, FileEntry>;
fn small_url_encode(s: &str) -> String {
- s.replace("<", "%3C")
- .replace(">", "%3E")
- .replace(" ", "%20")
- .replace("?", "%3F")
- .replace("'", "%27")
- .replace("&", "%26")
- .replace(",", "%2C")
- .replace(":", "%3A")
- .replace(";", "%3B")
- .replace("[", "%5B")
- .replace("]", "%5D")
- .replace("\"", "%22")
+ s.replace('<', "%3C")
+ .replace('>', "%3E")
+ .replace(' ', "%20")
+ .replace('?', "%3F")
+ .replace('\'', "%27")
+ .replace('&', "%26")
+ .replace(',', "%2C")
+ .replace(':', "%3A")
+ .replace(';', "%3B")
+ .replace('[', "%5B")
+ .replace(']', "%5D")
+ .replace('\"', "%22")
}
impl Checker {
@@ -267,7 +267,6 @@ impl Checker {
FileEntry::OtherFile => return,
FileEntry::Redirect { target } => {
let t = target.clone();
- drop(target);
let (target, redir_entry) = self.load_file(&t, report);
match redir_entry {
FileEntry::Missing => {
@@ -391,7 +390,7 @@ impl Checker {
const ERROR_INVALID_NAME: i32 = 123;
let pretty_path =
- file.strip_prefix(&self.root).unwrap_or(&file).to_str().unwrap().to_string();
+ file.strip_prefix(&self.root).unwrap_or(file).to_str().unwrap().to_string();
let entry =
self.cache.entry(pretty_path.clone()).or_insert_with(|| match fs::metadata(file) {
@@ -470,10 +469,8 @@ fn is_exception(file: &Path, link: &str) -> bool {
// NOTE: This cannot be added to `LINKCHECK_EXCEPTIONS` because the resolved path
// calculated in `check` function is outside `build/<triple>/doc` dir.
// So the `strip_prefix` method just returns the old absolute broken path.
- if file.ends_with("std/primitive.slice.html") {
- if link.ends_with("primitive.slice.html") {
- return true;
- }
+ if file.ends_with("std/primitive.slice.html") && link.ends_with("primitive.slice.html") {
+ return true;
}
false
}
@@ -545,7 +542,7 @@ fn with_attrs_in_source<F: FnMut(&str, usize, &str)>(source: &str, attr: &str, m
fn parse_ids(ids: &mut HashSet<String>, file: &str, source: &str, report: &mut Report) {
if ids.is_empty() {
with_attrs_in_source(source, " id", |fragment, i, _| {
- let frag = fragment.trim_start_matches("#").to_owned();
+ let frag = fragment.trim_start_matches('#').to_owned();
let encoded = small_url_encode(&frag);
if !ids.insert(frag) {
report.errors += 1;
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index 10079ba85b6..737423a2cd1 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -19,18 +19,18 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
-version = "0.7.20"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
+checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
-version = "1.0.70"
+version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
+checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
[[package]]
name = "atty"
@@ -38,7 +38,7 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
- "hermit-abi",
+ "hermit-abi 0.1.19",
"libc",
"winapi",
]
@@ -72,9 +72,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bstr"
-version = "1.1.0"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b45ea9b00a7b3f2988e9a65ad3917e62123c38dba709b666506207be96d1790b"
+checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09"
dependencies = [
"memchr",
"once_cell",
@@ -84,9 +84,9 @@ dependencies = [
[[package]]
name = "camino"
-version = "1.1.1"
+version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e"
+checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2"
dependencies = [
"serde",
]
@@ -102,9 +102,9 @@ dependencies = [
[[package]]
name = "cargo_metadata"
-version = "0.15.2"
+version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "982a0cf6a99c350d7246035613882e376d58cebe571785abc5da4f648d53ac0a"
+checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a"
dependencies = [
"camino",
"cargo-platform",
@@ -116,9 +116,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.0.78"
+version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "cfg-if"
@@ -166,9 +166,9 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
-version = "0.5.6"
+version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
+checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
dependencies = [
"cfg-if",
"crossbeam-utils",
@@ -176,9 +176,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
-version = "0.8.14"
+version = "0.8.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
+checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
dependencies = [
"cfg-if",
]
@@ -203,6 +203,27 @@ dependencies = [
]
[[package]]
+name = "errno"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
+dependencies = [
+ "errno-dragonfly",
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "errno-dragonfly"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
name = "eyre"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -214,18 +235,18 @@ dependencies = [
[[package]]
name = "fastrand"
-version = "1.8.0"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
+checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
dependencies = [
"instant",
]
[[package]]
name = "getrandom"
-version = "0.2.8"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
+checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
dependencies = [
"cfg-if",
"libc",
@@ -234,9 +255,9 @@ dependencies = [
[[package]]
name = "gimli"
-version = "0.27.0"
+version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793"
+checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4"
[[package]]
name = "hermit-abi"
@@ -248,6 +269,12 @@ dependencies = [
]
[[package]]
+name = "hermit-abi"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
+
+[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -269,10 +296,21 @@ dependencies = [
]
[[package]]
+name = "io-lifetimes"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
+dependencies = [
+ "hermit-abi 0.3.1",
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
name = "itoa"
-version = "1.0.5"
+version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
+checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "lazy_static"
@@ -282,9 +320,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
-version = "0.2.139"
+version = "0.2.142"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
+checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
[[package]]
name = "libffi"
@@ -316,6 +354,12 @@ dependencies = [
]
[[package]]
+name = "linux-raw-sys"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"
+
+[[package]]
name = "lock_api"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -336,9 +380,9 @@ dependencies = [
[[package]]
name = "measureme"
-version = "10.1.0"
+version = "10.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbdc226fa10994e8f66a4d2f6f000148bc563a1c671b6dcd2135737018033d8a"
+checksum = "1930d162935fecd56fc4e0f6729eb3483bac1264542eb4ea31570b86a434b6bc"
dependencies = [
"log",
"memmap2",
@@ -395,18 +439,18 @@ dependencies = [
[[package]]
name = "object"
-version = "0.30.0"
+version = "0.30.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb"
+checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
-version = "1.16.0"
+version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
+checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "owo-colors"
@@ -434,16 +478,16 @@ dependencies = [
"cfg-if",
"instant",
"libc",
- "redox_syscall",
+ "redox_syscall 0.2.16",
"smallvec",
"winapi",
]
[[package]]
name = "perf-event-open-sys"
-version = "1.0.1"
+version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce9bedf5da2c234fdf2391ede2b90fabf585355f33100689bc364a3ea558561a"
+checksum = "b29be2ba35c12c6939f6bc73187f728bba82c3c062ecdc5fa90ea739282a1f58"
dependencies = [
"libc",
]
@@ -462,18 +506,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
-version = "1.0.49"
+version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
+checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.23"
+version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
+checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
dependencies = [
"proc-macro2",
]
@@ -518,10 +562,19 @@ dependencies = [
]
[[package]]
+name = "redox_syscall"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
name = "regex"
-version = "1.7.0"
+version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
+checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
dependencies = [
"aho-corasick",
"memchr",
@@ -536,24 +589,15 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]]
name = "regex-syntax"
-version = "0.6.28"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
-
-[[package]]
-name = "remove_dir_all"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
-dependencies = [
- "winapi",
-]
+checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
[[package]]
name = "rustc-demangle"
-version = "0.1.21"
+version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
+checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustc-hash"
@@ -589,10 +633,24 @@ dependencies = [
]
[[package]]
+name = "rustix"
+version = "0.37.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
+dependencies = [
+ "bitflags",
+ "errno",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
name = "ryu"
-version = "1.0.12"
+version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
+checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]]
name = "scopeguard"
@@ -602,27 +660,27 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
-version = "1.0.16"
+version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
+checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
dependencies = [
"serde",
]
[[package]]
name = "serde"
-version = "1.0.152"
+version = "1.0.162"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
+checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.152"
+version = "1.0.162"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
+checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6"
dependencies = [
"proc-macro2",
"quote",
@@ -631,9 +689,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.91"
+version = "1.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
+checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
dependencies = [
"itoa",
"ryu",
@@ -657,9 +715,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "syn"
-version = "1.0.107"
+version = "2.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
+checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
dependencies = [
"proc-macro2",
"quote",
@@ -668,41 +726,40 @@ dependencies = [
[[package]]
name = "tempfile"
-version = "3.3.0"
+version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
+checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
dependencies = [
"cfg-if",
"fastrand",
- "libc",
- "redox_syscall",
- "remove_dir_all",
- "winapi",
+ "redox_syscall 0.3.5",
+ "rustix",
+ "windows-sys 0.45.0",
]
[[package]]
name = "termcolor"
-version = "1.1.3"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [
"winapi-util",
]
[[package]]
name = "thiserror"
-version = "1.0.38"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
+checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.38"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
+checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
dependencies = [
"proc-macro2",
"quote",
@@ -711,10 +768,11 @@ dependencies = [
[[package]]
name = "thread_local"
-version = "1.1.4"
+version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
+checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
dependencies = [
+ "cfg-if",
"once_cell",
]
@@ -751,9 +809,9 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
-version = "0.3.16"
+version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
+checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
dependencies = [
"sharded-slab",
"thread_local",
@@ -762,9 +820,9 @@ dependencies = [
[[package]]
name = "ui_test"
-version = "0.6.2"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e10f5f88ce8c331a388deda1e6e2bd533c73ca89cc5f539a3df02ed35c8efba"
+checksum = "191a442639ea102fa62671026047e51d574bfda44b7fdf32151d7314624c1cd2"
dependencies = [
"bstr",
"cargo-platform",
@@ -784,9 +842,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
-version = "1.0.6"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
+checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
[[package]]
name = "valuable"
@@ -830,3 +888,135 @@ 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.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.0",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.0",
+ "windows_aarch64_msvc 0.48.0",
+ "windows_i686_gnu 0.48.0",
+ "windows_i686_msvc 0.48.0",
+ "windows_x86_64_gnu 0.48.0",
+ "windows_x86_64_gnullvm 0.48.0",
+ "windows_x86_64_msvc 0.48.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index b962d0c1096..5987b0df8d6 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -39,7 +39,7 @@ libloading = "0.7"
[dev-dependencies]
colored = "2"
-ui_test = "0.6.2"
+ui_test = "0.10"
rustc_version = "0.4"
# Features chosen to match those required by env_logger, to avoid rebuilds
regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] }
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 640a953dac9..79b0daf9e82 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -389,7 +389,7 @@ to Miri failing to detect cases of undefined behavior in a program.
Follow [the discussion on supporting other types](https://github.com/rust-lang/miri/issues/2365).
* `-Zmiri-measureme=<name>` enables `measureme` profiling for the interpreted program.
This can be used to find which parts of your program are executing slowly under Miri.
- The profile is written out to a file with the prefix `<name>`, and can be processed
+ The profile is written out to a file inside a directory called `<name>`, and can be processed
using the tools in the repository https://github.com/rust-lang/measureme.
* `-Zmiri-mute-stdout-stderr` silently ignores all writes to stdout and stderr,
but reports to the program that it did actually write. This is useful when you
diff --git a/src/tools/miri/bench-cargo-miri/zip-equal/Cargo.lock b/src/tools/miri/bench-cargo-miri/zip-equal/Cargo.lock
new file mode 100644
index 00000000000..de6760a0359
--- /dev/null
+++ b/src/tools/miri/bench-cargo-miri/zip-equal/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "zip-equal"
+version = "0.1.0"
diff --git a/src/tools/miri/bench-cargo-miri/zip-equal/Cargo.toml b/src/tools/miri/bench-cargo-miri/zip-equal/Cargo.toml
new file mode 100644
index 00000000000..f4208de727d
--- /dev/null
+++ b/src/tools/miri/bench-cargo-miri/zip-equal/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "zip-equal"
+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/tools/miri/bench-cargo-miri/zip-equal/src/main.rs b/src/tools/miri/bench-cargo-miri/zip-equal/src/main.rs
new file mode 100644
index 00000000000..ba4e9b41d1d
--- /dev/null
+++ b/src/tools/miri/bench-cargo-miri/zip-equal/src/main.rs
@@ -0,0 +1,22 @@
+//! This is a pathological pattern in which opportunities to merge
+//! adjacent identical items in the RangeMap are not properly detected
+//! because `RangeMap::iter_mut` is never called on overlapping ranges
+//! and thus never merges previously split ranges. This does not produce any
+//! additional cost for access operations, but it makes the job of the Tree Borrows
+//! GC procedure much more costly.
+//! See https://github.com/rust-lang/miri/issues/2863
+
+const LENGTH: usize = (1 << 14) - 1;
+const LONG: &[u8] = &[b'x'; LENGTH];
+
+fn main() {
+ assert!(eq(LONG, LONG))
+}
+
+fn eq(s1: &[u8], s2: &[u8]) -> bool {
+ if s1.len() != s2.len() {
+ return false;
+ }
+
+ s1.iter().zip(s2).all(|(c1, c2)| *c1 == *c2)
+}
diff --git a/src/tools/miri/cargo-miri/Cargo.lock b/src/tools/miri/cargo-miri/Cargo.lock
index 76badcf94af..727e46a028d 100644
--- a/src/tools/miri/cargo-miri/Cargo.lock
+++ b/src/tools/miri/cargo-miri/Cargo.lock
@@ -4,9 +4,9 @@ version = 3
[[package]]
name = "anyhow"
-version = "1.0.68"
+version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
+checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
[[package]]
name = "bitflags"
@@ -16,9 +16,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "camino"
-version = "1.1.1"
+version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e"
+checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2"
dependencies = [
"serde",
]
@@ -48,9 +48,9 @@ dependencies = [
[[package]]
name = "cargo_metadata"
-version = "0.15.2"
+version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "982a0cf6a99c350d7246035613882e376d58cebe571785abc5da4f648d53ac0a"
+checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a"
dependencies = [
"camino",
"cargo-platform",
@@ -61,6 +61,12 @@ dependencies = [
]
[[package]]
+name = "cc"
+version = "1.0.79"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+
+[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -87,19 +93,40 @@ dependencies = [
]
[[package]]
+name = "errno"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
+dependencies = [
+ "errno-dragonfly",
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "errno-dragonfly"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
name = "fastrand"
-version = "1.8.0"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
+checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
dependencies = [
"instant",
]
[[package]]
name = "getrandom"
-version = "0.2.8"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
+checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
dependencies = [
"cfg-if",
"libc",
@@ -107,6 +134,12 @@ dependencies = [
]
[[package]]
+name = "hermit-abi"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
+
+[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -116,31 +149,48 @@ dependencies = [
]
[[package]]
+name = "io-lifetimes"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
name = "itoa"
-version = "1.0.5"
+version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
+checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "libc"
-version = "0.2.139"
+version = "0.2.142"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
+checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"
[[package]]
name = "proc-macro2"
-version = "1.0.49"
+version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
+checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.23"
+version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
+checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
dependencies = [
"proc-macro2",
]
@@ -155,30 +205,30 @@ dependencies = [
]
[[package]]
-name = "redox_users"
-version = "0.4.3"
+name = "redox_syscall"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
+checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
- "getrandom",
- "redox_syscall",
- "thiserror",
+ "bitflags",
]
[[package]]
-name = "remove_dir_all"
-version = "0.5.3"
+name = "redox_users"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [
- "winapi",
+ "getrandom",
+ "redox_syscall 0.2.16",
+ "thiserror",
]
[[package]]
name = "rustc-build-sysroot"
-version = "0.4.1"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d65b1271cdac365b71b59570ea35d945dea2dd2cc47eba3d33b4bd1e0190ac6d"
+checksum = "8ed2a90dfa5232ed5ff21d53d4df655f315ab316ea06fc508f1c74bcedb1ce6c"
dependencies = [
"anyhow",
"rustc_version",
@@ -207,34 +257,48 @@ dependencies = [
]
[[package]]
+name = "rustix"
+version = "0.37.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
+dependencies = [
+ "bitflags",
+ "errno",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
name = "ryu"
-version = "1.0.12"
+version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
+checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]]
name = "semver"
-version = "1.0.16"
+version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
+checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
dependencies = [
"serde",
]
[[package]]
name = "serde"
-version = "1.0.152"
+version = "1.0.162"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
+checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.152"
+version = "1.0.162"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
+checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6"
dependencies = [
"proc-macro2",
"quote",
@@ -243,9 +307,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.91"
+version = "1.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
+checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
dependencies = [
"itoa",
"ryu",
@@ -254,9 +318,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.107"
+version = "2.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
+checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
dependencies = [
"proc-macro2",
"quote",
@@ -265,32 +329,31 @@ dependencies = [
[[package]]
name = "tempfile"
-version = "3.3.0"
+version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
+checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
dependencies = [
"cfg-if",
"fastrand",
- "libc",
- "redox_syscall",
- "remove_dir_all",
- "winapi",
+ "redox_syscall 0.3.5",
+ "rustix",
+ "windows-sys 0.45.0",
]
[[package]]
name = "thiserror"
-version = "1.0.38"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
+checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.38"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
+checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
dependencies = [
"proc-macro2",
"quote",
@@ -299,9 +362,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
-version = "1.0.6"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
+checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
[[package]]
name = "wasi"
@@ -330,3 +393,135 @@ 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.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.0",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.0",
+ "windows_aarch64_msvc 0.48.0",
+ "windows_i686_gnu 0.48.0",
+ "windows_i686_msvc 0.48.0",
+ "windows_x86_64_gnu 0.48.0",
+ "windows_x86_64_gnullvm 0.48.0",
+ "windows_x86_64_msvc 0.48.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
diff --git a/src/tools/miri/miri b/src/tools/miri/miri
index 4be970b398d..48a46a76a12 100755
--- a/src/tools/miri/miri
+++ b/src/tools/miri/miri
@@ -306,7 +306,7 @@ test|bless)
# Only in root project as `cargo-miri` has no tests.
$CARGO test $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/Cargo.toml "$@"
;;
-run)
+run|run-dep)
# Scan for "--target" to overwrite the "MIRI_TEST_TARGET" env var so
# that we set the MIRI_SYSROOT up the right way.
FOUND_TARGET_OPT=0
@@ -323,11 +323,17 @@ run)
# Make sure Miri actually uses this target.
MIRIFLAGS="$MIRIFLAGS --target $MIRI_TEST_TARGET"
fi
+
# First build and get a sysroot.
$CARGO build $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/Cargo.toml
find_sysroot
# Then run the actual command.
- exec $CARGO run $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/Cargo.toml -- $MIRIFLAGS "$@"
+
+ if [ "$COMMAND" = "run-dep" ]; then
+ exec $CARGO test --test compiletest $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/Cargo.toml -- --miri-run-dep-mode $MIRIFLAGS "$@"
+ else
+ exec $CARGO run $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/Cargo.toml -- $MIRIFLAGS "$@"
+ fi
;;
fmt)
find "$MIRIDIR" -not \( -name target -prune \) -name '*.rs' \
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index d4bffe5f945..b450f986149 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-eb62877597000ccf8bb99ab131b5977344afdfa3
+69fef92ab2f287f072b66fb7b4f62c8bb4acba43
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 65bc004fc4a..083dd4800d9 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -28,8 +28,8 @@ use rustc_middle::{
middle::exported_symbols::{
ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
},
- query::LocalCrate,
- ty::{query::ExternProviders, TyCtxt},
+ query::{ExternProviders, LocalCrate},
+ ty::TyCtxt,
};
use rustc_session::config::OptLevel;
@@ -63,7 +63,9 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
queries: &'tcx rustc_interface::Queries<'tcx>,
) -> Compilation {
queries.global_ctxt().unwrap().enter(|tcx| {
- tcx.sess.abort_if_errors();
+ if tcx.sess.compile_status().is_err() {
+ tcx.sess.fatal("miri cannot be run on programs that fail compilation");
+ }
init_late_loggers(tcx);
if !tcx.sess.crate_types().contains(&CrateType::Executable) {
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index 4d7bbb643b8..29881bbcfca 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -459,7 +459,7 @@ impl<'tcx> Stack {
impl Stacks {
pub fn remove_unreachable_tags(&mut self, live_tags: &FxHashSet<BorTag>) {
if self.modified_since_last_gc {
- for stack in self.stacks.iter_mut_all() {
+ for (_stack_range, stack) in self.stacks.iter_mut_all() {
if stack.len() > 64 {
stack.retain(live_tags);
}
@@ -511,8 +511,8 @@ impl<'tcx> Stacks {
) -> InterpResult<'tcx>,
) -> InterpResult<'tcx> {
self.modified_since_last_gc = true;
- for (offset, stack) in self.stacks.iter_mut(range.start, range.size) {
- let mut dcx = dcx_builder.build(&mut self.history, offset);
+ for (stack_range, stack) in self.stacks.iter_mut(range.start, range.size) {
+ let mut dcx = dcx_builder.build(&mut self.history, Size::from_bytes(stack_range.start));
f(stack, &mut dcx, &mut self.exposed_tags)?;
dcx_builder = dcx.unbuild();
}
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
index 064dbe025af..a1e949183ad 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
@@ -83,7 +83,7 @@ impl Stack {
self.borrows.truncate(write_idx);
#[cfg(not(feature = "stack-cache"))]
- drop(first_removed); // This is only needed for the stack-cache
+ let _unused = first_removed; // This is only needed for the stack-cache
#[cfg(feature = "stack-cache")]
if let Some(first_removed) = first_removed {
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs
index 2c6d27ced01..10873c46a6c 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs
@@ -3,7 +3,6 @@ use std::ops::Range;
use rustc_data_structures::fx::FxHashMap;
use rustc_span::{Span, SpanData};
-use rustc_target::abi::Size;
use crate::borrow_tracker::tree_borrows::{
perms::{PermTransition, Permission},
@@ -14,18 +13,30 @@ use crate::borrow_tracker::{AccessKind, ProtectorKind};
use crate::*;
/// Complete data for an event:
-/// - `kind` is what happened to the permissions
-/// - `access_kind` and `access_range` describe the access that caused the event
-/// - `offset` allows filtering only the relevant events for a given memory location
-/// (see how we perform the filtering in `History::extract_relevant`.
-/// - `span` is the line of code in question
#[derive(Clone, Debug)]
pub struct Event {
+ /// Transformation of permissions that occured because of this event
pub transition: PermTransition,
+ /// Kind of the access that triggered this event
pub access_kind: AccessKind,
+ /// Relative position of the tag to the one used for the access
pub is_foreign: bool,
+ /// User-visible range of the access
pub access_range: AllocRange,
- pub offset: Size,
+ /// The transition recorded by this event only occured on a subrange of
+ /// `access_range`: a single access on `access_range` triggers several events,
+ /// each with their own mutually disjoint `transition_range`. No-op transitions
+ /// should not be recorded as events, so the union of all `transition_range` is not
+ /// necessarily the entire `access_range`.
+ ///
+ /// No data from any `transition_range` should ever be user-visible, because
+ /// both the start and end of `transition_range` are entirely dependent on the
+ /// internal representation of `RangeMap` which is supposed to be opaque.
+ /// What will be shown in the error message is the first byte `error_offset` of
+ /// the `TbError`, which should satisfy
+ /// `event.transition_range.contains(error.error_offset)`.
+ pub transition_range: Range<u64>,
+ /// Line of code that triggered this event
pub span: Span,
}
@@ -35,9 +46,9 @@ pub struct Event {
/// Available filtering methods include `History::forget` and `History::extract_relevant`.
#[derive(Clone, Debug)]
pub struct History {
- pub tag: BorTag,
- pub created: (Span, Permission),
- pub events: Vec<Event>,
+ tag: BorTag,
+ created: (Span, Permission),
+ events: Vec<Event>,
}
/// History formatted for use by `src/diagnostics.rs`.
@@ -60,12 +71,7 @@ impl HistoryData {
// Format events from `new_history` into those recorded by `self`.
//
// NOTE: also converts `Span` to `SpanData`.
- pub fn extend(
- &mut self,
- new_history: History,
- tag_name: &'static str,
- show_initial_state: bool,
- ) {
+ fn extend(&mut self, new_history: History, tag_name: &'static str, show_initial_state: bool) {
let History { tag, created, events } = new_history;
let this = format!("the {tag_name} tag {tag:?}");
let msg_initial_state = format!(", in the initial state {}", created.1);
@@ -75,9 +81,16 @@ impl HistoryData {
);
self.events.push((Some(created.0.data()), msg_creation));
- for &Event { transition, access_kind, is_foreign, access_range, span, offset: _ } in &events
+ for &Event {
+ transition,
+ access_kind,
+ is_foreign,
+ access_range,
+ span,
+ transition_range: _,
+ } in &events
{
- // NOTE: `offset` is explicitly absent from the error message, it has no significance
+ // NOTE: `transition_range` is explicitly absent from the error message, it has no significance
// to the user. The meaningful one is `access_range`.
self.events.push((Some(span.data()), format!("{this} then transitioned {transition} due to a {rel} {access_kind} at offsets {access_range:?}", rel = if is_foreign { "foreign" } else { "child" })));
self.events.push((None, format!("this corresponds to {}", transition.summary())));
@@ -197,44 +210,19 @@ impl History {
History { events: Vec::new(), created: self.created, tag: self.tag }
}
- /// Reconstruct the history relevant to `error_offset` knowing that
- /// its permission followed `complete_transition`.
- ///
- /// Here's how we do this:
- /// - we know `full := complete_transition` the transition of the permission from
- /// its initialization to the state just before the error was caused,
- /// we want to find a chain of events that produces `full`
- /// - we decompose `full` into `pre o post` where
- /// `pre` is the best applicable transition from recorded events
- /// - we select the event that caused `pre` and iterate
- /// to find the chain of events that produces `full := post`
- ///
- /// To find the "best applicable transition" for full:
- /// - eliminate events that cannot be applied because their offset is too big
- /// - eliminate events that cannot be applied because their starting point is wrong
- /// - select the one that happened closest to the range of interest
- fn extract_relevant(&self, complete_transition: PermTransition, error_offset: Size) -> Self {
- let mut selected_events: Vec<Event> = Vec::new();
- let mut full = complete_transition;
- while !full.is_noop() {
- let (pre, post) = self
+ /// Reconstruct the history relevant to `error_offset` by filtering
+ /// only events whose range contains the offset we are interested in.
+ fn extract_relevant(&self, error_offset: u64) -> Self {
+ History {
+ events: self
.events
.iter()
- .filter(|e| e.offset <= error_offset)
- .filter_map(|pre_canditate| {
- full.apply_start(pre_canditate.transition)
- .map(|post_canditate| (pre_canditate, post_canditate))
- })
- .max_by_key(|(pre_canditate, _post_candidate)| pre_canditate.offset)
- .unwrap();
- // If this occurs we will loop infinitely !
- // Make sure to only put non-noop transitions in `History`.
- assert!(!pre.transition.is_noop());
- full = post;
- selected_events.push(pre.clone());
+ .filter(|e| e.transition_range.contains(&error_offset))
+ .cloned()
+ .collect::<Vec<_>>(),
+ created: self.created,
+ tag: self.tag,
}
-
- History { events: selected_events, created: self.created, tag: self.tag }
}
}
@@ -242,8 +230,8 @@ impl History {
pub(super) struct TbError<'node> {
/// What failure occurred.
pub error_kind: TransitionError,
- /// The byte at which the conflict occured.
- pub error_offset: Size,
+ /// The offset (into the allocation) at which the conflict occurred.
+ pub error_offset: u64,
/// The tag on which the error was triggered.
/// On protector violations, this is the tag that was protected.
/// On accesses rejected due to insufficient permissions, this is the
@@ -261,12 +249,11 @@ impl TbError<'_> {
/// Produce a UB error.
pub fn build<'tcx>(self) -> InterpError<'tcx> {
use TransitionError::*;
- let started_as = self.conflicting_info.history.created.1;
let kind = self.access_kind;
let accessed = self.accessed_info;
let conflicting = self.conflicting_info;
let accessed_is_conflicting = accessed.tag == conflicting.tag;
- let (pre_error, title, details, conflicting_tag_name) = match self.error_kind {
+ let (title, details, conflicting_tag_name) = match self.error_kind {
ChildAccessForbidden(perm) => {
let conflicting_tag_name =
if accessed_is_conflicting { "accessed" } else { "conflicting" };
@@ -280,7 +267,7 @@ impl TbError<'_> {
details.push(format!(
"the {conflicting_tag_name} tag {conflicting} has state {perm} which forbids child {kind}es"
));
- (perm, title, details, conflicting_tag_name)
+ (title, details, conflicting_tag_name)
}
ProtectedTransition(transition) => {
let conflicting_tag_name = "protected";
@@ -297,7 +284,7 @@ impl TbError<'_> {
loss = transition.summary(),
),
];
- (transition.started(), title, details, conflicting_tag_name)
+ (title, details, conflicting_tag_name)
}
ProtectedDealloc => {
let conflicting_tag_name = "strongly protected";
@@ -308,16 +295,15 @@ impl TbError<'_> {
),
format!("the {conflicting_tag_name} tag {conflicting} disallows deallocations"),
];
- (started_as, title, details, conflicting_tag_name)
+ (title, details, conflicting_tag_name)
}
};
- let pre_transition = PermTransition::from(started_as, pre_error).unwrap();
let mut history = HistoryData::default();
if !accessed_is_conflicting {
history.extend(self.accessed_info.history.forget(), "accessed", false);
}
history.extend(
- self.conflicting_info.history.extract_relevant(pre_transition, self.error_offset),
+ self.conflicting_info.history.extract_relevant(self.error_offset),
conflicting_tag_name,
true,
);
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
index 6392f5101ad..52947aa0f9f 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
@@ -311,7 +311,7 @@ impl<'tcx> Tree {
parent_tag: BorTag,
new_tag: BorTag,
default_initial_perm: Permission,
- range: AllocRange,
+ reborrow_range: AllocRange,
span: Span,
) -> InterpResult<'tcx> {
assert!(!self.tag_mapping.contains_key(&new_tag));
@@ -332,7 +332,8 @@ impl<'tcx> Tree {
self.nodes.get_mut(parent_idx).unwrap().children.push(idx);
// Initialize perms
let perm = LocationState::new(default_initial_perm).with_access();
- for (_range, perms) in self.rperms.iter_mut(range.start, range.size) {
+ for (_perms_range, perms) in self.rperms.iter_mut(reborrow_range.start, reborrow_range.size)
+ {
perms.insert(idx, perm);
}
Ok(())
@@ -344,12 +345,12 @@ impl<'tcx> Tree {
pub fn dealloc(
&mut self,
tag: BorTag,
- range: AllocRange,
+ access_range: AllocRange,
global: &GlobalState,
span: Span, // diagnostics
) -> InterpResult<'tcx> {
- self.perform_access(AccessKind::Write, tag, range, global, span)?;
- for (offset, perms) in self.rperms.iter_mut(range.start, range.size) {
+ self.perform_access(AccessKind::Write, tag, access_range, global, span)?;
+ for (perms_range, perms) in self.rperms.iter_mut(access_range.start, access_range.size) {
TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms }
.traverse_parents_this_children_others(
tag,
@@ -368,7 +369,7 @@ impl<'tcx> Tree {
TbError {
conflicting_info,
access_kind: AccessKind::Write,
- error_offset: offset,
+ error_offset: perms_range.start,
error_kind,
accessed_info,
}
@@ -388,11 +389,11 @@ impl<'tcx> Tree {
&mut self,
access_kind: AccessKind,
tag: BorTag,
- range: AllocRange,
+ access_range: AllocRange,
global: &GlobalState,
span: Span, // diagnostics
) -> InterpResult<'tcx> {
- for (offset, perms) in self.rperms.iter_mut(range.start, range.size) {
+ for (perms_range, perms) in self.rperms.iter_mut(access_range.start, access_range.size) {
TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms }
.traverse_parents_this_children_others(
tag,
@@ -456,9 +457,9 @@ impl<'tcx> Tree {
node.debug_info.history.push(diagnostics::Event {
transition,
access_kind,
- access_range: range,
is_foreign: rel_pos.is_foreign(),
- offset,
+ access_range,
+ transition_range: perms_range.clone(),
span,
});
old_state.permission =
@@ -472,7 +473,7 @@ impl<'tcx> Tree {
TbError {
conflicting_info,
access_kind,
- error_offset: offset,
+ error_offset: perms_range.start,
error_kind,
accessed_info,
}
@@ -487,7 +488,13 @@ impl<'tcx> Tree {
/// Integration with the BorTag garbage collector
impl Tree {
pub fn remove_unreachable_tags(&mut self, live_tags: &FxHashSet<BorTag>) {
- assert!(self.keep_only_needed(self.root, live_tags)); // root can't be removed
+ let root_is_needed = self.keep_only_needed(self.root, live_tags); // root can't be removed
+ assert!(root_is_needed);
+ // Right after the GC runs is a good moment to check if we can
+ // merge some adjacent ranges that were made equal by the removal of some
+ // tags (this does not necessarily mean that they have identical internal representations,
+ // see the `PartialEq` impl for `UniValMap`)
+ self.rperms.merge_adjacent_thorough();
}
/// Traverses the entire tree looking for useless tags.
@@ -530,7 +537,7 @@ impl Tree {
// the tag from the mapping.
let tag = node.tag;
self.nodes.remove(idx);
- for perms in self.rperms.iter_mut_all() {
+ for (_perms_range, perms) in self.rperms.iter_mut_all() {
perms.remove(idx);
}
self.tag_mapping.remove(&tag);
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs
index c1d452ca89e..58af32385c5 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs
@@ -36,13 +36,42 @@ pub struct UniKeyMap<K> {
}
/// From UniIndex to V
-#[derive(Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Clone, Eq)]
pub struct UniValMap<V> {
/// The mapping data. Thanks to Vec we get both fast accesses, and
/// a memory-optimal representation if there are few deletions.
data: Vec<Option<V>>,
}
+impl<V: PartialEq> UniValMap<V> {
+ /// Exact equality of two maps.
+ /// Less accurate but faster than `equivalent`, mostly because
+ /// of the fast path when the lengths are different.
+ pub fn identical(&self, other: &Self) -> bool {
+ self.data == other.data
+ }
+
+ /// Equality up to trailing `None`s of two maps, i.e.
+ /// do they represent the same mapping ?
+ pub fn equivalent(&self, other: &Self) -> bool {
+ let min_len = self.data.len().min(other.data.len());
+ self.data[min_len..].iter().all(Option::is_none)
+ && other.data[min_len..].iter().all(Option::is_none)
+ && (self.data[..min_len] == other.data[..min_len])
+ }
+}
+
+impl<V: PartialEq> PartialEq for UniValMap<V> {
+ /// 2023-05: We found that using `equivalent` rather than `identical`
+ /// in the equality testing of the `RangeMap` is neutral for most
+ /// benchmarks, while being quite beneficial for `zip-equal`
+ /// and to a lesser extent for `unicode`, `slice-get-unchecked` and
+ /// `backtraces` as well.
+ fn eq(&self, other: &Self) -> bool {
+ self.equivalent(other)
+ }
+}
+
impl<V> Default for UniValMap<V> {
fn default() -> Self {
Self { data: Vec::default() }
diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs
index 13306b4809c..f6252c43f9f 100644
--- a/src/tools/miri/src/concurrency/data_race.rs
+++ b/src/tools/miri/src/concurrency/data_race.rs
@@ -275,20 +275,20 @@ impl MemoryCellClocks {
/// not used previously as atomic memory.
fn load_acquire(
&mut self,
- clocks: &mut ThreadClockSet,
+ thread_clocks: &mut ThreadClockSet,
index: VectorIdx,
) -> Result<(), DataRace> {
- self.atomic_read_detect(clocks, index)?;
+ self.atomic_read_detect(thread_clocks, index)?;
if let Some(atomic) = self.atomic() {
- clocks.clock.join(&atomic.sync_vector);
+ thread_clocks.clock.join(&atomic.sync_vector);
}
Ok(())
}
/// Checks if the memory cell access is ordered with all prior atomic reads and writes
- fn race_free_with_atomic(&self, clocks: &ThreadClockSet) -> bool {
+ fn race_free_with_atomic(&self, thread_clocks: &ThreadClockSet) -> bool {
if let Some(atomic) = self.atomic() {
- atomic.read_vector <= clocks.clock && atomic.write_vector <= clocks.clock
+ atomic.read_vector <= thread_clocks.clock && atomic.write_vector <= thread_clocks.clock
} else {
true
}
@@ -299,54 +299,70 @@ impl MemoryCellClocks {
/// not used previously as atomic memory.
fn load_relaxed(
&mut self,
- clocks: &mut ThreadClockSet,
+ thread_clocks: &mut ThreadClockSet,
index: VectorIdx,
) -> Result<(), DataRace> {
- self.atomic_read_detect(clocks, index)?;
+ self.atomic_read_detect(thread_clocks, index)?;
if let Some(atomic) = self.atomic() {
- clocks.fence_acquire.join(&atomic.sync_vector);
+ thread_clocks.fence_acquire.join(&atomic.sync_vector);
}
Ok(())
}
/// Update the memory cell data-race tracking for atomic
/// store release semantics.
- fn store_release(&mut self, clocks: &ThreadClockSet, index: VectorIdx) -> Result<(), DataRace> {
- self.atomic_write_detect(clocks, index)?;
+ fn store_release(
+ &mut self,
+ thread_clocks: &ThreadClockSet,
+ index: VectorIdx,
+ ) -> Result<(), DataRace> {
+ self.atomic_write_detect(thread_clocks, index)?;
let atomic = self.atomic_mut();
- atomic.sync_vector.clone_from(&clocks.clock);
+ atomic.sync_vector.clone_from(&thread_clocks.clock);
Ok(())
}
/// Update the memory cell data-race tracking for atomic
/// store relaxed semantics.
- fn store_relaxed(&mut self, clocks: &ThreadClockSet, index: VectorIdx) -> Result<(), DataRace> {
- self.atomic_write_detect(clocks, index)?;
+ fn store_relaxed(
+ &mut self,
+ thread_clocks: &ThreadClockSet,
+ index: VectorIdx,
+ ) -> Result<(), DataRace> {
+ self.atomic_write_detect(thread_clocks, index)?;
// The handling of release sequences was changed in C++20 and so
// the code here is different to the paper since now all relaxed
// stores block release sequences. The exception for same-thread
// relaxed stores has been removed.
let atomic = self.atomic_mut();
- atomic.sync_vector.clone_from(&clocks.fence_release);
+ atomic.sync_vector.clone_from(&thread_clocks.fence_release);
Ok(())
}
/// Update the memory cell data-race tracking for atomic
/// store release semantics for RMW operations.
- fn rmw_release(&mut self, clocks: &ThreadClockSet, index: VectorIdx) -> Result<(), DataRace> {
- self.atomic_write_detect(clocks, index)?;
+ fn rmw_release(
+ &mut self,
+ thread_clocks: &ThreadClockSet,
+ index: VectorIdx,
+ ) -> Result<(), DataRace> {
+ self.atomic_write_detect(thread_clocks, index)?;
let atomic = self.atomic_mut();
- atomic.sync_vector.join(&clocks.clock);
+ atomic.sync_vector.join(&thread_clocks.clock);
Ok(())
}
/// Update the memory cell data-race tracking for atomic
/// store relaxed semantics for RMW operations.
- fn rmw_relaxed(&mut self, clocks: &ThreadClockSet, index: VectorIdx) -> Result<(), DataRace> {
- self.atomic_write_detect(clocks, index)?;
+ fn rmw_relaxed(
+ &mut self,
+ thread_clocks: &ThreadClockSet,
+ index: VectorIdx,
+ ) -> Result<(), DataRace> {
+ self.atomic_write_detect(thread_clocks, index)?;
let atomic = self.atomic_mut();
- atomic.sync_vector.join(&clocks.fence_release);
+ atomic.sync_vector.join(&thread_clocks.fence_release);
Ok(())
}
@@ -354,26 +370,26 @@ impl MemoryCellClocks {
/// not happen-before the atomic-read.
fn atomic_read_detect(
&mut self,
- clocks: &ThreadClockSet,
+ thread_clocks: &ThreadClockSet,
index: VectorIdx,
) -> Result<(), DataRace> {
- log::trace!("Atomic read with vectors: {:#?} :: {:#?}", self, clocks);
+ log::trace!("Atomic read with vectors: {:#?} :: {:#?}", self, thread_clocks);
let atomic = self.atomic_mut();
- atomic.read_vector.set_at_index(&clocks.clock, index);
- if self.write <= clocks.clock[self.write_index] { Ok(()) } else { Err(DataRace) }
+ atomic.read_vector.set_at_index(&thread_clocks.clock, index);
+ if self.write <= thread_clocks.clock[self.write_index] { Ok(()) } else { Err(DataRace) }
}
/// Detect data-races with an atomic write, either with a non-atomic read or with
/// a non-atomic write.
fn atomic_write_detect(
&mut self,
- clocks: &ThreadClockSet,
+ thread_clocks: &ThreadClockSet,
index: VectorIdx,
) -> Result<(), DataRace> {
- log::trace!("Atomic write with vectors: {:#?} :: {:#?}", self, clocks);
+ log::trace!("Atomic write with vectors: {:#?} :: {:#?}", self, thread_clocks);
let atomic = self.atomic_mut();
- atomic.write_vector.set_at_index(&clocks.clock, index);
- if self.write <= clocks.clock[self.write_index] && self.read <= clocks.clock {
+ atomic.write_vector.set_at_index(&thread_clocks.clock, index);
+ if self.write <= thread_clocks.clock[self.write_index] && self.read <= thread_clocks.clock {
Ok(())
} else {
Err(DataRace)
@@ -384,21 +400,21 @@ impl MemoryCellClocks {
/// returns true if a data-race is detected.
fn read_race_detect(
&mut self,
- clocks: &mut ThreadClockSet,
+ thread_clocks: &mut ThreadClockSet,
index: VectorIdx,
current_span: Span,
) -> Result<(), DataRace> {
- log::trace!("Unsynchronized read with vectors: {:#?} :: {:#?}", self, clocks);
+ log::trace!("Unsynchronized read with vectors: {:#?} :: {:#?}", self, thread_clocks);
if !current_span.is_dummy() {
- clocks.clock[index].span = current_span;
+ thread_clocks.clock[index].span = current_span;
}
- if self.write <= clocks.clock[self.write_index] {
+ if self.write <= thread_clocks.clock[self.write_index] {
let race_free = if let Some(atomic) = self.atomic() {
- atomic.write_vector <= clocks.clock
+ atomic.write_vector <= thread_clocks.clock
} else {
true
};
- self.read.set_at_index(&clocks.clock, index);
+ self.read.set_at_index(&thread_clocks.clock, index);
if race_free { Ok(()) } else { Err(DataRace) }
} else {
Err(DataRace)
@@ -409,22 +425,23 @@ impl MemoryCellClocks {
/// returns true if a data-race is detected.
fn write_race_detect(
&mut self,
- clocks: &mut ThreadClockSet,
+ thread_clocks: &mut ThreadClockSet,
index: VectorIdx,
write_type: WriteType,
current_span: Span,
) -> Result<(), DataRace> {
- log::trace!("Unsynchronized write with vectors: {:#?} :: {:#?}", self, clocks);
+ log::trace!("Unsynchronized write with vectors: {:#?} :: {:#?}", self, thread_clocks);
if !current_span.is_dummy() {
- clocks.clock[index].span = current_span;
+ thread_clocks.clock[index].span = current_span;
}
- if self.write <= clocks.clock[self.write_index] && self.read <= clocks.clock {
+ if self.write <= thread_clocks.clock[self.write_index] && self.read <= thread_clocks.clock {
let race_free = if let Some(atomic) = self.atomic() {
- atomic.write_vector <= clocks.clock && atomic.read_vector <= clocks.clock
+ atomic.write_vector <= thread_clocks.clock
+ && atomic.read_vector <= thread_clocks.clock
} else {
true
};
- self.write = clocks.clock[index];
+ self.write = thread_clocks.clock[index];
self.write_index = index;
self.write_type = write_type;
if race_free {
@@ -764,24 +781,24 @@ impl VClockAlloc {
fn report_data_race<'tcx>(
global: &GlobalState,
thread_mgr: &ThreadManager<'_, '_>,
- range: &MemoryCellClocks,
+ mem_clocks: &MemoryCellClocks,
action: &str,
is_atomic: bool,
ptr_dbg: Pointer<AllocId>,
) -> InterpResult<'tcx> {
let (current_index, current_clocks) = global.current_thread_state(thread_mgr);
let write_clock;
- let (other_action, other_thread, other_clock) = if range.write
- > current_clocks.clock[range.write_index]
+ let (other_action, other_thread, other_clock) = if mem_clocks.write
+ > current_clocks.clock[mem_clocks.write_index]
{
// Convert the write action into the vector clock it
// represents for diagnostic purposes.
- write_clock = VClock::new_with_index(range.write_index, range.write);
- (range.write_type.get_descriptor(), range.write_index, &write_clock)
- } else if let Some(idx) = Self::find_gt_index(&range.read, &current_clocks.clock) {
- ("Read", idx, &range.read)
+ write_clock = VClock::new_with_index(mem_clocks.write_index, mem_clocks.write);
+ (mem_clocks.write_type.get_descriptor(), mem_clocks.write_index, &write_clock)
+ } else if let Some(idx) = Self::find_gt_index(&mem_clocks.read, &current_clocks.clock) {
+ ("Read", idx, &mem_clocks.read)
} else if !is_atomic {
- if let Some(atomic) = range.atomic() {
+ if let Some(atomic) = mem_clocks.atomic() {
if let Some(idx) = Self::find_gt_index(&atomic.write_vector, &current_clocks.clock)
{
("Atomic Store", idx, &atomic.write_vector)
@@ -832,10 +849,10 @@ impl VClockAlloc {
thread_mgr: &ThreadManager<'_, '_>,
) -> bool {
if global.race_detecting() {
- let (_, clocks) = global.current_thread_state(thread_mgr);
+ let (_, thread_clocks) = global.current_thread_state(thread_mgr);
let alloc_ranges = self.alloc_ranges.borrow();
- for (_, range) in alloc_ranges.iter(range.start, range.size) {
- if !range.race_free_with_atomic(&clocks) {
+ for (_, mem_clocks) in alloc_ranges.iter(range.start, range.size) {
+ if !mem_clocks.race_free_with_atomic(&thread_clocks) {
return false;
}
}
@@ -851,25 +868,29 @@ impl VClockAlloc {
pub fn read<'tcx>(
&self,
alloc_id: AllocId,
- range: AllocRange,
+ access_range: AllocRange,
machine: &MiriMachine<'_, '_>,
) -> InterpResult<'tcx> {
let current_span = machine.current_span();
let global = machine.data_race.as_ref().unwrap();
if global.race_detecting() {
- let (index, mut clocks) = global.current_thread_state_mut(&machine.threads);
+ let (index, mut thread_clocks) = global.current_thread_state_mut(&machine.threads);
let mut alloc_ranges = self.alloc_ranges.borrow_mut();
- for (offset, range) in alloc_ranges.iter_mut(range.start, range.size) {
- if let Err(DataRace) = range.read_race_detect(&mut clocks, index, current_span) {
- drop(clocks);
+ for (mem_clocks_range, mem_clocks) in
+ alloc_ranges.iter_mut(access_range.start, access_range.size)
+ {
+ if let Err(DataRace) =
+ mem_clocks.read_race_detect(&mut thread_clocks, index, current_span)
+ {
+ drop(thread_clocks);
// Report data-race.
return Self::report_data_race(
global,
&machine.threads,
- range,
+ mem_clocks,
"Read",
false,
- Pointer::new(alloc_id, offset),
+ Pointer::new(alloc_id, Size::from_bytes(mem_clocks_range.start)),
);
}
}
@@ -883,27 +904,32 @@ impl VClockAlloc {
fn unique_access<'tcx>(
&mut self,
alloc_id: AllocId,
- range: AllocRange,
+ access_range: AllocRange,
write_type: WriteType,
machine: &mut MiriMachine<'_, '_>,
) -> InterpResult<'tcx> {
let current_span = machine.current_span();
let global = machine.data_race.as_mut().unwrap();
if global.race_detecting() {
- let (index, mut clocks) = global.current_thread_state_mut(&machine.threads);
- for (offset, range) in self.alloc_ranges.get_mut().iter_mut(range.start, range.size) {
- if let Err(DataRace) =
- range.write_race_detect(&mut clocks, index, write_type, current_span)
- {
- drop(clocks);
+ let (index, mut thread_clocks) = global.current_thread_state_mut(&machine.threads);
+ for (mem_clocks_range, mem_clocks) in
+ self.alloc_ranges.get_mut().iter_mut(access_range.start, access_range.size)
+ {
+ if let Err(DataRace) = mem_clocks.write_race_detect(
+ &mut thread_clocks,
+ index,
+ write_type,
+ current_span,
+ ) {
+ drop(thread_clocks);
// Report data-race
return Self::report_data_race(
global,
&machine.threads,
- range,
+ mem_clocks,
write_type.get_descriptor(),
false,
- Pointer::new(alloc_id, offset),
+ Pointer::new(alloc_id, Size::from_bytes(mem_clocks_range.start)),
);
}
}
@@ -1125,19 +1151,23 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
data_race.maybe_perform_sync_operation(
&this.machine.threads,
current_span,
- |index, mut clocks| {
- for (offset, range) in
+ |index, mut thread_clocks| {
+ for (mem_clocks_range, mem_clocks) in
alloc_meta.alloc_ranges.borrow_mut().iter_mut(base_offset, size)
{
- if let Err(DataRace) = op(range, &mut clocks, index, atomic) {
- mem::drop(clocks);
+ if let Err(DataRace) = op(mem_clocks, &mut thread_clocks, index, atomic)
+ {
+ mem::drop(thread_clocks);
return VClockAlloc::report_data_race(
data_race,
&this.machine.threads,
- range,
+ mem_clocks,
description,
true,
- Pointer::new(alloc_id, offset),
+ Pointer::new(
+ alloc_id,
+ Size::from_bytes(mem_clocks_range.start),
+ ),
)
.map(|_| true);
}
@@ -1150,13 +1180,14 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
// Log changes to atomic memory.
if log::log_enabled!(log::Level::Trace) {
- for (_offset, range) in alloc_meta.alloc_ranges.borrow().iter(base_offset, size)
+ for (_offset, mem_clocks) in
+ alloc_meta.alloc_ranges.borrow().iter(base_offset, size)
{
log::trace!(
"Updated atomic memory({:?}, size={}) to {:#?}",
place.ptr,
size.bytes(),
- range.atomic_ops
+ mem_clocks.atomic_ops
);
}
}
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index a93f3eb84f2..e3f81a78eea 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -289,7 +289,7 @@ pub fn report_error<'tcx, 'mir>(
(None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")),
],
InvalidProgram(
- InvalidProgramInfo::AlreadyReported(rustc_errors::ErrorGuaranteed { .. })
+ InvalidProgramInfo::AlreadyReported(_)
) => {
// This got already reported. No point in reporting it again.
return None;
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index fc938080a0e..893a4dbd4c8 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -47,7 +47,6 @@ extern crate rustc_ast;
extern crate rustc_middle;
extern crate rustc_const_eval;
extern crate rustc_data_structures;
-extern crate rustc_errors;
extern crate rustc_hir;
extern crate rustc_index;
extern crate rustc_session;
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 21c5a9c1b70..32717a0d28b 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -4,6 +4,8 @@
use std::borrow::Cow;
use std::cell::RefCell;
use std::fmt;
+use std::path::Path;
+use std::process;
use rand::rngs::StdRng;
use rand::SeedableRng;
@@ -498,7 +500,21 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
let layouts =
PrimitiveLayouts::new(layout_cx).expect("Couldn't get layouts of primitive types");
let profiler = config.measureme_out.as_ref().map(|out| {
- measureme::Profiler::new(out).expect("Couldn't create `measureme` profiler")
+ let crate_name = layout_cx
+ .tcx
+ .sess
+ .opts
+ .crate_name
+ .clone()
+ .unwrap_or_else(|| "unknown-crate".to_string());
+ let pid = process::id();
+ // We adopt the same naming scheme for the profiler output that rustc uses. In rustc,
+ // the PID is padded so that the nondeterministic value of the PID does not spread
+ // nondeterminisim to the allocator. In Miri we are not aiming for such performance
+ // control, we just pad for consistency with rustc.
+ let filename = format!("{crate_name}-{pid:07}");
+ let path = Path::new(out).join(filename);
+ measureme::Profiler::new(path).expect("Couldn't create `measureme` profiler")
});
let rng = StdRng::seed_from_u64(config.seed.unwrap_or(0));
let borrow_tracker = config.borrow_tracker.map(|bt| bt.instantiate_global_state(config));
diff --git a/src/tools/miri/src/range_map.rs b/src/tools/miri/src/range_map.rs
index 62198061827..146715ddda2 100644
--- a/src/tools/miri/src/range_map.rs
+++ b/src/tools/miri/src/range_map.rs
@@ -62,8 +62,10 @@ impl<T> RangeMap<T> {
/// *not* split items if they overlap with the edges. Do not use this to mutate
/// through interior mutability.
///
- /// The iterator also provides the offset of the given element.
- pub fn iter(&self, offset: Size, len: Size) -> impl Iterator<Item = (Size, &T)> {
+ /// The iterator also provides the range of the given element.
+ /// How exactly the ranges are split can differ even for otherwise identical
+ /// maps, so user-visible behavior should never depend on the exact range.
+ pub fn iter(&self, offset: Size, len: Size) -> impl Iterator<Item = (ops::Range<u64>, &T)> {
let offset = offset.bytes();
let len = len.bytes();
// Compute a slice starting with the elements we care about.
@@ -84,13 +86,21 @@ impl<T> RangeMap<T> {
slice
.iter()
.take_while(move |elem| elem.range.start < end)
- .map(|elem| (Size::from_bytes(elem.range.start), &elem.data))
+ .map(|elem| (elem.range.clone(), &elem.data))
}
- pub fn iter_mut_all(&mut self) -> impl Iterator<Item = &mut T> {
- self.v.iter_mut().map(|elem| &mut elem.data)
+ /// Provides mutable iteration over all elements.
+ /// The iterator also provides the range of the given element.
+ /// How exactly the ranges are split can differ even for otherwise identical
+ /// maps, so user-visible behavior should never depend on the exact range.
+ pub fn iter_mut_all(&mut self) -> impl Iterator<Item = (ops::Range<u64>, &mut T)> {
+ self.v.iter_mut().map(|elem| (elem.range.clone(), &mut elem.data))
}
+ /// Provides iteration over all elements.
+ /// The iterator also provides the range of the given element.
+ /// How exactly the ranges are split can differ even for otherwise identical
+ /// maps, so user-visible behavior should never depend on the exact range.
pub fn iter_all(&self) -> impl Iterator<Item = (ops::Range<u64>, &T)> {
self.v.iter().map(|elem| (elem.range.clone(), &elem.data))
}
@@ -126,8 +136,15 @@ impl<T> RangeMap<T> {
/// to make sure that when they are mutated, the effect is constrained to the given range.
/// Moreover, this will opportunistically merge neighbouring equal blocks.
///
- /// The iterator also provides the offset of the given element.
- pub fn iter_mut(&mut self, offset: Size, len: Size) -> impl Iterator<Item = (Size, &mut T)>
+ /// The iterator also provides the range of the given element.
+ /// How exactly the ranges are split (both prior to and resulting from the execution of this
+ /// function) can differ even for otherwise identical maps,
+ /// so user-visible behavior should never depend on the exact range.
+ pub fn iter_mut(
+ &mut self,
+ offset: Size,
+ len: Size,
+ ) -> impl Iterator<Item = (ops::Range<u64>, &mut T)>
where
T: Clone + PartialEq,
{
@@ -208,7 +225,25 @@ impl<T> RangeMap<T> {
// Now we yield the slice. `end` is inclusive.
&mut self.v[first_idx..=end_idx]
};
- slice.iter_mut().map(|elem| (Size::from_bytes(elem.range.start), &mut elem.data))
+ slice.iter_mut().map(|elem| (elem.range.clone(), &mut elem.data))
+ }
+
+ /// Remove all adjacent duplicates
+ pub fn merge_adjacent_thorough(&mut self)
+ where
+ T: PartialEq,
+ {
+ let clean = Vec::with_capacity(self.v.len());
+ for elem in std::mem::replace(&mut self.v, clean) {
+ if let Some(prev) = self.v.last_mut() {
+ if prev.data == elem.data {
+ assert_eq!(prev.range.end, elem.range.start);
+ prev.range.end = elem.range.end;
+ continue;
+ }
+ }
+ self.v.push(elem);
+ }
}
}
diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs
index d101f8d3111..114c66253f7 100644
--- a/src/tools/miri/src/shims/intrinsics/simd.rs
+++ b/src/tools/miri/src/shims/intrinsics/simd.rs
@@ -421,14 +421,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}
}
#[rustfmt::skip]
- "cast" | "as" => {
+ "cast" | "as" | "cast_ptr" | "expose_addr" | "from_exposed_addr" => {
let [op] = check_arg_count(args)?;
let (op, op_len) = this.operand_to_simd(op)?;
let (dest, dest_len) = this.place_to_simd(dest)?;
assert_eq!(dest_len, op_len);
+ let unsafe_cast = intrinsic_name == "cast";
let safe_cast = intrinsic_name == "as";
+ let ptr_cast = intrinsic_name == "cast_ptr";
+ let expose_cast = intrinsic_name == "expose_addr";
+ let from_exposed_cast = intrinsic_name == "from_exposed_addr";
for i in 0..dest_len {
let op = this.read_immediate(&this.mplace_index(&op, i)?.into())?;
@@ -436,19 +440,31 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let val = match (op.layout.ty.kind(), dest.layout.ty.kind()) {
// Int-to-(int|float): always safe
- (ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_)) =>
+ (ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_)) if safe_cast || unsafe_cast =>
this.int_to_int_or_float(&op, dest.layout.ty)?,
// Float-to-float: always safe
- (ty::Float(_), ty::Float(_)) =>
+ (ty::Float(_), ty::Float(_)) if safe_cast || unsafe_cast =>
this.float_to_float_or_int(&op, dest.layout.ty)?,
// Float-to-int in safe mode
(ty::Float(_), ty::Int(_) | ty::Uint(_)) if safe_cast =>
this.float_to_float_or_int(&op, dest.layout.ty)?,
// Float-to-int in unchecked mode
- (ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if !safe_cast =>
+ (ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if unsafe_cast =>
this.float_to_int_unchecked(op.to_scalar().to_f32()?, dest.layout.ty)?.into(),
- (ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if !safe_cast =>
+ (ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if unsafe_cast =>
this.float_to_int_unchecked(op.to_scalar().to_f64()?, dest.layout.ty)?.into(),
+ // Ptr-to-ptr cast
+ (ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast => {
+ this.ptr_to_ptr(&op, dest.layout.ty)?
+ }
+ // Ptr/Int casts
+ (ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast => {
+ this.pointer_expose_address_cast(&op, dest.layout.ty)?
+ }
+ (ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast => {
+ this.pointer_from_exposed_address_cast(&op, dest.layout.ty)?
+ }
+ // Error otherwise
_ =>
throw_unsup_format!(
"Unsupported SIMD cast from element type {from_ty} to {to_ty}",
diff --git a/src/tools/miri/test-cargo-miri/subcrate/src/lib.rs b/src/tools/miri/test-cargo-miri/subcrate/src/lib.rs
index 2ccb6704b05..98c22fef076 100644
--- a/src/tools/miri/test-cargo-miri/subcrate/src/lib.rs
+++ b/src/tools/miri/test-cargo-miri/subcrate/src/lib.rs
@@ -1,5 +1,16 @@
+// This is a proc-macro crate.
+
+extern crate proc_macro; // make sure proc_macro is in the sysroot
+
#[cfg(doctest)]
compile_error!("rustdoc should not touch me");
-#[cfg(test)]
+#[cfg(miri)]
compile_error!("Miri should not touch me");
+
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn make_answer(_item: TokenStream) -> TokenStream {
+ "fn answer() -> u32 { 42 }".parse().unwrap()
+}
diff --git a/src/tools/miri/tests/compiletest.rs b/src/tools/miri/tests/compiletest.rs
index 52deba9108c..fa06c4b6a12 100644
--- a/src/tools/miri/tests/compiletest.rs
+++ b/src/tools/miri/tests/compiletest.rs
@@ -1,7 +1,10 @@
use colored::*;
use regex::bytes::Regex;
+use std::ffi::OsString;
use std::path::{Path, PathBuf};
use std::{env, process::Command};
+use ui_test::status_emitter::StatusEmitter;
+use ui_test::CommandBuilder;
use ui_test::{color_eyre::Result, Config, Match, Mode, OutputConflictHandling};
fn miri_path() -> PathBuf {
@@ -43,18 +46,10 @@ fn build_so_for_c_ffi_tests() -> PathBuf {
so_file_path
}
-fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> Result<()> {
- let mut config = Config {
- target: Some(target.to_owned()),
- stderr_filters: STDERR.clone(),
- stdout_filters: STDOUT.clone(),
- root_dir: PathBuf::from(path),
- mode,
- program: miri_path(),
- quiet: false,
- edition: Some("2018".into()),
- ..Config::default()
- };
+fn test_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) -> Config {
+ // Miri is rustc-like, so we create a default builder for rustc and modify it
+ let mut program = CommandBuilder::rustc();
+ program.program = miri_path();
let in_rustc_test_suite = option_env!("RUSTC_STAGE").is_some();
@@ -62,22 +57,20 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R
if in_rustc_test_suite {
// Less aggressive warnings to make the rustc toolstate management less painful.
// (We often get warnings when e.g. a feature gets stabilized or some lint gets added/improved.)
- config.args.push("-Astable-features".into());
- config.args.push("-Aunused".into());
+ program.args.push("-Astable-features".into());
+ program.args.push("-Aunused".into());
} else {
- config.args.push("-Dwarnings".into());
- config.args.push("-Dunused".into());
+ program.args.push("-Dwarnings".into());
+ program.args.push("-Dunused".into());
}
if let Ok(extra_flags) = env::var("MIRIFLAGS") {
for flag in extra_flags.split_whitespace() {
- config.args.push(flag.into());
+ program.args.push(flag.into());
}
}
- config.args.push("-Zui-testing".into());
- if let Some(target) = &config.target {
- config.args.push("--target".into());
- config.args.push(target.into());
- }
+ program.args.push("-Zui-testing".into());
+ program.args.push("--target".into());
+ program.args.push(target.into());
// If we're on linux, and we're testing the extern-so functionality,
// then build the shared object file for testing external C function calls
@@ -86,18 +79,51 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R
let so_file_path = build_so_for_c_ffi_tests();
let mut flag = std::ffi::OsString::from("-Zmiri-extern-so-file=");
flag.push(so_file_path.into_os_string());
- config.args.push(flag);
+ program.args.push(flag);
}
let skip_ui_checks = env::var_os("MIRI_SKIP_UI_CHECKS").is_some();
- config.output_conflict_handling = match (env::var_os("MIRI_BLESS").is_some(), skip_ui_checks) {
+ let output_conflict_handling = match (env::var_os("MIRI_BLESS").is_some(), skip_ui_checks) {
(false, false) => OutputConflictHandling::Error,
(true, false) => OutputConflictHandling::Bless,
(false, true) => OutputConflictHandling::Ignore,
(true, true) => panic!("cannot use MIRI_BLESS and MIRI_SKIP_UI_CHECKS at the same time"),
};
+ let mut config = Config {
+ target: Some(target.to_owned()),
+ stderr_filters: STDERR.clone(),
+ stdout_filters: STDOUT.clone(),
+ root_dir: PathBuf::from(path),
+ mode,
+ program,
+ output_conflict_handling,
+ quiet: false,
+ edition: Some("2021".into()),
+ ..Config::default()
+ };
+
+ let use_std = env::var_os("MIRI_NO_STD").is_none();
+
+ if with_dependencies && use_std {
+ config.dependencies_crate_manifest_path =
+ Some(Path::new("test_dependencies").join("Cargo.toml"));
+ config.dependency_builder.args = vec![
+ "run".into(),
+ "--manifest-path".into(),
+ "cargo-miri/Cargo.toml".into(),
+ "--".into(),
+ "miri".into(),
+ "run".into(), // There is no `cargo miri build` so we just use `cargo miri run`.
+ ];
+ }
+ config
+}
+
+fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> Result<()> {
+ let mut config = test_config(target, path, mode, with_dependencies);
+
// Handle command-line arguments.
let mut after_dashdash = false;
config.path_filter.extend(std::env::args().skip(1).filter(|arg| {
@@ -121,21 +147,15 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R
}
}));
- let use_std = env::var_os("MIRI_NO_STD").is_none();
-
- if with_dependencies && use_std {
- config.dependencies_crate_manifest_path =
- Some(Path::new("test_dependencies").join("Cargo.toml"));
- config.dependency_builder.args = vec![
- "run".into(),
- "--manifest-path".into(),
- "cargo-miri/Cargo.toml".into(),
- "--".into(),
- "miri".into(),
- "run".into(), // There is no `cargo miri build` so we just use `cargo miri run`.
- ];
- }
- ui_test::run_tests(config)
+ eprintln!(" Compiler: {}", config.program.display());
+ ui_test::run_tests_generic(
+ config,
+ // The files we're actually interested in (all `.rs` files).
+ |path| path.extension().is_some_and(|ext| ext == "rs"),
+ // This could be used to overwrite the `Config` on a per-test basis.
+ |_, _| None,
+ TextAndGha,
+ )
}
macro_rules! regexes {
@@ -212,8 +232,18 @@ fn get_target() -> String {
fn main() -> Result<()> {
ui_test::color_eyre::install()?;
+
let target = get_target();
+ let mut args = std::env::args_os();
+
+ // Skip the program name and check whether this is a `./miri run-dep` invocation
+ if let Some(first) = args.nth(1) {
+ if first == "--miri-run-dep-mode" {
+ return run_dep_mode(target, args);
+ }
+ }
+
// Add a test env var to do environment communication tests.
env::set_var("MIRI_ENV_VAR_TEST", "0");
// Let the tests know where to store temp files (they might run for a different target, which can make this hard to find).
@@ -235,3 +265,60 @@ fn main() -> Result<()> {
Ok(())
}
+
+fn run_dep_mode(target: String, mut args: impl Iterator<Item = OsString>) -> Result<()> {
+ let path = args.next().expect("./miri run-dep must be followed by a file name");
+ let mut config = test_config(&target, "", Mode::Yolo, /* with dependencies */ true);
+ config.program.args.remove(0); // remove the `--error-format=json` argument
+ config.program.args.push("--color".into());
+ config.program.args.push("always".into());
+ let mut cmd = ui_test::test_command(config, Path::new(&path))?;
+ // Separate the arguments to the `cargo miri` invocation from
+ // the arguments to the interpreted prog
+ cmd.arg("--");
+ cmd.args(args);
+ println!("{cmd:?}");
+ if cmd.spawn()?.wait()?.success() { Ok(()) } else { std::process::exit(1) }
+}
+
+/// This is a custom renderer for `ui_test` output that does not emit github actions
+/// `group`s, while still producing regular github actions messages on test failures.
+struct TextAndGha;
+impl StatusEmitter for TextAndGha {
+ fn failed_test<'a>(
+ &'a self,
+ revision: &'a str,
+ path: &'a Path,
+ cmd: &'a Command,
+ stderr: &'a [u8],
+ ) -> Box<dyn std::fmt::Debug + 'a> {
+ Box::new((
+ ui_test::status_emitter::Gha::<false>.failed_test(revision, path, cmd, stderr),
+ ui_test::status_emitter::Text.failed_test(revision, path, cmd, stderr),
+ ))
+ }
+
+ fn run_tests(&self, _config: &Config) -> Box<dyn ui_test::status_emitter::DuringTestRun> {
+ Box::new(TextAndGha)
+ }
+
+ fn finalize(
+ &self,
+ failures: usize,
+ succeeded: usize,
+ ignored: usize,
+ filtered: usize,
+ ) -> Box<dyn ui_test::status_emitter::Summary> {
+ Box::new((
+ ui_test::status_emitter::Gha::<false>.finalize(failures, succeeded, ignored, filtered),
+ ui_test::status_emitter::Text.finalize(failures, succeeded, ignored, filtered),
+ ))
+ }
+}
+
+impl ui_test::status_emitter::DuringTestRun for TextAndGha {
+ fn test_result(&mut self, path: &Path, revision: &str, result: &ui_test::TestResult) {
+ ui_test::status_emitter::Text.test_result(path, revision, result);
+ ui_test::status_emitter::Gha::<false>.test_result(path, revision, result);
+ }
+}
diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs
index a07d8254ad3..e8ba824db71 100644
--- a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs
+++ b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs
@@ -1,6 +1,6 @@
use std::alloc::{alloc, dealloc, Layout};
-//@error-pattern: has size 1 and alignment 1, but gave size 1 and alignment 2
+//@error-in-other-file: has size 1 and alignment 1, but gave size 1 and alignment 2
fn main() {
unsafe {
diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs
index 47aaef1935e..e3f9a20ac3b 100644
--- a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs
+++ b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs
@@ -1,6 +1,6 @@
use std::alloc::{alloc, dealloc, Layout};
-//@error-pattern: has size 1 and alignment 1, but gave size 2 and alignment 1
+//@error-in-other-file: has size 1 and alignment 1, but gave size 2 and alignment 1
fn main() {
unsafe {
diff --git a/src/tools/miri/tests/fail/alloc/deallocate-twice.rs b/src/tools/miri/tests/fail/alloc/deallocate-twice.rs
index 1eb9bbf91ca..f07bbda4a9b 100644
--- a/src/tools/miri/tests/fail/alloc/deallocate-twice.rs
+++ b/src/tools/miri/tests/fail/alloc/deallocate-twice.rs
@@ -1,6 +1,6 @@
use std::alloc::{alloc, dealloc, Layout};
-//@error-pattern: dereferenced after this allocation got freed
+//@error-in-other-file: dereferenced after this allocation got freed
fn main() {
unsafe {
diff --git a/src/tools/miri/tests/fail/alloc/global_system_mixup.rs b/src/tools/miri/tests/fail/alloc/global_system_mixup.rs
index 47b098c71a2..2e88e5644e4 100644
--- a/src/tools/miri/tests/fail/alloc/global_system_mixup.rs
+++ b/src/tools/miri/tests/fail/alloc/global_system_mixup.rs
@@ -1,6 +1,6 @@
// Make sure we detect when the `Global` and `System` allocators are mixed
// (even when the default `Global` uses `System`).
-//@error-pattern: /deallocating .*, which is Rust heap memory, using .* heap deallocation operation/
+//@error-in-other-file: /deallocating .*, which is Rust heap memory, using .* heap deallocation operation/
//@normalize-stderr-test: "using [A-Za-z]+ heap deallocation operation" -> "using PLATFORM heap deallocation operation"
//@normalize-stderr-test: "\| +\^+" -> "| ^"
diff --git a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs
index 145c3393d67..49b2c62d7e4 100644
--- a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs
+++ b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs
@@ -1,6 +1,6 @@
use std::alloc::{alloc, realloc, Layout};
-//@error-pattern: has size 1 and alignment 1, but gave size 2 and alignment 1
+//@error-in-other-file: has size 1 and alignment 1, but gave size 2 and alignment 1
fn main() {
unsafe {
diff --git a/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs b/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs
index 34f1658344a..130e2a8301e 100644
--- a/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs
+++ b/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs
@@ -1,6 +1,6 @@
use std::alloc::{alloc, dealloc, realloc, Layout};
-//@error-pattern: dereferenced after this allocation got freed
+//@error-in-other-file: dereferenced after this allocation got freed
fn main() {
unsafe {
diff --git a/src/tools/miri/tests/fail/alloc/stack_free.rs b/src/tools/miri/tests/fail/alloc/stack_free.rs
index baf53decc44..15a17a25afe 100644
--- a/src/tools/miri/tests/fail/alloc/stack_free.rs
+++ b/src/tools/miri/tests/fail/alloc/stack_free.rs
@@ -1,7 +1,7 @@
// Validation/SB changes why we fail
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
-//@error-pattern: /deallocating .*, which is stack variable memory, using Rust heap deallocation operation/
+//@error-in-other-file: /deallocating .*, which is stack variable memory, using Rust heap deallocation operation/
fn main() {
let x = 42;
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs b/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs
index 065ad2d725f..7e6f490bb3d 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs
+++ b/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs
@@ -1,5 +1,5 @@
//@ignore-target-windows: No libc on Windows
-//@error-pattern: the main thread terminated without waiting for all remaining threads
+//@error-in-other-file: the main thread terminated without waiting for all remaining threads
// Check that we terminate the program when the main thread terminates.
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr b/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr
index 94463bef8f0..c2de4afd68f 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr
+++ b/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr
@@ -7,8 +7,8 @@ LL | panic!()
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
- = note: inside `thread_start` at RUSTLIB/std/src/panic.rs:LL:CC
- = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: inside `thread_start` at RUSTLIB/core/src/panic.rs:LL:CC
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr b/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr
index fdbe91cc8a8..85ae930d439 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr
+++ b/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr
@@ -7,8 +7,8 @@ LL | panic!()
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
- = note: inside `thread_start` at RUSTLIB/std/src/panic.rs:LL:CC
- = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: inside `thread_start` at RUSTLIB/core/src/panic.rs:LL:CC
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
diff --git a/src/tools/miri/tests/fail/concurrency/windows_join_detached.rs b/src/tools/miri/tests/fail/concurrency/windows_join_detached.rs
index 548ed63534d..b68a07797f8 100644
--- a/src/tools/miri/tests/fail/concurrency/windows_join_detached.rs
+++ b/src/tools/miri/tests/fail/concurrency/windows_join_detached.rs
@@ -1,5 +1,5 @@
//@only-target-windows: Uses win32 api functions
-//@error-pattern: Undefined Behavior: trying to join a detached thread
+//@error-in-other-file: Undefined Behavior: trying to join a detached thread
// Joining a detached thread is undefined behavior.
diff --git a/src/tools/miri/tests/fail/const-ub-checks.rs b/src/tools/miri/tests/fail/const-ub-checks.rs
index fa522c30cbd..9cc8b91ff50 100644
--- a/src/tools/miri/tests/fail/const-ub-checks.rs
+++ b/src/tools/miri/tests/fail/const-ub-checks.rs
@@ -1,5 +1,3 @@
-#![feature(const_ptr_read)]
-
const UNALIGNED_READ: () = unsafe {
let x = &[0u8; 4];
let ptr = x.as_ptr().cast::<u32>();
diff --git a/src/tools/miri/tests/fail/data_race/alloc_read_race.rs b/src/tools/miri/tests/fail/data_race/alloc_read_race.rs
index 2698c63a445..42077dfae2d 100644
--- a/src/tools/miri/tests/fail/data_race/alloc_read_race.rs
+++ b/src/tools/miri/tests/fail/data_race/alloc_read_race.rs
@@ -26,6 +26,7 @@ pub fn main() {
// 2. write
unsafe {
let j1 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
// Concurrent allocate the memory.
// Uses relaxed semantics to not generate
// a release sequence.
@@ -34,6 +35,7 @@ pub fn main() {
});
let j2 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
// Note: could also error due to reading uninitialized memory, but the data-race detector triggers first.
diff --git a/src/tools/miri/tests/fail/data_race/alloc_write_race.rs b/src/tools/miri/tests/fail/data_race/alloc_write_race.rs
index b78d5ef27d3..53f4e637a19 100644
--- a/src/tools/miri/tests/fail/data_race/alloc_write_race.rs
+++ b/src/tools/miri/tests/fail/data_race/alloc_write_race.rs
@@ -25,6 +25,7 @@ pub fn main() {
// 2. write
unsafe {
let j1 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
// Concurrent allocate the memory.
// Uses relaxed semantics to not generate
// a release sequence.
@@ -34,6 +35,7 @@ pub fn main() {
});
let j2 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
*pointer.load(Ordering::Relaxed) = 2; //~ ERROR: Data race detected between (1) Allocate on thread `<unnamed>` and (2) Write on thread `<unnamed>`
});
diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs
index 3f811d0f64d..9606df1d6ff 100644
--- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs
+++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs
@@ -16,10 +16,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
*(c.0 as *mut usize) = 32;
});
let j2 = spawn(move || {
+ let c = c; // avoid field capturing
(&*c.0).load(Ordering::SeqCst) //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Atomic Load on thread `<unnamed>`
});
diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs
index 34fb3ac066f..0e29ab32eef 100644
--- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs
+++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs
@@ -17,11 +17,13 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
let atomic_ref = &mut *c.0;
atomic_ref.load(Ordering::SeqCst)
});
let j2 = spawn(move || {
+ let c = c; // avoid field capturing
let atomic_ref = &mut *c.0;
*atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between (1) Atomic Load on thread `<unnamed>` and (2) Write on thread `<unnamed>`
});
diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs
index 63b0806f3bb..6f1792bc8f4 100644
--- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs
+++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs
@@ -17,11 +17,13 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
let atomic_ref = &mut *c.0;
atomic_ref.store(32, Ordering::SeqCst)
});
let j2 = spawn(move || {
+ let c = c; // avoid field capturing
let atomic_ref = &mut *c.0;
*atomic_ref.get_mut() //~ ERROR: Data race detected between (1) Atomic Store on thread `<unnamed>` and (2) Read on thread `<unnamed>`
});
diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs
index 9092254be21..e84207e655d 100644
--- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs
+++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs
@@ -16,10 +16,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
let _val = *(c.0 as *mut usize);
});
let j2 = spawn(move || {
+ let c = c; // avoid field capturing
(&*c.0).store(32, Ordering::SeqCst); //~ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Atomic Store on thread `<unnamed>`
});
diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs
index 5a713905f4e..ca269b1bd2a 100644
--- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs
+++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs
@@ -16,10 +16,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
*(c.0 as *mut usize) = 32;
});
let j2 = spawn(move || {
+ let c = c; // avoid field capturing
(&*c.0).store(64, Ordering::SeqCst); //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Atomic Store on thread `<unnamed>`
});
diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs
index 5848aa262b3..0d69a9a332d 100644
--- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs
+++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs
@@ -17,11 +17,13 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
let atomic_ref = &mut *c.0;
atomic_ref.store(64, Ordering::SeqCst);
});
let j2 = spawn(move || {
+ let c = c; // avoid field capturing
let atomic_ref = &mut *c.0;
*atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between (1) Atomic Store on thread `<unnamed>` and (2) Write on thread `<unnamed>`
});
diff --git a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs
index eecb980e905..0679b81f012 100644
--- a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs
+++ b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs
@@ -18,6 +18,7 @@ fn main() {
let join = unsafe {
spawn(move || {
+ let c = c; // capture `c`, not just its field.
*c.0 = 32;
})
};
@@ -34,6 +35,7 @@ fn main() {
let join2 = unsafe {
spawn(move || {
+ let c = c; // capture `c`, not just its field.
*c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>`
})
};
diff --git a/src/tools/miri/tests/fail/data_race/dangling_thread_race.rs b/src/tools/miri/tests/fail/data_race/dangling_thread_race.rs
index 4c7fbdd7fe6..3c5dd424eb1 100644
--- a/src/tools/miri/tests/fail/data_race/dangling_thread_race.rs
+++ b/src/tools/miri/tests/fail/data_race/dangling_thread_race.rs
@@ -18,6 +18,7 @@ fn main() {
let join = unsafe {
spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 32;
})
};
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs
index 18593cf56ae..3c25cdc0d8d 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs
@@ -20,10 +20,12 @@ pub fn main() {
unsafe {
let j1 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
let _val = *ptr.0;
});
let j2 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
__rust_dealloc(
//~^ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>`
ptr.0 as *mut _,
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs
index a6f83d489e5..5d7a0cc1dc9 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs
@@ -20,6 +20,7 @@ pub fn main() {
unsafe {
let j1 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
__rust_dealloc(
ptr.0 as *mut _,
std::mem::size_of::<usize>(),
@@ -28,6 +29,7 @@ pub fn main() {
});
let j2 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
// Also an error of the form: Data race detected between (1) Deallocate on thread `<unnamed>` and (2) Read on thread `<unnamed>`
// but the invalid allocation is detected first.
*ptr.0 //~ ERROR: dereferenced after this allocation got freed
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs
index c82bfed09ee..87b5f204816 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs
@@ -26,6 +26,7 @@ pub fn main() {
// 3. stack-deallocate
unsafe {
let j1 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
{
let mut stack_var = 0usize;
@@ -39,6 +40,7 @@ pub fn main() {
});
let j2 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
*pointer.load(Ordering::Acquire)
});
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs
index 1e93a6cb094..b700f50ce19 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs
@@ -19,10 +19,12 @@ pub fn main() {
unsafe {
let j1 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
*ptr.0 = 2;
});
let j2 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
__rust_dealloc(
//~^ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>`
ptr.0 as *mut _,
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs
index 385584db27f..a7f43f03c02 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs
@@ -19,6 +19,7 @@ pub fn main() {
unsafe {
let j1 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
__rust_dealloc(
ptr.0 as *mut _,
std::mem::size_of::<usize>(),
@@ -27,6 +28,7 @@ pub fn main() {
});
let j2 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
// Also an error of the form: Data race detected between (1) Deallocate on thread `<unnamed>` and (2) Write on thread `<unnamed>`
// but the invalid allocation is detected first.
*ptr.0 = 2; //~ ERROR: dereferenced after this allocation got freed
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs
index 259fbdc497a..3d35187a018 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs
@@ -26,6 +26,7 @@ pub fn main() {
// 3. stack-deallocate
unsafe {
let j1 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
{
let mut stack_var = 0usize;
@@ -39,6 +40,7 @@ pub fn main() {
});
let j2 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
*pointer.load(Ordering::Acquire) = 3;
});
diff --git a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs
index 3d47b1accb3..b44be4ac64e 100644
--- a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs
+++ b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs
@@ -26,10 +26,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 32;
});
let j2 = spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>`
});
diff --git a/src/tools/miri/tests/fail/data_race/read_write_race.rs b/src/tools/miri/tests/fail/data_race/read_write_race.rs
index d996141db3e..aed3ca767f6 100644
--- a/src/tools/miri/tests/fail/data_race/read_write_race.rs
+++ b/src/tools/miri/tests/fail/data_race/read_write_race.rs
@@ -15,10 +15,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
let _val = *c.0;
});
let j2 = spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 64; //~ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Write on thread `<unnamed>`
});
diff --git a/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs b/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs
index b4e371f430d..40224ced12d 100644
--- a/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs
+++ b/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs
@@ -31,6 +31,7 @@ pub fn main() {
// 5. read-value
unsafe {
let j1 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
// Concurrent allocate the memory.
// Uses relaxed semantics to not generate
// a release sequence.
@@ -46,6 +47,7 @@ pub fn main() {
});
let j2 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
*pointer.load(Ordering::Acquire) = 3;
});
diff --git a/src/tools/miri/tests/fail/data_race/relax_acquire_race.rs b/src/tools/miri/tests/fail/data_race/relax_acquire_race.rs
index b7226fa626f..1b691b996f1 100644
--- a/src/tools/miri/tests/fail/data_race/relax_acquire_race.rs
+++ b/src/tools/miri/tests/fail/data_race/relax_acquire_race.rs
@@ -25,6 +25,7 @@ pub fn main() {
// 4. load acquire : 2
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 1;
SYNC.store(1, Ordering::Release);
});
@@ -36,6 +37,7 @@ pub fn main() {
});
let j3 = spawn(move || {
+ let c = c; // avoid field capturing
if SYNC.load(Ordering::Acquire) == 2 {
*c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`
} else {
diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race.rs b/src/tools/miri/tests/fail/data_race/release_seq_race.rs
index dff33a42a1c..80b30053fc7 100644
--- a/src/tools/miri/tests/fail/data_race/release_seq_race.rs
+++ b/src/tools/miri/tests/fail/data_race/release_seq_race.rs
@@ -27,6 +27,7 @@ pub fn main() {
// 4. load acquire : 3
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 1;
SYNC.store(1, Ordering::Release);
sleep(Duration::from_millis(200));
@@ -39,6 +40,7 @@ pub fn main() {
});
let j3 = spawn(move || {
+ let c = c; // avoid field capturing
sleep(Duration::from_millis(500));
if SYNC.load(Ordering::Acquire) == 3 {
*c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`
diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs
index f7a523841b8..33de1f17558 100644
--- a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs
+++ b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs
@@ -25,6 +25,7 @@ pub fn main() {
// 3. load acquire : 2
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 1;
SYNC.store(1, Ordering::Release);
@@ -36,6 +37,7 @@ pub fn main() {
});
let j2 = spawn(move || {
+ let c = c; // avoid field capturing
if SYNC.load(Ordering::Acquire) == 2 {
*c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`
} else {
diff --git a/src/tools/miri/tests/fail/data_race/rmw_race.rs b/src/tools/miri/tests/fail/data_race/rmw_race.rs
index 2201362b167..4d0ce8f9433 100644
--- a/src/tools/miri/tests/fail/data_race/rmw_race.rs
+++ b/src/tools/miri/tests/fail/data_race/rmw_race.rs
@@ -25,6 +25,7 @@ pub fn main() {
// 4. load acquire : 3
unsafe {
let j1 = spawn(move || {
+ let c = c; // capture `c`, not just its field.
*c.0 = 1;
SYNC.store(1, Ordering::Release);
});
@@ -37,6 +38,7 @@ pub fn main() {
});
let j3 = spawn(move || {
+ let c = c; // capture `c`, not just its field.
if SYNC.load(Ordering::Acquire) == 3 {
*c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`
} else {
diff --git a/src/tools/miri/tests/fail/data_race/stack_pop_race.rs b/src/tools/miri/tests/fail/data_race/stack_pop_race.rs
index dec5ff274cc..d3c2ab3e4a4 100644
--- a/src/tools/miri/tests/fail/data_race/stack_pop_race.rs
+++ b/src/tools/miri/tests/fail/data_race/stack_pop_race.rs
@@ -13,7 +13,7 @@ fn main() {
fn race(local: i32) {
let ptr = MakeSend(&local as *const i32);
thread::spawn(move || {
- let ptr = ptr;
+ let ptr = ptr; // avoid field capturing
let _val = unsafe { *ptr.0 };
});
// Make the other thread go first so that it does not UAF.
diff --git a/src/tools/miri/tests/fail/data_race/write_write_race.rs b/src/tools/miri/tests/fail/data_race/write_write_race.rs
index fe02d02f9dc..30e3460f222 100644
--- a/src/tools/miri/tests/fail/data_race/write_write_race.rs
+++ b/src/tools/miri/tests/fail/data_race/write_write_race.rs
@@ -15,10 +15,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 32;
});
let j2 = spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>`
});
diff --git a/src/tools/miri/tests/fail/data_race/write_write_race_stack.rs b/src/tools/miri/tests/fail/data_race/write_write_race_stack.rs
index c1c1b1fa6e3..25be42bd4eb 100644
--- a/src/tools/miri/tests/fail/data_race/write_write_race_stack.rs
+++ b/src/tools/miri/tests/fail/data_race/write_write_race_stack.rs
@@ -28,6 +28,7 @@ pub fn main() {
// 5. write-value
unsafe {
let j1 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
// Concurrent allocate the memory.
// Uses relaxed semantics to not generate
// a release sequence.
@@ -46,6 +47,7 @@ pub fn main() {
});
let j2 = spawn(move || {
+ let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
*pointer.load(Ordering::Acquire) = 3;
});
diff --git a/src/tools/miri/tests/fail/deny_lint.rs b/src/tools/miri/tests/fail/deny_lint.rs
new file mode 100644
index 00000000000..f49fa49d09d
--- /dev/null
+++ b/src/tools/miri/tests/fail/deny_lint.rs
@@ -0,0 +1,8 @@
+//@error-in-other-file: miri cannot be run on programs that fail compilation
+
+#![deny(warnings, unused)]
+
+struct Foo;
+//~^ ERROR: struct `Foo` is never constructed
+
+fn main() {}
diff --git a/src/tools/miri/tests/fail/deny_lint.stderr b/src/tools/miri/tests/fail/deny_lint.stderr
new file mode 100644
index 00000000000..d1c9b481807
--- /dev/null
+++ b/src/tools/miri/tests/fail/deny_lint.stderr
@@ -0,0 +1,17 @@
+error: struct `Foo` is never constructed
+ --> $DIR/deny_lint.rs:LL:CC
+ |
+LL | struct Foo;
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/deny_lint.rs:LL:CC
+ |
+LL | #![deny(warnings, unused)]
+ | ^^^^^^
+ = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
+
+error: miri cannot be run on programs that fail compilation
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/miri/tests/fail/erroneous_const.stderr b/src/tools/miri/tests/fail/erroneous_const.stderr
index c32ebf67a11..209c4a932dc 100644
--- a/src/tools/miri/tests/fail/erroneous_const.stderr
+++ b/src/tools/miri/tests/fail/erroneous_const.stderr
@@ -4,7 +4,7 @@ error[E0080]: evaluation of `PrintName::<i32>::VOID` failed
LL | const VOID: ! = panic!();
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/erroneous_const.rs:LL:CC
|
- = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: erroneous constant used
--> $DIR/erroneous_const.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.rs b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.rs
index a5bae36d92a..10939c0f1c3 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.rs
@@ -1,9 +1,8 @@
-//@error-pattern: cannot be represented in target type `i32`
#![feature(portable_simd)]
use std::simd::*;
fn main() {
unsafe {
- let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked();
+ let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked(); //~ERROR: cannot be represented in target type `i32`
}
}
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr
index 5c73c76a161..ea5ad62aea9 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr
@@ -1,18 +1,13 @@
error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
- --> RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC
+ --> $DIR/simd-float-to-int.rs:LL:CC
|
-LL | unsafe { intrinsics::simd_cast(self) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
+LL | let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
- = note: inside `std::simd::Simd::<f32, 2>::to_int_unchecked::<i32>` at RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC
-note: inside `main`
- --> $DIR/simd-float-to-int.rs:LL:CC
- |
-LL | let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: inside `main` at $DIR/simd-float-to-int.rs:LL:CC
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-gather.rs b/src/tools/miri/tests/fail/intrinsics/simd-gather.rs
index e394cce9a4f..ceb7beebd8a 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-gather.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-gather.rs
@@ -1,4 +1,3 @@
-//@error-pattern: pointer to 1 byte starting at offset 9 is out-of-bounds
#![feature(portable_simd)]
use std::simd::*;
@@ -6,6 +5,6 @@ fn main() {
unsafe {
let vec: &[i8] = &[10, 11, 12, 13, 14, 15, 16, 17, 18];
let idxs = Simd::from_array([9, 3, 0, 17]);
- let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true), idxs, Simd::splat(0));
+ let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true), idxs, Simd::splat(0)); //~ERROR: pointer to 1 byte starting at offset 9 is out-of-bounds
}
}
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr b/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr
index 7512d57f672..f82b30a9633 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr
@@ -1,18 +1,13 @@
error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds
- --> RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC
+ --> $DIR/simd-gather.rs:LL:CC
|
-LL | unsafe { intrinsics::simd_gather(or, ptrs, enable.to_int()) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds
+LL | let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true), idxs, Simd::splat(0));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
- = note: inside `std::simd::Simd::<i8, 4>::gather_select_unchecked` at RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC
-note: inside `main`
- --> $DIR/simd-gather.rs:LL:CC
- |
-LL | let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true), idxs, Simd::splat(0));
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: inside `main` at $DIR/simd-gather.rs:LL:CC
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-scatter.rs b/src/tools/miri/tests/fail/intrinsics/simd-scatter.rs
index d2bc7339954..98b6749c584 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-scatter.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-scatter.rs
@@ -1,4 +1,3 @@
-//@error-pattern: pointer to 1 byte starting at offset 9 is out-of-bounds
#![feature(portable_simd)]
use std::simd::*;
@@ -7,6 +6,7 @@ fn main() {
let mut vec: Vec<i8> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
let idxs = Simd::from_array([9, 3, 0, 17]);
Simd::from_array([-27, 82, -41, 124]).scatter_select_unchecked(
+ //~^ERROR: pointer to 1 byte starting at offset 9 is out-of-bounds
&mut vec,
Mask::splat(true),
idxs,
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr b/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr
index a9ad60a0e5b..a745b61029d 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr
@@ -1,22 +1,18 @@
error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds
- --> RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC
- |
-LL | intrinsics::simd_scatter(self, ptrs, enable.to_int())
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds
- |
- = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
- = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
- = note: BACKTRACE:
- = note: inside `std::simd::Simd::<i8, 4>::scatter_select_unchecked` at RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC
-note: inside `main`
--> $DIR/simd-scatter.rs:LL:CC
|
LL | / Simd::from_array([-27, 82, -41, 124]).scatter_select_unchecked(
+LL | |
LL | | &mut vec,
LL | | Mask::splat(true),
LL | | idxs,
LL | | );
- | |_________^
+ | |_________^ dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds
+ |
+ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+ = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+ = note: BACKTRACE:
+ = note: inside `main` at $DIR/simd-scatter.rs:LL:CC
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/layout_cycle.rs b/src/tools/miri/tests/fail/layout_cycle.rs
index d050310bd80..3e0dd881db8 100644
--- a/src/tools/miri/tests/fail/layout_cycle.rs
+++ b/src/tools/miri/tests/fail/layout_cycle.rs
@@ -1,4 +1,4 @@
-//@error-pattern: a cycle occurred during layout computation
+//@error-in-other-file: a cycle occurred during layout computation
//~^ ERROR: cycle detected when computing layout of
use std::mem;
diff --git a/src/tools/miri/tests/fail/memleak.rs b/src/tools/miri/tests/fail/memleak.rs
index cbeb163b56c..984b44d6d40 100644
--- a/src/tools/miri/tests/fail/memleak.rs
+++ b/src/tools/miri/tests/fail/memleak.rs
@@ -1,4 +1,4 @@
-//@error-pattern: memory leaked
+//@error-in-other-file: memory leaked
//@normalize-stderr-test: ".*│.*" -> "$$stripped$$"
fn main() {
diff --git a/src/tools/miri/tests/fail/memleak_no_backtrace.rs b/src/tools/miri/tests/fail/memleak_no_backtrace.rs
index 24d4a02df71..a1f8d9957ff 100644
--- a/src/tools/miri/tests/fail/memleak_no_backtrace.rs
+++ b/src/tools/miri/tests/fail/memleak_no_backtrace.rs
@@ -1,5 +1,5 @@
//@compile-flags: -Zmiri-disable-leak-backtraces
-//@error-pattern: the evaluated program leaked memory
+//@error-in-other-file: the evaluated program leaked memory
//@normalize-stderr-test: ".*│.*" -> "$$stripped$$"
fn main() {
diff --git a/src/tools/miri/tests/fail/memleak_rc.rs b/src/tools/miri/tests/fail/memleak_rc.rs
index cf4671912ad..0927612d08e 100644
--- a/src/tools/miri/tests/fail/memleak_rc.rs
+++ b/src/tools/miri/tests/fail/memleak_rc.rs
@@ -1,4 +1,4 @@
-//@error-pattern: memory leaked
+//@error-in-other-file: memory leaked
//@stderr-per-bitwidth
//@normalize-stderr-test: ".*│.*" -> "$$stripped$$"
diff --git a/src/tools/miri/tests/fail/no_main.rs b/src/tools/miri/tests/fail/no_main.rs
index e2820504087..01b8c7bd66b 100644
--- a/src/tools/miri/tests/fail/no_main.rs
+++ b/src/tools/miri/tests/fail/no_main.rs
@@ -1,2 +1,2 @@
-//@error-pattern: miri can only run programs that have a main function
+//@error-in-other-file: miri can only run programs that have a main function
#![no_main]
diff --git a/src/tools/miri/tests/fail/panic/double_panic.rs b/src/tools/miri/tests/fail/panic/double_panic.rs
index c9501d90b3b..9378adb8609 100644
--- a/src/tools/miri/tests/fail/panic/double_panic.rs
+++ b/src/tools/miri/tests/fail/panic/double_panic.rs
@@ -1,4 +1,4 @@
-//@error-pattern: the program aborted
+//@error-in-other-file: the program aborted
//@normalize-stderr-test: "\| +\^+" -> "| ^"
//@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();"
//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "$1"
diff --git a/src/tools/miri/tests/fail/panic/double_panic.stderr b/src/tools/miri/tests/fail/panic/double_panic.stderr
index 5384f6f6716..77d5fc5d7ce 100644
--- a/src/tools/miri/tests/fail/panic/double_panic.stderr
+++ b/src/tools/miri/tests/fail/panic/double_panic.stderr
@@ -12,7 +12,8 @@ LL | ABORT();
= note: inside `std::sys::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
- = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::rt::begin_panic<&str>::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
+ = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
+ = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
note: inside `<Foo as std::ops::Drop>::drop`
--> $DIR/double_panic.rs:LL:CC
|
@@ -24,7 +25,7 @@ note: inside `main`
|
LL | }
| ^
- = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/panic/no_std.stderr b/src/tools/miri/tests/fail/panic/no_std.stderr
index 39ad0d268b9..f8307c0c23b 100644
--- a/src/tools/miri/tests/fail/panic/no_std.stderr
+++ b/src/tools/miri/tests/fail/panic/no_std.stderr
@@ -11,7 +11,7 @@ note: inside `start`
|
LL | panic!("blarg I am dead")
| ^^^^^^^^^^^^^^^^^^^^^^^^^
- = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.rs b/src/tools/miri/tests/fail/panic/panic_abort1.rs
index 00a01ce6e81..300bfa32ecb 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort1.rs
+++ b/src/tools/miri/tests/fail/panic/panic_abort1.rs
@@ -1,4 +1,4 @@
-//@error-pattern: the program aborted execution
+//@error-in-other-file: the program aborted execution
//@normalize-stderr-test: "\| +\^+" -> "| ^"
//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();"
//@compile-flags: -C panic=abort
diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.stderr b/src/tools/miri/tests/fail/panic/panic_abort1.stderr
index d25dd7be635..d9303fd0d06 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort1.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort1.stderr
@@ -11,13 +11,14 @@ LL | ABORT();
= note: inside `std::panicking::rust_panic` at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
- = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::rt::begin_panic<&str>::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
+ = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
+ = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
note: inside `main`
--> $DIR/panic_abort1.rs:LL:CC
|
LL | std::panic!("panicking from libstd");
| ^
- = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.rs b/src/tools/miri/tests/fail/panic/panic_abort2.rs
index dee0de96703..5d691350577 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort2.rs
+++ b/src/tools/miri/tests/fail/panic/panic_abort2.rs
@@ -1,4 +1,4 @@
-//@error-pattern: the program aborted execution
+//@error-in-other-file: the program aborted execution
//@normalize-stderr-test: "\| +\^+" -> "| ^"
//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();"
//@compile-flags: -C panic=abort
diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.stderr b/src/tools/miri/tests/fail/panic/panic_abort2.stderr
index f56d509a697..54cbc9b5f6d 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort2.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort2.stderr
@@ -18,7 +18,7 @@ note: inside `main`
|
LL | std::panic!("{}-panicking from libstd", 42);
| ^
- = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.rs b/src/tools/miri/tests/fail/panic/panic_abort3.rs
index a448aab3ea4..25afc315628 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort3.rs
+++ b/src/tools/miri/tests/fail/panic/panic_abort3.rs
@@ -1,4 +1,4 @@
-//@error-pattern: the program aborted execution
+//@error-in-other-file: the program aborted execution
//@normalize-stderr-test: "\| +\^+" -> "| ^"
//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();"
//@compile-flags: -C panic=abort
diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.stderr b/src/tools/miri/tests/fail/panic/panic_abort3.stderr
index 43792f76993..64eea47b14b 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort3.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort3.stderr
@@ -18,7 +18,7 @@ note: inside `main`
|
LL | core::panic!("panicking from libcore");
| ^
- = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.rs b/src/tools/miri/tests/fail/panic/panic_abort4.rs
index 4995dad9d71..025b51a5cf5 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort4.rs
+++ b/src/tools/miri/tests/fail/panic/panic_abort4.rs
@@ -1,4 +1,4 @@
-//@error-pattern: the program aborted execution
+//@error-in-other-file: the program aborted execution
//@normalize-stderr-test: "\| +\^+" -> "| ^"
//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();"
//@compile-flags: -C panic=abort
diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.stderr b/src/tools/miri/tests/fail/panic/panic_abort4.stderr
index 89e181bfb27..21beb100645 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort4.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort4.stderr
@@ -18,7 +18,7 @@ note: inside `main`
|
LL | core::panic!("{}-panicking from libcore", 42);
| ^
- = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_file.rs b/src/tools/miri/tests/fail/shims/fs/isolated_file.rs
index 9b664ffe52a..2f27e95297b 100644
--- a/src/tools/miri/tests/fail/shims/fs/isolated_file.rs
+++ b/src/tools/miri/tests/fail/shims/fs/isolated_file.rs
@@ -1,5 +1,5 @@
//@ignore-target-windows: File handling is not implemented yet
-//@error-pattern: `open` not available when isolation is enabled
+//@error-in-other-file: `open` not available when isolation is enabled
fn main() {
let _file = std::fs::File::open("file.txt").unwrap();
diff --git a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.rs b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.rs
index 4036dce5beb..a34df7c7fe3 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.rs
@@ -1,4 +1,4 @@
-//@error-pattern: /deallocating while item \[Unique for .*\] is strongly protected/
+//@error-in-other-file: /deallocating while item \[Unique for .*\] is strongly protected/
fn inner(x: &mut i32, f: fn(&mut i32)) {
// `f` may mutate, but it may not deallocate!
diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs
index 8180e2f03a7..9126b7e8575 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs
@@ -1,7 +1,7 @@
//! Test that drop_in_place mutably retags the entire place, even for a type that does not need
//! dropping, ensuring among other things that it is writeable
-//@error-pattern: /retag .* for Unique permission .* only grants SharedReadOnly permission/
+//@error-in-other-file: /retag .* for Unique permission .* only grants SharedReadOnly permission/
fn main() {
unsafe {
diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs
index 670dd4baad8..b2ec23bda02 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs
@@ -1,4 +1,4 @@
-//@error-pattern: /deallocation .* tag does not exist in the borrow stack/
+//@error-in-other-file: /deallocation .* tag does not exist in the borrow stack/
use std::alloc::{alloc, dealloc, Layout};
fn main() {
diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs b/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs
index 70c51e671fe..bf4204c61fd 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs
@@ -1,3 +1,5 @@
+#![allow(drop_ref)]
+
fn main() {
let target = &mut 42;
let target2 = target as *mut _;
diff --git a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.rs b/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.rs
index 1e44cc6c800..075efe49412 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.rs
@@ -1,4 +1,4 @@
-//@error-pattern: pointer to 4 bytes starting at offset 0 is out-of-bounds
+//@error-in-other-file: pointer to 4 bytes starting at offset 0 is out-of-bounds
fn main() {
unsafe {
diff --git a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.rs b/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.rs
index 6e90559a9ef..1b43daa9253 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.rs
@@ -1,4 +1,4 @@
-//@error-pattern: is a dangling pointer
+//@error-in-other-file: is a dangling pointer
use std::ptr::NonNull;
fn main() {
diff --git a/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs b/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs
index c19bcb99cc1..1ae6740924c 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs
@@ -1,4 +1,4 @@
-//@error-pattern: which is strongly protected
+//@error-in-other-file: which is strongly protected
struct Newtype<'a>(&'a mut i32, i32);
fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) {
diff --git a/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs b/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs
index 2bbe7122ec7..f106274b811 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs
@@ -1,4 +1,4 @@
-//@error-pattern: which is strongly protected
+//@error-in-other-file: which is strongly protected
struct Newtype<'a>(&'a mut i32);
fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) {
diff --git a/src/tools/miri/tests/fail/stacked_borrows/zst_slice.rs b/src/tools/miri/tests/fail/stacked_borrows/zst_slice.rs
index 77daa9c9811..fd51fa6468a 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/zst_slice.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/zst_slice.rs
@@ -1,5 +1,5 @@
//@compile-flags: -Zmiri-strict-provenance
-//@error-pattern: /retag .* tag does not exist in the borrow stack/
+//@error-in-other-file: /retag .* tag does not exist in the borrow stack/
fn main() {
unsafe {
diff --git a/src/tools/miri/tests/fail/tokio/sleep.rs b/src/tools/miri/tests/fail/tokio/sleep.rs
index 6fdfbc9913a..d96d778e6ca 100644
--- a/src/tools/miri/tests/fail/tokio/sleep.rs
+++ b/src/tools/miri/tests/fail/tokio/sleep.rs
@@ -1,6 +1,6 @@
//@compile-flags: -Zmiri-permissive-provenance -Zmiri-backtrace=full
//@only-target-x86_64-unknown-linux: support for tokio only on linux and x86
-//@error-pattern: returning ready events from epoll_wait is not yet implemented
+//@error-in-other-file: returning ready events from epoll_wait is not yet implemented
//@normalize-stderr-test: " += note:.*\n" -> ""
use tokio::time::{sleep, Duration, Instant};
diff --git a/src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs b/src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs
index a68efea890c..484c7c3bbff 100644
--- a/src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs
+++ b/src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs
@@ -1,5 +1,5 @@
//@compile-flags: -Zmiri-tree-borrows
-//@error-pattern: /deallocation through .* is forbidden/
+//@error-in-other-file: /deallocation through .* is forbidden/
fn inner(x: &mut i32, f: fn(&mut i32)) {
// `f` may mutate, but it may not deallocate!
diff --git a/src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr b/src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr
index 97088d5854c..071b216ff98 100644
--- a/src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr
+++ b/src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr
@@ -17,6 +17,12 @@ help: the strongly protected tag <TAG> was created here, in the initial state Re
|
LL | fn inner(x: &mut i32, f: fn(&mut i32)) {
| ^
+help: the strongly protected tag <TAG> then transitioned from Reserved to Active due to a child write access at offsets [0x0..0x4]
+ --> $DIR/strongly-protected.rs:LL:CC
+ |
+LL | drop(unsafe { Box::from_raw(raw) });
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = help: this corresponds to an activation
= note: BACKTRACE (of the first span):
= note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
= note: inside `<std::alloc::Global as std::alloc::Allocator>::deallocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs
index 8a40e527f0e..d8cab68ac5d 100644
--- a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs
+++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs
@@ -13,7 +13,7 @@ struct PartialDrop {
b: u8,
}
-//@error-pattern: /alignment 2 is required/
+//@error-in-other-file: /alignment 2 is required/
fn main() {
unsafe {
// Create an unaligned pointer
diff --git a/src/tools/miri/tests/fail/uninit_buffer.rs b/src/tools/miri/tests/fail/uninit_buffer.rs
index d21371225e5..8a330058375 100644
--- a/src/tools/miri/tests/fail/uninit_buffer.rs
+++ b/src/tools/miri/tests/fail/uninit_buffer.rs
@@ -1,4 +1,6 @@
-//@error-pattern: memory is uninitialized at [0x4..0x10]
+//@error-in-other-file: memory is uninitialized at [0x4..0x10]
+
+#![allow(drop_copy)]
use std::alloc::{alloc, dealloc, Layout};
use std::slice::from_raw_parts;
diff --git a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs
index 170bc6e1ed1..443f481c087 100644
--- a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs
+++ b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs
@@ -1,6 +1,7 @@
-//@error-pattern: memory is uninitialized at [0x4..0x8]
+//@error-in-other-file: memory is uninitialized at [0x4..0x8]
//@normalize-stderr-test: "a[0-9]+" -> "ALLOC"
#![feature(strict_provenance)]
+#![allow(drop_copy)]
// Test printing allocations that contain single-byte provenance.
diff --git a/src/tools/miri/tests/panic/panic1.stderr b/src/tools/miri/tests/panic/panic1.stderr
index 15834d58bc6..0f4535e6792 100644
--- a/src/tools/miri/tests/panic/panic1.stderr
+++ b/src/tools/miri/tests/panic/panic1.stderr
@@ -1,9 +1,11 @@
thread 'main' panicked at 'panicking from libstd', $DIR/panic1.rs:LL:CC
stack backtrace:
- 0: std::rt::begin_panic
+ 0: std::panicking::begin_panic_handler
at RUSTLIB/std/src/panicking.rs:LL:CC
- 1: main
+ 1: std::rt::panic_fmt
+ at RUSTLIB/core/src/panicking.rs:LL:CC
+ 2: main
at $DIR/panic1.rs:LL:CC
- 2: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn())
+ 3: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn())
at RUSTLIB/core/src/ops/function.rs:LL:CC
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs
index 82ef59427ae..68504cb1c79 100644
--- a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs
+++ b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs
@@ -101,7 +101,6 @@ fn test_posix_realpath_errors() {
#[cfg(target_os = "linux")]
fn test_posix_fadvise() {
- use std::convert::TryInto;
use std::io::Write;
let path = tmp().join("miri_test_libc_posix_fadvise.txt");
diff --git a/src/tools/miri/tests/pass/0weak_memory_consistency.rs b/src/tools/miri/tests/pass/0weak_memory_consistency.rs
index 3a531eede67..abfe3b0adeb 100644
--- a/src/tools/miri/tests/pass/0weak_memory_consistency.rs
+++ b/src/tools/miri/tests/pass/0weak_memory_consistency.rs
@@ -116,11 +116,13 @@ fn test_message_passing() {
#[rustfmt::skip]
let j1 = spawn(move || {
+ let x = x; // avoid field capturing
unsafe { *x.0 = 1 }; // -----------------------------------------+
y.store(1, Release); // ---------------------+ |
}); // | |
#[rustfmt::skip] // |synchronizes-with | happens-before
let j2 = spawn(move || { // | |
+ let x = x; // avoid field capturing | |
acquires_value(&y, 1); // <------------------+ |
unsafe { *x.0 } // <---------------------------------------------+
});
diff --git a/src/tools/miri/tests/pass/concurrency/data_race.rs b/src/tools/miri/tests/pass/concurrency/data_race.rs
index 4e3c99058a0..d31420380a5 100644
--- a/src/tools/miri/tests/pass/concurrency/data_race.rs
+++ b/src/tools/miri/tests/pass/concurrency/data_race.rs
@@ -17,12 +17,14 @@ fn test_fence_sync() {
let evil_ptr = EvilSend(ptr);
let j1 = spawn(move || {
+ let evil_ptr = evil_ptr; // avoid field capturing
unsafe { *evil_ptr.0 = 1 };
fence(Ordering::Release);
SYNC.store(1, Ordering::Relaxed)
});
let j2 = spawn(move || {
+ let evil_ptr = evil_ptr; // avoid field capturing
if SYNC.load(Ordering::Relaxed) == 1 {
fence(Ordering::Acquire);
unsafe { *evil_ptr.0 }
@@ -40,10 +42,10 @@ fn test_multiple_reads() {
let ptr = &mut var as *mut u32;
let evil_ptr = EvilSend(ptr);
- let j1 = spawn(move || unsafe { *evil_ptr.0 });
- let j2 = spawn(move || unsafe { *evil_ptr.0 });
- let j3 = spawn(move || unsafe { *evil_ptr.0 });
- let j4 = spawn(move || unsafe { *evil_ptr.0 });
+ let j1 = spawn(move || unsafe { *{ evil_ptr }.0 });
+ let j2 = spawn(move || unsafe { *{ evil_ptr }.0 });
+ let j3 = spawn(move || unsafe { *{ evil_ptr }.0 });
+ let j4 = spawn(move || unsafe { *{ evil_ptr }.0 });
assert_eq!(j1.join().unwrap(), 42);
assert_eq!(j2.join().unwrap(), 42);
@@ -63,6 +65,7 @@ pub fn test_rmw_no_block() {
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 1;
SYNC.store(1, Ordering::Release);
});
@@ -73,7 +76,10 @@ pub fn test_rmw_no_block() {
}
});
- let j3 = spawn(move || if SYNC.load(Ordering::Acquire) == 2 { *c.0 } else { 0 });
+ let j3 = spawn(move || {
+ let c = c; // avoid field capturing
+ if SYNC.load(Ordering::Acquire) == 2 { *c.0 } else { 0 }
+ });
j1.join().unwrap();
j2.join().unwrap();
@@ -91,11 +97,15 @@ pub fn test_simple_release() {
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 1;
SYNC.store(1, Ordering::Release);
});
- let j2 = spawn(move || if SYNC.load(Ordering::Acquire) == 1 { *c.0 } else { 0 });
+ let j2 = spawn(move || {
+ let c = c; // avoid field capturing
+ if SYNC.load(Ordering::Acquire) == 1 { *c.0 } else { 0 }
+ });
j1.join().unwrap();
assert_eq!(j2.join().unwrap(), 1); // relies on thread 2 going last
diff --git a/src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs b/src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs
index d71e51b0384..049b5e7f498 100644
--- a/src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs
+++ b/src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs
@@ -14,10 +14,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 32;
});
let j2 = spawn(move || {
+ let c = c; // avoid field capturing
*c.0 = 64; // Data race (but not detected as the detector is disabled)
});
diff --git a/src/tools/miri/tests/pass/concurrency/sync.rs b/src/tools/miri/tests/pass/concurrency/sync.rs
index 3bd1e542407..dccc9d104dd 100644
--- a/src/tools/miri/tests/pass/concurrency/sync.rs
+++ b/src/tools/miri/tests/pass/concurrency/sync.rs
@@ -201,8 +201,10 @@ fn park_timeout() {
thread::park_timeout(Duration::from_millis(200));
// Normally, waiting in park/park_timeout may spuriously wake up early, but we
// know Miri's timed synchronization primitives do not do that.
-
- assert!((200..1000).contains(&start.elapsed().as_millis()));
+ // We allow much longer sleeps as well since the macOS GHA runners seem very oversubscribed
+ // and sometimes just pause for 1 second or more.
+ let elapsed = start.elapsed();
+ assert!((200..2000).contains(&elapsed.as_millis()), "bad sleep time: {elapsed:?}");
}
fn park_unpark() {
@@ -219,8 +221,10 @@ fn park_unpark() {
thread::park();
// Normally, waiting in park/park_timeout may spuriously wake up early, but we
// know Miri's timed synchronization primitives do not do that.
-
- assert!((200..1000).contains(&start.elapsed().as_millis()));
+ // We allow much longer sleeps as well since the macOS GHA runners seem very oversubscribed
+ // and sometimes just pause for 1 second or more.
+ let elapsed = start.elapsed();
+ assert!((200..2000).contains(&elapsed.as_millis()), "bad sleep time: {elapsed:?}");
t2.join().unwrap();
}
diff --git a/src/tools/miri/tests/pass/concurrency/thread_locals.rs b/src/tools/miri/tests/pass/concurrency/thread_locals.rs
index 13c11b55775..fc4c8a283dd 100644
--- a/src/tools/miri/tests/pass/concurrency/thread_locals.rs
+++ b/src/tools/miri/tests/pass/concurrency/thread_locals.rs
@@ -42,6 +42,7 @@ fn main() {
};
thread::spawn(move || unsafe {
+ let ptr = ptr; // avoid field capturing
assert_eq!(*ptr.0, 5);
assert_eq!(A, 0);
assert_eq!(B, 0);
diff --git a/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs b/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs
index d89320bfe59..3b27af9094c 100644
--- a/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs
+++ b/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs
@@ -44,6 +44,8 @@ fn all_shared() {
// waiters
for i in 0..5 {
handles.push(thread::spawn(move || {
+ let condvar_ptr = condvar_ptr; // avoid field capture
+ let lock_ptr = lock_ptr; // avoid field capture
unsafe {
AcquireSRWLockShared(lock_ptr.0);
}
@@ -71,6 +73,7 @@ fn all_shared() {
// readers
for i in 0..5 {
handles.push(thread::spawn(move || {
+ let lock_ptr = lock_ptr; // avoid field capture
unsafe {
AcquireSRWLockShared(lock_ptr.0);
}
@@ -111,6 +114,8 @@ fn shared_sleep_and_exclusive_lock() {
let mut waiters = Vec::with_capacity(5);
for i in 0..5 {
waiters.push(thread::spawn(move || {
+ let lock_ptr = lock_ptr; // avoid field capture
+ let condvar_ptr = condvar_ptr; // avoid field capture
unsafe {
AcquireSRWLockShared(lock_ptr.0);
}
@@ -170,6 +175,8 @@ fn exclusive_sleep_and_shared_lock() {
let mut handles = Vec::with_capacity(10);
for i in 0..5 {
handles.push(thread::spawn(move || {
+ let lock_ptr = lock_ptr; // avoid field capture
+ let condvar_ptr = condvar_ptr; // avoid field capture
unsafe {
AcquireSRWLockExclusive(lock_ptr.0);
}
@@ -193,6 +200,7 @@ fn exclusive_sleep_and_shared_lock() {
for i in 0..5 {
handles.push(thread::spawn(move || {
+ let lock_ptr = lock_ptr; // avoid field capture
unsafe {
AcquireSRWLockShared(lock_ptr.0);
}
diff --git a/src/tools/miri/tests/pass/concurrency/windows_init_once.rs b/src/tools/miri/tests/pass/concurrency/windows_init_once.rs
index 4eb88379620..b2412f7dbb0 100644
--- a/src/tools/miri/tests/pass/concurrency/windows_init_once.rs
+++ b/src/tools/miri/tests/pass/concurrency/windows_init_once.rs
@@ -66,6 +66,7 @@ fn block_until_complete() {
let init_once_ptr = SendPtr(&mut init_once);
let waiter = move || unsafe {
+ let init_once_ptr = init_once_ptr; // avoid field capture
let mut pending = 0;
assert_eq!(InitOnceBeginInitialize(init_once_ptr.0, 0, &mut pending, null_mut()), TRUE);
@@ -102,6 +103,7 @@ fn retry_on_fail() {
let init_once_ptr = SendPtr(&mut init_once);
let waiter = move || unsafe {
+ let init_once_ptr = init_once_ptr; // avoid field capture
let mut pending = 0;
assert_eq!(InitOnceBeginInitialize(init_once_ptr.0, 0, &mut pending, null_mut()), TRUE);
@@ -146,6 +148,8 @@ fn no_data_race_after_complete() {
let place_ptr = SendPtr(&mut place);
let reader = thread::spawn(move || unsafe {
+ let init_once_ptr = init_once_ptr; // avoid field capture
+ let place_ptr = place_ptr; // avoid field capture
let mut pending = 0;
// this doesn't block because reader only executes after `InitOnceComplete` is called
diff --git a/src/tools/miri/tests/pass/concurrency/windows_join_multiple.rs b/src/tools/miri/tests/pass/concurrency/windows_join_multiple.rs
index 986e2b8cc10..5da5497f982 100644
--- a/src/tools/miri/tests/pass/concurrency/windows_join_multiple.rs
+++ b/src/tools/miri/tests/pass/concurrency/windows_join_multiple.rs
@@ -22,10 +22,8 @@ fn main() {
})
.into_raw_handle() as usize;
- let waiter = move || {
- unsafe {
- assert_eq!(WaitForSingleObject(blocker, INFINITE), 0);
- }
+ let waiter = move || unsafe {
+ assert_eq!(WaitForSingleObject(blocker, INFINITE), 0);
};
let waiter1 = thread::spawn(waiter);
diff --git a/src/tools/miri/tests/pass/panic/catch_panic.rs b/src/tools/miri/tests/pass/panic/catch_panic.rs
index 5d57df4e52b..1b00f7cea30 100644
--- a/src/tools/miri/tests/pass/panic/catch_panic.rs
+++ b/src/tools/miri/tests/pass/panic/catch_panic.rs
@@ -49,13 +49,12 @@ fn main() {
// Std panics
test(None, |_old_val| std::panic!("Hello from panic: std"));
- test(None, |old_val| std::panic!(format!("Hello from panic: {:?}", old_val)));
+ test(None, |old_val| std::panic::panic_any(format!("Hello from panic: {:?}", old_val)));
test(None, |old_val| std::panic!("Hello from panic: {:?}", old_val));
- test(None, |_old_val| std::panic!(1337));
+ test(None, |_old_val| std::panic::panic_any(1337));
// Core panics
test(None, |_old_val| core::panic!("Hello from panic: core"));
- test(None, |old_val| core::panic!(&format!("Hello from panic: {:?}", old_val)));
test(None, |old_val| core::panic!("Hello from panic: {:?}", old_val));
// Built-in panics; also make sure the message is right.
diff --git a/src/tools/miri/tests/pass/panic/catch_panic.stderr b/src/tools/miri/tests/pass/panic/catch_panic.stderr
index 0ced5588cc1..f43434582a2 100644
--- a/src/tools/miri/tests/pass/panic/catch_panic.stderr
+++ b/src/tools/miri/tests/pass/panic/catch_panic.stderr
@@ -11,8 +11,6 @@ thread 'main' panicked at 'Hello from panic: core', $DIR/catch_panic.rs:LL:CC
Caught panic message (&str): Hello from panic: core
thread 'main' panicked at 'Hello from panic: 5', $DIR/catch_panic.rs:LL:CC
Caught panic message (String): Hello from panic: 5
-thread 'main' panicked at 'Hello from panic: 6', $DIR/catch_panic.rs:LL:CC
-Caught panic message (String): Hello from panic: 6
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 4', $DIR/catch_panic.rs:LL:CC
Caught panic message (String): index out of bounds: the len is 3 but the index is 4
thread 'main' panicked at 'attempt to divide by zero', $DIR/catch_panic.rs:LL:CC
diff --git a/src/tools/miri/tests/pass/panic/concurrent-panic.rs b/src/tools/miri/tests/pass/panic/concurrent-panic.rs
index 776bc2057f3..7cc1e2a973f 100644
--- a/src/tools/miri/tests/pass/panic/concurrent-panic.rs
+++ b/src/tools/miri/tests/pass/panic/concurrent-panic.rs
@@ -57,7 +57,7 @@ fn main() {
let t2_started_pair = t2_started_pair.clone();
let block_on_drop = BlockOnDrop::new(t1);
spawn(move || {
- let _ = block_on_drop;
+ let _capture = block_on_drop;
let (mutex, condvar) = &*t2_started_pair;
*mutex.lock().unwrap() = true;
diff --git a/src/tools/miri/tests/pass/portable-simd-ptrs.rs b/src/tools/miri/tests/pass/portable-simd-ptrs.rs
new file mode 100644
index 00000000000..303c99834f5
--- /dev/null
+++ b/src/tools/miri/tests/pass/portable-simd-ptrs.rs
@@ -0,0 +1,12 @@
+// Separate test without strict provenance
+//@compile-flags: -Zmiri-permissive-provenance
+#![feature(portable_simd, platform_intrinsics)]
+use std::ptr;
+use std::simd::*;
+
+fn main() {
+ // Pointer casts
+ let _val: Simd<*const u8, 4> = Simd::<*const i32, 4>::splat(ptr::null()).cast_ptr();
+ let addrs = Simd::<*const i32, 4>::splat(ptr::null()).expose_addr();
+ let _ptrs = Simd::<*const i32, 4>::from_exposed_addr(addrs);
+}
diff --git a/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs b/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs
index ce3c8b7d5f1..9f743f0b566 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs
@@ -1,5 +1,8 @@
//@compile-flags: -Zmiri-retag-fields
// Checks that the test does not run forever (which relies on a fast path).
+
+#![allow(drop_copy)]
+
fn main() {
let array = [(); usize::MAX];
drop(array); // Pass the array to a function, retagging its fields
diff --git a/src/tools/miri/tests/pass/sysroot.rs b/src/tools/miri/tests/pass/sysroot.rs
new file mode 100644
index 00000000000..2c80e5bbd84
--- /dev/null
+++ b/src/tools/miri/tests/pass/sysroot.rs
@@ -0,0 +1,9 @@
+//! Just check that some things are available in the sysroot.
+#![feature(test)]
+#![allow(unused)]
+
+extern crate proc_macro;
+extern crate std;
+extern crate test;
+
+fn main() {}
diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js
index 692d5e3fcef..b26480f668b 100644
--- a/src/tools/rustdoc-gui/tester.js
+++ b/src/tools/rustdoc-gui/tester.js
@@ -143,7 +143,7 @@ async function runTests(opts, framework_options, files, results, status_bar, sho
const tests_queue = [];
for (const testPath of files) {
- const callback = runTest(testPath, framework_options)
+ const callback = runTest(testPath, {"options": framework_options})
.then(out => {
const [output, nb_failures] = out;
results[nb_failures === 0 ? "successful" : "failed"].push({
@@ -323,6 +323,7 @@ async function main(argv) {
if (results.failed.length > 0 || results.errored.length > 0) {
process.exit(1);
}
+ process.exit(0);
}
main(process.argv);
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index baef4bb0140..e1004c796c5 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -6,47 +6,53 @@ use std::path::Path;
/// These are licenses that are allowed for all crates, including the runtime,
/// rustc, tools, etc.
+#[rustfmt::skip]
const LICENSES: &[&str] = &[
- "MIT/Apache-2.0",
- "MIT / Apache-2.0",
- "Apache-2.0/MIT",
+ // tidy-alphabetical-start
+ "(MIT OR Apache-2.0) AND Unicode-DFS-2016", // unicode_ident
+ "0BSD OR MIT OR Apache-2.0", // adler license
+ "0BSD",
"Apache-2.0 / MIT",
- "MIT OR Apache-2.0",
"Apache-2.0 OR MIT",
"Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", // wasi license
- "MIT",
+ "Apache-2.0/MIT",
"ISC",
- "Unlicense/MIT",
+ "MIT / Apache-2.0",
+ "MIT OR Apache-2.0 OR Zlib", // tinyvec_macros
+ "MIT OR Apache-2.0",
+ "MIT OR Zlib OR Apache-2.0", // miniz_oxide
+ "MIT",
+ "MIT/Apache-2.0",
+ "Unicode-DFS-2016", // tinystr and icu4x
"Unlicense OR MIT",
- "0BSD",
- "0BSD OR MIT OR Apache-2.0", // adler license
- "Zlib OR Apache-2.0 OR MIT", // tinyvec
- "MIT OR Apache-2.0 OR Zlib", // tinyvec_macros
- "MIT OR Zlib OR Apache-2.0", // miniz_oxide
- "(MIT OR Apache-2.0) AND Unicode-DFS-2016", // unicode_ident
- "Unicode-DFS-2016", // tinystr and icu4x
+ "Unlicense/MIT",
+ "Zlib OR Apache-2.0 OR MIT", // tinyvec
+ // tidy-alphabetical-end
];
/// These are exceptions to Rust's permissive licensing policy, and
/// should be considered bugs. Exceptions are only allowed in Rust
/// tooling. It is _crucial_ that no exception crates be dependencies
/// of the Rust runtime (std/test).
+#[rustfmt::skip]
const EXCEPTIONS: &[(&str, &str)] = &[
+ // tidy-alphabetical-start
("ar_archive_writer", "Apache-2.0 WITH LLVM-exception"), // rustc
- ("mdbook", "MPL-2.0"), // mdbook
+ ("codespan-reporting", "Apache-2.0"), // cxx via iana-time-zone-haiku via time, only on haiku
("colored", "MPL-2.0"), // rustfmt
+ ("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps)
+ ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations)
+ ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target. FIXME: this dependency violates the documentation comment above.
+ ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot
+ ("mdbook", "MPL-2.0"), // mdbook
("ryu", "Apache-2.0 OR BSL-1.0"), // cargo/... (because of serde)
- ("codespan-reporting", "Apache-2.0"), // cxx via iana-time-zone-haiku via time, only on haiku
- ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot
- ("snap", "BSD-3-Clause"), // rustc
- ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations)
- ("self_cell", "Apache-2.0"), // rustc (fluent translations)
- // FIXME: this dependency violates the documentation comment above:
- ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target
- ("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps)
+ ("self_cell", "Apache-2.0"), // rustc (fluent translations)
+ ("snap", "BSD-3-Clause"), // rustc
+ // tidy-alphabetical-end
];
const EXCEPTIONS_CARGO: &[(&str, &str)] = &[
+ // tidy-alphabetical-start
("bitmaps", "MPL-2.0+"),
("bytesize", "Apache-2.0"),
("dunce", "CC0-1.0 OR MIT-0"),
@@ -62,9 +68,11 @@ const EXCEPTIONS_CARGO: &[(&str, &str)] = &[
("sized-chunks", "MPL-2.0+"),
("subtle", "BSD-3-Clause"),
("unicode-bom", "Apache-2.0"),
+ // tidy-alphabetical-end
];
const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[
+ // tidy-alphabetical-start
("cranelift-bforest", "Apache-2.0 WITH LLVM-exception"),
("cranelift-codegen", "Apache-2.0 WITH LLVM-exception"),
("cranelift-codegen-meta", "Apache-2.0 WITH LLVM-exception"),
@@ -80,6 +88,7 @@ const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[
("regalloc2", "Apache-2.0 WITH LLVM-exception"),
("target-lexicon", "Apache-2.0 WITH LLVM-exception"),
("wasmtime-jit-icache-coherence", "Apache-2.0 WITH LLVM-exception"),
+ // tidy-alphabetical-end
];
const EXCEPTIONS_BOOTSTRAP: &[(&str, &str)] = &[
@@ -95,6 +104,7 @@ const RUNTIME_CRATES: &[&str] = &["std", "core", "alloc", "test", "panic_abort",
/// This list is here to provide a speed-bump to adding a new dependency to
/// rustc. Please check with the compiler team before adding an entry.
const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
+ // tidy-alphabetical-start
"addr2line",
"adler",
"ahash",
@@ -113,8 +123,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"chalk-engine",
"chalk-ir",
"chalk-solve",
- "convert_case", // dependency of derive_more
"compiler_builtins",
+ "convert_case", // dependency of derive_more
"cpufeatures",
"crc32fast",
"crossbeam-channel",
@@ -135,6 +145,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"expect-test",
"fallible-iterator", // dependency of `thorin`
"fastrand",
+ "field-offset",
"fixedbitset",
"flate2",
"fluent-bundle",
@@ -187,8 +198,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"ppv-lite86",
"proc-macro-hack",
"proc-macro2",
- "pulldown-cmark",
"psm",
+ "pulldown-cmark",
"punycode",
"quote",
"rand",
@@ -227,6 +238,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"tempfile",
"termcolor",
"termize",
+ "thin-vec",
"thiserror",
"thiserror-impl",
"thorin-dwp",
@@ -234,7 +246,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"tinystr",
"tinyvec",
"tinyvec_macros",
- "thin-vec",
"tracing",
"tracing-attributes",
"tracing-core",
@@ -263,29 +274,37 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"valuable",
"version_check",
"wasi",
- "windows",
"winapi",
"winapi-i686-pc-windows-gnu",
"winapi-util",
"winapi-x86_64-pc-windows-gnu",
+ "windows",
+ "windows-targets",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
"writeable",
- // this is a false-positive: it's only used by rustfmt, but because it's enabled through a
- // feature, tidy thinks it's used by rustc as well.
- "yansi-term",
+ "yansi-term", // this is a false-positive: it's only used by rustfmt, but because it's enabled through a feature, tidy thinks it's used by rustc as well.
"yoke",
"yoke-derive",
"zerofrom",
"zerofrom-derive",
"zerovec",
"zerovec-derive",
+ // tidy-alphabetical-end
];
const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
+ // tidy-alphabetical-start
"ahash",
"anyhow",
"autocfg",
- "bumpalo",
"bitflags",
+ "bumpalo",
"byteorder",
"cfg-if",
"cranelift-bforest",
@@ -324,6 +343,7 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
"windows-sys",
+ // tidy-alphabetical-end
];
/// Dependency checks.
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 5f388ee47bb..d0257d71697 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -296,6 +296,12 @@ pub fn check(path: &Path, bad: &mut bool) {
if filename.contains("ignore-tidy") {
return;
}
+ // Shell completions are automatically generated
+ if let Some(p) = file.parent() {
+ if p.ends_with(Path::new("src/etc/completions")) {
+ return;
+ }
+ }
// apfloat shouldn't be changed because of license problems
if is_in(file, "compiler", "rustc_apfloat") {
return;
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index e4f328ec0dd..ee12f4acb10 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -4,13 +4,38 @@
use ignore::Walk;
use std::collections::HashMap;
+use std::ffi::OsStr;
use std::fs;
use std::path::{Path, PathBuf};
const ENTRY_LIMIT: usize = 900;
// FIXME: The following limits should be reduced eventually.
-const ISSUES_ENTRY_LIMIT: usize = 1953;
-const ROOT_ENTRY_LIMIT: usize = 895;
+const ISSUES_ENTRY_LIMIT: usize = 1920;
+const ROOT_ENTRY_LIMIT: usize = 896;
+
+const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
+ "rs", // test source files
+ "stderr", // expected stderr file, corresponds to a rs file
+ "stdout", // expected stdout file, corresponds to a rs file
+ "fixed", // expected source file after applying fixes
+ "md", // test directory descriptions
+ "ftl", // translation tests
+];
+
+const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
+ "tests/ui/asm/named-asm-labels.s", // loading an external asm file to test named labels lint
+ "tests/ui/check-cfg/my-awesome-platform.json", // testing custom targets with cfgs
+ "tests/ui/commandline-argfile-badutf8.args", // passing args via a file
+ "tests/ui/commandline-argfile.args", // passing args via a file
+ "tests/ui/crate-loading/auxiliary/libfoo.rlib", // testing loading a manually created rlib
+ "tests/ui/include-macros/data.bin", // testing including data with the include macros
+ "tests/ui/include-macros/file.txt", // testing including data with the include macros
+ "tests/ui/macros/macro-expanded-include/file.txt", // testing including data with the include macros
+ "tests/ui/macros/not-utf8.bin", // testing including data with the include macros
+ "tests/ui/macros/syntax-extension-source-utils-files/includeme.fragment", // more include
+ "tests/ui/unused-crate-deps/test.mk", // why would you use make
+ "tests/ui/proc-macro/auxiliary/included-file.txt", // more include
+];
fn check_entries(tests_path: &Path, bad: &mut bool) {
let mut directories: HashMap<PathBuf, usize> = HashMap::new();
@@ -66,7 +91,14 @@ pub fn check(path: &Path, bad: &mut bool) {
let paths = [ui.as_path(), ui_fulldeps.as_path()];
crate::walk::walk_no_read(&paths, |_, _| false, &mut |entry| {
let file_path = entry.path();
- if let Some(ext) = file_path.extension() {
+ if let Some(ext) = file_path.extension().and_then(OsStr::to_str) {
+ // files that are neither an expected extension or an exception should not exist
+ // they're probably typos or not meant to exist
+ if !(EXPECTED_TEST_FILE_EXTENSIONS.contains(&ext)
+ || EXTENSION_EXCEPTION_PATHS.iter().any(|path| file_path.ends_with(path)))
+ {
+ tidy_error!(bad, "file {} has unexpected extension {}", file_path.display(), ext);
+ }
if ext == "stderr" || ext == "stdout" {
// Test output filenames have one of the formats:
// ```
diff --git a/tests/codegen/addr-of-mutate.rs b/tests/codegen/addr-of-mutate.rs
new file mode 100644
index 00000000000..bea1aad2352
--- /dev/null
+++ b/tests/codegen/addr-of-mutate.rs
@@ -0,0 +1,34 @@
+// compile-flags: -C opt-level=3 -C no-prepopulate-passes
+// min-llvm-version: 15.0 (for opaque pointers)
+
+#![crate_type = "lib"]
+
+// Test for the absence of `readonly` on the argument when it is mutated via `&raw const`.
+// See <https://github.com/rust-lang/rust/issues/111502>.
+
+// CHECK: i8 @foo(ptr noalias nocapture noundef dereferenceable(128) %x)
+#[no_mangle]
+pub fn foo(x: [u8; 128]) -> u8 {
+ let ptr = core::ptr::addr_of!(x).cast_mut();
+ unsafe {
+ (*ptr)[0] = 1;
+ }
+ x[0]
+}
+
+// CHECK: i1 @second(ptr noalias nocapture noundef dereferenceable({{[0-9]+}}) %a_ptr_and_b)
+#[no_mangle]
+pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
+ let b_bool_ptr = core::ptr::addr_of!(a_ptr_and_b.1.1).cast_mut();
+ (*b_bool_ptr) = true;
+ a_ptr_and_b.1.1
+}
+
+// If going through a deref (and there are no other mutating accesses), then `readonly` is fine.
+// CHECK: i1 @third(ptr noalias nocapture noundef readonly dereferenceable({{[0-9]+}}) %a_ptr_and_b)
+#[no_mangle]
+pub unsafe fn third(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
+ let b_bool_ptr = core::ptr::addr_of!((*a_ptr_and_b.0).1).cast_mut();
+ (*b_bool_ptr) = true;
+ a_ptr_and_b.1.1
+}
diff --git a/tests/codegen/binary-search-index-no-bound-check.rs b/tests/codegen/binary-search-index-no-bound-check.rs
index c1766a4a44a..595969a8979 100644
--- a/tests/codegen/binary-search-index-no-bound-check.rs
+++ b/tests/codegen/binary-search-index-no-bound-check.rs
@@ -9,7 +9,9 @@
#[no_mangle]
pub fn binary_search_index_no_bounds_check(s: &[u8]) -> u8 {
// CHECK-NOT: panic
- // CHECK-NOT: slice_index_len_fail
+ // CHECK-NOT: slice_start_index_len_fail
+ // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: panic_bounds_check
if let Ok(idx) = s.binary_search(&b'\\') {
s[idx]
} else {
diff --git a/tests/codegen/fewer-names.rs b/tests/codegen/fewer-names.rs
index 7f383a5c149..a09c795924c 100644
--- a/tests/codegen/fewer-names.rs
+++ b/tests/codegen/fewer-names.rs
@@ -7,14 +7,14 @@
#[no_mangle]
pub fn sum(x: u32, y: u32) -> u32 {
-// YES-LABEL: define{{.*}}i32 @sum(i32 noundef %0, i32 noundef %1)
-// YES-NEXT: %3 = add i32 %1, %0
-// YES-NEXT: ret i32 %3
+ // YES-LABEL: define{{.*}}i32 @sum(i32 noundef %0, i32 noundef %1)
+ // YES-NEXT: %3 = add i32 %1, %0
+ // YES-NEXT: ret i32 %3
-// NO-LABEL: define{{.*}}i32 @sum(i32 noundef %x, i32 noundef %y)
-// NO-NEXT: start:
-// NO-NEXT: %0 = add i32 %y, %x
-// NO-NEXT: ret i32 %0
+ // NO-LABEL: define{{.*}}i32 @sum(i32 noundef %x, i32 noundef %y)
+ // NO-NEXT: start:
+ // NO-NEXT: %0 = add i32 %y, %x
+ // NO-NEXT: ret i32 %0
let z = x + y;
z
}
diff --git a/tests/codegen/issues/issue-73396-bounds-check-after-position.rs b/tests/codegen/issues/issue-73396-bounds-check-after-position.rs
index 8d07a67a1b4..2d779788791 100644
--- a/tests/codegen/issues/issue-73396-bounds-check-after-position.rs
+++ b/tests/codegen/issues/issue-73396-bounds-check-after-position.rs
@@ -9,7 +9,10 @@
#[no_mangle]
pub fn position_slice_to_no_bounds_check(s: &[u8]) -> &[u8] {
// CHECK-NOT: panic
- // CHECK-NOT: slice_index_len_fail
+ // CHECK-NOT: slice_start_index_len_fail
+ // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: panic_bounds_check
+ // CHECK-NOT: unreachable
if let Some(idx) = s.iter().position(|b| *b == b'\\') {
&s[..idx]
} else {
@@ -21,7 +24,10 @@ pub fn position_slice_to_no_bounds_check(s: &[u8]) -> &[u8] {
#[no_mangle]
pub fn position_slice_from_no_bounds_check(s: &[u8]) -> &[u8] {
// CHECK-NOT: panic
- // CHECK-NOT: slice_index_len_fail
+ // CHECK-NOT: slice_start_index_len_fail
+ // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: panic_bounds_check
+ // CHECK-NOT: unreachable
if let Some(idx) = s.iter().position(|b| *b == b'\\') {
&s[idx..]
} else {
@@ -33,7 +39,10 @@ pub fn position_slice_from_no_bounds_check(s: &[u8]) -> &[u8] {
#[no_mangle]
pub fn position_index_no_bounds_check(s: &[u8]) -> u8 {
// CHECK-NOT: panic
- // CHECK-NOT: slice_index_len_fail
+ // CHECK-NOT: slice_start_index_len_fail
+ // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: panic_bounds_check
+ // CHECK-NOT: unreachable
if let Some(idx) = s.iter().position(|b| *b == b'\\') {
s[idx]
} else {
@@ -44,7 +53,10 @@ pub fn position_index_no_bounds_check(s: &[u8]) -> u8 {
#[no_mangle]
pub fn rposition_slice_to_no_bounds_check(s: &[u8]) -> &[u8] {
// CHECK-NOT: panic
- // CHECK-NOT: slice_index_len_fail
+ // CHECK-NOT: slice_start_index_len_fail
+ // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: panic_bounds_check
+ // CHECK-NOT: unreachable
if let Some(idx) = s.iter().rposition(|b| *b == b'\\') {
&s[..idx]
} else {
@@ -56,7 +68,10 @@ pub fn rposition_slice_to_no_bounds_check(s: &[u8]) -> &[u8] {
#[no_mangle]
pub fn rposition_slice_from_no_bounds_check(s: &[u8]) -> &[u8] {
// CHECK-NOT: panic
- // CHECK-NOT: slice_index_len_fail
+ // CHECK-NOT: slice_start_index_len_fail
+ // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: panic_bounds_check
+ // CHECK-NOT: unreachable
if let Some(idx) = s.iter().rposition(|b| *b == b'\\') {
&s[idx..]
} else {
@@ -68,7 +83,10 @@ pub fn rposition_slice_from_no_bounds_check(s: &[u8]) -> &[u8] {
#[no_mangle]
pub fn rposition_index_no_bounds_check(s: &[u8]) -> u8 {
// CHECK-NOT: panic
- // CHECK-NOT: slice_index_len_fail
+ // CHECK-NOT: slice_start_index_len_fail
+ // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: panic_bounds_check
+ // CHECK-NOT: unreachable
if let Some(idx) = s.iter().rposition(|b| *b == b'\\') {
s[idx]
} else {
diff --git a/tests/codegen/mem-replace-big-type.rs b/tests/codegen/mem-replace-big-type.rs
index 81e56b5490d..c6b920cf599 100644
--- a/tests/codegen/mem-replace-big-type.rs
+++ b/tests/codegen/mem-replace-big-type.rs
@@ -13,7 +13,7 @@ pub struct Big([u64; 7]);
pub fn replace_big(dst: &mut Big, src: Big) -> Big {
// Back in 1.68, this emitted six `memcpy`s.
// `read_via_copy` in 1.69 got that down to three.
- // `write_via_move` has it down to just the two essential ones.
+ // `write_via_move` and nvro get this down to the essential two.
std::mem::replace(dst, src)
}
@@ -22,13 +22,12 @@ pub fn replace_big(dst: &mut Big, src: Big) -> Big {
// CHECK-NOT: call void @llvm.memcpy
-// For a large type, we expect exactly two `memcpy`s
+// For a large type, we expect exactly three `memcpy`s
// CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big)
- // CHECK-NOT: alloca
- // CHECK-NOT: call void @llvm.memcpy
- // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %0, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false)
- // CHECK-NOT: call void @llvm.memcpy
- // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %dest, {{i8\*|ptr}} align 8 %src, i{{.*}} 56, i1 false)
- // CHECK-NOT: call void @llvm.memcpy
+// CHECK-NOT: call void @llvm.memcpy
+// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %0, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false)
+// CHECK-NOT: call void @llvm.memcpy
+// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %dest, {{i8\*|ptr}} align 8 %src, i{{.*}} 56, i1 false)
+// CHECK-NOT: call void @llvm.memcpy
// CHECK-NOT: call void @llvm.memcpy
diff --git a/tests/codegen/nrvo.rs b/tests/codegen/nrvo.rs
index fddb0d1fb3c..b2ae99f3761 100644
--- a/tests/codegen/nrvo.rs
+++ b/tests/codegen/nrvo.rs
@@ -8,7 +8,7 @@
pub fn nrvo(init: fn(&mut [u8; 4096])) -> [u8; 4096] {
// CHECK-LABEL: nrvo
// CHECK: @llvm.memset
- // CHECK-NOT: @llvm.memcpy
+ // FIXME: turn on nrvo then check-not: @llvm.memcpy
// CHECK: ret
// CHECK-EMPTY
let mut buf = [0; 4096];
diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs
new file mode 100644
index 00000000000..ab5dcec7936
--- /dev/null
+++ b/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs
@@ -0,0 +1,44 @@
+// Verifies that type metadata identifiers for trait objects are emitted correctly.
+//
+// needs-sanitizer-cfi
+// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi
+
+#![crate_type="lib"]
+
+trait Trait1 {
+ fn foo(&self);
+}
+
+struct Type1;
+
+impl Trait1 for Type1 {
+ fn foo(&self) {
+ }
+}
+
+pub fn foo() {
+ let a = Type1;
+ a.foo();
+ // CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}}
+ // CHECK: call <sanitizer_cfi_emit_type_metadata_trait_objects::Type1 as sanitizer_cfi_emit_type_metadata_trait_objects::Trait1>::foo
+}
+
+pub fn bar() {
+ let a = Type1;
+ let b = &a as &dyn Trait1;
+ b.foo();
+ // CHECK-LABEL: define{{.*}}bar{{.*}}!type !{{[0-9]+}}
+ // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0|%1}}, metadata !"[[TYPE1:[[:print:]]+]]")
+}
+
+pub fn baz() {
+ let a = Type1;
+ let b = &a as &dyn Trait1;
+ a.foo();
+ b.foo();
+ // CHECK-LABEL: define{{.*}}baz{{.*}}!type !{{[0-9]+}}
+ // CHECK: call <sanitizer_cfi_emit_type_metadata_trait_objects::Type1 as sanitizer_cfi_emit_type_metadata_trait_objects::Trait1>::foo
+ // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0|%1}}, metadata !"[[TYPE1:[[:print:]]+]]")
+}
+
+// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE1]]"}
diff --git a/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs
new file mode 100644
index 00000000000..81e0d9344f7
--- /dev/null
+++ b/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs
@@ -0,0 +1,69 @@
+// Verifies that type metadata identifiers for trait objects are emitted correctly.
+//
+// revisions: aarch64 x86_64
+// [aarch64] compile-flags: --target aarch64-unknown-none
+// [aarch64] needs-llvm-components: aarch64
+// [x86_64] compile-flags: --target x86_64-unknown-none
+// [x86_64] needs-llvm-components:
+// compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0
+
+#![crate_type="lib"]
+#![feature(arbitrary_self_types, no_core, lang_items)]
+#![no_core]
+
+#[lang="sized"]
+trait Sized { }
+#[lang="copy"]
+trait Copy { }
+#[lang="receiver"]
+trait Receiver { }
+#[lang="dispatch_from_dyn"]
+trait DispatchFromDyn<T> { }
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
+#[lang = "unsize"]
+trait Unsize<T: ?Sized> { }
+#[lang = "coerce_unsized"]
+pub trait CoerceUnsized<T: ?Sized> { }
+impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
+#[lang="freeze"]
+trait Freeze { }
+#[lang="drop_in_place"]
+fn drop_in_place_fn<T>() { }
+
+trait Trait1 {
+ fn foo(&self);
+}
+
+struct Type1;
+
+impl Trait1 for Type1 {
+ fn foo(&self) {
+ }
+}
+
+pub fn foo() {
+ let a = Type1;
+ a.foo();
+ // CHECK-LABEL: define{{.*}}foo{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
+ // CHECK: call <sanitizer_kcfi_emit_type_metadata_trait_objects::Type1 as sanitizer_kcfi_emit_type_metadata_trait_objects::Trait1>::foo
+}
+
+pub fn bar() {
+ let a = Type1;
+ let b = &a as &dyn Trait1;
+ b.foo();
+ // CHECK-LABEL: define{{.*}}bar{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
+ // CHECK: call void %0({{\{\}\*|ptr}} align 1 {{%b\.0|%_1}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ]
+}
+
+pub fn baz() {
+ let a = Type1;
+ let b = &a as &dyn Trait1;
+ a.foo();
+ b.foo();
+ // CHECK-LABEL: define{{.*}}baz{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
+ // CHECK: call <sanitizer_kcfi_emit_type_metadata_trait_objects::Type1 as sanitizer_kcfi_emit_type_metadata_trait_objects::Trait1>::foo
+ // CHECK: call void %0({{\{\}\*|ptr}} align 1 {{%b\.0|%_1}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ]
+}
+
+// CHECK: !{{[0-9]+}} = !{i32 [[TYPE1]]}
diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs
new file mode 100644
index 00000000000..997bdaf5636
--- /dev/null
+++ b/tests/codegen/slice-iter-nonnull.rs
@@ -0,0 +1,77 @@
+// no-system-llvm
+// compile-flags: -O
+// ignore-debug (these add extra checks that make it hard to verify)
+#![crate_type = "lib"]
+
+// The slice iterator used to `assume` that the `start` pointer was non-null.
+// That ought to be unneeded, though, since the type is `NonNull`, so this test
+// confirms that the appropriate metadata is included to denote that.
+
+// CHECK-LABEL: @slice_iter_next(
+#[no_mangle]
+pub fn slice_iter_next<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> {
+ // CHECK: %[[ENDP:.+]] = getelementptr{{.+}}ptr %it,{{.+}} 1
+ // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]]
+ // CHECK-SAME: !nonnull
+ // CHECK-SAME: !noundef
+ // CHECK: %[[START:.+]] = load ptr, ptr %it,
+ // CHECK-SAME: !nonnull
+ // CHECK-SAME: !noundef
+ // CHECK: icmp eq ptr %[[START]], %[[END]]
+
+ // CHECK: store ptr{{.+}}, ptr %it,
+
+ it.next()
+}
+
+// CHECK-LABEL: @slice_iter_next_back(
+#[no_mangle]
+pub fn slice_iter_next_back<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> {
+ // CHECK: %[[ENDP:.+]] = getelementptr{{.+}}ptr %it,{{.+}} 1
+ // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]]
+ // CHECK-SAME: !nonnull
+ // CHECK-SAME: !noundef
+ // CHECK: %[[START:.+]] = load ptr, ptr %it,
+ // CHECK-SAME: !nonnull
+ // CHECK-SAME: !noundef
+ // CHECK: icmp eq ptr %[[START]], %[[END]]
+
+ // CHECK: store ptr{{.+}}, ptr %[[ENDP]],
+
+ it.next_back()
+}
+
+// The slice iterator `new` methods used to `assume` that the pointer is non-null,
+// but passing slices already requires that, to the extent that LLVM actually
+// removed the `call @llvm.assume` anyway. These tests just demonstrate that the
+// attribute is there, and confirms adding the assume back doesn't do anything.
+
+// CHECK-LABEL: @slice_iter_new
+// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef %slice.1)
+#[no_mangle]
+pub fn slice_iter_new(slice: &[u32]) -> std::slice::Iter<'_, u32> {
+ // CHECK-NOT: slice
+ // CHECK: %[[END:.+]] = getelementptr inbounds i32{{.+}} %slice.0{{.+}} %slice.1
+ // CHECK-NOT: slice
+ // CHECK: insertvalue {{.+}} ptr %slice.0, 0
+ // CHECK-NOT: slice
+ // CHECK: insertvalue {{.+}} ptr %[[END]], 1
+ // CHECK-NOT: slice
+ // CHECK: }
+ slice.iter()
+}
+
+// CHECK-LABEL: @slice_iter_mut_new
+// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef %slice.1)
+#[no_mangle]
+pub fn slice_iter_mut_new(slice: &mut [u32]) -> std::slice::IterMut<'_, u32> {
+ // CHECK-NOT: slice
+ // CHECK: %[[END:.+]] = getelementptr inbounds i32{{.+}} %slice.0{{.+}} %slice.1
+ // CHECK-NOT: slice
+ // CHECK: insertvalue {{.+}} ptr %slice.0, 0
+ // CHECK-NOT: slice
+ // CHECK: insertvalue {{.+}} ptr %[[END]], 1
+ // CHECK-NOT: slice
+ // CHECK: }
+ slice.iter_mut()
+}
diff --git a/tests/codegen/vec-shrink-panik.rs b/tests/codegen/vec-shrink-panik.rs
index b3c3483fea9..88b7edff260 100644
--- a/tests/codegen/vec-shrink-panik.rs
+++ b/tests/codegen/vec-shrink-panik.rs
@@ -25,7 +25,7 @@ pub fn issue71861(vec: Vec<u32>) -> Box<[u32]> {
// Call to panic_cannot_unwind in case of double-panic is expected
// on LLVM 16 and older, but other panics are not.
- // CHECK: cleanup
+ // old: filter
// old-NEXT: ; call core::panicking::panic_cannot_unwind
// old-NEXT: panic_cannot_unwind
@@ -40,7 +40,7 @@ pub fn issue75636<'a>(iter: &[&'a str]) -> Box<[&'a str]> {
// Call to panic_cannot_unwind in case of double-panic is expected,
// on LLVM 16 and older, but other panics are not.
- // CHECK: cleanup
+ // old: filter
// old-NEXT: ; call core::panicking::panic_cannot_unwind
// old-NEXT: panic_cannot_unwind
diff --git a/tests/debuginfo/reference-debuginfo.rs b/tests/debuginfo/reference-debuginfo.rs
new file mode 100644
index 00000000000..85ade170ac6
--- /dev/null
+++ b/tests/debuginfo/reference-debuginfo.rs
@@ -0,0 +1,173 @@
+// Copy of `borrowed-basic.rs` which enables the `ReferencePropagation` MIR pass.
+// That pass replaces debuginfo for `a => _x` where `_x = &b` to be `a => &b`,
+// and leaves codegen to create a ladder of allocations so as `*a == b`.
+//
+// compile-flags:-g -Zmir-enable-passes=+ReferencePropagation,-ConstDebugInfo
+// min-lldb-version: 310
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+// gdb-command:print *bool_ref
+// gdb-check:$1 = true
+
+// gdb-command:print *int_ref
+// gdb-check:$2 = -1
+
+// gdb-command:print/d *char_ref
+// gdb-check:$3 = 97
+
+// gdb-command:print *i8_ref
+// gdbg-check:$4 = 68 'D'
+// gdbr-check:$4 = 68
+
+// gdb-command:print *i16_ref
+// gdb-check:$5 = -16
+
+// gdb-command:print *i32_ref
+// gdb-check:$6 = -32
+
+// gdb-command:print *i64_ref
+// gdb-check:$7 = -64
+
+// gdb-command:print *uint_ref
+// gdb-check:$8 = 1
+
+// gdb-command:print *u8_ref
+// gdbg-check:$9 = 100 'd'
+// gdbr-check:$9 = 100
+
+// gdb-command:print *u16_ref
+// gdb-check:$10 = 16
+
+// gdb-command:print *u32_ref
+// gdb-check:$11 = 32
+
+// gdb-command:print *u64_ref
+// gdb-check:$12 = 64
+
+// gdb-command:print *f32_ref
+// gdb-check:$13 = 2.5
+
+// gdb-command:print *f64_ref
+// gdb-check:$14 = 3.5
+
+// gdb-command:print *f64_double_ref
+// gdb-check:$15 = 3.5
+
+
+// === LLDB TESTS ==================================================================================
+
+// lldb-command:run
+// lldb-command:print *bool_ref
+// lldbg-check:[...]$0 = true
+// lldbr-check:(bool) *bool_ref = true
+
+// lldb-command:print *int_ref
+// lldbg-check:[...]$1 = -1
+// lldbr-check:(isize) *int_ref = -1
+
+// NOTE: only rust-enabled lldb supports 32bit chars
+// lldbr-command:print *char_ref
+// lldbr-check:(char) *char_ref = 'a'
+
+// lldb-command:print *i8_ref
+// lldbg-check:[...]$2 = 'D'
+// lldbr-check:(i8) *i8_ref = 68
+
+// lldb-command:print *i16_ref
+// lldbg-check:[...]$3 = -16
+// lldbr-check:(i16) *i16_ref = -16
+
+// lldb-command:print *i32_ref
+// lldbg-check:[...]$4 = -32
+// lldbr-check:(i32) *i32_ref = -32
+
+// lldb-command:print *i64_ref
+// lldbg-check:[...]$5 = -64
+// lldbr-check:(i64) *i64_ref = -64
+
+// lldb-command:print *uint_ref
+// lldbg-check:[...]$6 = 1
+// lldbr-check:(usize) *uint_ref = 1
+
+// lldb-command:print *u8_ref
+// lldbg-check:[...]$7 = 'd'
+// lldbr-check:(u8) *u8_ref = 100
+
+// lldb-command:print *u16_ref
+// lldbg-check:[...]$8 = 16
+// lldbr-check:(u16) *u16_ref = 16
+
+// lldb-command:print *u32_ref
+// lldbg-check:[...]$9 = 32
+// lldbr-check:(u32) *u32_ref = 32
+
+// lldb-command:print *u64_ref
+// lldbg-check:[...]$10 = 64
+// lldbr-check:(u64) *u64_ref = 64
+
+// lldb-command:print *f32_ref
+// lldbg-check:[...]$11 = 2.5
+// lldbr-check:(f32) *f32_ref = 2.5
+
+// lldb-command:print *f64_ref
+// lldbg-check:[...]$12 = 3.5
+// lldbr-check:(f64) *f64_ref = 3.5
+
+// lldb-command:print *f64_double_ref
+// lldbg-check:[...]$13 = 3.5
+// lldbr-check:(f64) **f64_double_ref = 3.5
+
+#![allow(unused_variables)]
+#![feature(omit_gdb_pretty_printer_section)]
+#![omit_gdb_pretty_printer_section]
+
+fn main() {
+ let bool_val: bool = true;
+ let bool_ref: &bool = &bool_val;
+
+ let int_val: isize = -1;
+ let int_ref: &isize = &int_val;
+
+ let char_val: char = 'a';
+ let char_ref: &char = &char_val;
+
+ let i8_val: i8 = 68;
+ let i8_ref: &i8 = &i8_val;
+
+ let i16_val: i16 = -16;
+ let i16_ref: &i16 = &i16_val;
+
+ let i32_val: i32 = -32;
+ let i32_ref: &i32 = &i32_val;
+
+ let i64_val: i64 = -64;
+ let i64_ref: &i64 = &i64_val;
+
+ let uint_val: usize = 1;
+ let uint_ref: &usize = &uint_val;
+
+ let u8_val: u8 = 100;
+ let u8_ref: &u8 = &u8_val;
+
+ let u16_val: u16 = 16;
+ let u16_ref: &u16 = &u16_val;
+
+ let u32_val: u32 = 32;
+ let u32_ref: &u32 = &u32_val;
+
+ let u64_val: u64 = 64;
+ let u64_ref: &u64 = &u64_val;
+
+ let f32_val: f32 = 2.5;
+ let f32_ref: &f32 = &f32_val;
+
+ let f64_val: f64 = 3.5;
+ let f64_ref: &f64 = &f64_val;
+ let f64_double_ref: &f64 = &f64_ref;
+
+ zzz(); // #break
+}
+
+fn zzz() {()}
diff --git a/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir b/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir
new file mode 100644
index 00000000000..5233d0489c6
--- /dev/null
+++ b/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir
@@ -0,0 +1,12 @@
+// MIR for `copy_for_deref` after built
+
+fn copy_for_deref(_1: (&i32, i32)) -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/projections.rs:+0:38: +0:41
+ let mut _2: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _2 = deref_copy (_1.0: &i32); // scope 0 at $DIR/projections.rs:+4:13: +4:37
+ _0 = (*_2); // scope 0 at $DIR/projections.rs:+5:13: +5:24
+ return; // scope 0 at $DIR/projections.rs:+6:13: +6:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/projections.rs b/tests/mir-opt/building/custom/projections.rs
index 5e472e531c7..3c155deae4b 100644
--- a/tests/mir-opt/building/custom/projections.rs
+++ b/tests/mir-opt/building/custom/projections.rs
@@ -21,13 +21,10 @@ fn unions(u: U) -> i32 {
#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
fn tuples(i: (u32, i32)) -> (u32, i32) {
mir!(
- // FIXME(JakobDegen): This is necessary because we can't give type hints for `RET`
- let temp: (u32, i32);
+ type RET = (u32, i32);
{
- temp.0 = i.0;
- temp.1 = i.1;
-
- RET = temp;
+ RET.0 = i.0;
+ RET.1 = i.1;
Return()
}
)
@@ -71,6 +68,19 @@ fn simple_index(a: [i32; 10], b: &[i32]) -> i32 {
})
}
+// EMIT_MIR projections.copy_for_deref.built.after.mir
+#[custom_mir(dialect = "runtime", phase = "initial")]
+fn copy_for_deref(x: (&i32, i32)) -> i32 {
+ mir!(
+ let temp: &i32;
+ {
+ temp = CopyForDeref(x.0);
+ RET = *temp;
+ Return()
+ }
+ )
+}
+
fn main() {
assert_eq!(unions(U { a: 5 }), 5);
assert_eq!(tuples((5, 6)), (5, 6));
@@ -82,4 +92,7 @@ fn main() {
assert_eq!(o, Some(10));
assert_eq!(simple_index([0; 10], &[0; 10]), 0);
+
+ let one = 1;
+ assert_eq!(copy_for_deref((&one, one)), 1);
}
diff --git a/tests/mir-opt/building/custom/projections.tuples.built.after.mir b/tests/mir-opt/building/custom/projections.tuples.built.after.mir
index 65487d3c9ed..dec575200c6 100644
--- a/tests/mir-opt/building/custom/projections.tuples.built.after.mir
+++ b/tests/mir-opt/building/custom/projections.tuples.built.after.mir
@@ -2,12 +2,10 @@
fn tuples(_1: (u32, i32)) -> (u32, i32) {
let mut _0: (u32, i32); // return place in scope 0 at $DIR/projections.rs:+0:29: +0:39
- let mut _2: (u32, i32); // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
bb0: {
- (_2.0: u32) = (_1.0: u32); // scope 0 at $DIR/projections.rs:+5:13: +5:25
- (_2.1: i32) = (_1.1: i32); // scope 0 at $DIR/projections.rs:+6:13: +6:25
- _0 = _2; // scope 0 at $DIR/projections.rs:+8:13: +8:23
- return; // scope 0 at $DIR/projections.rs:+9:13: +9:21
+ (_0.0: u32) = (_1.0: u32); // scope 0 at $DIR/projections.rs:+4:13: +4:24
+ (_0.1: i32) = (_1.1: i32); // scope 0 at $DIR/projections.rs:+5:13: +5:24
+ return; // scope 0 at $DIR/projections.rs:+6:13: +6:21
}
}
diff --git a/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff b/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff
index c5907e7cf18..15117ea890e 100644
--- a/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff
+++ b/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff
@@ -4,59 +4,29 @@
fn adt_transmutes() -> () {
let mut _0: (); // return place in scope 0 at $DIR/combine_transmutes.rs:+0:32: +0:32
let _1: u8; // in scope 0 at $DIR/combine_transmutes.rs:+1:9: +1:11
- let mut _2: EnumNoRepr; // in scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41
- let mut _4: EnumNoRepr; // in scope 0 at $DIR/combine_transmutes.rs:+2:28: +2:41
- let mut _6: EnumReprIsize; // in scope 0 at $DIR/combine_transmutes.rs:+3:31: +3:47
- let mut _8: EnumReprIsize; // in scope 0 at $DIR/combine_transmutes.rs:+4:31: +4:47
- let mut _10: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+5:28: +5:52
- let mut _12: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+6:28: +6:52
- let mut _14: std::option::Option<std::num::NonZeroU8>; // in scope 0 at $DIR/combine_transmutes.rs:+7:28: +7:58
- let mut _16: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+8:29: +8:54
- let mut _18: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+9:29: +9:54
- let mut _20: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+10:29: +10:47
- let mut _22: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+11:29: +11:47
- let mut _24: std::mem::MaybeUninit<std::string::String>; // in scope 0 at $DIR/combine_transmutes.rs:+12:46: +12:77
+ let mut _2: std::option::Option<std::num::NonZeroU8>; // in scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:58
+ let mut _4: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+2:29: +2:54
+ let mut _6: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+3:29: +3:54
+ let mut _8: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+4:29: +4:47
+ let mut _10: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+5:29: +5:47
+ let mut _12: std::mem::MaybeUninit<std::string::String>; // in scope 0 at $DIR/combine_transmutes.rs:+6:46: +6:77
scope 1 {
debug _a => _1; // in scope 1 at $DIR/combine_transmutes.rs:+1:9: +1:11
- let _3: i8; // in scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11
+ let _3: i16; // in scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11
scope 2 {
debug _a => _3; // in scope 2 at $DIR/combine_transmutes.rs:+2:9: +2:11
- let _5: usize; // in scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11
+ let _5: u16; // in scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11
scope 3 {
debug _a => _5; // in scope 3 at $DIR/combine_transmutes.rs:+3:9: +3:11
- let _7: isize; // in scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11
+ let _7: u32; // in scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11
scope 4 {
debug _a => _7; // in scope 4 at $DIR/combine_transmutes.rs:+4:9: +4:11
- let _9: u8; // in scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11
+ let _9: i32; // in scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11
scope 5 {
debug _a => _9; // in scope 5 at $DIR/combine_transmutes.rs:+5:9: +5:11
- let _11: i8; // in scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11
+ let _11: std::mem::ManuallyDrop<std::string::String>; // in scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11
scope 6 {
debug _a => _11; // in scope 6 at $DIR/combine_transmutes.rs:+6:9: +6:11
- let _13: u8; // in scope 6 at $DIR/combine_transmutes.rs:+7:9: +7:11
- scope 7 {
- debug _a => _13; // in scope 7 at $DIR/combine_transmutes.rs:+7:9: +7:11
- let _15: i16; // in scope 7 at $DIR/combine_transmutes.rs:+8:9: +8:11
- scope 8 {
- debug _a => _15; // in scope 8 at $DIR/combine_transmutes.rs:+8:9: +8:11
- let _17: u16; // in scope 8 at $DIR/combine_transmutes.rs:+9:9: +9:11
- scope 9 {
- debug _a => _17; // in scope 9 at $DIR/combine_transmutes.rs:+9:9: +9:11
- let _19: u32; // in scope 9 at $DIR/combine_transmutes.rs:+10:9: +10:11
- scope 10 {
- debug _a => _19; // in scope 10 at $DIR/combine_transmutes.rs:+10:9: +10:11
- let _21: i32; // in scope 10 at $DIR/combine_transmutes.rs:+11:9: +11:11
- scope 11 {
- debug _a => _21; // in scope 11 at $DIR/combine_transmutes.rs:+11:9: +11:11
- let _23: std::mem::ManuallyDrop<std::string::String>; // in scope 11 at $DIR/combine_transmutes.rs:+12:9: +12:11
- scope 12 {
- debug _a => _23; // in scope 12 at $DIR/combine_transmutes.rs:+12:9: +12:11
- }
- }
- }
- }
- }
- }
}
}
}
@@ -66,93 +36,55 @@
bb0: {
StorageLive(_1); // scope 0 at $DIR/combine_transmutes.rs:+1:9: +1:11
- StorageLive(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41
- _2 = EnumNoRepr::A; // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41
- _1 = move _2 as u8 (Transmute); // scope 0 at $DIR/combine_transmutes.rs:+1:18: +1:42
- StorageDead(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:41: +1:42
+ StorageLive(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:58
+ _2 = Option::<NonZeroU8>::Some(const _); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:58
+ // mir::Constant
+ // + span: $DIR/combine_transmutes.rs:35:33: 35:57
+ // + literal: Const { ty: NonZeroU8, val: Unevaluated(NonZeroU8::MAX, [], None) }
+ _1 = move _2 as u8 (Transmute); // scope 0 at $DIR/combine_transmutes.rs:+1:18: +1:59
+ StorageDead(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:58: +1:59
StorageLive(_3); // scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11
- StorageLive(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:28: +2:41
- _4 = EnumNoRepr::B; // scope 1 at $DIR/combine_transmutes.rs:+2:28: +2:41
- _3 = move _4 as i8 (Transmute); // scope 1 at $DIR/combine_transmutes.rs:+2:18: +2:42
- StorageDead(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:41: +2:42
+ StorageLive(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:29: +2:54
+ _4 = Wrapping::<i16>(const 0_i16); // scope 1 at $DIR/combine_transmutes.rs:+2:29: +2:54
+- _3 = move _4 as i16 (Transmute); // scope 1 at $DIR/combine_transmutes.rs:+2:19: +2:55
++ _3 = move (_4.0: i16); // scope 1 at $DIR/combine_transmutes.rs:+2:19: +2:55
+ StorageDead(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:54: +2:55
StorageLive(_5); // scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11
- StorageLive(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:31: +3:47
- _6 = EnumReprIsize::A; // scope 2 at $DIR/combine_transmutes.rs:+3:31: +3:47
- _5 = move _6 as usize (Transmute); // scope 2 at $DIR/combine_transmutes.rs:+3:21: +3:48
- StorageDead(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:47: +3:48
+ StorageLive(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:29: +3:54
+ _6 = Wrapping::<i16>(const 0_i16); // scope 2 at $DIR/combine_transmutes.rs:+3:29: +3:54
+ _5 = move _6 as u16 (Transmute); // scope 2 at $DIR/combine_transmutes.rs:+3:19: +3:55
+ StorageDead(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:54: +3:55
StorageLive(_7); // scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11
- StorageLive(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:31: +4:47
- _8 = EnumReprIsize::B; // scope 3 at $DIR/combine_transmutes.rs:+4:31: +4:47
-- _7 = move _8 as isize (Transmute); // scope 3 at $DIR/combine_transmutes.rs:+4:21: +4:48
-+ _7 = discriminant(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:21: +4:48
+ StorageLive(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:29: +4:47
+ _8 = Union32 { u32: const 0_i32 }; // scope 3 at $DIR/combine_transmutes.rs:+4:29: +4:47
+ _7 = move _8 as u32 (Transmute); // scope 3 at $DIR/combine_transmutes.rs:+4:19: +4:48
StorageDead(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:47: +4:48
StorageLive(_9); // scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11
- StorageLive(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:28: +5:52
- _10 = Less; // scope 4 at $DIR/combine_transmutes.rs:+5:28: +5:52
- _9 = move _10 as u8 (Transmute); // scope 4 at $DIR/combine_transmutes.rs:+5:18: +5:53
- StorageDead(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:52: +5:53
+ StorageLive(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:29: +5:47
+ _10 = Union32 { u32: const 0_u32 }; // scope 4 at $DIR/combine_transmutes.rs:+5:29: +5:47
+ _9 = move _10 as i32 (Transmute); // scope 4 at $DIR/combine_transmutes.rs:+5:19: +5:48
+ StorageDead(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:47: +5:48
StorageLive(_11); // scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11
- StorageLive(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:28: +6:52
- _12 = Less; // scope 5 at $DIR/combine_transmutes.rs:+6:28: +6:52
-- _11 = move _12 as i8 (Transmute); // scope 5 at $DIR/combine_transmutes.rs:+6:18: +6:53
-+ _11 = discriminant(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:18: +6:53
- StorageDead(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:52: +6:53
- StorageLive(_13); // scope 6 at $DIR/combine_transmutes.rs:+7:9: +7:11
- StorageLive(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58
- _14 = Option::<NonZeroU8>::Some(const _); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58
- // mir::Constant
- // + span: $DIR/combine_transmutes.rs:41:33: 41:57
- // + literal: Const { ty: NonZeroU8, val: Unevaluated(NonZeroU8::MAX, [], None) }
- _13 = move _14 as u8 (Transmute); // scope 6 at $DIR/combine_transmutes.rs:+7:18: +7:59
- StorageDead(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:58: +7:59
- StorageLive(_15); // scope 7 at $DIR/combine_transmutes.rs:+8:9: +8:11
- StorageLive(_16); // scope 7 at $DIR/combine_transmutes.rs:+8:29: +8:54
- _16 = Wrapping::<i16>(const 0_i16); // scope 7 at $DIR/combine_transmutes.rs:+8:29: +8:54
-- _15 = move _16 as i16 (Transmute); // scope 7 at $DIR/combine_transmutes.rs:+8:19: +8:55
-+ _15 = move (_16.0: i16); // scope 7 at $DIR/combine_transmutes.rs:+8:19: +8:55
- StorageDead(_16); // scope 7 at $DIR/combine_transmutes.rs:+8:54: +8:55
- StorageLive(_17); // scope 8 at $DIR/combine_transmutes.rs:+9:9: +9:11
- StorageLive(_18); // scope 8 at $DIR/combine_transmutes.rs:+9:29: +9:54
- _18 = Wrapping::<i16>(const 0_i16); // scope 8 at $DIR/combine_transmutes.rs:+9:29: +9:54
- _17 = move _18 as u16 (Transmute); // scope 8 at $DIR/combine_transmutes.rs:+9:19: +9:55
- StorageDead(_18); // scope 8 at $DIR/combine_transmutes.rs:+9:54: +9:55
- StorageLive(_19); // scope 9 at $DIR/combine_transmutes.rs:+10:9: +10:11
- StorageLive(_20); // scope 9 at $DIR/combine_transmutes.rs:+10:29: +10:47
- _20 = Union32 { u32: const 0_i32 }; // scope 9 at $DIR/combine_transmutes.rs:+10:29: +10:47
- _19 = move _20 as u32 (Transmute); // scope 9 at $DIR/combine_transmutes.rs:+10:19: +10:48
- StorageDead(_20); // scope 9 at $DIR/combine_transmutes.rs:+10:47: +10:48
- StorageLive(_21); // scope 10 at $DIR/combine_transmutes.rs:+11:9: +11:11
- StorageLive(_22); // scope 10 at $DIR/combine_transmutes.rs:+11:29: +11:47
- _22 = Union32 { u32: const 0_u32 }; // scope 10 at $DIR/combine_transmutes.rs:+11:29: +11:47
- _21 = move _22 as i32 (Transmute); // scope 10 at $DIR/combine_transmutes.rs:+11:19: +11:48
- StorageDead(_22); // scope 10 at $DIR/combine_transmutes.rs:+11:47: +11:48
- StorageLive(_23); // scope 11 at $DIR/combine_transmutes.rs:+12:9: +12:11
- StorageLive(_24); // scope 11 at $DIR/combine_transmutes.rs:+12:46: +12:77
- _24 = MaybeUninit::<String>::uninit() -> [return: bb1, unwind unreachable]; // scope 11 at $DIR/combine_transmutes.rs:+12:46: +12:77
+ StorageLive(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:46: +6:77
+ _12 = MaybeUninit::<String>::uninit() -> [return: bb1, unwind unreachable]; // scope 5 at $DIR/combine_transmutes.rs:+6:46: +6:77
// mir::Constant
- // + span: $DIR/combine_transmutes.rs:46:46: 46:75
- // + user_ty: UserType(23)
+ // + span: $DIR/combine_transmutes.rs:40:46: 40:75
+ // + user_ty: UserType(11)
// + literal: Const { ty: fn() -> MaybeUninit<String> {MaybeUninit::<String>::uninit}, val: Value(<ZST>) }
}
bb1: {
-- _23 = move _24 as std::mem::ManuallyDrop<std::string::String> (Transmute); // scope 11 at $DIR/combine_transmutes.rs:+12:36: +12:78
-+ _23 = move (_24.1: std::mem::ManuallyDrop<std::string::String>); // scope 11 at $DIR/combine_transmutes.rs:+12:36: +12:78
- StorageDead(_24); // scope 11 at $DIR/combine_transmutes.rs:+12:77: +12:78
- _0 = const (); // scope 0 at $DIR/combine_transmutes.rs:+0:32: +13:2
- StorageDead(_23); // scope 11 at $DIR/combine_transmutes.rs:+13:1: +13:2
- StorageDead(_21); // scope 10 at $DIR/combine_transmutes.rs:+13:1: +13:2
- StorageDead(_19); // scope 9 at $DIR/combine_transmutes.rs:+13:1: +13:2
- StorageDead(_17); // scope 8 at $DIR/combine_transmutes.rs:+13:1: +13:2
- StorageDead(_15); // scope 7 at $DIR/combine_transmutes.rs:+13:1: +13:2
- StorageDead(_13); // scope 6 at $DIR/combine_transmutes.rs:+13:1: +13:2
- StorageDead(_11); // scope 5 at $DIR/combine_transmutes.rs:+13:1: +13:2
- StorageDead(_9); // scope 4 at $DIR/combine_transmutes.rs:+13:1: +13:2
- StorageDead(_7); // scope 3 at $DIR/combine_transmutes.rs:+13:1: +13:2
- StorageDead(_5); // scope 2 at $DIR/combine_transmutes.rs:+13:1: +13:2
- StorageDead(_3); // scope 1 at $DIR/combine_transmutes.rs:+13:1: +13:2
- StorageDead(_1); // scope 0 at $DIR/combine_transmutes.rs:+13:1: +13:2
- return; // scope 0 at $DIR/combine_transmutes.rs:+13:2: +13:2
+- _11 = move _12 as std::mem::ManuallyDrop<std::string::String> (Transmute); // scope 5 at $DIR/combine_transmutes.rs:+6:36: +6:78
++ _11 = move (_12.1: std::mem::ManuallyDrop<std::string::String>); // scope 5 at $DIR/combine_transmutes.rs:+6:36: +6:78
+ StorageDead(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:77: +6:78
+ _0 = const (); // scope 0 at $DIR/combine_transmutes.rs:+0:32: +7:2
+ StorageDead(_11); // scope 5 at $DIR/combine_transmutes.rs:+7:1: +7:2
+ StorageDead(_9); // scope 4 at $DIR/combine_transmutes.rs:+7:1: +7:2
+ StorageDead(_7); // scope 3 at $DIR/combine_transmutes.rs:+7:1: +7:2
+ StorageDead(_5); // scope 2 at $DIR/combine_transmutes.rs:+7:1: +7:2
+ StorageDead(_3); // scope 1 at $DIR/combine_transmutes.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/combine_transmutes.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/combine_transmutes.rs:+7:2: +7:2
}
}
diff --git a/tests/mir-opt/combine_transmutes.rs b/tests/mir-opt/combine_transmutes.rs
index 7088488c1b8..403f9356ce2 100644
--- a/tests/mir-opt/combine_transmutes.rs
+++ b/tests/mir-opt/combine_transmutes.rs
@@ -32,12 +32,6 @@ pub unsafe fn integer_transmutes() {
// EMIT_MIR combine_transmutes.adt_transmutes.InstSimplify.diff
pub unsafe fn adt_transmutes() {
- let _a: u8 = transmute(EnumNoRepr::A);
- let _a: i8 = transmute(EnumNoRepr::B);
- let _a: usize = transmute(EnumReprIsize::A);
- let _a: isize = transmute(EnumReprIsize::B);
- let _a: u8 = transmute(std::cmp::Ordering::Less);
- let _a: i8 = transmute(std::cmp::Ordering::Less);
let _a: u8 = transmute(Some(std::num::NonZeroU8::MAX));
let _a: i16 = transmute(std::num::Wrapping(0_i16));
let _a: u16 = transmute(std::num::Wrapping(0_i16));
@@ -46,20 +40,4 @@ pub unsafe fn adt_transmutes() {
let _a: ManuallyDrop<String> = transmute(MaybeUninit::<String>::uninit());
}
-#[inline(always)]
-#[custom_mir(dialect = "runtime", phase = "initial")]
-const unsafe fn mir_transmute<T, U>(x: T) -> U {
- mir!{
- {
- RET = CastTransmute(x);
- Return()
- }
- }
-}
-
-pub enum EnumNoRepr { A, B, C }
-
-#[repr(isize)]
-pub enum EnumReprIsize { A, B, C }
-
pub union Union32 { u32: u32, i32: i32 }
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
index f63ee705d92..d72675c2d11 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
@@ -45,7 +45,8 @@
}
bb1: {
- _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ _5 = (*_1)[3 of 4]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26
_0 = const (); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6
StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
index f63ee705d92..d72675c2d11 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
@@ -45,7 +45,8 @@
}
bb1: {
- _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ _5 = (*_1)[3 of 4]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26
_0 = const (); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6
StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6
diff --git a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff
index 36336d967a9..33bbad2f422 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff
@@ -27,7 +27,8 @@
}
bb1: {
- _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+- _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
++ _1 = _2[2 of 3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33
StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33
_0 = const (); // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2
diff --git a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff
index 36336d967a9..33bbad2f422 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff
@@ -27,7 +27,8 @@
}
bb1: {
- _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+- _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
++ _1 = _2[2 of 3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33
StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33
_0 = const (); // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2
diff --git a/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff
index e768a47a96d..e3757941c8c 100644
--- a/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff
+++ b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff
@@ -22,17 +22,17 @@
bb0: {
StorageLive(_1); // scope 0 at $DIR/offset_of.rs:+1:9: +1:10
-- _1 = OffsetOf(Alpha, [0]); // scope 0 at $DIR/offset_of.rs:+1:13: +1:33
-+ _1 = const 4_usize; // scope 0 at $DIR/offset_of.rs:+1:13: +1:33
+- _1 = OffsetOf(Alpha, [0]); // scope 0 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
++ _1 = const 4_usize; // scope 0 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
StorageLive(_2); // scope 1 at $DIR/offset_of.rs:+2:9: +2:10
-- _2 = OffsetOf(Alpha, [1]); // scope 1 at $DIR/offset_of.rs:+2:13: +2:33
-+ _2 = const 0_usize; // scope 1 at $DIR/offset_of.rs:+2:13: +2:33
+- _2 = OffsetOf(Alpha, [1]); // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
++ _2 = const 0_usize; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
StorageLive(_3); // scope 2 at $DIR/offset_of.rs:+3:9: +3:11
-- _3 = OffsetOf(Alpha, [2, 0]); // scope 2 at $DIR/offset_of.rs:+3:14: +3:36
-+ _3 = const 2_usize; // scope 2 at $DIR/offset_of.rs:+3:14: +3:36
+- _3 = OffsetOf(Alpha, [2, 0]); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
++ _3 = const 2_usize; // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
StorageLive(_4); // scope 3 at $DIR/offset_of.rs:+4:9: +4:11
-- _4 = OffsetOf(Alpha, [2, 1]); // scope 3 at $DIR/offset_of.rs:+4:14: +4:36
-+ _4 = const 3_usize; // scope 3 at $DIR/offset_of.rs:+4:14: +4:36
+- _4 = OffsetOf(Alpha, [2, 1]); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
++ _4 = const 3_usize; // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
_0 = const (); // scope 0 at $DIR/offset_of.rs:+0:15: +5:2
StorageDead(_4); // scope 3 at $DIR/offset_of.rs:+5:1: +5:2
StorageDead(_3); // scope 2 at $DIR/offset_of.rs:+5:1: +5:2
diff --git a/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff
index e40fdbd79d8..4a655604cd1 100644
--- a/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff
+++ b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff
@@ -22,13 +22,13 @@
bb0: {
StorageLive(_1); // scope 0 at $DIR/offset_of.rs:+1:9: +1:11
- _1 = OffsetOf(Gamma<T>, [0]); // scope 0 at $DIR/offset_of.rs:+1:14: +1:37
+ _1 = OffsetOf(Gamma<T>, [0]); // scope 0 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
StorageLive(_2); // scope 1 at $DIR/offset_of.rs:+2:9: +2:11
- _2 = OffsetOf(Gamma<T>, [1]); // scope 1 at $DIR/offset_of.rs:+2:14: +2:37
+ _2 = OffsetOf(Gamma<T>, [1]); // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
StorageLive(_3); // scope 2 at $DIR/offset_of.rs:+3:9: +3:11
- _3 = OffsetOf(Delta<T>, [1]); // scope 2 at $DIR/offset_of.rs:+3:14: +3:37
+ _3 = OffsetOf(Delta<T>, [1]); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
StorageLive(_4); // scope 3 at $DIR/offset_of.rs:+4:9: +4:11
- _4 = OffsetOf(Delta<T>, [2]); // scope 3 at $DIR/offset_of.rs:+4:14: +4:37
+ _4 = OffsetOf(Delta<T>, [2]); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
_0 = const (); // scope 0 at $DIR/offset_of.rs:+0:17: +5:2
StorageDead(_4); // scope 3 at $DIR/offset_of.rs:+5:1: +5:2
StorageDead(_3); // scope 2 at $DIR/offset_of.rs:+5:1: +5:2
diff --git a/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff
index 2a0bff57db9..51707e71661 100644
--- a/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff
+++ b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff
@@ -20,8 +20,7 @@
}
bb1: {
-- _0 = opaque::<u8>(_3) -> bb2; // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38
-+ _0 = opaque::<u8>(_1) -> bb2; // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38
+ _0 = opaque::<u8>(_3) -> bb2; // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38
// mir::Constant
// + span: $DIR/borrowed_local.rs:28:28: 28:34
// + literal: Const { ty: fn(u8) -> bool {opaque::<u8>}, val: Value(<ZST>) }
diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff
index 69acebf7642..1c7b6494d6d 100644
--- a/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff
+++ b/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff
@@ -6,15 +6,17 @@
let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:27: +0:30
let _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
scope 1 {
- debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
+- debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
++ debug y => _0; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
+- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
+- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
++ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
_1 = const 123_i32; // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12
- _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2
+- _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
+- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2
return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2
}
}
diff --git a/tests/mir-opt/copy-prop/partial_init.main.CopyProp.diff b/tests/mir-opt/copy-prop/partial_init.main.CopyProp.diff
new file mode 100644
index 00000000000..5866439055e
--- /dev/null
+++ b/tests/mir-opt/copy-prop/partial_init.main.CopyProp.diff
@@ -0,0 +1,13 @@
+- // MIR for `main` before CopyProp
++ // MIR for `main` after CopyProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/partial_init.rs:+0:15: +0:15
+ let mut _1: (isize,); // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ (_1.0: isize) = const 1_isize; // scope 0 at $DIR/partial_init.rs:+4:13: +4:20
+ return; // scope 0 at $DIR/partial_init.rs:+5:13: +5:21
+ }
+ }
+
diff --git a/tests/mir-opt/copy-prop/partial_init.rs b/tests/mir-opt/copy-prop/partial_init.rs
new file mode 100644
index 00000000000..f5ab9974f71
--- /dev/null
+++ b/tests/mir-opt/copy-prop/partial_init.rs
@@ -0,0 +1,18 @@
+// unit-test: CopyProp
+// Verify that we do not ICE on partial initializations.
+
+#![feature(custom_mir, core_intrinsics)]
+extern crate core;
+use core::intrinsics::mir::*;
+
+// EMIT_MIR partial_init.main.CopyProp.diff
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+pub fn main() {
+ mir! (
+ let x: (isize, );
+ {
+ x.0 = 1;
+ Return()
+ }
+ )
+}
diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
index abb89b91dd3..73b9ea46c44 100644
--- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
+++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
@@ -21,9 +21,9 @@
let _13: &T; // in scope 1 at $DIR/issue_76432.rs:+3:18: +3:24
let _14: &T; // in scope 1 at $DIR/issue_76432.rs:+3:26: +3:32
scope 2 {
- debug v1 => _12; // in scope 2 at $DIR/issue_76432.rs:+3:10: +3:16
- debug v2 => _13; // in scope 2 at $DIR/issue_76432.rs:+3:18: +3:24
- debug v3 => _14; // in scope 2 at $DIR/issue_76432.rs:+3:26: +3:32
+ debug v1 => &(*_2)[0 of 3]; // in scope 2 at $DIR/issue_76432.rs:+3:10: +3:16
+ debug v2 => &(*_2)[1 of 3]; // in scope 2 at $DIR/issue_76432.rs:+3:18: +3:24
+ debug v3 => &(*_2)[2 of 3]; // in scope 2 at $DIR/issue_76432.rs:+3:26: +3:32
}
}
@@ -52,15 +52,6 @@
}
bb2: {
- StorageLive(_12); // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16
- _12 = &(*_2)[0 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16
- StorageLive(_13); // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24
- _13 = &(*_2)[1 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24
- StorageLive(_14); // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32
- _14 = &(*_2)[2 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32
- StorageDead(_14); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85
- StorageDead(_13); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85
- StorageDead(_12); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85
StorageDead(_5); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2
StorageDead(_2); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2
return; // scope 0 at $DIR/issue_76432.rs:+6:2: +6:2
diff --git a/tests/mir-opt/issue_99325.main.built.after.mir b/tests/mir-opt/issue_99325.main.built.after.mir
index f0c9ef419bd..0424ce3abeb 100644
--- a/tests/mir-opt/issue_99325.main.built.after.mir
+++ b/tests/mir-opt/issue_99325.main.built.after.mir
@@ -1,8 +1,8 @@
// MIR for `main` after built
| User Type Annotations
-| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::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 }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
-| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), substs: [] }) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)]) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated([], DefId(0:8 ~ issue_99325[22bb]::main::{constant#1})) }], user_self_ty: None }), max_universe: U0, variables: [] }, 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/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff
index 0bfb34acac2..217f27efe5c 100644
--- a/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff
+++ b/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff
@@ -30,10 +30,10 @@
_4 = _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46
StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49
_5 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49
-- _3 = wrapping_add::<i32>(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
+- _3 = std::intrinsics::wrapping_add::<i32>(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
- // mir::Constant
- // + 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>) }
+- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {std::intrinsics::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
}
@@ -46,10 +46,10 @@
_7 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+2:45: +2:46
StorageLive(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:48: +2:49
_8 = _2; // scope 1 at $DIR/lower_intrinsics.rs:+2:48: +2:49
-- _6 = wrapping_sub::<i32>(move _7, move _8) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
+- _6 = std::intrinsics::wrapping_sub::<i32>(move _7, move _8) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
- // mir::Constant
- // + 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>) }
+- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {std::intrinsics::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
}
diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
index 71bdfcc5c49..c425f3cd506 100644
--- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
+++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
@@ -22,7 +22,7 @@
|
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11
- let mut _1: [usize; Const(Value(Leaf(0x00000003)): usize)]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14
+ let mut _1: [usize; Const { ty: usize, kind: Leaf(0x00000003) }]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14
let _3: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:16: +2:17
let mut _4: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
let mut _5: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
index 9fa8609b751..22ad24f8d77 100644
--- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
+++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
@@ -22,7 +22,7 @@
|
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11
- let mut _1: [usize; Const(Value(Leaf(0x0000000000000003)): usize)]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14
+ let mut _1: [usize; Const { ty: usize, kind: Leaf(0x0000000000000003) }]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14
let _3: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:16: +2:17
let mut _4: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
let mut _5: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
diff --git a/tests/mir-opt/nrvo_miscompile_111005.rs b/tests/mir-opt/nrvo_miscompile_111005.rs
new file mode 100644
index 00000000000..a9f391b79d5
--- /dev/null
+++ b/tests/mir-opt/nrvo_miscompile_111005.rs
@@ -0,0 +1,22 @@
+// This is a miscompilation, #111005 to track
+
+// unit-test: RenameReturnPlace
+
+#![feature(custom_mir, core_intrinsics)]
+extern crate core;
+use core::intrinsics::mir::*;
+
+// EMIT_MIR nrvo_miscompile_111005.wrong.RenameReturnPlace.diff
+#[custom_mir(dialect = "runtime", phase = "initial")]
+pub fn wrong(arg: char) -> char {
+ mir!({
+ let temp = arg;
+ RET = temp;
+ temp = 'b';
+ Return()
+ })
+}
+
+fn main() {
+ assert_eq!(wrong('a'), 'a');
+}
diff --git a/tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff b/tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff
new file mode 100644
index 00000000000..a0acb6e7e11
--- /dev/null
+++ b/tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff
@@ -0,0 +1,18 @@
+- // MIR for `wrong` before RenameReturnPlace
++ // MIR for `wrong` after RenameReturnPlace
+
+ fn wrong(_1: char) -> char {
+- let mut _0: char; // return place in scope 0 at $DIR/nrvo_miscompile_111005.rs:+0:28: +0:32
++ let mut _0: char; // return place in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _2: char; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+- _2 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+- _0 = _2; // scope 0 at $DIR/nrvo_miscompile_111005.rs:+3:9: +3:19
+- _2 = const 'b'; // scope 0 at $DIR/nrvo_miscompile_111005.rs:+4:9: +4:19
++ _0 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
++ _0 = const 'b'; // scope 0 at $DIR/nrvo_miscompile_111005.rs:+4:9: +4:19
+ return; // scope 0 at $DIR/nrvo_miscompile_111005.rs:+5:9: +5:17
+ }
+ }
+
diff --git a/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir
index 2b4971e2ef9..1d23871029d 100644
--- a/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir
@@ -3,7 +3,7 @@
fn manual_replace(_1: &mut u32, _2: u32) -> u32 {
debug r => _1; // in scope 0 at $DIR/mem_replace.rs:+0:23: +0:24
debug v => _2; // in scope 0 at $DIR/mem_replace.rs:+0:36: +0:37
- let mut _0: u32; // return place in scope 0 at $DIR/mem_replace.rs:+1:9: +1:13
+ let mut _0: u32; // return place in scope 0 at $DIR/mem_replace.rs:+0:47: +0:50
scope 1 {
debug temp => _0; // in scope 1 at $DIR/mem_replace.rs:+1:9: +1:13
}
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir
index ea0a44cf3bf..7a10b929ebd 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir
@@ -3,7 +3,7 @@
fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> &mut [u32] {
debug slice => _1; // in scope 0 at $DIR/slice_index.rs:+0:45: +0:50
debug index => _2; // in scope 0 at $DIR/slice_index.rs:+0:64: +0:69
- let mut _0: &mut [u32]; // return place in scope 0 at $DIR/slice_index.rs:+1:5: +1:35
+ let mut _0: &mut [u32]; // return place in scope 0 at $DIR/slice_index.rs:+0:88: +0:98
scope 1 (inlined core::slice::<impl [u32]>::get_unchecked_mut::<std::ops::Range<usize>>) { // at $DIR/slice_index.rs:26:11: 26:35
debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
debug index => _2; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir
index 35dd973b55f..dcf79a4a4e7 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir
@@ -3,15 +3,15 @@
fn slice_index_range(_1: &[u32], _2: std::ops::Range<usize>) -> &[u32] {
debug slice => _1; // in scope 0 at $DIR/slice_index.rs:+0:26: +0:31
debug index => _2; // in scope 0 at $DIR/slice_index.rs:+0:41: +0:46
- let mut _0: &[u32]; // return place in scope 0 at $DIR/slice_index.rs:+1:5: +1:18
- let _3: &[u32]; // in scope 0 at $DIR/slice_index.rs:+1:6: +1:18
+ let mut _0: &[u32]; // return place in scope 0 at $DIR/slice_index.rs:+0:65: +0:71
scope 1 (inlined #[track_caller] core::slice::index::<impl Index<std::ops::Range<usize>> for [u32]>::index) { // at $DIR/slice_index.rs:21:6: 21:18
debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL
debug index => _2; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+ let _3: &[u32]; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/slice_index.rs:+1:6: +1:18
+ StorageLive(_3); // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL
_3 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, _1) -> bb1; // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/slice/index.rs:LL:COL
@@ -19,8 +19,8 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range<usize>) -> &[u32] {
}
bb1: {
- _0 = _3; // scope 0 at $DIR/slice_index.rs:+1:5: +1:18
- StorageDead(_3); // scope 0 at $DIR/slice_index.rs:+2:1: +2:2
+ _0 = _3; // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+ StorageDead(_3); // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL
return; // scope 0 at $DIR/slice_index.rs:+2:2: +2:2
}
}
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir
index f27525bf3d9..0da7e5536ae 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir
@@ -6,58 +6,120 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
let mut _0: (); // return place in scope 0 at $DIR/slice_iter.rs:+0:60: +0:60
let mut _3: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
let mut _4: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
- let mut _5: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
- let _6: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
- let mut _7: std::option::Option<&T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
- let mut _8: &mut std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
- let mut _9: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6
- let mut _11: &impl Fn(&T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10
- let mut _12: (&T,); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:13
+ let _5: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
+ let mut _6: std::option::Option<&T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
+ let mut _7: &mut std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
+ let mut _8: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6
+ let mut _10: &impl Fn(&T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10
+ let mut _11: (&T,); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:13
scope 1 {
- debug iter => _5; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
- let _10: &T; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10
+ debug iter => _4; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
+ let _9: &T; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10
scope 2 {
- debug x => _10; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10
+ debug x => _9; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10
}
}
scope 3 (inlined core::slice::<impl [T]>::iter) { // at $DIR/slice_iter.rs:28:20: 28:26
debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ scope 4 (inlined std::slice::Iter::<'_, T>::new) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ debug slice => _1; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let _12: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let mut _14: bool; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let mut _15: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let mut _16: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let mut _17: std::ptr::NonNull<T>; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let mut _18: *mut T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let mut _19: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ scope 5 {
+ debug ptr => _12; // in scope 5 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ scope 6 {
+ let _13: *const T; // in scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ scope 7 {
+ debug end => _13; // in scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ scope 13 (inlined NonNull::<T>::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ debug ptr => _18; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
+ let mut _21: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
+ let mut _22: *mut T; // in scope 13 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+ scope 14 {
+ scope 15 (inlined NonNull::<T>::new_unchecked::runtime::<T>) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+ debug ptr => _22; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+ scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
+ debug self => _22; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ let mut _23: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ scope 17 {
+ scope 18 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ debug ptr => _23; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ debug self => _23; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ scope 20 {
+ scope 21 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ debug self => _23; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ scope 9 (inlined invalid::<T>) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ debug addr => _15; // in scope 9 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ scope 10 {
+ }
+ }
+ scope 11 (inlined ptr::const_ptr::<impl *const T>::add) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ debug self => _12; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ debug count => _16; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ scope 12 {
+ }
+ }
+ }
+ }
+ scope 8 (inlined core::slice::<impl [T]>::as_ptr) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ debug self => _1; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ let mut _20: *const [T]; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ }
+ }
}
- scope 4 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:28:14: 28:26
- debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ scope 22 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:28:14: 28:26
+ debug self => _3; // in scope 22 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
- StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
- _4 = std::slice::Iter::<'_, T>::new(_1) -> [return: bb10, unwind: bb8]; // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
- // mir::Constant
- // + span: $SRC_DIR/core/src/slice/mod.rs:LL:COL
- // + user_ty: UserType(0)
- // + literal: Const { ty: fn(&[T]) -> std::slice::Iter<'_, T> {std::slice::Iter::<'_, T>::new}, val: Value(<ZST>) }
+ StorageLive(_12); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ StorageLive(_20); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ _20 = &raw const (*_1); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ _12 = move _20 as *const T (PtrToPtr); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ StorageDead(_20); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ StorageLive(_13); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_14); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _14 = const _; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ switchInt(move _14) -> [0: bb11, otherwise: bb10]; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
}
bb1: {
- StorageLive(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
- _8 = &mut _5; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
- _7 = <std::slice::Iter<'_, T> as Iterator>::next(_8) -> [return: bb2, unwind: bb8]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
+ StorageLive(_6); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
+ _7 = &mut _4; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
+ _6 = <std::slice::Iter<'_, T> as Iterator>::next(_7) -> [return: bb2, unwind: bb8]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
// mir::Constant
// + span: $DIR/slice_iter.rs:28:14: 28:26
// + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option<<std::slice::Iter<'_, T> as Iterator>::Item> {<std::slice::Iter<'_, T> as Iterator>::next}, val: Value(<ZST>) }
}
bb2: {
- _9 = discriminant(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
- switchInt(move _9) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
+ _8 = discriminant(_6); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
+ switchInt(move _8) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
}
bb3: {
- _10 = ((_7 as Some).0: &T); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10
- StorageLive(_11); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10
- _11 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10
- StorageLive(_12); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13
- _12 = (_10,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13
- _6 = <impl Fn(&T) as Fn<(&T,)>>::call(move _11, move _12) -> [return: bb6, unwind: bb8]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13
+ _9 = ((_6 as Some).0: &T); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10
+ StorageLive(_10); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10
+ _10 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10
+ StorageLive(_11); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13
+ _11 = (_9,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13
+ _5 = <impl Fn(&T) as Fn<(&T,)>>::call(move _10, move _11) -> [return: bb6, unwind: bb8]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13
// mir::Constant
// + span: $DIR/slice_iter.rs:29:9: 29:10
// + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(&T), (&T,)) -> <impl Fn(&T) as FnOnce<(&T,)>>::Output {<impl Fn(&T) as Fn<(&T,)>>::call}, val: Value(<ZST>) }
@@ -68,16 +130,15 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb5: {
- StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6
- StorageDead(_5); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6
- StorageDead(_3); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6
+ StorageDead(_6); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6
+ StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6
drop(_2) -> bb7; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2
}
bb6: {
- StorageDead(_12); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13
StorageDead(_11); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13
- StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6
+ StorageDead(_10); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13
+ StorageDead(_6); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6
goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6
}
@@ -94,10 +155,49 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb10: {
- _3 = move _4; // scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
- StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+1:25: +1:26
- StorageLive(_5); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
- _5 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
+ StorageLive(_15); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _15 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _13 = _15 as *const T (Transmute); // scope 10 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ StorageDead(_15); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ goto -> bb12; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ }
+
+ bb11: {
+ StorageLive(_16); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _16 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _13 = Offset(_12, _16); // scope 12 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ StorageDead(_16); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ goto -> bb12; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ }
+
+ bb12: {
+ StorageDead(_14); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_17); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_18); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _18 = _12 as *mut T (PtrToPtr); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_21); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _21 = _18 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
+ _17 = NonNull::<T> { pointer: _21 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
+ StorageDead(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageDead(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageDead(_21); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageDead(_18); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_19); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _19 = _13; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _3 = std::slice::Iter::<'_, T> { ptr: move _17, end: move _19, _marker: const ZeroSized: PhantomData<&T> }; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ // mir::Constant
+ // + span: no-location
+ // + literal: Const { ty: PhantomData<&T>, val: Value(<ZST>) }
+ // adt
+ // + user_ty: UserType(1)
+ StorageDead(_19); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageDead(_17); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageDead(_13); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageDead(_12); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
+ _4 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6
}
}
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir
index 62dd9667d96..45b41b54c8b 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir
@@ -19,39 +19,104 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
scope 2 {
debug x => _10; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10
}
- scope 7 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) { // at $DIR/slice_iter.rs:35:14: 35:32
- debug self => _8; // in scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
- let mut _13: &mut std::slice::Iter<'_, T>; // in scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
+ scope 25 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) { // at $DIR/slice_iter.rs:35:14: 35:32
+ debug self => _8; // in scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
+ let mut _25: &mut std::slice::Iter<'_, T>; // in scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
}
}
scope 3 (inlined core::slice::<impl [T]>::iter) { // at $DIR/slice_iter.rs:35:20: 35:26
debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ scope 4 (inlined std::slice::Iter::<'_, T>::new) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ debug slice => _1; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let _13: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let mut _15: bool; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let mut _16: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let mut _17: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let mut _18: std::ptr::NonNull<T>; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let mut _19: *mut T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ let mut _20: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ scope 5 {
+ debug ptr => _13; // in scope 5 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ scope 6 {
+ let _14: *const T; // in scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ scope 7 {
+ debug end => _14; // in scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ scope 13 (inlined NonNull::<T>::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ debug ptr => _19; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
+ let mut _22: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
+ let mut _23: *mut T; // in scope 13 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+ scope 14 {
+ scope 15 (inlined NonNull::<T>::new_unchecked::runtime::<T>) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+ debug ptr => _23; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+ scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
+ debug self => _23; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ let mut _24: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ scope 17 {
+ scope 18 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ debug ptr => _24; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ debug self => _24; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ scope 20 {
+ scope 21 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ debug self => _24; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ scope 9 (inlined invalid::<T>) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ debug addr => _16; // in scope 9 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ scope 10 {
+ }
+ }
+ scope 11 (inlined ptr::const_ptr::<impl *const T>::add) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ debug self => _13; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ debug count => _17; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ scope 12 {
+ }
+ }
+ }
+ }
+ scope 8 (inlined core::slice::<impl [T]>::as_ptr) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ debug self => _1; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ let mut _21: *const [T]; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ }
+ }
}
- scope 4 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) { // at $DIR/slice_iter.rs:35:27: 35:32
- debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
- scope 5 (inlined Rev::<std::slice::Iter<'_, T>>::new) { // at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
- debug iter => _4; // in scope 5 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
+ scope 22 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) { // at $DIR/slice_iter.rs:35:27: 35:32
+ debug self => _4; // in scope 22 at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ scope 23 (inlined Rev::<std::slice::Iter<'_, T>>::new) { // at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ debug iter => _4; // in scope 23 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
}
}
- scope 6 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:35:14: 35:32
- debug self => _3; // in scope 6 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ scope 24 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:35:14: 35:32
+ debug self => _3; // in scope 24 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
}
bb0: {
StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
- _4 = std::slice::Iter::<'_, T>::new(_1) -> [return: bb9, unwind: bb7]; // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
- // mir::Constant
- // + span: $SRC_DIR/core/src/slice/mod.rs:LL:COL
- // + user_ty: UserType(0)
- // + literal: Const { ty: fn(&[T]) -> std::slice::Iter<'_, T> {std::slice::Iter::<'_, T>::new}, val: Value(<ZST>) }
+ StorageLive(_13); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ StorageLive(_21); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ _21 = &raw const (*_1); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ _13 = move _21 as *const T (PtrToPtr); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ StorageDead(_21); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ StorageLive(_14); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_15); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _15 = const _; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ switchInt(move _15) -> [0: bb10, otherwise: bb9]; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
}
bb1: {
StorageLive(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32
_8 = &mut _5; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32
- StorageLive(_13); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
- _13 = &mut ((*_8).0: std::slice::Iter<'_, T>); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
- _7 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _13) -> [return: bb10, unwind: bb7]; // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
+ StorageLive(_25); // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
+ _25 = &mut ((*_8).0: std::slice::Iter<'_, T>); // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
+ _7 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _25) -> [return: bb12, unwind: bb7]; // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
// + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option<<std::slice::Iter<'_, T> as Iterator>::Item> {<std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back}, val: Value(<ZST>) }
@@ -99,15 +164,56 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb9: {
- _3 = Rev::<std::slice::Iter<'_, T>> { iter: move _4 }; // scope 5 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
+ StorageLive(_16); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _16 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _14 = _16 as *const T (Transmute); // scope 10 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ StorageDead(_16); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ goto -> bb11; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ }
+
+ bb10: {
+ StorageLive(_17); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _17 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _14 = Offset(_13, _17); // scope 12 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ StorageDead(_17); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ goto -> bb11; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ }
+
+ bb11: {
+ StorageDead(_15); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_18); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_19); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _19 = _13 as *mut T (PtrToPtr); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_24); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _22 = _19 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
+ _18 = NonNull::<T> { pointer: _22 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
+ StorageDead(_24); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageDead(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageDead(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageDead(_19); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageLive(_20); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _20 = _14; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ _4 = std::slice::Iter::<'_, T> { ptr: move _18, end: move _20, _marker: const ZeroSized: PhantomData<&T> }; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ // mir::Constant
+ // + span: no-location
+ // + literal: Const { ty: PhantomData<&T>, val: Value(<ZST>) }
+ // adt
+ // + user_ty: UserType(1)
+ StorageDead(_20); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageDead(_18); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageDead(_14); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
+ StorageDead(_13); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+ _3 = Rev::<std::slice::Iter<'_, T>> { iter: move _4 }; // scope 23 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+1:31: +1:32
StorageLive(_5); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:32
_5 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:32
goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6
}
- bb10: {
- StorageDead(_13); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
+ bb12: {
+ StorageDead(_25); // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
_9 = discriminant(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32
switchInt(move _9) -> [0: bb4, 1: bb2, otherwise: bb3]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32
}
diff --git a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
new file mode 100644
index 00000000000..07bd48fc846
--- /dev/null
+++ b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
@@ -0,0 +1,175 @@
+- // MIR for `debuginfo` before ReferencePropagation
++ // MIR for `debuginfo` after ReferencePropagation
+
+ fn debuginfo() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:16: +0:16
+ let _1: &mut u8; // in scope 0 at $DIR/reference_prop.rs:+3:9: +3:19
+ let mut _2: u8; // in scope 0 at $DIR/reference_prop.rs:+3:27: +3:31
+ let _4: debuginfo::T; // in scope 0 at $DIR/reference_prop.rs:+4:18: +4:22
+ let _6: (); // in scope 0 at $DIR/reference_prop.rs:+9:5: +12:6
+ let mut _7: std::option::Option<i32>; // in scope 0 at $DIR/reference_prop.rs:+9:11: +9:18
+ let mut _8: isize; // in scope 0 at $DIR/reference_prop.rs:+10:9: +10:13
+ let _10: (); // in scope 0 at $DIR/reference_prop.rs:+16:5: +17:6
+ let mut _11: &[i32]; // in scope 0 at $DIR/reference_prop.rs:+16:82: +16:94
+ let _12: &[i32]; // in scope 0 at $DIR/reference_prop.rs:+16:83: +16:94
+ let mut _13: &[i32; 10]; // in scope 0 at $DIR/reference_prop.rs:+16:83: +16:90
+ let _14: [i32; 10]; // in scope 0 at $DIR/reference_prop.rs:+16:83: +16:90
+ let mut _15: std::ops::RangeFull; // in scope 0 at $DIR/reference_prop.rs:+16:91: +16:93
+ let mut _16: usize; // in scope 0 at $DIR/reference_prop.rs:+16:12: +16:79
+ let mut _17: usize; // in scope 0 at $DIR/reference_prop.rs:+16:12: +16:79
+ let mut _18: bool; // in scope 0 at $DIR/reference_prop.rs:+16:12: +16:79
+ let _23: &&mut u8; // in scope 0 at $DIR/reference_prop.rs:+19:28: +19:40
+ let _24: &mut u8; // in scope 0 at $DIR/reference_prop.rs:+19:29: +19:40
+ let mut _25: debuginfo::T; // in scope 0 at $DIR/reference_prop.rs:+19:34: +19:38
+ scope 1 {
+- debug ref_mut_u8 => _1; // in scope 1 at $DIR/reference_prop.rs:+3:9: +3:19
++ debug ref_mut_u8 => &_2; // in scope 1 at $DIR/reference_prop.rs:+3:9: +3:19
+ let _3: &u8; // in scope 1 at $DIR/reference_prop.rs:+4:9: +4:14
+ let mut _28: &debuginfo::T; // in scope 1 at $DIR/reference_prop.rs:+4:17: +4:24
+ scope 2 {
+- debug field => _3; // in scope 2 at $DIR/reference_prop.rs:+4:9: +4:14
++ debug field => &((*_28).0: u8); // in scope 2 at $DIR/reference_prop.rs:+4:9: +4:14
+ let _5: &u8; // in scope 2 at $DIR/reference_prop.rs:+7:9: +7:17
+ scope 3 {
+- debug reborrow => _5; // in scope 3 at $DIR/reference_prop.rs:+7:9: +7:17
++ debug reborrow => &_2; // in scope 3 at $DIR/reference_prop.rs:+7:9: +7:17
+ let _9: &i32; // in scope 3 at $DIR/reference_prop.rs:+11:14: +11:31
+ let _22: &&&mut u8; // in scope 3 at $DIR/reference_prop.rs:+19:9: +19:24
+ let mut _27: &std::option::Option<i32>; // in scope 3 at $DIR/reference_prop.rs:+11:14: +11:31
+ scope 4 {
+- debug variant_field => _9; // in scope 4 at $DIR/reference_prop.rs:+11:14: +11:31
++ debug variant_field => &(((*_27) as Some).0: i32); // in scope 4 at $DIR/reference_prop.rs:+11:14: +11:31
+ }
+ scope 5 {
+- debug constant_index => _19; // in scope 5 at $DIR/reference_prop.rs:+16:16: +16:34
++ debug constant_index => &(*_11)[1 of 3]; // in scope 5 at $DIR/reference_prop.rs:+16:16: +16:34
+ debug subslice => _20; // in scope 5 at $DIR/reference_prop.rs:+16:36: +16:44
+ debug constant_index_from_end => _21; // in scope 5 at $DIR/reference_prop.rs:+16:51: +16:78
+ let _19: &i32; // in scope 5 at $DIR/reference_prop.rs:+16:16: +16:34
+ let _20: &[i32]; // in scope 5 at $DIR/reference_prop.rs:+16:36: +16:44
+ let _21: &i32; // in scope 5 at $DIR/reference_prop.rs:+16:51: +16:78
+ let mut _26: &[i32; 10]; // in scope 5 at $DIR/reference_prop.rs:+16:83: +16:90
+ }
+ scope 6 {
+- debug multiple_borrow => _22; // in scope 6 at $DIR/reference_prop.rs:+19:9: +19:24
++ debug multiple_borrow => &&&(_25.0: u8); // in scope 6 at $DIR/reference_prop.rs:+19:9: +19:24
+ }
+ }
+ }
+ }
+
+ bb0: {
+- StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+3:9: +3:19
+ StorageLive(_2); // scope 0 at $DIR/reference_prop.rs:+3:27: +3:31
+ _2 = const 5_u8; // scope 0 at $DIR/reference_prop.rs:+3:27: +3:31
+- _1 = &mut _2; // scope 0 at $DIR/reference_prop.rs:+3:22: +3:31
+- StorageLive(_3); // scope 1 at $DIR/reference_prop.rs:+4:9: +4:14
+ _28 = const _; // scope 1 at $DIR/reference_prop.rs:+4:17: +4:24
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:535:17: 535:24
+ // + literal: Const { ty: &T, val: Unevaluated(debuginfo, [], Some(promoted[2])) }
+- _3 = &((*_28).0: u8); // scope 1 at $DIR/reference_prop.rs:+4:17: +4:24
+- StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+7:9: +7:17
+- _5 = &(*_1); // scope 2 at $DIR/reference_prop.rs:+7:20: +7:32
+- StorageLive(_6); // scope 3 at $DIR/reference_prop.rs:+9:5: +12:6
+ StorageLive(_7); // scope 3 at $DIR/reference_prop.rs:+9:11: +9:18
+ _7 = Option::<i32>::Some(const 0_i32); // scope 3 at $DIR/reference_prop.rs:+9:11: +9:18
+ _8 = discriminant(_7); // scope 3 at $DIR/reference_prop.rs:+9:11: +9:18
+ switchInt(move _8) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 3 at $DIR/reference_prop.rs:+9:5: +9:18
+ }
+
+ bb1: {
+- StorageLive(_9); // scope 3 at $DIR/reference_prop.rs:+11:14: +11:31
+ _27 = const _; // scope 3 at $DIR/reference_prop.rs:+11:14: +11:31
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:542:14: 542:31
+ // + literal: Const { ty: &Option<i32>, val: Unevaluated(debuginfo, [], Some(promoted[1])) }
+- _9 = &(((*_27) as Some).0: i32); // scope 3 at $DIR/reference_prop.rs:+11:14: +11:31
+- _6 = const (); // scope 4 at $DIR/reference_prop.rs:+11:36: +11:38
+- StorageDead(_9); // scope 3 at $DIR/reference_prop.rs:+11:37: +11:38
+ goto -> bb4; // scope 3 at $DIR/reference_prop.rs:+11:37: +11:38
+ }
+
+ bb2: {
+ unreachable; // scope 3 at $DIR/reference_prop.rs:+9:11: +9:18
+ }
+
+ bb3: {
+- _6 = const (); // scope 3 at $DIR/reference_prop.rs:+10:17: +10:19
+ goto -> bb4; // scope 3 at $DIR/reference_prop.rs:+10:17: +10:19
+ }
+
+ bb4: {
+ StorageDead(_7); // scope 3 at $DIR/reference_prop.rs:+12:5: +12:6
+- StorageDead(_6); // scope 3 at $DIR/reference_prop.rs:+12:5: +12:6
+- StorageLive(_10); // scope 3 at $DIR/reference_prop.rs:+16:5: +17:6
+ StorageLive(_11); // scope 5 at $DIR/reference_prop.rs:+16:82: +16:94
+ StorageLive(_12); // scope 5 at $DIR/reference_prop.rs:+16:83: +16:94
+ StorageLive(_13); // scope 5 at $DIR/reference_prop.rs:+16:83: +16:90
+ _26 = const _; // scope 5 at $DIR/reference_prop.rs:+16:83: +16:90
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:547:83: 547:90
+ // + literal: Const { ty: &[i32; 10], val: Unevaluated(debuginfo, [], Some(promoted[0])) }
+ _13 = &(*_26); // scope 5 at $DIR/reference_prop.rs:+16:83: +16:90
+ StorageLive(_15); // scope 5 at $DIR/reference_prop.rs:+16:91: +16:93
+ _15 = RangeFull; // scope 5 at $DIR/reference_prop.rs:+16:91: +16:93
+ _12 = <[i32; 10] as Index<RangeFull>>::index(move _13, move _15) -> bb5; // scope 5 at $DIR/reference_prop.rs:+16:83: +16:94
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:547:83: 547:94
+ // + literal: Const { ty: for<'a> fn(&'a [i32; 10], RangeFull) -> &'a <[i32; 10] as Index<RangeFull>>::Output {<[i32; 10] as Index<RangeFull>>::index}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ StorageDead(_15); // scope 5 at $DIR/reference_prop.rs:+16:93: +16:94
+ StorageDead(_13); // scope 5 at $DIR/reference_prop.rs:+16:93: +16:94
+ _11 = &(*_12); // scope 5 at $DIR/reference_prop.rs:+16:82: +16:94
+ _16 = Len((*_11)); // scope 5 at $DIR/reference_prop.rs:+16:12: +16:79
+ _17 = const 3_usize; // scope 5 at $DIR/reference_prop.rs:+16:12: +16:79
+ _18 = Ge(move _16, move _17); // scope 5 at $DIR/reference_prop.rs:+16:12: +16:79
+ switchInt(move _18) -> [0: bb7, otherwise: bb6]; // scope 5 at $DIR/reference_prop.rs:+16:12: +16:79
+ }
+
+ bb6: {
+- StorageLive(_19); // scope 5 at $DIR/reference_prop.rs:+16:16: +16:34
+- _19 = &(*_11)[1 of 3]; // scope 5 at $DIR/reference_prop.rs:+16:16: +16:34
+ StorageLive(_20); // scope 5 at $DIR/reference_prop.rs:+16:36: +16:44
+ _20 = &(*_11)[2:-1]; // scope 5 at $DIR/reference_prop.rs:+16:36: +16:44
+ StorageLive(_21); // scope 5 at $DIR/reference_prop.rs:+16:51: +16:78
+ _21 = &(*_11)[-1 of 3]; // scope 5 at $DIR/reference_prop.rs:+16:51: +16:78
+- _10 = const (); // scope 5 at $DIR/reference_prop.rs:+16:95: +17:6
+ StorageDead(_21); // scope 3 at $DIR/reference_prop.rs:+17:5: +17:6
+ StorageDead(_20); // scope 3 at $DIR/reference_prop.rs:+17:5: +17:6
+- StorageDead(_19); // scope 3 at $DIR/reference_prop.rs:+17:5: +17:6
+ goto -> bb8; // scope 3 at $DIR/reference_prop.rs:+16:5: +17:6
+ }
+
+ bb7: {
+- _10 = const (); // scope 3 at $DIR/reference_prop.rs:+17:6: +17:6
+ goto -> bb8; // scope 3 at $DIR/reference_prop.rs:+16:5: +17:6
+ }
+
+ bb8: {
+ StorageDead(_12); // scope 3 at $DIR/reference_prop.rs:+17:5: +17:6
+ StorageDead(_11); // scope 3 at $DIR/reference_prop.rs:+17:5: +17:6
+- StorageDead(_10); // scope 3 at $DIR/reference_prop.rs:+17:5: +17:6
+- StorageLive(_22); // scope 3 at $DIR/reference_prop.rs:+19:9: +19:24
+- StorageLive(_23); // scope 3 at $DIR/reference_prop.rs:+19:28: +19:40
+- StorageLive(_24); // scope 3 at $DIR/reference_prop.rs:+19:29: +19:40
+ StorageLive(_25); // scope 3 at $DIR/reference_prop.rs:+19:34: +19:38
+ _25 = T(const 6_u8); // scope 3 at $DIR/reference_prop.rs:+19:34: +19:38
+- _24 = &mut (_25.0: u8); // scope 3 at $DIR/reference_prop.rs:+19:29: +19:40
+- _23 = &_24; // scope 3 at $DIR/reference_prop.rs:+19:28: +19:40
+- _22 = &_23; // scope 3 at $DIR/reference_prop.rs:+19:27: +19:40
+ _0 = const (); // scope 0 at $DIR/reference_prop.rs:+0:16: +20:2
+ StorageDead(_25); // scope 3 at $DIR/reference_prop.rs:+20:1: +20:2
+- StorageDead(_24); // scope 3 at $DIR/reference_prop.rs:+20:1: +20:2
+- StorageDead(_23); // scope 3 at $DIR/reference_prop.rs:+20:1: +20:2
+- StorageDead(_22); // scope 3 at $DIR/reference_prop.rs:+20:1: +20:2
+- StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+20:1: +20:2
+- StorageDead(_3); // scope 1 at $DIR/reference_prop.rs:+20:1: +20:2
+ StorageDead(_2); // scope 0 at $DIR/reference_prop.rs:+20:1: +20:2
+- StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+20:1: +20:2
+ return; // scope 0 at $DIR/reference_prop.rs:+20:2: +20:2
+ }
+ }
+
diff --git a/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff b/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff
new file mode 100644
index 00000000000..e158f64e9c3
--- /dev/null
+++ b/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff
@@ -0,0 +1,38 @@
+- // MIR for `dominate_storage` before ReferencePropagation
++ // MIR for `dominate_storage` after ReferencePropagation
+
+ fn dominate_storage() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:23: +0:23
+ let mut _1: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _2: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _4: bool; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _5: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _6: bool; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ goto -> bb1; // scope 0 at $DIR/reference_prop.rs:+8:11: +8:20
+ }
+
+ bb1: {
+ _1 = const 5_i32; // scope 0 at $DIR/reference_prop.rs:+10:13: +10:18
+ _2 = &_1; // scope 0 at $DIR/reference_prop.rs:+11:13: +11:19
+ goto -> bb2; // scope 0 at $DIR/reference_prop.rs:+12:13: +12:22
+ }
+
+ bb2: {
+ _5 = (*_2); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _0 = opaque::<i32>(_5) -> bb3; // scope 0 at $DIR/reference_prop.rs:+16:13: +16:38
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:455:28: 455:34
+ // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+19:13: +19:27
+ StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+20:13: +20:27
+ _6 = const true; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ switchInt(_6) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/reference_prop.rs:+22:13: +22:47
+ }
+ }
+
diff --git a/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff b/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff
new file mode 100644
index 00000000000..38ab16cedb7
--- /dev/null
+++ b/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff
@@ -0,0 +1,56 @@
+- // MIR for `maybe_dead` before ReferencePropagation
++ // MIR for `maybe_dead` after ReferencePropagation
+
+ fn maybe_dead(_1: bool) -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:24: +0:24
+ let mut _2: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _4: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _5: &mut i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _6: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _7: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _8: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/reference_prop.rs:+7:13: +7:27
+ StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+8:13: +8:27
+ _2 = const 5_i32; // scope 0 at $DIR/reference_prop.rs:+9:13: +9:18
+ _3 = const 5_i32; // scope 0 at $DIR/reference_prop.rs:+10:13: +10:18
+ _4 = &_2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _5 = &mut _3; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ (*_5) = const 7_i32; // scope 0 at $DIR/reference_prop.rs:+14:13: +14:19
+- _6 = (*_4); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
++ _6 = _2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ switchInt(_1) -> [1: bb1, otherwise: bb2]; // scope 0 at $DIR/reference_prop.rs:+17:13: +17:46
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 0 at $DIR/reference_prop.rs:+20:13: +20:27
+ StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+21:13: +21:27
+ _0 = opaque::<i32>(_6) -> bb2; // scope 0 at $DIR/reference_prop.rs:+22:13: +22:38
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:489:28: 489:34
+ // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ _7 = (*_4); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _0 = opaque::<i32>(_7) -> bb3; // scope 0 at $DIR/reference_prop.rs:+27:13: +27:38
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:494:28: 494:34
+ // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ _8 = (*_5); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _0 = opaque::<i32>(_8) -> bb4; // scope 0 at $DIR/reference_prop.rs:+33:13: +33:43
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:500:33: 500:39
+ // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/reference_prop.rs:+36:13: +36:21
+ }
+ }
+
diff --git a/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff b/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff
new file mode 100644
index 00000000000..6e451786870
--- /dev/null
+++ b/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff
@@ -0,0 +1,27 @@
+- // MIR for `multiple_storage` before ReferencePropagation
++ // MIR for `multiple_storage` after ReferencePropagation
+
+ fn multiple_storage() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:23: +0:23
+ let mut _1: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _2: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+6:13: +6:27
+ _1 = const 5_i32; // scope 0 at $DIR/reference_prop.rs:+7:13: +7:18
+ _2 = &_1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+9:13: +9:27
+ StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+10:13: +10:27
+ _3 = (*_2); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _0 = opaque::<i32>(_3) -> bb1; // scope 0 at $DIR/reference_prop.rs:+14:13: +14:43
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:429:33: 429:39
+ // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ return; // scope 0 at $DIR/reference_prop.rs:+18:13: +18:21
+ }
+ }
+
diff --git a/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff
new file mode 100644
index 00000000000..d99e110359f
--- /dev/null
+++ b/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff
@@ -0,0 +1,75 @@
+- // MIR for `mut_raw_then_mut_shr` before ReferencePropagation
++ // MIR for `mut_raw_then_mut_shr` after ReferencePropagation
+
+ fn mut_raw_then_mut_shr() -> (i32, i32) {
+ let mut _0: (i32, i32); // return place in scope 0 at $DIR/reference_prop.rs:+0:30: +0:40
+ let mut _1: i32; // in scope 0 at $DIR/reference_prop.rs:+1:9: +1:14
+ let mut _4: *mut i32; // in scope 0 at $DIR/reference_prop.rs:+3:16: +3:36
+ let mut _5: &mut i32; // in scope 0 at $DIR/reference_prop.rs:+3:16: +3:26
+ let _8: (); // in scope 0 at $DIR/reference_prop.rs:+7:5: +7:26
+ let mut _9: i32; // in scope 0 at $DIR/reference_prop.rs:+8:6: +8:7
+ let mut _10: i32; // in scope 0 at $DIR/reference_prop.rs:+8:9: +8:10
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/reference_prop.rs:+1:9: +1:14
+ let _2: &mut i32; // in scope 1 at $DIR/reference_prop.rs:+2:9: +2:13
+ scope 2 {
+- debug xref => _2; // in scope 2 at $DIR/reference_prop.rs:+2:9: +2:13
++ debug xref => &_1; // in scope 2 at $DIR/reference_prop.rs:+2:9: +2:13
+ let _3: *mut i32; // in scope 2 at $DIR/reference_prop.rs:+3:9: +3:13
+ scope 3 {
+- debug xraw => _3; // in scope 3 at $DIR/reference_prop.rs:+3:9: +3:13
++ debug xraw => &_1; // in scope 3 at $DIR/reference_prop.rs:+3:9: +3:13
+ let _6: &i32; // in scope 3 at $DIR/reference_prop.rs:+4:9: +4:13
+ scope 4 {
+- debug xshr => _6; // in scope 4 at $DIR/reference_prop.rs:+4:9: +4:13
++ debug xshr => &_1; // in scope 4 at $DIR/reference_prop.rs:+4:9: +4:13
+ let _7: i32; // in scope 4 at $DIR/reference_prop.rs:+6:9: +6:10
+ scope 5 {
+ debug a => _7; // in scope 5 at $DIR/reference_prop.rs:+6:9: +6:10
+ scope 6 {
+ }
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+1:9: +1:14
+ _1 = const 2_i32; // scope 0 at $DIR/reference_prop.rs:+1:17: +1:18
+- StorageLive(_2); // scope 1 at $DIR/reference_prop.rs:+2:9: +2:13
+- _2 = &mut _1; // scope 1 at $DIR/reference_prop.rs:+2:16: +2:22
+- StorageLive(_3); // scope 2 at $DIR/reference_prop.rs:+3:9: +3:13
+- StorageLive(_4); // scope 2 at $DIR/reference_prop.rs:+3:16: +3:36
+- StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+3:16: +3:26
+- _5 = &mut (*_2); // scope 2 at $DIR/reference_prop.rs:+3:16: +3:26
+- _4 = &raw mut (*_5); // scope 2 at $DIR/reference_prop.rs:+3:16: +3:26
+- _3 = _4; // scope 2 at $DIR/reference_prop.rs:+3:16: +3:36
+- StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+3:36: +3:37
+- StorageDead(_4); // scope 2 at $DIR/reference_prop.rs:+3:36: +3:37
+- StorageLive(_6); // scope 3 at $DIR/reference_prop.rs:+4:9: +4:13
+- _6 = &(*_2); // scope 3 at $DIR/reference_prop.rs:+4:16: +4:22
+ StorageLive(_7); // scope 4 at $DIR/reference_prop.rs:+6:9: +6:10
+- _7 = (*_6); // scope 4 at $DIR/reference_prop.rs:+6:13: +6:18
+- StorageLive(_8); // scope 5 at $DIR/reference_prop.rs:+7:5: +7:26
+- (*_3) = const 4_i32; // scope 6 at $DIR/reference_prop.rs:+7:14: +7:23
+- _8 = const (); // scope 6 at $DIR/reference_prop.rs:+7:5: +7:26
+- StorageDead(_8); // scope 5 at $DIR/reference_prop.rs:+7:25: +7:26
++ _7 = _1; // scope 4 at $DIR/reference_prop.rs:+6:13: +6:18
++ _1 = const 4_i32; // scope 6 at $DIR/reference_prop.rs:+7:14: +7:23
+ StorageLive(_9); // scope 5 at $DIR/reference_prop.rs:+8:6: +8:7
+ _9 = _7; // scope 5 at $DIR/reference_prop.rs:+8:6: +8:7
+ StorageLive(_10); // scope 5 at $DIR/reference_prop.rs:+8:9: +8:10
+ _10 = _1; // scope 5 at $DIR/reference_prop.rs:+8:9: +8:10
+ _0 = (move _9, move _10); // scope 5 at $DIR/reference_prop.rs:+8:5: +8:11
+ StorageDead(_10); // scope 5 at $DIR/reference_prop.rs:+8:10: +8:11
+ StorageDead(_9); // scope 5 at $DIR/reference_prop.rs:+8:10: +8:11
+ StorageDead(_7); // scope 4 at $DIR/reference_prop.rs:+9:1: +9:2
+- StorageDead(_6); // scope 3 at $DIR/reference_prop.rs:+9:1: +9:2
+- StorageDead(_3); // scope 2 at $DIR/reference_prop.rs:+9:1: +9:2
+- StorageDead(_2); // scope 1 at $DIR/reference_prop.rs:+9:1: +9:2
+ StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+9:1: +9:2
+ return; // scope 0 at $DIR/reference_prop.rs:+9:2: +9:2
+ }
+ }
+
diff --git a/tests/mir-opt/reference_prop.read_through_raw.ReferencePropagation.diff b/tests/mir-opt/reference_prop.read_through_raw.ReferencePropagation.diff
new file mode 100644
index 00000000000..75c1f8f57cc
--- /dev/null
+++ b/tests/mir-opt/reference_prop.read_through_raw.ReferencePropagation.diff
@@ -0,0 +1,23 @@
+- // MIR for `read_through_raw` before ReferencePropagation
++ // MIR for `read_through_raw` after ReferencePropagation
+
+ fn read_through_raw(_1: &mut usize) -> usize {
+ let mut _0: usize; // return place in scope 0 at $DIR/reference_prop.rs:+0:39: +0:44
+ let mut _2: &mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _3: &mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _4: *mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _5: *mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+- _2 = &mut (*_1); // scope 0 at $DIR/reference_prop.rs:+10:13: +10:25
+- _3 = &mut (*_2); // scope 0 at $DIR/reference_prop.rs:+11:13: +11:26
+- _4 = &raw mut (*_2); // scope 0 at $DIR/reference_prop.rs:+12:13: +12:30
+- _5 = &raw mut (*_3); // scope 0 at $DIR/reference_prop.rs:+13:13: +13:30
+- _0 = (*_4); // scope 0 at $DIR/reference_prop.rs:+15:13: +15:22
+- _0 = (*_5); // scope 0 at $DIR/reference_prop.rs:+16:13: +16:22
++ _0 = (*_1); // scope 0 at $DIR/reference_prop.rs:+15:13: +15:22
++ _0 = (*_1); // scope 0 at $DIR/reference_prop.rs:+16:13: +16:22
+ return; // scope 0 at $DIR/reference_prop.rs:+17:13: +17:21
+ }
+ }
+
diff --git a/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff
new file mode 100644
index 00000000000..7b31ee695ce
--- /dev/null
+++ b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff
@@ -0,0 +1,475 @@
+- // MIR for `reference_propagation` before ReferencePropagation
++ // MIR for `reference_propagation` after ReferencePropagation
+
+ fn reference_propagation(_1: &T, _2: &T) -> () {
+ debug single => _1; // in scope 0 at $DIR/reference_prop.rs:+0:39: +0:45
+ debug multiple => _2; // in scope 0 at $DIR/reference_prop.rs:+0:54: +0:66
+ let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:75: +0:75
+ let _3: (); // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+ let _4: usize; // in scope 0 at $DIR/reference_prop.rs:+3:13: +3:14
+ let _7: (); // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19
+ let mut _8: (); // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18
+ let _9: (); // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+ let _10: usize; // in scope 0 at $DIR/reference_prop.rs:+11:13: +11:14
+ let mut _13: &usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:16
+ let _14: &usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:16
+ let _16: (); // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19
+ let mut _17: (); // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18
+ let _18: (); // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+ let _19: usize; // in scope 0 at $DIR/reference_prop.rs:+22:13: +22:14
+ let _23: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:18
+ let mut _24: &&usize; // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:17
+ let _25: (); // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+ let _26: usize; // in scope 0 at $DIR/reference_prop.rs:+31:13: +31:14
+ let _30: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:18
+ let mut _31: *mut &usize; // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:17
+ let _32: (); // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+ let _33: usize; // in scope 0 at $DIR/reference_prop.rs:+40:13: +40:14
+ let _36: (); // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18
+ let mut _37: &usize; // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17
+ let _38: (); // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+ let _39: usize; // in scope 0 at $DIR/reference_prop.rs:+48:13: +48:14
+ let _45: (); // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19
+ let mut _46: &usize; // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18
+ let _47: (); // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+ let _48: &T; // in scope 0 at $DIR/reference_prop.rs:+61:13: +61:14
+ let _50: (); // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19
+ let mut _51: (); // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18
+ let _52: (); // in scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+ let _53: &T; // in scope 0 at $DIR/reference_prop.rs:+68:13: +68:14
+ let mut _54: &T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:28
+ let _55: &T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:28
+ let _57: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19
+ let mut _58: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18
+ let _59: (); // in scope 0 at $DIR/reference_prop.rs:+75:5: +81:6
+ let _60: usize; // in scope 0 at $DIR/reference_prop.rs:+76:13: +76:14
+ let _64: (); // in scope 0 at $DIR/reference_prop.rs:+80:9: +80:19
+ let mut _65: (); // in scope 0 at $DIR/reference_prop.rs:+80:16: +80:18
+ let _66: usize; // in scope 0 at $DIR/reference_prop.rs:+85:13: +85:14
+ let _70: (); // in scope 0 at $DIR/reference_prop.rs:+89:9: +89:19
+ let mut _71: (); // in scope 0 at $DIR/reference_prop.rs:+89:16: +89:18
+ scope 1 {
+ debug a => _4; // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:14
+ let _5: &usize; // in scope 1 at $DIR/reference_prop.rs:+4:13: +4:14
+ scope 2 {
+- debug b => _5; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
++ debug b => &_4; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
+ let _6: usize; // in scope 2 at $DIR/reference_prop.rs:+5:13: +5:14
+ scope 3 {
+ debug c => _6; // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
+ }
+ }
+ }
+ scope 4 {
+ debug a => _10; // in scope 4 at $DIR/reference_prop.rs:+11:13: +11:14
+ let _11: usize; // in scope 4 at $DIR/reference_prop.rs:+12:13: +12:15
+ scope 5 {
+ debug a2 => _11; // in scope 5 at $DIR/reference_prop.rs:+12:13: +12:15
+ let mut _12: &usize; // in scope 5 at $DIR/reference_prop.rs:+13:13: +13:18
+ scope 6 {
+ debug b => _12; // in scope 6 at $DIR/reference_prop.rs:+13:13: +13:18
+ let _15: usize; // in scope 6 at $DIR/reference_prop.rs:+16:13: +16:14
+ scope 7 {
+ debug c => _15; // in scope 7 at $DIR/reference_prop.rs:+16:13: +16:14
+ }
+ }
+ }
+ }
+ scope 8 {
+ debug a => _19; // in scope 8 at $DIR/reference_prop.rs:+22:13: +22:14
+ let _20: &usize; // in scope 8 at $DIR/reference_prop.rs:+23:13: +23:14
+ scope 9 {
+ debug b => _20; // in scope 9 at $DIR/reference_prop.rs:+23:13: +23:14
+ let _21: &&usize; // in scope 9 at $DIR/reference_prop.rs:+24:13: +24:14
+ scope 10 {
+ debug d => _21; // in scope 10 at $DIR/reference_prop.rs:+24:13: +24:14
+ let _22: usize; // in scope 10 at $DIR/reference_prop.rs:+25:13: +25:14
+ scope 11 {
+ debug c => _22; // in scope 11 at $DIR/reference_prop.rs:+25:13: +25:14
+ }
+ }
+ }
+ }
+ scope 12 {
+ debug a => _26; // in scope 12 at $DIR/reference_prop.rs:+31:13: +31:14
+ let mut _27: &usize; // in scope 12 at $DIR/reference_prop.rs:+32:13: +32:18
+ scope 13 {
+ debug b => _27; // in scope 13 at $DIR/reference_prop.rs:+32:13: +32:18
+ let _28: *mut &usize; // in scope 13 at $DIR/reference_prop.rs:+33:13: +33:14
+ scope 14 {
+ debug d => _28; // in scope 14 at $DIR/reference_prop.rs:+33:13: +33:14
+ let _29: usize; // in scope 14 at $DIR/reference_prop.rs:+34:13: +34:14
+ scope 15 {
+ debug c => _29; // in scope 15 at $DIR/reference_prop.rs:+34:13: +34:14
+ }
+ }
+ }
+ }
+ scope 16 {
+ debug a => _33; // in scope 16 at $DIR/reference_prop.rs:+40:13: +40:14
+ let _34: &usize; // in scope 16 at $DIR/reference_prop.rs:+41:13: +41:14
+ scope 17 {
+ debug b => _34; // in scope 17 at $DIR/reference_prop.rs:+41:13: +41:14
+ let _35: usize; // in scope 17 at $DIR/reference_prop.rs:+42:13: +42:14
+ scope 18 {
+ debug c => _35; // in scope 18 at $DIR/reference_prop.rs:+42:13: +42:14
+ }
+ }
+ }
+ scope 19 {
+ debug a => _39; // in scope 19 at $DIR/reference_prop.rs:+48:13: +48:14
+ let _40: &usize; // in scope 19 at $DIR/reference_prop.rs:+49:13: +49:15
+ scope 20 {
+ debug b1 => _40; // in scope 20 at $DIR/reference_prop.rs:+49:13: +49:15
+ let _41: usize; // in scope 20 at $DIR/reference_prop.rs:+50:13: +50:14
+ scope 21 {
+ debug c => _41; // in scope 21 at $DIR/reference_prop.rs:+50:13: +50:14
+ let _42: &usize; // in scope 21 at $DIR/reference_prop.rs:+51:13: +51:15
+ scope 22 {
+ debug b2 => _42; // in scope 22 at $DIR/reference_prop.rs:+51:13: +51:15
+ let _43: usize; // in scope 22 at $DIR/reference_prop.rs:+52:13: +52:15
+ scope 23 {
+ debug c2 => _43; // in scope 23 at $DIR/reference_prop.rs:+52:13: +52:15
+ let _44: &usize; // in scope 23 at $DIR/reference_prop.rs:+53:13: +53:15
+ scope 24 {
+ debug b3 => _44; // in scope 24 at $DIR/reference_prop.rs:+53:13: +53:15
+ }
+ }
+ }
+ }
+ }
+ }
+ scope 25 {
+- debug a => _48; // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14
++ debug a => _1; // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14
+ let _49: T; // in scope 25 at $DIR/reference_prop.rs:+62:13: +62:14
+ scope 26 {
+ debug b => _49; // in scope 26 at $DIR/reference_prop.rs:+62:13: +62:14
+ }
+ }
+ scope 27 {
+ debug a => _53; // in scope 27 at $DIR/reference_prop.rs:+68:13: +68:14
+ let _56: T; // in scope 27 at $DIR/reference_prop.rs:+70:13: +70:14
+ scope 28 {
+ debug b => _56; // in scope 28 at $DIR/reference_prop.rs:+70:13: +70:14
+ }
+ }
+ scope 29 {
+ debug a => _60; // in scope 29 at $DIR/reference_prop.rs:+76:13: +76:14
+ let _61: &usize; // in scope 29 at $DIR/reference_prop.rs:+77:13: +77:14
+ scope 30 {
+- debug b => _61; // in scope 30 at $DIR/reference_prop.rs:+77:13: +77:14
++ debug b => &_60; // in scope 30 at $DIR/reference_prop.rs:+77:13: +77:14
+ let _62: &&usize; // in scope 30 at $DIR/reference_prop.rs:+78:13: +78:14
+ scope 31 {
+- debug d => _62; // in scope 31 at $DIR/reference_prop.rs:+78:13: +78:14
++ debug d => &&_60; // in scope 31 at $DIR/reference_prop.rs:+78:13: +78:14
+ let _63: usize; // in scope 31 at $DIR/reference_prop.rs:+79:13: +79:14
+ scope 32 {
+ debug c => _63; // in scope 32 at $DIR/reference_prop.rs:+79:13: +79:14
+ }
+ }
+ }
+ }
+ scope 33 {
+ debug a => _66; // in scope 33 at $DIR/reference_prop.rs:+85:13: +85:14
+ let mut _67: &usize; // in scope 33 at $DIR/reference_prop.rs:+86:13: +86:18
+ scope 34 {
+- debug b => _67; // in scope 34 at $DIR/reference_prop.rs:+86:13: +86:18
++ debug b => &_66; // in scope 34 at $DIR/reference_prop.rs:+86:13: +86:18
+ let _68: &mut &usize; // in scope 34 at $DIR/reference_prop.rs:+87:13: +87:14
+ scope 35 {
+- debug d => _68; // in scope 35 at $DIR/reference_prop.rs:+87:13: +87:14
++ debug d => &&_66; // in scope 35 at $DIR/reference_prop.rs:+87:13: +87:14
+ let _69: usize; // in scope 35 at $DIR/reference_prop.rs:+88:13: +88:14
+ scope 36 {
+ debug c => _69; // in scope 36 at $DIR/reference_prop.rs:+88:13: +88:14
+ }
+ }
+ }
+ }
+
+ bb0: {
+- StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+ StorageLive(_4); // scope 0 at $DIR/reference_prop.rs:+3:13: +3:14
+ _4 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+3:17: +3:24
+- StorageLive(_5); // scope 1 at $DIR/reference_prop.rs:+4:13: +4:14
+- _5 = &_4; // scope 1 at $DIR/reference_prop.rs:+4:17: +4:19
+ StorageLive(_6); // scope 2 at $DIR/reference_prop.rs:+5:13: +5:14
+- _6 = (*_5); // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19
++ _6 = _4; // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19
+ StorageLive(_7); // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19
+ StorageLive(_8); // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18
+ _8 = (); // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18
+ _7 = opaque::<()>(move _8) -> bb1; // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:16:9: 16:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_8); // scope 3 at $DIR/reference_prop.rs:+6:18: +6:19
+ StorageDead(_7); // scope 3 at $DIR/reference_prop.rs:+6:19: +6:20
+- _3 = const (); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+ StorageDead(_6); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
+- StorageDead(_5); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6
+ StorageDead(_4); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+- StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+- StorageLive(_9); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+ StorageLive(_10); // scope 0 at $DIR/reference_prop.rs:+11:13: +11:14
+ _10 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+11:17: +11:24
+ StorageLive(_11); // scope 4 at $DIR/reference_prop.rs:+12:13: +12:15
+ _11 = const 7_usize; // scope 4 at $DIR/reference_prop.rs:+12:18: +12:25
+ StorageLive(_12); // scope 5 at $DIR/reference_prop.rs:+13:13: +13:18
+ _12 = &_10; // scope 5 at $DIR/reference_prop.rs:+13:21: +13:23
+ StorageLive(_13); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
+- StorageLive(_14); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
+- _14 = &_11; // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
+- _13 = &(*_14); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
++ _13 = &_11; // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
+ _12 = move _13; // scope 6 at $DIR/reference_prop.rs:+14:9: +14:16
+ StorageDead(_13); // scope 6 at $DIR/reference_prop.rs:+14:15: +14:16
+- StorageDead(_14); // scope 6 at $DIR/reference_prop.rs:+14:16: +14:17
+ StorageLive(_15); // scope 6 at $DIR/reference_prop.rs:+16:13: +16:14
+ _15 = (*_12); // scope 6 at $DIR/reference_prop.rs:+16:17: +16:19
+ StorageLive(_16); // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19
+ StorageLive(_17); // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18
+ _17 = (); // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18
+ _16 = opaque::<()>(move _17) -> bb2; // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:27:9: 27:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_17); // scope 7 at $DIR/reference_prop.rs:+17:18: +17:19
+ StorageDead(_16); // scope 7 at $DIR/reference_prop.rs:+17:19: +17:20
+- _9 = const (); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+ StorageDead(_15); // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6
+ StorageDead(_12); // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6
+ StorageDead(_11); // scope 4 at $DIR/reference_prop.rs:+18:5: +18:6
+ StorageDead(_10); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
+- StorageDead(_9); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
+- StorageLive(_18); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+ StorageLive(_19); // scope 0 at $DIR/reference_prop.rs:+22:13: +22:14
+ _19 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+22:17: +22:24
+ StorageLive(_20); // scope 8 at $DIR/reference_prop.rs:+23:13: +23:14
+ _20 = &_19; // scope 8 at $DIR/reference_prop.rs:+23:17: +23:19
+ StorageLive(_21); // scope 9 at $DIR/reference_prop.rs:+24:13: +24:14
+ _21 = &_20; // scope 9 at $DIR/reference_prop.rs:+24:17: +24:19
+ StorageLive(_22); // scope 10 at $DIR/reference_prop.rs:+25:13: +25:14
+ _22 = (*_20); // scope 10 at $DIR/reference_prop.rs:+25:17: +25:19
+ StorageLive(_23); // scope 11 at $DIR/reference_prop.rs:+26:9: +26:18
+ StorageLive(_24); // scope 11 at $DIR/reference_prop.rs:+26:16: +26:17
+ _24 = _21; // scope 11 at $DIR/reference_prop.rs:+26:16: +26:17
+ _23 = opaque::<&&usize>(move _24) -> bb3; // scope 11 at $DIR/reference_prop.rs:+26:9: +26:18
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:36:9: 36:15
+ // + literal: Const { ty: fn(&&usize) {opaque::<&&usize>}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_24); // scope 11 at $DIR/reference_prop.rs:+26:17: +26:18
+ StorageDead(_23); // scope 11 at $DIR/reference_prop.rs:+26:18: +26:19
+- _18 = const (); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+ StorageDead(_22); // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6
+ StorageDead(_21); // scope 9 at $DIR/reference_prop.rs:+27:5: +27:6
+ StorageDead(_20); // scope 8 at $DIR/reference_prop.rs:+27:5: +27:6
+ StorageDead(_19); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
+- StorageDead(_18); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
+- StorageLive(_25); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+ StorageLive(_26); // scope 0 at $DIR/reference_prop.rs:+31:13: +31:14
+ _26 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+31:17: +31:24
+ StorageLive(_27); // scope 12 at $DIR/reference_prop.rs:+32:13: +32:18
+ _27 = &_26; // scope 12 at $DIR/reference_prop.rs:+32:21: +32:23
+ StorageLive(_28); // scope 13 at $DIR/reference_prop.rs:+33:13: +33:14
+ _28 = &raw mut _27; // scope 13 at $DIR/reference_prop.rs:+33:17: +33:27
+ StorageLive(_29); // scope 14 at $DIR/reference_prop.rs:+34:13: +34:14
+ _29 = (*_27); // scope 14 at $DIR/reference_prop.rs:+34:17: +34:19
+ StorageLive(_30); // scope 15 at $DIR/reference_prop.rs:+35:9: +35:18
+ StorageLive(_31); // scope 15 at $DIR/reference_prop.rs:+35:16: +35:17
+ _31 = _28; // scope 15 at $DIR/reference_prop.rs:+35:16: +35:17
+ _30 = opaque::<*mut &usize>(move _31) -> bb4; // scope 15 at $DIR/reference_prop.rs:+35:9: +35:18
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:45:9: 45:15
+ // + literal: Const { ty: fn(*mut &usize) {opaque::<*mut &usize>}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ StorageDead(_31); // scope 15 at $DIR/reference_prop.rs:+35:17: +35:18
+ StorageDead(_30); // scope 15 at $DIR/reference_prop.rs:+35:18: +35:19
+- _25 = const (); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+ StorageDead(_29); // scope 14 at $DIR/reference_prop.rs:+36:5: +36:6
+ StorageDead(_28); // scope 13 at $DIR/reference_prop.rs:+36:5: +36:6
+ StorageDead(_27); // scope 12 at $DIR/reference_prop.rs:+36:5: +36:6
+ StorageDead(_26); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
+- StorageDead(_25); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
+- StorageLive(_32); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+ StorageLive(_33); // scope 0 at $DIR/reference_prop.rs:+40:13: +40:14
+ _33 = const 7_usize; // scope 0 at $DIR/reference_prop.rs:+40:17: +40:24
+ StorageLive(_34); // scope 16 at $DIR/reference_prop.rs:+41:13: +41:14
+ _34 = &_33; // scope 16 at $DIR/reference_prop.rs:+41:17: +41:19
+ StorageLive(_35); // scope 17 at $DIR/reference_prop.rs:+42:13: +42:14
+- _35 = (*_34); // scope 17 at $DIR/reference_prop.rs:+42:17: +42:19
++ _35 = _33; // scope 17 at $DIR/reference_prop.rs:+42:17: +42:19
+ StorageLive(_36); // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18
+ StorageLive(_37); // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17
+ _37 = _34; // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17
+ _36 = opaque::<&usize>(move _37) -> bb5; // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:53:9: 53:15
+ // + literal: Const { ty: fn(&usize) {opaque::<&usize>}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ StorageDead(_37); // scope 18 at $DIR/reference_prop.rs:+43:17: +43:18
+ StorageDead(_36); // scope 18 at $DIR/reference_prop.rs:+43:18: +43:19
+- _32 = const (); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+ StorageDead(_35); // scope 17 at $DIR/reference_prop.rs:+44:5: +44:6
+ StorageDead(_34); // scope 16 at $DIR/reference_prop.rs:+44:5: +44:6
+ StorageDead(_33); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
+- StorageDead(_32); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
+- StorageLive(_38); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+ StorageLive(_39); // scope 0 at $DIR/reference_prop.rs:+48:13: +48:14
+ _39 = const 7_usize; // scope 0 at $DIR/reference_prop.rs:+48:17: +48:24
+ StorageLive(_40); // scope 19 at $DIR/reference_prop.rs:+49:13: +49:15
+ _40 = &_39; // scope 19 at $DIR/reference_prop.rs:+49:18: +49:20
+ StorageLive(_41); // scope 20 at $DIR/reference_prop.rs:+50:13: +50:14
+- _41 = (*_40); // scope 20 at $DIR/reference_prop.rs:+50:17: +50:20
++ _41 = _39; // scope 20 at $DIR/reference_prop.rs:+50:17: +50:20
+ StorageLive(_42); // scope 21 at $DIR/reference_prop.rs:+51:13: +51:15
+ _42 = _40; // scope 21 at $DIR/reference_prop.rs:+51:18: +51:20
+ StorageLive(_43); // scope 22 at $DIR/reference_prop.rs:+52:13: +52:15
+- _43 = (*_42); // scope 22 at $DIR/reference_prop.rs:+52:18: +52:21
++ _43 = _39; // scope 22 at $DIR/reference_prop.rs:+52:18: +52:21
+ StorageLive(_44); // scope 23 at $DIR/reference_prop.rs:+53:13: +53:15
+ _44 = _42; // scope 23 at $DIR/reference_prop.rs:+53:18: +53:20
+ StorageLive(_45); // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19
+ StorageLive(_46); // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18
+ _46 = _44; // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18
+ _45 = opaque::<&usize>(move _46) -> bb6; // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:66:9: 66:15
+ // + literal: Const { ty: fn(&usize) {opaque::<&usize>}, val: Value(<ZST>) }
+ }
+
+ bb6: {
+ StorageDead(_46); // scope 24 at $DIR/reference_prop.rs:+56:18: +56:19
+ StorageDead(_45); // scope 24 at $DIR/reference_prop.rs:+56:19: +56:20
+- _38 = const (); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+ StorageDead(_44); // scope 23 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_43); // scope 22 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_42); // scope 21 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_41); // scope 20 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_40); // scope 19 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_39); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
+- StorageDead(_38); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
+- StorageLive(_47); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+- StorageLive(_48); // scope 0 at $DIR/reference_prop.rs:+61:13: +61:14
+- _48 = &(*_1); // scope 0 at $DIR/reference_prop.rs:+61:17: +61:25
+ StorageLive(_49); // scope 25 at $DIR/reference_prop.rs:+62:13: +62:14
+- _49 = (*_48); // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19
++ _49 = (*_1); // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19
+ StorageLive(_50); // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19
+ StorageLive(_51); // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18
+ _51 = (); // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18
+ _50 = opaque::<()>(move _51) -> bb7; // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:73:9: 73:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb7: {
+ StorageDead(_51); // scope 26 at $DIR/reference_prop.rs:+63:18: +63:19
+ StorageDead(_50); // scope 26 at $DIR/reference_prop.rs:+63:19: +63:20
+- _47 = const (); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+ StorageDead(_49); // scope 25 at $DIR/reference_prop.rs:+64:5: +64:6
+- StorageDead(_48); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
+- StorageDead(_47); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
+- StorageLive(_52); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+ StorageLive(_53); // scope 0 at $DIR/reference_prop.rs:+68:13: +68:14
+ _53 = &(*_2); // scope 0 at $DIR/reference_prop.rs:+68:17: +68:27
+ StorageLive(_54); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
+- StorageLive(_55); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
+- _55 = &(*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
+- _54 = &(*_55); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
++ _54 = &(*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
+ _2 = move _54; // scope 27 at $DIR/reference_prop.rs:+69:9: +69:28
+ StorageDead(_54); // scope 27 at $DIR/reference_prop.rs:+69:27: +69:28
+- StorageDead(_55); // scope 27 at $DIR/reference_prop.rs:+69:28: +69:29
+ StorageLive(_56); // scope 27 at $DIR/reference_prop.rs:+70:13: +70:14
+ _56 = (*_53); // scope 27 at $DIR/reference_prop.rs:+70:17: +70:19
+ StorageLive(_57); // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19
+ StorageLive(_58); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18
+ _58 = (); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18
+ _57 = opaque::<()>(move _58) -> bb8; // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:81:9: 81:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb8: {
+ StorageDead(_58); // scope 28 at $DIR/reference_prop.rs:+71:18: +71:19
+ StorageDead(_57); // scope 28 at $DIR/reference_prop.rs:+71:19: +71:20
+- _52 = const (); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+ StorageDead(_56); // scope 27 at $DIR/reference_prop.rs:+72:5: +72:6
+ StorageDead(_53); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6
+- StorageDead(_52); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6
+- StorageLive(_59); // scope 0 at $DIR/reference_prop.rs:+75:5: +81:6
+ StorageLive(_60); // scope 0 at $DIR/reference_prop.rs:+76:13: +76:14
+ _60 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+76:17: +76:24
+- StorageLive(_61); // scope 29 at $DIR/reference_prop.rs:+77:13: +77:14
+- _61 = &_60; // scope 29 at $DIR/reference_prop.rs:+77:17: +77:19
+- StorageLive(_62); // scope 30 at $DIR/reference_prop.rs:+78:13: +78:14
+- _62 = &_61; // scope 30 at $DIR/reference_prop.rs:+78:17: +78:19
+ StorageLive(_63); // scope 31 at $DIR/reference_prop.rs:+79:13: +79:14
+- _63 = (*_61); // scope 31 at $DIR/reference_prop.rs:+79:17: +79:19
++ _63 = _60; // scope 31 at $DIR/reference_prop.rs:+79:17: +79:19
+ StorageLive(_64); // scope 32 at $DIR/reference_prop.rs:+80:9: +80:19
+ StorageLive(_65); // scope 32 at $DIR/reference_prop.rs:+80:16: +80:18
+ _65 = (); // scope 32 at $DIR/reference_prop.rs:+80:16: +80:18
+ _64 = opaque::<()>(move _65) -> bb9; // scope 32 at $DIR/reference_prop.rs:+80:9: +80:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:90:9: 90:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb9: {
+ StorageDead(_65); // scope 32 at $DIR/reference_prop.rs:+80:18: +80:19
+ StorageDead(_64); // scope 32 at $DIR/reference_prop.rs:+80:19: +80:20
+- _59 = const (); // scope 0 at $DIR/reference_prop.rs:+75:5: +81:6
+ StorageDead(_63); // scope 31 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageDead(_62); // scope 30 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageDead(_61); // scope 29 at $DIR/reference_prop.rs:+81:5: +81:6
+ StorageDead(_60); // scope 0 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageDead(_59); // scope 0 at $DIR/reference_prop.rs:+81:5: +81:6
+ StorageLive(_66); // scope 0 at $DIR/reference_prop.rs:+85:13: +85:14
+ _66 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+85:17: +85:24
+- StorageLive(_67); // scope 33 at $DIR/reference_prop.rs:+86:13: +86:18
+- _67 = &_66; // scope 33 at $DIR/reference_prop.rs:+86:21: +86:23
+- StorageLive(_68); // scope 34 at $DIR/reference_prop.rs:+87:13: +87:14
+- _68 = &mut _67; // scope 34 at $DIR/reference_prop.rs:+87:17: +87:23
+ StorageLive(_69); // scope 35 at $DIR/reference_prop.rs:+88:13: +88:14
+- _69 = (*_67); // scope 35 at $DIR/reference_prop.rs:+88:17: +88:19
++ _69 = _66; // scope 35 at $DIR/reference_prop.rs:+88:17: +88:19
+ StorageLive(_70); // scope 36 at $DIR/reference_prop.rs:+89:9: +89:19
+ StorageLive(_71); // scope 36 at $DIR/reference_prop.rs:+89:16: +89:18
+ _71 = (); // scope 36 at $DIR/reference_prop.rs:+89:16: +89:18
+ _70 = opaque::<()>(move _71) -> bb10; // scope 36 at $DIR/reference_prop.rs:+89:9: +89:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:99:9: 99:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb10: {
+ StorageDead(_71); // scope 36 at $DIR/reference_prop.rs:+89:18: +89:19
+ StorageDead(_70); // scope 36 at $DIR/reference_prop.rs:+89:19: +89:20
+ _0 = const (); // scope 0 at $DIR/reference_prop.rs:+84:5: +90:6
+ StorageDead(_69); // scope 35 at $DIR/reference_prop.rs:+90:5: +90:6
+- StorageDead(_68); // scope 34 at $DIR/reference_prop.rs:+90:5: +90:6
+- StorageDead(_67); // scope 33 at $DIR/reference_prop.rs:+90:5: +90:6
+ StorageDead(_66); // scope 0 at $DIR/reference_prop.rs:+90:5: +90:6
+ return; // scope 0 at $DIR/reference_prop.rs:+91:2: +91:2
+ }
+ }
+
diff --git a/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
new file mode 100644
index 00000000000..ddeb04e50c7
--- /dev/null
+++ b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
@@ -0,0 +1,536 @@
+- // MIR for `reference_propagation_const_ptr` before ReferencePropagation
++ // MIR for `reference_propagation_const_ptr` after ReferencePropagation
+
+ fn reference_propagation_const_ptr(_1: *const T, _2: *const T) -> () {
+ debug single => _1; // in scope 0 at $DIR/reference_prop.rs:+0:45: +0:51
+ debug multiple => _2; // in scope 0 at $DIR/reference_prop.rs:+0:63: +0:75
+ let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:87: +0:87
+ let _3: (); // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+ let _7: (); // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19
+ let mut _8: (); // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18
+ let _9: (); // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+ let mut _13: *const usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:26
+ let _15: (); // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19
+ let mut _16: (); // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18
+ let _17: (); // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+ let _22: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:18
+ let mut _23: &*const usize; // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:17
+ let _24: (); // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+ let _29: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:18
+ let mut _30: *mut *const usize; // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:17
+ let _31: (); // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+ let _35: (); // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18
+ let mut _36: *const usize; // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17
+ let _37: (); // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+ let _44: (); // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19
+ let mut _45: *const usize; // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18
+ let _46: (); // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+ let _49: (); // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19
+ let mut _50: (); // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18
+ let _51: (); // in scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+ let mut _53: *const T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:38
+ let _55: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19
+ let mut _56: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18
+ let _57: (); // in scope 0 at $DIR/reference_prop.rs:+75:5: +81:6
+ let _62: (); // in scope 0 at $DIR/reference_prop.rs:+80:9: +80:19
+ let mut _63: (); // in scope 0 at $DIR/reference_prop.rs:+80:16: +80:18
+ let _64: (); // in scope 0 at $DIR/reference_prop.rs:+84:5: +90:6
+ let _69: (); // in scope 0 at $DIR/reference_prop.rs:+89:9: +89:19
+ let mut _70: (); // in scope 0 at $DIR/reference_prop.rs:+89:16: +89:18
+ let _75: (); // in scope 0 at $DIR/reference_prop.rs:+98:9: +98:19
+ let mut _76: (); // in scope 0 at $DIR/reference_prop.rs:+98:16: +98:18
+ scope 1 {
+ let _4: usize; // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:14
+ scope 2 {
+ debug a => _4; // in scope 2 at $DIR/reference_prop.rs:+3:13: +3:14
+ let _5: *const usize; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
+ scope 3 {
+- debug b => _5; // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14
++ debug b => &_4; // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14
+ let _6: usize; // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
+ scope 4 {
+ debug c => _6; // in scope 4 at $DIR/reference_prop.rs:+5:13: +5:14
+ }
+ }
+ }
+ }
+ scope 5 {
+ let _10: usize; // in scope 5 at $DIR/reference_prop.rs:+11:13: +11:14
+ scope 6 {
+ debug a => _10; // in scope 6 at $DIR/reference_prop.rs:+11:13: +11:14
+ let _11: usize; // in scope 6 at $DIR/reference_prop.rs:+12:13: +12:15
+ scope 7 {
+ debug a2 => _11; // in scope 7 at $DIR/reference_prop.rs:+12:13: +12:15
+ let mut _12: *const usize; // in scope 7 at $DIR/reference_prop.rs:+13:13: +13:18
+ scope 8 {
+ debug b => _12; // in scope 8 at $DIR/reference_prop.rs:+13:13: +13:18
+ let _14: usize; // in scope 8 at $DIR/reference_prop.rs:+16:13: +16:14
+ scope 9 {
+ debug c => _14; // in scope 9 at $DIR/reference_prop.rs:+16:13: +16:14
+ }
+ }
+ }
+ }
+ }
+ scope 10 {
+ let _18: usize; // in scope 10 at $DIR/reference_prop.rs:+22:13: +22:14
+ scope 11 {
+ debug a => _18; // in scope 11 at $DIR/reference_prop.rs:+22:13: +22:14
+ let _19: *const usize; // in scope 11 at $DIR/reference_prop.rs:+23:13: +23:14
+ scope 12 {
+ debug b => _19; // in scope 12 at $DIR/reference_prop.rs:+23:13: +23:14
+ let _20: &*const usize; // in scope 12 at $DIR/reference_prop.rs:+24:13: +24:14
+ scope 13 {
+ debug d => _20; // in scope 13 at $DIR/reference_prop.rs:+24:13: +24:14
+ let _21: usize; // in scope 13 at $DIR/reference_prop.rs:+25:13: +25:14
+ scope 14 {
+ debug c => _21; // in scope 14 at $DIR/reference_prop.rs:+25:13: +25:14
+ }
+ }
+ }
+ }
+ }
+ scope 15 {
+ let _25: usize; // in scope 15 at $DIR/reference_prop.rs:+31:13: +31:14
+ scope 16 {
+ debug a => _25; // in scope 16 at $DIR/reference_prop.rs:+31:13: +31:14
+ let mut _26: *const usize; // in scope 16 at $DIR/reference_prop.rs:+32:13: +32:18
+ scope 17 {
+ debug b => _26; // in scope 17 at $DIR/reference_prop.rs:+32:13: +32:18
+ let _27: *mut *const usize; // in scope 17 at $DIR/reference_prop.rs:+33:13: +33:14
+ scope 18 {
+ debug d => _27; // in scope 18 at $DIR/reference_prop.rs:+33:13: +33:14
+ let _28: usize; // in scope 18 at $DIR/reference_prop.rs:+34:13: +34:14
+ scope 19 {
+ debug c => _28; // in scope 19 at $DIR/reference_prop.rs:+34:13: +34:14
+ }
+ }
+ }
+ }
+ }
+ scope 20 {
+ let _32: usize; // in scope 20 at $DIR/reference_prop.rs:+40:13: +40:14
+ scope 21 {
+ debug a => _32; // in scope 21 at $DIR/reference_prop.rs:+40:13: +40:14
+ let _33: *const usize; // in scope 21 at $DIR/reference_prop.rs:+41:13: +41:14
+ scope 22 {
+ debug b => _33; // in scope 22 at $DIR/reference_prop.rs:+41:13: +41:14
+ let _34: usize; // in scope 22 at $DIR/reference_prop.rs:+42:13: +42:14
+ scope 23 {
+ debug c => _34; // in scope 23 at $DIR/reference_prop.rs:+42:13: +42:14
+ }
+ }
+ }
+ }
+ scope 24 {
+ let _38: usize; // in scope 24 at $DIR/reference_prop.rs:+48:13: +48:14
+ scope 25 {
+ debug a => _38; // in scope 25 at $DIR/reference_prop.rs:+48:13: +48:14
+ let _39: *const usize; // in scope 25 at $DIR/reference_prop.rs:+49:13: +49:15
+ scope 26 {
+ debug b1 => _39; // in scope 26 at $DIR/reference_prop.rs:+49:13: +49:15
+ let _40: usize; // in scope 26 at $DIR/reference_prop.rs:+50:13: +50:14
+ scope 27 {
+ debug c => _40; // in scope 27 at $DIR/reference_prop.rs:+50:13: +50:14
+ let _41: *const usize; // in scope 27 at $DIR/reference_prop.rs:+51:13: +51:15
+ scope 28 {
+ debug b2 => _41; // in scope 28 at $DIR/reference_prop.rs:+51:13: +51:15
+ let _42: usize; // in scope 28 at $DIR/reference_prop.rs:+52:13: +52:15
+ scope 29 {
+ debug c2 => _42; // in scope 29 at $DIR/reference_prop.rs:+52:13: +52:15
+ let _43: *const usize; // in scope 29 at $DIR/reference_prop.rs:+53:13: +53:15
+ scope 30 {
+ debug b3 => _43; // in scope 30 at $DIR/reference_prop.rs:+53:13: +53:15
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ scope 31 {
+ let _47: *const T; // in scope 31 at $DIR/reference_prop.rs:+61:13: +61:14
+ scope 32 {
+- debug a => _47; // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14
++ debug a => _1; // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14
+ let _48: T; // in scope 32 at $DIR/reference_prop.rs:+62:13: +62:14
+ scope 33 {
+ debug b => _48; // in scope 33 at $DIR/reference_prop.rs:+62:13: +62:14
+ }
+ }
+ }
+ scope 34 {
+ let _52: *const T; // in scope 34 at $DIR/reference_prop.rs:+68:13: +68:14
+ scope 35 {
+ debug a => _52; // in scope 35 at $DIR/reference_prop.rs:+68:13: +68:14
+ let _54: T; // in scope 35 at $DIR/reference_prop.rs:+70:13: +70:14
+ scope 36 {
+ debug b => _54; // in scope 36 at $DIR/reference_prop.rs:+70:13: +70:14
+ }
+ }
+ }
+ scope 37 {
+ let _58: usize; // in scope 37 at $DIR/reference_prop.rs:+76:13: +76:14
+ scope 38 {
+ debug a => _58; // in scope 38 at $DIR/reference_prop.rs:+76:13: +76:14
+ let _59: *const usize; // in scope 38 at $DIR/reference_prop.rs:+77:13: +77:14
+ scope 39 {
+- debug b => _59; // in scope 39 at $DIR/reference_prop.rs:+77:13: +77:14
++ debug b => &_58; // in scope 39 at $DIR/reference_prop.rs:+77:13: +77:14
+ let _60: *const usize; // in scope 39 at $DIR/reference_prop.rs:+78:13: +78:14
+ scope 40 {
+- debug c => _60; // in scope 40 at $DIR/reference_prop.rs:+78:13: +78:14
++ debug c => &_58; // in scope 40 at $DIR/reference_prop.rs:+78:13: +78:14
+ let _61: usize; // in scope 40 at $DIR/reference_prop.rs:+79:13: +79:14
+ scope 41 {
+ debug e => _61; // in scope 41 at $DIR/reference_prop.rs:+79:13: +79:14
+ }
+ }
+ }
+ }
+ }
+ scope 42 {
+ let _65: usize; // in scope 42 at $DIR/reference_prop.rs:+85:13: +85:14
+ scope 43 {
+ debug a => _65; // in scope 43 at $DIR/reference_prop.rs:+85:13: +85:14
+ let _66: *const usize; // in scope 43 at $DIR/reference_prop.rs:+86:13: +86:14
+ scope 44 {
+- debug b => _66; // in scope 44 at $DIR/reference_prop.rs:+86:13: +86:14
++ debug b => &_65; // in scope 44 at $DIR/reference_prop.rs:+86:13: +86:14
+ let _67: &*const usize; // in scope 44 at $DIR/reference_prop.rs:+87:13: +87:14
+ scope 45 {
+- debug d => _67; // in scope 45 at $DIR/reference_prop.rs:+87:13: +87:14
++ debug d => &&_65; // in scope 45 at $DIR/reference_prop.rs:+87:13: +87:14
+ let _68: usize; // in scope 45 at $DIR/reference_prop.rs:+88:13: +88:14
+ scope 46 {
+ debug c => _68; // in scope 46 at $DIR/reference_prop.rs:+88:13: +88:14
+ }
+ }
+ }
+ }
+ }
+ scope 47 {
+ let _71: usize; // in scope 47 at $DIR/reference_prop.rs:+94:13: +94:14
+ scope 48 {
+ debug a => _71; // in scope 48 at $DIR/reference_prop.rs:+94:13: +94:14
+ let mut _72: *const usize; // in scope 48 at $DIR/reference_prop.rs:+95:13: +95:18
+ scope 49 {
+- debug b => _72; // in scope 49 at $DIR/reference_prop.rs:+95:13: +95:18
++ debug b => &_71; // in scope 49 at $DIR/reference_prop.rs:+95:13: +95:18
+ let _73: &mut *const usize; // in scope 49 at $DIR/reference_prop.rs:+96:13: +96:14
+ scope 50 {
+- debug d => _73; // in scope 50 at $DIR/reference_prop.rs:+96:13: +96:14
++ debug d => &&_71; // in scope 50 at $DIR/reference_prop.rs:+96:13: +96:14
+ let _74: usize; // in scope 50 at $DIR/reference_prop.rs:+97:13: +97:14
+ scope 51 {
+ debug c => _74; // in scope 51 at $DIR/reference_prop.rs:+97:13: +97:14
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+- StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+ StorageLive(_4); // scope 1 at $DIR/reference_prop.rs:+3:13: +3:14
+ _4 = const 5_usize; // scope 1 at $DIR/reference_prop.rs:+3:17: +3:24
+- StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
+- _5 = &raw const _4; // scope 2 at $DIR/reference_prop.rs:+4:17: +4:29
+ StorageLive(_6); // scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
+- _6 = (*_5); // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19
++ _6 = _4; // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19
+ StorageLive(_7); // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19
+ StorageLive(_8); // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18
+ _8 = (); // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18
+ _7 = opaque::<()>(move _8) -> bb1; // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:202:9: 202:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_8); // scope 4 at $DIR/reference_prop.rs:+6:18: +6:19
+ StorageDead(_7); // scope 4 at $DIR/reference_prop.rs:+6:19: +6:20
+- _3 = const (); // scope 1 at $DIR/reference_prop.rs:+2:5: +7:6
+ StorageDead(_6); // scope 3 at $DIR/reference_prop.rs:+7:5: +7:6
+- StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
+ StorageDead(_4); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6
+- StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+- StorageLive(_9); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+ StorageLive(_10); // scope 5 at $DIR/reference_prop.rs:+11:13: +11:14
+ _10 = const 5_usize; // scope 5 at $DIR/reference_prop.rs:+11:17: +11:24
+ StorageLive(_11); // scope 6 at $DIR/reference_prop.rs:+12:13: +12:15
+ _11 = const 7_usize; // scope 6 at $DIR/reference_prop.rs:+12:18: +12:25
+ StorageLive(_12); // scope 7 at $DIR/reference_prop.rs:+13:13: +13:18
+ _12 = &raw const _10; // scope 7 at $DIR/reference_prop.rs:+13:21: +13:33
+ StorageLive(_13); // scope 8 at $DIR/reference_prop.rs:+14:13: +14:26
+ _13 = &raw const _11; // scope 8 at $DIR/reference_prop.rs:+14:13: +14:26
+ _12 = move _13; // scope 8 at $DIR/reference_prop.rs:+14:9: +14:26
+ StorageDead(_13); // scope 8 at $DIR/reference_prop.rs:+14:25: +14:26
+ StorageLive(_14); // scope 8 at $DIR/reference_prop.rs:+16:13: +16:14
+ _14 = (*_12); // scope 8 at $DIR/reference_prop.rs:+16:17: +16:19
+ StorageLive(_15); // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19
+ StorageLive(_16); // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18
+ _16 = (); // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18
+ _15 = opaque::<()>(move _16) -> bb2; // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:213:9: 213:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_16); // scope 9 at $DIR/reference_prop.rs:+17:18: +17:19
+ StorageDead(_15); // scope 9 at $DIR/reference_prop.rs:+17:19: +17:20
+- _9 = const (); // scope 5 at $DIR/reference_prop.rs:+10:5: +18:6
+ StorageDead(_14); // scope 8 at $DIR/reference_prop.rs:+18:5: +18:6
+ StorageDead(_12); // scope 7 at $DIR/reference_prop.rs:+18:5: +18:6
+ StorageDead(_11); // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6
+ StorageDead(_10); // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6
+- StorageDead(_9); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
+- StorageLive(_17); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+ StorageLive(_18); // scope 10 at $DIR/reference_prop.rs:+22:13: +22:14
+ _18 = const 5_usize; // scope 10 at $DIR/reference_prop.rs:+22:17: +22:24
+ StorageLive(_19); // scope 11 at $DIR/reference_prop.rs:+23:13: +23:14
+ _19 = &raw const _18; // scope 11 at $DIR/reference_prop.rs:+23:17: +23:29
+ StorageLive(_20); // scope 12 at $DIR/reference_prop.rs:+24:13: +24:14
+ _20 = &_19; // scope 12 at $DIR/reference_prop.rs:+24:17: +24:19
+ StorageLive(_21); // scope 13 at $DIR/reference_prop.rs:+25:13: +25:14
+ _21 = (*_19); // scope 13 at $DIR/reference_prop.rs:+25:17: +25:19
+ StorageLive(_22); // scope 14 at $DIR/reference_prop.rs:+26:9: +26:18
+ StorageLive(_23); // scope 14 at $DIR/reference_prop.rs:+26:16: +26:17
+ _23 = _20; // scope 14 at $DIR/reference_prop.rs:+26:16: +26:17
+ _22 = opaque::<&*const usize>(move _23) -> bb3; // scope 14 at $DIR/reference_prop.rs:+26:9: +26:18
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:222:9: 222:15
+ // + literal: Const { ty: fn(&*const usize) {opaque::<&*const usize>}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_23); // scope 14 at $DIR/reference_prop.rs:+26:17: +26:18
+ StorageDead(_22); // scope 14 at $DIR/reference_prop.rs:+26:18: +26:19
+- _17 = const (); // scope 10 at $DIR/reference_prop.rs:+21:5: +27:6
+ StorageDead(_21); // scope 13 at $DIR/reference_prop.rs:+27:5: +27:6
+ StorageDead(_20); // scope 12 at $DIR/reference_prop.rs:+27:5: +27:6
+ StorageDead(_19); // scope 11 at $DIR/reference_prop.rs:+27:5: +27:6
+ StorageDead(_18); // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6
+- StorageDead(_17); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
+- StorageLive(_24); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+ StorageLive(_25); // scope 15 at $DIR/reference_prop.rs:+31:13: +31:14
+ _25 = const 5_usize; // scope 15 at $DIR/reference_prop.rs:+31:17: +31:24
+ StorageLive(_26); // scope 16 at $DIR/reference_prop.rs:+32:13: +32:18
+ _26 = &raw const _25; // scope 16 at $DIR/reference_prop.rs:+32:21: +32:33
+ StorageLive(_27); // scope 17 at $DIR/reference_prop.rs:+33:13: +33:14
+ _27 = &raw mut _26; // scope 17 at $DIR/reference_prop.rs:+33:17: +33:27
+ StorageLive(_28); // scope 18 at $DIR/reference_prop.rs:+34:13: +34:14
+ _28 = (*_26); // scope 18 at $DIR/reference_prop.rs:+34:17: +34:19
+ StorageLive(_29); // scope 19 at $DIR/reference_prop.rs:+35:9: +35:18
+ StorageLive(_30); // scope 19 at $DIR/reference_prop.rs:+35:16: +35:17
+ _30 = _27; // scope 19 at $DIR/reference_prop.rs:+35:16: +35:17
+ _29 = opaque::<*mut *const usize>(move _30) -> bb4; // scope 19 at $DIR/reference_prop.rs:+35:9: +35:18
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:231:9: 231:15
+ // + literal: Const { ty: fn(*mut *const usize) {opaque::<*mut *const usize>}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ StorageDead(_30); // scope 19 at $DIR/reference_prop.rs:+35:17: +35:18
+ StorageDead(_29); // scope 19 at $DIR/reference_prop.rs:+35:18: +35:19
+- _24 = const (); // scope 15 at $DIR/reference_prop.rs:+30:5: +36:6
+ StorageDead(_28); // scope 18 at $DIR/reference_prop.rs:+36:5: +36:6
+ StorageDead(_27); // scope 17 at $DIR/reference_prop.rs:+36:5: +36:6
+ StorageDead(_26); // scope 16 at $DIR/reference_prop.rs:+36:5: +36:6
+ StorageDead(_25); // scope 15 at $DIR/reference_prop.rs:+36:5: +36:6
+- StorageDead(_24); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
+- StorageLive(_31); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+ StorageLive(_32); // scope 20 at $DIR/reference_prop.rs:+40:13: +40:14
+ _32 = const 7_usize; // scope 20 at $DIR/reference_prop.rs:+40:17: +40:24
+ StorageLive(_33); // scope 21 at $DIR/reference_prop.rs:+41:13: +41:14
+ _33 = &raw const _32; // scope 21 at $DIR/reference_prop.rs:+41:17: +41:29
+ StorageLive(_34); // scope 22 at $DIR/reference_prop.rs:+42:13: +42:14
+- _34 = (*_33); // scope 22 at $DIR/reference_prop.rs:+42:17: +42:19
++ _34 = _32; // scope 22 at $DIR/reference_prop.rs:+42:17: +42:19
+ StorageLive(_35); // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18
+ StorageLive(_36); // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17
+ _36 = _33; // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17
+ _35 = opaque::<*const usize>(move _36) -> bb5; // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:239:9: 239:15
+ // + literal: Const { ty: fn(*const usize) {opaque::<*const usize>}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ StorageDead(_36); // scope 23 at $DIR/reference_prop.rs:+43:17: +43:18
+ StorageDead(_35); // scope 23 at $DIR/reference_prop.rs:+43:18: +43:19
+- _31 = const (); // scope 20 at $DIR/reference_prop.rs:+39:5: +44:6
+ StorageDead(_34); // scope 22 at $DIR/reference_prop.rs:+44:5: +44:6
+ StorageDead(_33); // scope 21 at $DIR/reference_prop.rs:+44:5: +44:6
+ StorageDead(_32); // scope 20 at $DIR/reference_prop.rs:+44:5: +44:6
+- StorageDead(_31); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
+- StorageLive(_37); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+ StorageLive(_38); // scope 24 at $DIR/reference_prop.rs:+48:13: +48:14
+ _38 = const 7_usize; // scope 24 at $DIR/reference_prop.rs:+48:17: +48:24
+ StorageLive(_39); // scope 25 at $DIR/reference_prop.rs:+49:13: +49:15
+ _39 = &raw const _38; // scope 25 at $DIR/reference_prop.rs:+49:18: +49:30
+ StorageLive(_40); // scope 26 at $DIR/reference_prop.rs:+50:13: +50:14
+- _40 = (*_39); // scope 26 at $DIR/reference_prop.rs:+50:17: +50:20
++ _40 = _38; // scope 26 at $DIR/reference_prop.rs:+50:17: +50:20
+ StorageLive(_41); // scope 27 at $DIR/reference_prop.rs:+51:13: +51:15
+ _41 = _39; // scope 27 at $DIR/reference_prop.rs:+51:18: +51:20
+ StorageLive(_42); // scope 28 at $DIR/reference_prop.rs:+52:13: +52:15
+- _42 = (*_41); // scope 28 at $DIR/reference_prop.rs:+52:18: +52:21
++ _42 = _38; // scope 28 at $DIR/reference_prop.rs:+52:18: +52:21
+ StorageLive(_43); // scope 29 at $DIR/reference_prop.rs:+53:13: +53:15
+ _43 = _41; // scope 29 at $DIR/reference_prop.rs:+53:18: +53:20
+ StorageLive(_44); // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19
+ StorageLive(_45); // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18
+ _45 = _43; // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18
+ _44 = opaque::<*const usize>(move _45) -> bb6; // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:252:9: 252:15
+ // + literal: Const { ty: fn(*const usize) {opaque::<*const usize>}, val: Value(<ZST>) }
+ }
+
+ bb6: {
+ StorageDead(_45); // scope 30 at $DIR/reference_prop.rs:+56:18: +56:19
+ StorageDead(_44); // scope 30 at $DIR/reference_prop.rs:+56:19: +56:20
+- _37 = const (); // scope 24 at $DIR/reference_prop.rs:+47:5: +57:6
+ StorageDead(_43); // scope 29 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_42); // scope 28 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_41); // scope 27 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_40); // scope 26 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_39); // scope 25 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_38); // scope 24 at $DIR/reference_prop.rs:+57:5: +57:6
+- StorageDead(_37); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
+- StorageLive(_46); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+- StorageLive(_47); // scope 31 at $DIR/reference_prop.rs:+61:13: +61:14
+- _47 = &raw const (*_1); // scope 31 at $DIR/reference_prop.rs:+61:17: +61:35
+ StorageLive(_48); // scope 32 at $DIR/reference_prop.rs:+62:13: +62:14
+- _48 = (*_47); // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19
++ _48 = (*_1); // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19
+ StorageLive(_49); // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19
+ StorageLive(_50); // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18
+ _50 = (); // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18
+ _49 = opaque::<()>(move _50) -> bb7; // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:259:9: 259:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb7: {
+ StorageDead(_50); // scope 33 at $DIR/reference_prop.rs:+63:18: +63:19
+ StorageDead(_49); // scope 33 at $DIR/reference_prop.rs:+63:19: +63:20
+- _46 = const (); // scope 31 at $DIR/reference_prop.rs:+60:5: +64:6
+ StorageDead(_48); // scope 32 at $DIR/reference_prop.rs:+64:5: +64:6
+- StorageDead(_47); // scope 31 at $DIR/reference_prop.rs:+64:5: +64:6
+- StorageDead(_46); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
+- StorageLive(_51); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+ StorageLive(_52); // scope 34 at $DIR/reference_prop.rs:+68:13: +68:14
+ _52 = &raw const (*_2); // scope 34 at $DIR/reference_prop.rs:+68:17: +68:37
+ StorageLive(_53); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:38
+ _53 = &raw const (*_1); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:38
+ _2 = move _53; // scope 35 at $DIR/reference_prop.rs:+69:9: +69:38
+ StorageDead(_53); // scope 35 at $DIR/reference_prop.rs:+69:37: +69:38
+ StorageLive(_54); // scope 35 at $DIR/reference_prop.rs:+70:13: +70:14
+ _54 = (*_52); // scope 35 at $DIR/reference_prop.rs:+70:17: +70:19
+ StorageLive(_55); // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19
+ StorageLive(_56); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18
+ _56 = (); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18
+ _55 = opaque::<()>(move _56) -> bb8; // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:267:9: 267:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb8: {
+ StorageDead(_56); // scope 36 at $DIR/reference_prop.rs:+71:18: +71:19
+ StorageDead(_55); // scope 36 at $DIR/reference_prop.rs:+71:19: +71:20
+- _51 = const (); // scope 34 at $DIR/reference_prop.rs:+67:5: +72:6
+ StorageDead(_54); // scope 35 at $DIR/reference_prop.rs:+72:5: +72:6
+ StorageDead(_52); // scope 34 at $DIR/reference_prop.rs:+72:5: +72:6
+- StorageDead(_51); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6
+- StorageLive(_57); // scope 0 at $DIR/reference_prop.rs:+75:5: +81:6
+ StorageLive(_58); // scope 37 at $DIR/reference_prop.rs:+76:13: +76:14
+ _58 = const 13_usize; // scope 37 at $DIR/reference_prop.rs:+76:17: +76:25
+- StorageLive(_59); // scope 38 at $DIR/reference_prop.rs:+77:13: +77:14
+- _59 = &raw const _58; // scope 38 at $DIR/reference_prop.rs:+77:17: +77:29
+- StorageLive(_60); // scope 39 at $DIR/reference_prop.rs:+78:13: +78:14
+- _60 = &raw const (*_59); // scope 39 at $DIR/reference_prop.rs:+78:17: +78:30
+ StorageLive(_61); // scope 40 at $DIR/reference_prop.rs:+79:13: +79:14
+- _61 = (*_60); // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19
++ _61 = _58; // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19
+ StorageLive(_62); // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19
+ StorageLive(_63); // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18
+ _63 = (); // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18
+ _62 = opaque::<()>(move _63) -> bb9; // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:276:9: 276:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb9: {
+ StorageDead(_63); // scope 41 at $DIR/reference_prop.rs:+80:18: +80:19
+ StorageDead(_62); // scope 41 at $DIR/reference_prop.rs:+80:19: +80:20
+- _57 = const (); // scope 37 at $DIR/reference_prop.rs:+75:5: +81:6
+ StorageDead(_61); // scope 40 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageDead(_60); // scope 39 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageDead(_59); // scope 38 at $DIR/reference_prop.rs:+81:5: +81:6
+ StorageDead(_58); // scope 37 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageDead(_57); // scope 0 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageLive(_64); // scope 0 at $DIR/reference_prop.rs:+84:5: +90:6
+ StorageLive(_65); // scope 42 at $DIR/reference_prop.rs:+85:13: +85:14
+ _65 = const 5_usize; // scope 42 at $DIR/reference_prop.rs:+85:17: +85:24
+- StorageLive(_66); // scope 43 at $DIR/reference_prop.rs:+86:13: +86:14
+- _66 = &raw const _65; // scope 43 at $DIR/reference_prop.rs:+86:17: +86:29
+- StorageLive(_67); // scope 44 at $DIR/reference_prop.rs:+87:13: +87:14
+- _67 = &_66; // scope 44 at $DIR/reference_prop.rs:+87:17: +87:19
+ StorageLive(_68); // scope 45 at $DIR/reference_prop.rs:+88:13: +88:14
+- _68 = (*_66); // scope 45 at $DIR/reference_prop.rs:+88:17: +88:19
++ _68 = _65; // scope 45 at $DIR/reference_prop.rs:+88:17: +88:19
+ StorageLive(_69); // scope 46 at $DIR/reference_prop.rs:+89:9: +89:19
+ StorageLive(_70); // scope 46 at $DIR/reference_prop.rs:+89:16: +89:18
+ _70 = (); // scope 46 at $DIR/reference_prop.rs:+89:16: +89:18
+ _69 = opaque::<()>(move _70) -> bb10; // scope 46 at $DIR/reference_prop.rs:+89:9: +89:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:285:9: 285:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb10: {
+ StorageDead(_70); // scope 46 at $DIR/reference_prop.rs:+89:18: +89:19
+ StorageDead(_69); // scope 46 at $DIR/reference_prop.rs:+89:19: +89:20
+- _64 = const (); // scope 42 at $DIR/reference_prop.rs:+84:5: +90:6
+ StorageDead(_68); // scope 45 at $DIR/reference_prop.rs:+90:5: +90:6
+- StorageDead(_67); // scope 44 at $DIR/reference_prop.rs:+90:5: +90:6
+- StorageDead(_66); // scope 43 at $DIR/reference_prop.rs:+90:5: +90:6
+ StorageDead(_65); // scope 42 at $DIR/reference_prop.rs:+90:5: +90:6
+- StorageDead(_64); // scope 0 at $DIR/reference_prop.rs:+90:5: +90:6
+ StorageLive(_71); // scope 47 at $DIR/reference_prop.rs:+94:13: +94:14
+ _71 = const 5_usize; // scope 47 at $DIR/reference_prop.rs:+94:17: +94:24
+- StorageLive(_72); // scope 48 at $DIR/reference_prop.rs:+95:13: +95:18
+- _72 = &raw const _71; // scope 48 at $DIR/reference_prop.rs:+95:21: +95:33
+- StorageLive(_73); // scope 49 at $DIR/reference_prop.rs:+96:13: +96:14
+- _73 = &mut _72; // scope 49 at $DIR/reference_prop.rs:+96:17: +96:23
+ StorageLive(_74); // scope 50 at $DIR/reference_prop.rs:+97:13: +97:14
+- _74 = (*_72); // scope 50 at $DIR/reference_prop.rs:+97:17: +97:19
++ _74 = _71; // scope 50 at $DIR/reference_prop.rs:+97:17: +97:19
+ StorageLive(_75); // scope 51 at $DIR/reference_prop.rs:+98:9: +98:19
+ StorageLive(_76); // scope 51 at $DIR/reference_prop.rs:+98:16: +98:18
+ _76 = (); // scope 51 at $DIR/reference_prop.rs:+98:16: +98:18
+ _75 = opaque::<()>(move _76) -> bb11; // scope 51 at $DIR/reference_prop.rs:+98:9: +98:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:294:9: 294:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb11: {
+ StorageDead(_76); // scope 51 at $DIR/reference_prop.rs:+98:18: +98:19
+ StorageDead(_75); // scope 51 at $DIR/reference_prop.rs:+98:19: +98:20
+ _0 = const (); // scope 47 at $DIR/reference_prop.rs:+93:5: +99:6
+ StorageDead(_74); // scope 50 at $DIR/reference_prop.rs:+99:5: +99:6
+- StorageDead(_73); // scope 49 at $DIR/reference_prop.rs:+99:5: +99:6
+- StorageDead(_72); // scope 48 at $DIR/reference_prop.rs:+99:5: +99:6
+ StorageDead(_71); // scope 47 at $DIR/reference_prop.rs:+99:5: +99:6
+ return; // scope 0 at $DIR/reference_prop.rs:+100:2: +100:2
+ }
+ }
+
diff --git a/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff
new file mode 100644
index 00000000000..8d059de5b87
--- /dev/null
+++ b/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff
@@ -0,0 +1,472 @@
+- // MIR for `reference_propagation_mut` before ReferencePropagation
++ // MIR for `reference_propagation_mut` after ReferencePropagation
+
+ fn reference_propagation_mut(_1: &mut T, _2: &mut T) -> () {
+ debug single => _1; // in scope 0 at $DIR/reference_prop.rs:+0:43: +0:49
+ debug multiple => _2; // in scope 0 at $DIR/reference_prop.rs:+0:62: +0:74
+ let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:87: +0:87
+ let _3: (); // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+ let mut _4: usize; // in scope 0 at $DIR/reference_prop.rs:+3:13: +3:18
+ let _7: (); // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19
+ let mut _8: (); // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18
+ let _9: (); // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+ let mut _10: usize; // in scope 0 at $DIR/reference_prop.rs:+11:13: +11:18
+ let mut _13: &mut usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:20
+ let mut _14: &mut usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:20
+ let _16: (); // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19
+ let mut _17: (); // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18
+ let _18: (); // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+ let mut _19: usize; // in scope 0 at $DIR/reference_prop.rs:+22:13: +22:18
+ let _23: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:18
+ let mut _24: &&mut usize; // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:17
+ let _25: (); // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+ let mut _26: usize; // in scope 0 at $DIR/reference_prop.rs:+31:13: +31:18
+ let _30: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:18
+ let mut _31: *mut &mut usize; // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:17
+ let _32: (); // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+ let mut _33: usize; // in scope 0 at $DIR/reference_prop.rs:+40:13: +40:18
+ let _36: (); // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18
+ let mut _37: &mut usize; // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17
+ let _38: (); // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+ let mut _39: usize; // in scope 0 at $DIR/reference_prop.rs:+48:13: +48:18
+ let _45: (); // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19
+ let mut _46: &mut usize; // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18
+ let _47: (); // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+ let _48: &mut T; // in scope 0 at $DIR/reference_prop.rs:+61:13: +61:14
+ let _50: (); // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19
+ let mut _51: (); // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18
+ let _52: (); // in scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+ let _53: &mut T; // in scope 0 at $DIR/reference_prop.rs:+68:13: +68:14
+ let mut _54: &mut T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:32
+ let mut _55: &mut T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:32
+ let _57: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19
+ let mut _58: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18
+ let _59: (); // in scope 0 at $DIR/reference_prop.rs:+75:5: +81:6
+ let mut _60: usize; // in scope 0 at $DIR/reference_prop.rs:+76:13: +76:18
+ let _64: (); // in scope 0 at $DIR/reference_prop.rs:+80:9: +80:19
+ let mut _65: (); // in scope 0 at $DIR/reference_prop.rs:+80:16: +80:18
+ let mut _66: usize; // in scope 0 at $DIR/reference_prop.rs:+85:13: +85:18
+ let _70: (); // in scope 0 at $DIR/reference_prop.rs:+89:9: +89:19
+ let mut _71: (); // in scope 0 at $DIR/reference_prop.rs:+89:16: +89:18
+ scope 1 {
+ debug a => _4; // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:18
+ let _5: &mut usize; // in scope 1 at $DIR/reference_prop.rs:+4:13: +4:14
+ scope 2 {
+- debug b => _5; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
++ debug b => &_4; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
+ let _6: usize; // in scope 2 at $DIR/reference_prop.rs:+5:13: +5:14
+ scope 3 {
+ debug c => _6; // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
+ }
+ }
+ }
+ scope 4 {
+ debug a => _10; // in scope 4 at $DIR/reference_prop.rs:+11:13: +11:18
+ let mut _11: usize; // in scope 4 at $DIR/reference_prop.rs:+12:13: +12:19
+ scope 5 {
+ debug a2 => _11; // in scope 5 at $DIR/reference_prop.rs:+12:13: +12:19
+ let mut _12: &mut usize; // in scope 5 at $DIR/reference_prop.rs:+13:13: +13:18
+ scope 6 {
+ debug b => _12; // in scope 6 at $DIR/reference_prop.rs:+13:13: +13:18
+ let _15: usize; // in scope 6 at $DIR/reference_prop.rs:+16:13: +16:14
+ scope 7 {
+ debug c => _15; // in scope 7 at $DIR/reference_prop.rs:+16:13: +16:14
+ }
+ }
+ }
+ }
+ scope 8 {
+ debug a => _19; // in scope 8 at $DIR/reference_prop.rs:+22:13: +22:18
+ let _20: &mut usize; // in scope 8 at $DIR/reference_prop.rs:+23:13: +23:14
+ scope 9 {
+ debug b => _20; // in scope 9 at $DIR/reference_prop.rs:+23:13: +23:14
+ let _21: &&mut usize; // in scope 9 at $DIR/reference_prop.rs:+24:13: +24:14
+ scope 10 {
+ debug d => _21; // in scope 10 at $DIR/reference_prop.rs:+24:13: +24:14
+ let _22: usize; // in scope 10 at $DIR/reference_prop.rs:+25:13: +25:14
+ scope 11 {
+ debug c => _22; // in scope 11 at $DIR/reference_prop.rs:+25:13: +25:14
+ }
+ }
+ }
+ }
+ scope 12 {
+ debug a => _26; // in scope 12 at $DIR/reference_prop.rs:+31:13: +31:18
+ let mut _27: &mut usize; // in scope 12 at $DIR/reference_prop.rs:+32:13: +32:18
+ scope 13 {
+ debug b => _27; // in scope 13 at $DIR/reference_prop.rs:+32:13: +32:18
+ let _28: *mut &mut usize; // in scope 13 at $DIR/reference_prop.rs:+33:13: +33:14
+ scope 14 {
+ debug d => _28; // in scope 14 at $DIR/reference_prop.rs:+33:13: +33:14
+ let _29: usize; // in scope 14 at $DIR/reference_prop.rs:+34:13: +34:14
+ scope 15 {
+ debug c => _29; // in scope 15 at $DIR/reference_prop.rs:+34:13: +34:14
+ }
+ }
+ }
+ }
+ scope 16 {
+ debug a => _33; // in scope 16 at $DIR/reference_prop.rs:+40:13: +40:18
+ let _34: &mut usize; // in scope 16 at $DIR/reference_prop.rs:+41:13: +41:14
+ scope 17 {
+ debug b => _34; // in scope 17 at $DIR/reference_prop.rs:+41:13: +41:14
+ let _35: usize; // in scope 17 at $DIR/reference_prop.rs:+42:13: +42:14
+ scope 18 {
+ debug c => _35; // in scope 18 at $DIR/reference_prop.rs:+42:13: +42:14
+ }
+ }
+ }
+ scope 19 {
+ debug a => _39; // in scope 19 at $DIR/reference_prop.rs:+48:13: +48:18
+ let _40: &mut usize; // in scope 19 at $DIR/reference_prop.rs:+49:13: +49:15
+ scope 20 {
+ debug b1 => _40; // in scope 20 at $DIR/reference_prop.rs:+49:13: +49:15
+ let _41: usize; // in scope 20 at $DIR/reference_prop.rs:+50:13: +50:14
+ scope 21 {
+ debug c => _41; // in scope 21 at $DIR/reference_prop.rs:+50:13: +50:14
+ let _42: &mut usize; // in scope 21 at $DIR/reference_prop.rs:+51:13: +51:15
+ scope 22 {
+ debug b2 => _42; // in scope 22 at $DIR/reference_prop.rs:+51:13: +51:15
+ let _43: usize; // in scope 22 at $DIR/reference_prop.rs:+52:13: +52:15
+ scope 23 {
+ debug c2 => _43; // in scope 23 at $DIR/reference_prop.rs:+52:13: +52:15
+ let _44: &mut usize; // in scope 23 at $DIR/reference_prop.rs:+53:13: +53:15
+ scope 24 {
+ debug b3 => _44; // in scope 24 at $DIR/reference_prop.rs:+53:13: +53:15
+ }
+ }
+ }
+ }
+ }
+ }
+ scope 25 {
+- debug a => _48; // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14
++ debug a => _1; // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14
+ let _49: T; // in scope 25 at $DIR/reference_prop.rs:+62:13: +62:14
+ scope 26 {
+ debug b => _49; // in scope 26 at $DIR/reference_prop.rs:+62:13: +62:14
+ }
+ }
+ scope 27 {
+ debug a => _53; // in scope 27 at $DIR/reference_prop.rs:+68:13: +68:14
+ let _56: T; // in scope 27 at $DIR/reference_prop.rs:+70:13: +70:14
+ scope 28 {
+ debug b => _56; // in scope 28 at $DIR/reference_prop.rs:+70:13: +70:14
+ }
+ }
+ scope 29 {
+ debug a => _60; // in scope 29 at $DIR/reference_prop.rs:+76:13: +76:18
+ let _61: &mut usize; // in scope 29 at $DIR/reference_prop.rs:+77:13: +77:14
+ scope 30 {
+- debug b => _61; // in scope 30 at $DIR/reference_prop.rs:+77:13: +77:14
++ debug b => &_60; // in scope 30 at $DIR/reference_prop.rs:+77:13: +77:14
+ let _62: &&mut usize; // in scope 30 at $DIR/reference_prop.rs:+78:13: +78:14
+ scope 31 {
+- debug d => _62; // in scope 31 at $DIR/reference_prop.rs:+78:13: +78:14
++ debug d => &&_60; // in scope 31 at $DIR/reference_prop.rs:+78:13: +78:14
+ let _63: usize; // in scope 31 at $DIR/reference_prop.rs:+79:13: +79:14
+ scope 32 {
+ debug c => _63; // in scope 32 at $DIR/reference_prop.rs:+79:13: +79:14
+ }
+ }
+ }
+ }
+ scope 33 {
+ debug a => _66; // in scope 33 at $DIR/reference_prop.rs:+85:13: +85:18
+ let mut _67: &mut usize; // in scope 33 at $DIR/reference_prop.rs:+86:13: +86:18
+ scope 34 {
+- debug b => _67; // in scope 34 at $DIR/reference_prop.rs:+86:13: +86:18
++ debug b => &_66; // in scope 34 at $DIR/reference_prop.rs:+86:13: +86:18
+ let _68: &mut &mut usize; // in scope 34 at $DIR/reference_prop.rs:+87:13: +87:14
+ scope 35 {
+- debug d => _68; // in scope 35 at $DIR/reference_prop.rs:+87:13: +87:14
++ debug d => &&_66; // in scope 35 at $DIR/reference_prop.rs:+87:13: +87:14
+ let _69: usize; // in scope 35 at $DIR/reference_prop.rs:+88:13: +88:14
+ scope 36 {
+ debug c => _69; // in scope 36 at $DIR/reference_prop.rs:+88:13: +88:14
+ }
+ }
+ }
+ }
+
+ bb0: {
+- StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+ StorageLive(_4); // scope 0 at $DIR/reference_prop.rs:+3:13: +3:18
+ _4 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+3:21: +3:28
+- StorageLive(_5); // scope 1 at $DIR/reference_prop.rs:+4:13: +4:14
+- _5 = &mut _4; // scope 1 at $DIR/reference_prop.rs:+4:17: +4:23
+ StorageLive(_6); // scope 2 at $DIR/reference_prop.rs:+5:13: +5:14
+- _6 = (*_5); // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19
++ _6 = _4; // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19
+ StorageLive(_7); // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19
+ StorageLive(_8); // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18
+ _8 = (); // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18
+ _7 = opaque::<()>(move _8) -> bb1; // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:109:9: 109:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_8); // scope 3 at $DIR/reference_prop.rs:+6:18: +6:19
+ StorageDead(_7); // scope 3 at $DIR/reference_prop.rs:+6:19: +6:20
+- _3 = const (); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+ StorageDead(_6); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
+- StorageDead(_5); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6
+ StorageDead(_4); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+- StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+- StorageLive(_9); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+ StorageLive(_10); // scope 0 at $DIR/reference_prop.rs:+11:13: +11:18
+ _10 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+11:21: +11:28
+ StorageLive(_11); // scope 4 at $DIR/reference_prop.rs:+12:13: +12:19
+ _11 = const 7_usize; // scope 4 at $DIR/reference_prop.rs:+12:22: +12:29
+ StorageLive(_12); // scope 5 at $DIR/reference_prop.rs:+13:13: +13:18
+ _12 = &mut _10; // scope 5 at $DIR/reference_prop.rs:+13:21: +13:27
+ StorageLive(_13); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
+- StorageLive(_14); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
+- _14 = &mut _11; // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
+- _13 = &mut (*_14); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
++ _13 = &mut _11; // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
+ _12 = move _13; // scope 6 at $DIR/reference_prop.rs:+14:9: +14:20
+ StorageDead(_13); // scope 6 at $DIR/reference_prop.rs:+14:19: +14:20
+- StorageDead(_14); // scope 6 at $DIR/reference_prop.rs:+14:20: +14:21
+ StorageLive(_15); // scope 6 at $DIR/reference_prop.rs:+16:13: +16:14
+ _15 = (*_12); // scope 6 at $DIR/reference_prop.rs:+16:17: +16:19
+ StorageLive(_16); // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19
+ StorageLive(_17); // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18
+ _17 = (); // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18
+ _16 = opaque::<()>(move _17) -> bb2; // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:120:9: 120:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_17); // scope 7 at $DIR/reference_prop.rs:+17:18: +17:19
+ StorageDead(_16); // scope 7 at $DIR/reference_prop.rs:+17:19: +17:20
+- _9 = const (); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+ StorageDead(_15); // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6
+ StorageDead(_12); // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6
+ StorageDead(_11); // scope 4 at $DIR/reference_prop.rs:+18:5: +18:6
+ StorageDead(_10); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
+- StorageDead(_9); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
+- StorageLive(_18); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+ StorageLive(_19); // scope 0 at $DIR/reference_prop.rs:+22:13: +22:18
+ _19 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+22:21: +22:28
+ StorageLive(_20); // scope 8 at $DIR/reference_prop.rs:+23:13: +23:14
+ _20 = &mut _19; // scope 8 at $DIR/reference_prop.rs:+23:17: +23:23
+ StorageLive(_21); // scope 9 at $DIR/reference_prop.rs:+24:13: +24:14
+ _21 = &_20; // scope 9 at $DIR/reference_prop.rs:+24:17: +24:19
+ StorageLive(_22); // scope 10 at $DIR/reference_prop.rs:+25:13: +25:14
+ _22 = (*_20); // scope 10 at $DIR/reference_prop.rs:+25:17: +25:19
+ StorageLive(_23); // scope 11 at $DIR/reference_prop.rs:+26:9: +26:18
+ StorageLive(_24); // scope 11 at $DIR/reference_prop.rs:+26:16: +26:17
+ _24 = _21; // scope 11 at $DIR/reference_prop.rs:+26:16: +26:17
+ _23 = opaque::<&&mut usize>(move _24) -> bb3; // scope 11 at $DIR/reference_prop.rs:+26:9: +26:18
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:129:9: 129:15
+ // + literal: Const { ty: fn(&&mut usize) {opaque::<&&mut usize>}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_24); // scope 11 at $DIR/reference_prop.rs:+26:17: +26:18
+ StorageDead(_23); // scope 11 at $DIR/reference_prop.rs:+26:18: +26:19
+- _18 = const (); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+ StorageDead(_22); // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6
+ StorageDead(_21); // scope 9 at $DIR/reference_prop.rs:+27:5: +27:6
+ StorageDead(_20); // scope 8 at $DIR/reference_prop.rs:+27:5: +27:6
+ StorageDead(_19); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
+- StorageDead(_18); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
+- StorageLive(_25); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+ StorageLive(_26); // scope 0 at $DIR/reference_prop.rs:+31:13: +31:18
+ _26 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+31:21: +31:28
+ StorageLive(_27); // scope 12 at $DIR/reference_prop.rs:+32:13: +32:18
+ _27 = &mut _26; // scope 12 at $DIR/reference_prop.rs:+32:21: +32:27
+ StorageLive(_28); // scope 13 at $DIR/reference_prop.rs:+33:13: +33:14
+ _28 = &raw mut _27; // scope 13 at $DIR/reference_prop.rs:+33:17: +33:27
+ StorageLive(_29); // scope 14 at $DIR/reference_prop.rs:+34:13: +34:14
+ _29 = (*_27); // scope 14 at $DIR/reference_prop.rs:+34:17: +34:19
+ StorageLive(_30); // scope 15 at $DIR/reference_prop.rs:+35:9: +35:18
+ StorageLive(_31); // scope 15 at $DIR/reference_prop.rs:+35:16: +35:17
+ _31 = _28; // scope 15 at $DIR/reference_prop.rs:+35:16: +35:17
+ _30 = opaque::<*mut &mut usize>(move _31) -> bb4; // scope 15 at $DIR/reference_prop.rs:+35:9: +35:18
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:138:9: 138:15
+ // + literal: Const { ty: fn(*mut &mut usize) {opaque::<*mut &mut usize>}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ StorageDead(_31); // scope 15 at $DIR/reference_prop.rs:+35:17: +35:18
+ StorageDead(_30); // scope 15 at $DIR/reference_prop.rs:+35:18: +35:19
+- _25 = const (); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+ StorageDead(_29); // scope 14 at $DIR/reference_prop.rs:+36:5: +36:6
+ StorageDead(_28); // scope 13 at $DIR/reference_prop.rs:+36:5: +36:6
+ StorageDead(_27); // scope 12 at $DIR/reference_prop.rs:+36:5: +36:6
+ StorageDead(_26); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
+- StorageDead(_25); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
+- StorageLive(_32); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+ StorageLive(_33); // scope 0 at $DIR/reference_prop.rs:+40:13: +40:18
+ _33 = const 7_usize; // scope 0 at $DIR/reference_prop.rs:+40:21: +40:28
+ StorageLive(_34); // scope 16 at $DIR/reference_prop.rs:+41:13: +41:14
+ _34 = &mut _33; // scope 16 at $DIR/reference_prop.rs:+41:17: +41:23
+ StorageLive(_35); // scope 17 at $DIR/reference_prop.rs:+42:13: +42:14
+ _35 = (*_34); // scope 17 at $DIR/reference_prop.rs:+42:17: +42:19
+ StorageLive(_36); // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18
+ StorageLive(_37); // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17
+ _37 = move _34; // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17
+ _36 = opaque::<&mut usize>(move _37) -> bb5; // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:146:9: 146:15
+ // + literal: Const { ty: fn(&mut usize) {opaque::<&mut usize>}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ StorageDead(_37); // scope 18 at $DIR/reference_prop.rs:+43:17: +43:18
+ StorageDead(_36); // scope 18 at $DIR/reference_prop.rs:+43:18: +43:19
+- _32 = const (); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+ StorageDead(_35); // scope 17 at $DIR/reference_prop.rs:+44:5: +44:6
+ StorageDead(_34); // scope 16 at $DIR/reference_prop.rs:+44:5: +44:6
+ StorageDead(_33); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
+- StorageDead(_32); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
+- StorageLive(_38); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+ StorageLive(_39); // scope 0 at $DIR/reference_prop.rs:+48:13: +48:18
+ _39 = const 7_usize; // scope 0 at $DIR/reference_prop.rs:+48:21: +48:28
+ StorageLive(_40); // scope 19 at $DIR/reference_prop.rs:+49:13: +49:15
+ _40 = &mut _39; // scope 19 at $DIR/reference_prop.rs:+49:18: +49:24
+ StorageLive(_41); // scope 20 at $DIR/reference_prop.rs:+50:13: +50:14
+ _41 = (*_40); // scope 20 at $DIR/reference_prop.rs:+50:17: +50:20
+ StorageLive(_42); // scope 21 at $DIR/reference_prop.rs:+51:13: +51:15
+ _42 = move _40; // scope 21 at $DIR/reference_prop.rs:+51:18: +51:20
+ StorageLive(_43); // scope 22 at $DIR/reference_prop.rs:+52:13: +52:15
+ _43 = (*_42); // scope 22 at $DIR/reference_prop.rs:+52:18: +52:21
+ StorageLive(_44); // scope 23 at $DIR/reference_prop.rs:+53:13: +53:15
+ _44 = move _42; // scope 23 at $DIR/reference_prop.rs:+53:18: +53:20
+ StorageLive(_45); // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19
+ StorageLive(_46); // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18
+ _46 = move _44; // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18
+ _45 = opaque::<&mut usize>(move _46) -> bb6; // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:159:9: 159:15
+ // + literal: Const { ty: fn(&mut usize) {opaque::<&mut usize>}, val: Value(<ZST>) }
+ }
+
+ bb6: {
+ StorageDead(_46); // scope 24 at $DIR/reference_prop.rs:+56:18: +56:19
+ StorageDead(_45); // scope 24 at $DIR/reference_prop.rs:+56:19: +56:20
+- _38 = const (); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+ StorageDead(_44); // scope 23 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_43); // scope 22 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_42); // scope 21 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_41); // scope 20 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_40); // scope 19 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_39); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
+- StorageDead(_38); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
+- StorageLive(_47); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+- StorageLive(_48); // scope 0 at $DIR/reference_prop.rs:+61:13: +61:14
+- _48 = &mut (*_1); // scope 0 at $DIR/reference_prop.rs:+61:17: +61:29
+ StorageLive(_49); // scope 25 at $DIR/reference_prop.rs:+62:13: +62:14
+- _49 = (*_48); // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19
++ _49 = (*_1); // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19
+ StorageLive(_50); // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19
+ StorageLive(_51); // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18
+ _51 = (); // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18
+ _50 = opaque::<()>(move _51) -> bb7; // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:166:9: 166:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb7: {
+ StorageDead(_51); // scope 26 at $DIR/reference_prop.rs:+63:18: +63:19
+ StorageDead(_50); // scope 26 at $DIR/reference_prop.rs:+63:19: +63:20
+- _47 = const (); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+ StorageDead(_49); // scope 25 at $DIR/reference_prop.rs:+64:5: +64:6
+- StorageDead(_48); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
+- StorageDead(_47); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
+- StorageLive(_52); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+ StorageLive(_53); // scope 0 at $DIR/reference_prop.rs:+68:13: +68:14
+ _53 = &mut (*_2); // scope 0 at $DIR/reference_prop.rs:+68:17: +68:31
+ StorageLive(_54); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
+- StorageLive(_55); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
+- _55 = &mut (*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
+- _54 = &mut (*_55); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
++ _54 = &mut (*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
+ _2 = move _54; // scope 27 at $DIR/reference_prop.rs:+69:9: +69:32
+ StorageDead(_54); // scope 27 at $DIR/reference_prop.rs:+69:31: +69:32
+- StorageDead(_55); // scope 27 at $DIR/reference_prop.rs:+69:32: +69:33
+ StorageLive(_56); // scope 27 at $DIR/reference_prop.rs:+70:13: +70:14
+ _56 = (*_53); // scope 27 at $DIR/reference_prop.rs:+70:17: +70:19
+ StorageLive(_57); // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19
+ StorageLive(_58); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18
+ _58 = (); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18
+ _57 = opaque::<()>(move _58) -> bb8; // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:174:9: 174:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb8: {
+ StorageDead(_58); // scope 28 at $DIR/reference_prop.rs:+71:18: +71:19
+ StorageDead(_57); // scope 28 at $DIR/reference_prop.rs:+71:19: +71:20
+- _52 = const (); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+ StorageDead(_56); // scope 27 at $DIR/reference_prop.rs:+72:5: +72:6
+ StorageDead(_53); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6
+- StorageDead(_52); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6
+- StorageLive(_59); // scope 0 at $DIR/reference_prop.rs:+75:5: +81:6
+ StorageLive(_60); // scope 0 at $DIR/reference_prop.rs:+76:13: +76:18
+ _60 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+76:21: +76:28
+- StorageLive(_61); // scope 29 at $DIR/reference_prop.rs:+77:13: +77:14
+- _61 = &mut _60; // scope 29 at $DIR/reference_prop.rs:+77:17: +77:23
+- StorageLive(_62); // scope 30 at $DIR/reference_prop.rs:+78:13: +78:14
+- _62 = &_61; // scope 30 at $DIR/reference_prop.rs:+78:17: +78:19
+ StorageLive(_63); // scope 31 at $DIR/reference_prop.rs:+79:13: +79:14
+- _63 = (*_61); // scope 31 at $DIR/reference_prop.rs:+79:17: +79:19
++ _63 = _60; // scope 31 at $DIR/reference_prop.rs:+79:17: +79:19
+ StorageLive(_64); // scope 32 at $DIR/reference_prop.rs:+80:9: +80:19
+ StorageLive(_65); // scope 32 at $DIR/reference_prop.rs:+80:16: +80:18
+ _65 = (); // scope 32 at $DIR/reference_prop.rs:+80:16: +80:18
+ _64 = opaque::<()>(move _65) -> bb9; // scope 32 at $DIR/reference_prop.rs:+80:9: +80:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:183:9: 183:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb9: {
+ StorageDead(_65); // scope 32 at $DIR/reference_prop.rs:+80:18: +80:19
+ StorageDead(_64); // scope 32 at $DIR/reference_prop.rs:+80:19: +80:20
+- _59 = const (); // scope 0 at $DIR/reference_prop.rs:+75:5: +81:6
+ StorageDead(_63); // scope 31 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageDead(_62); // scope 30 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageDead(_61); // scope 29 at $DIR/reference_prop.rs:+81:5: +81:6
+ StorageDead(_60); // scope 0 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageDead(_59); // scope 0 at $DIR/reference_prop.rs:+81:5: +81:6
+ StorageLive(_66); // scope 0 at $DIR/reference_prop.rs:+85:13: +85:18
+ _66 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+85:21: +85:28
+- StorageLive(_67); // scope 33 at $DIR/reference_prop.rs:+86:13: +86:18
+- _67 = &mut _66; // scope 33 at $DIR/reference_prop.rs:+86:21: +86:27
+- StorageLive(_68); // scope 34 at $DIR/reference_prop.rs:+87:13: +87:14
+- _68 = &mut _67; // scope 34 at $DIR/reference_prop.rs:+87:17: +87:23
+ StorageLive(_69); // scope 35 at $DIR/reference_prop.rs:+88:13: +88:14
+- _69 = (*_67); // scope 35 at $DIR/reference_prop.rs:+88:17: +88:19
++ _69 = _66; // scope 35 at $DIR/reference_prop.rs:+88:17: +88:19
+ StorageLive(_70); // scope 36 at $DIR/reference_prop.rs:+89:9: +89:19
+ StorageLive(_71); // scope 36 at $DIR/reference_prop.rs:+89:16: +89:18
+ _71 = (); // scope 36 at $DIR/reference_prop.rs:+89:16: +89:18
+ _70 = opaque::<()>(move _71) -> bb10; // scope 36 at $DIR/reference_prop.rs:+89:9: +89:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:192:9: 192:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb10: {
+ StorageDead(_71); // scope 36 at $DIR/reference_prop.rs:+89:18: +89:19
+ StorageDead(_70); // scope 36 at $DIR/reference_prop.rs:+89:19: +89:20
+ _0 = const (); // scope 0 at $DIR/reference_prop.rs:+84:5: +90:6
+ StorageDead(_69); // scope 35 at $DIR/reference_prop.rs:+90:5: +90:6
+- StorageDead(_68); // scope 34 at $DIR/reference_prop.rs:+90:5: +90:6
+- StorageDead(_67); // scope 33 at $DIR/reference_prop.rs:+90:5: +90:6
+ StorageDead(_66); // scope 0 at $DIR/reference_prop.rs:+90:5: +90:6
+ return; // scope 0 at $DIR/reference_prop.rs:+91:2: +91:2
+ }
+ }
+
diff --git a/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
new file mode 100644
index 00000000000..c93aa52be11
--- /dev/null
+++ b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
@@ -0,0 +1,482 @@
+- // MIR for `reference_propagation_mut_ptr` before ReferencePropagation
++ // MIR for `reference_propagation_mut_ptr` after ReferencePropagation
+
+ fn reference_propagation_mut_ptr(_1: *mut T, _2: *mut T) -> () {
+ debug single => _1; // in scope 0 at $DIR/reference_prop.rs:+0:43: +0:49
+ debug multiple => _2; // in scope 0 at $DIR/reference_prop.rs:+0:59: +0:71
+ let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:81: +0:81
+ let _3: (); // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+ let _7: (); // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19
+ let mut _8: (); // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18
+ let _9: (); // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+ let mut _13: *mut usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:24
+ let _15: (); // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19
+ let mut _16: (); // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18
+ let _17: (); // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+ let _22: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:18
+ let mut _23: &*mut usize; // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:17
+ let _24: (); // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+ let _29: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:18
+ let mut _30: *mut *mut usize; // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:17
+ let _31: (); // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+ let _35: (); // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18
+ let mut _36: *mut usize; // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17
+ let _37: (); // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+ let _44: (); // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19
+ let mut _45: *mut usize; // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18
+ let _46: (); // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+ let _49: (); // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19
+ let mut _50: (); // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18
+ let _51: (); // in scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+ let mut _53: *mut T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:36
+ let _55: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19
+ let mut _56: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18
+ let _57: (); // in scope 0 at $DIR/reference_prop.rs:+75:5: +81:6
+ let _62: (); // in scope 0 at $DIR/reference_prop.rs:+80:9: +80:19
+ let mut _63: (); // in scope 0 at $DIR/reference_prop.rs:+80:16: +80:18
+ let _68: (); // in scope 0 at $DIR/reference_prop.rs:+89:9: +89:19
+ let mut _69: (); // in scope 0 at $DIR/reference_prop.rs:+89:16: +89:18
+ scope 1 {
+ let mut _4: usize; // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:18
+ scope 2 {
+ debug a => _4; // in scope 2 at $DIR/reference_prop.rs:+3:13: +3:18
+ let _5: *mut usize; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
+ scope 3 {
+- debug b => _5; // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14
++ debug b => &_4; // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14
+ let _6: usize; // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
+ scope 4 {
+ debug c => _6; // in scope 4 at $DIR/reference_prop.rs:+5:13: +5:14
+ }
+ }
+ }
+ }
+ scope 5 {
+ let mut _10: usize; // in scope 5 at $DIR/reference_prop.rs:+11:13: +11:18
+ scope 6 {
+ debug a => _10; // in scope 6 at $DIR/reference_prop.rs:+11:13: +11:18
+ let mut _11: usize; // in scope 6 at $DIR/reference_prop.rs:+12:13: +12:19
+ scope 7 {
+ debug a2 => _11; // in scope 7 at $DIR/reference_prop.rs:+12:13: +12:19
+ let mut _12: *mut usize; // in scope 7 at $DIR/reference_prop.rs:+13:13: +13:18
+ scope 8 {
+ debug b => _12; // in scope 8 at $DIR/reference_prop.rs:+13:13: +13:18
+ let _14: usize; // in scope 8 at $DIR/reference_prop.rs:+16:13: +16:14
+ scope 9 {
+ debug c => _14; // in scope 9 at $DIR/reference_prop.rs:+16:13: +16:14
+ }
+ }
+ }
+ }
+ }
+ scope 10 {
+ let mut _18: usize; // in scope 10 at $DIR/reference_prop.rs:+22:13: +22:18
+ scope 11 {
+ debug a => _18; // in scope 11 at $DIR/reference_prop.rs:+22:13: +22:18
+ let _19: *mut usize; // in scope 11 at $DIR/reference_prop.rs:+23:13: +23:14
+ scope 12 {
+ debug b => _19; // in scope 12 at $DIR/reference_prop.rs:+23:13: +23:14
+ let _20: &*mut usize; // in scope 12 at $DIR/reference_prop.rs:+24:13: +24:14
+ scope 13 {
+ debug d => _20; // in scope 13 at $DIR/reference_prop.rs:+24:13: +24:14
+ let _21: usize; // in scope 13 at $DIR/reference_prop.rs:+25:13: +25:14
+ scope 14 {
+ debug c => _21; // in scope 14 at $DIR/reference_prop.rs:+25:13: +25:14
+ }
+ }
+ }
+ }
+ }
+ scope 15 {
+ let mut _25: usize; // in scope 15 at $DIR/reference_prop.rs:+31:13: +31:18
+ scope 16 {
+ debug a => _25; // in scope 16 at $DIR/reference_prop.rs:+31:13: +31:18
+ let mut _26: *mut usize; // in scope 16 at $DIR/reference_prop.rs:+32:13: +32:18
+ scope 17 {
+ debug b => _26; // in scope 17 at $DIR/reference_prop.rs:+32:13: +32:18
+ let _27: *mut *mut usize; // in scope 17 at $DIR/reference_prop.rs:+33:13: +33:14
+ scope 18 {
+ debug d => _27; // in scope 18 at $DIR/reference_prop.rs:+33:13: +33:14
+ let _28: usize; // in scope 18 at $DIR/reference_prop.rs:+34:13: +34:14
+ scope 19 {
+ debug c => _28; // in scope 19 at $DIR/reference_prop.rs:+34:13: +34:14
+ }
+ }
+ }
+ }
+ }
+ scope 20 {
+ let mut _32: usize; // in scope 20 at $DIR/reference_prop.rs:+40:13: +40:18
+ scope 21 {
+ debug a => _32; // in scope 21 at $DIR/reference_prop.rs:+40:13: +40:18
+ let _33: *mut usize; // in scope 21 at $DIR/reference_prop.rs:+41:13: +41:14
+ scope 22 {
+ debug b => _33; // in scope 22 at $DIR/reference_prop.rs:+41:13: +41:14
+ let _34: usize; // in scope 22 at $DIR/reference_prop.rs:+42:13: +42:14
+ scope 23 {
+ debug c => _34; // in scope 23 at $DIR/reference_prop.rs:+42:13: +42:14
+ }
+ }
+ }
+ }
+ scope 24 {
+ let mut _38: usize; // in scope 24 at $DIR/reference_prop.rs:+48:13: +48:18
+ scope 25 {
+ debug a => _38; // in scope 25 at $DIR/reference_prop.rs:+48:13: +48:18
+ let _39: *mut usize; // in scope 25 at $DIR/reference_prop.rs:+49:13: +49:15
+ scope 26 {
+ debug b1 => _39; // in scope 26 at $DIR/reference_prop.rs:+49:13: +49:15
+ let _40: usize; // in scope 26 at $DIR/reference_prop.rs:+50:13: +50:14
+ scope 27 {
+ debug c => _40; // in scope 27 at $DIR/reference_prop.rs:+50:13: +50:14
+ let _41: *mut usize; // in scope 27 at $DIR/reference_prop.rs:+51:13: +51:15
+ scope 28 {
+ debug b2 => _41; // in scope 28 at $DIR/reference_prop.rs:+51:13: +51:15
+ let _42: usize; // in scope 28 at $DIR/reference_prop.rs:+52:13: +52:15
+ scope 29 {
+ debug c2 => _42; // in scope 29 at $DIR/reference_prop.rs:+52:13: +52:15
+ let _43: *mut usize; // in scope 29 at $DIR/reference_prop.rs:+53:13: +53:15
+ scope 30 {
+ debug b3 => _43; // in scope 30 at $DIR/reference_prop.rs:+53:13: +53:15
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ scope 31 {
+ let _47: *mut T; // in scope 31 at $DIR/reference_prop.rs:+61:13: +61:14
+ scope 32 {
+- debug a => _47; // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14
++ debug a => _1; // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14
+ let _48: T; // in scope 32 at $DIR/reference_prop.rs:+62:13: +62:14
+ scope 33 {
+ debug b => _48; // in scope 33 at $DIR/reference_prop.rs:+62:13: +62:14
+ }
+ }
+ }
+ scope 34 {
+ let _52: *mut T; // in scope 34 at $DIR/reference_prop.rs:+68:13: +68:14
+ scope 35 {
+ debug a => _52; // in scope 35 at $DIR/reference_prop.rs:+68:13: +68:14
+ let _54: T; // in scope 35 at $DIR/reference_prop.rs:+70:13: +70:14
+ scope 36 {
+ debug b => _54; // in scope 36 at $DIR/reference_prop.rs:+70:13: +70:14
+ }
+ }
+ }
+ scope 37 {
+ let mut _58: usize; // in scope 37 at $DIR/reference_prop.rs:+76:13: +76:18
+ scope 38 {
+ debug a => _58; // in scope 38 at $DIR/reference_prop.rs:+76:13: +76:18
+ let _59: *mut usize; // in scope 38 at $DIR/reference_prop.rs:+77:13: +77:14
+ scope 39 {
+- debug b => _59; // in scope 39 at $DIR/reference_prop.rs:+77:13: +77:14
++ debug b => &_58; // in scope 39 at $DIR/reference_prop.rs:+77:13: +77:14
+ let _60: &*mut usize; // in scope 39 at $DIR/reference_prop.rs:+78:13: +78:14
+ scope 40 {
+- debug d => _60; // in scope 40 at $DIR/reference_prop.rs:+78:13: +78:14
++ debug d => &&_58; // in scope 40 at $DIR/reference_prop.rs:+78:13: +78:14
+ let _61: usize; // in scope 40 at $DIR/reference_prop.rs:+79:13: +79:14
+ scope 41 {
+ debug c => _61; // in scope 41 at $DIR/reference_prop.rs:+79:13: +79:14
+ }
+ }
+ }
+ }
+ }
+ scope 42 {
+ let mut _64: usize; // in scope 42 at $DIR/reference_prop.rs:+85:13: +85:18
+ scope 43 {
+ debug a => _64; // in scope 43 at $DIR/reference_prop.rs:+85:13: +85:18
+ let mut _65: *mut usize; // in scope 43 at $DIR/reference_prop.rs:+86:13: +86:18
+ scope 44 {
+- debug b => _65; // in scope 44 at $DIR/reference_prop.rs:+86:13: +86:18
++ debug b => &_64; // in scope 44 at $DIR/reference_prop.rs:+86:13: +86:18
+ let _66: &mut *mut usize; // in scope 44 at $DIR/reference_prop.rs:+87:13: +87:14
+ scope 45 {
+- debug d => _66; // in scope 45 at $DIR/reference_prop.rs:+87:13: +87:14
++ debug d => &&_64; // in scope 45 at $DIR/reference_prop.rs:+87:13: +87:14
+ let _67: usize; // in scope 45 at $DIR/reference_prop.rs:+88:13: +88:14
+ scope 46 {
+ debug c => _67; // in scope 46 at $DIR/reference_prop.rs:+88:13: +88:14
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+- StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+ StorageLive(_4); // scope 1 at $DIR/reference_prop.rs:+3:13: +3:18
+ _4 = const 5_usize; // scope 1 at $DIR/reference_prop.rs:+3:21: +3:28
+- StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
+- _5 = &raw mut _4; // scope 2 at $DIR/reference_prop.rs:+4:17: +4:27
+ StorageLive(_6); // scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
+- _6 = (*_5); // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19
++ _6 = _4; // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19
+ StorageLive(_7); // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19
+ StorageLive(_8); // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18
+ _8 = (); // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18
+ _7 = opaque::<()>(move _8) -> bb1; // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:304:9: 304:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_8); // scope 4 at $DIR/reference_prop.rs:+6:18: +6:19
+ StorageDead(_7); // scope 4 at $DIR/reference_prop.rs:+6:19: +6:20
+- _3 = const (); // scope 1 at $DIR/reference_prop.rs:+2:5: +7:6
+ StorageDead(_6); // scope 3 at $DIR/reference_prop.rs:+7:5: +7:6
+- StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
+ StorageDead(_4); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6
+- StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+- StorageLive(_9); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+ StorageLive(_10); // scope 5 at $DIR/reference_prop.rs:+11:13: +11:18
+ _10 = const 5_usize; // scope 5 at $DIR/reference_prop.rs:+11:21: +11:28
+ StorageLive(_11); // scope 6 at $DIR/reference_prop.rs:+12:13: +12:19
+ _11 = const 7_usize; // scope 6 at $DIR/reference_prop.rs:+12:22: +12:29
+ StorageLive(_12); // scope 7 at $DIR/reference_prop.rs:+13:13: +13:18
+ _12 = &raw mut _10; // scope 7 at $DIR/reference_prop.rs:+13:21: +13:31
+ StorageLive(_13); // scope 8 at $DIR/reference_prop.rs:+14:13: +14:24
+ _13 = &raw mut _11; // scope 8 at $DIR/reference_prop.rs:+14:13: +14:24
+ _12 = move _13; // scope 8 at $DIR/reference_prop.rs:+14:9: +14:24
+ StorageDead(_13); // scope 8 at $DIR/reference_prop.rs:+14:23: +14:24
+ StorageLive(_14); // scope 8 at $DIR/reference_prop.rs:+16:13: +16:14
+ _14 = (*_12); // scope 8 at $DIR/reference_prop.rs:+16:17: +16:19
+ StorageLive(_15); // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19
+ StorageLive(_16); // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18
+ _16 = (); // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18
+ _15 = opaque::<()>(move _16) -> bb2; // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:315:9: 315:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_16); // scope 9 at $DIR/reference_prop.rs:+17:18: +17:19
+ StorageDead(_15); // scope 9 at $DIR/reference_prop.rs:+17:19: +17:20
+- _9 = const (); // scope 5 at $DIR/reference_prop.rs:+10:5: +18:6
+ StorageDead(_14); // scope 8 at $DIR/reference_prop.rs:+18:5: +18:6
+ StorageDead(_12); // scope 7 at $DIR/reference_prop.rs:+18:5: +18:6
+ StorageDead(_11); // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6
+ StorageDead(_10); // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6
+- StorageDead(_9); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
+- StorageLive(_17); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+ StorageLive(_18); // scope 10 at $DIR/reference_prop.rs:+22:13: +22:18
+ _18 = const 5_usize; // scope 10 at $DIR/reference_prop.rs:+22:21: +22:28
+ StorageLive(_19); // scope 11 at $DIR/reference_prop.rs:+23:13: +23:14
+ _19 = &raw mut _18; // scope 11 at $DIR/reference_prop.rs:+23:17: +23:27
+ StorageLive(_20); // scope 12 at $DIR/reference_prop.rs:+24:13: +24:14
+ _20 = &_19; // scope 12 at $DIR/reference_prop.rs:+24:17: +24:19
+ StorageLive(_21); // scope 13 at $DIR/reference_prop.rs:+25:13: +25:14
+ _21 = (*_19); // scope 13 at $DIR/reference_prop.rs:+25:17: +25:19
+ StorageLive(_22); // scope 14 at $DIR/reference_prop.rs:+26:9: +26:18
+ StorageLive(_23); // scope 14 at $DIR/reference_prop.rs:+26:16: +26:17
+ _23 = _20; // scope 14 at $DIR/reference_prop.rs:+26:16: +26:17
+ _22 = opaque::<&*mut usize>(move _23) -> bb3; // scope 14 at $DIR/reference_prop.rs:+26:9: +26:18
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:324:9: 324:15
+ // + literal: Const { ty: fn(&*mut usize) {opaque::<&*mut usize>}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_23); // scope 14 at $DIR/reference_prop.rs:+26:17: +26:18
+ StorageDead(_22); // scope 14 at $DIR/reference_prop.rs:+26:18: +26:19
+- _17 = const (); // scope 10 at $DIR/reference_prop.rs:+21:5: +27:6
+ StorageDead(_21); // scope 13 at $DIR/reference_prop.rs:+27:5: +27:6
+ StorageDead(_20); // scope 12 at $DIR/reference_prop.rs:+27:5: +27:6
+ StorageDead(_19); // scope 11 at $DIR/reference_prop.rs:+27:5: +27:6
+ StorageDead(_18); // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6
+- StorageDead(_17); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
+- StorageLive(_24); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+ StorageLive(_25); // scope 15 at $DIR/reference_prop.rs:+31:13: +31:18
+ _25 = const 5_usize; // scope 15 at $DIR/reference_prop.rs:+31:21: +31:28
+ StorageLive(_26); // scope 16 at $DIR/reference_prop.rs:+32:13: +32:18
+ _26 = &raw mut _25; // scope 16 at $DIR/reference_prop.rs:+32:21: +32:31
+ StorageLive(_27); // scope 17 at $DIR/reference_prop.rs:+33:13: +33:14
+ _27 = &raw mut _26; // scope 17 at $DIR/reference_prop.rs:+33:17: +33:27
+ StorageLive(_28); // scope 18 at $DIR/reference_prop.rs:+34:13: +34:14
+ _28 = (*_26); // scope 18 at $DIR/reference_prop.rs:+34:17: +34:19
+ StorageLive(_29); // scope 19 at $DIR/reference_prop.rs:+35:9: +35:18
+ StorageLive(_30); // scope 19 at $DIR/reference_prop.rs:+35:16: +35:17
+ _30 = _27; // scope 19 at $DIR/reference_prop.rs:+35:16: +35:17
+ _29 = opaque::<*mut *mut usize>(move _30) -> bb4; // scope 19 at $DIR/reference_prop.rs:+35:9: +35:18
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:333:9: 333:15
+ // + literal: Const { ty: fn(*mut *mut usize) {opaque::<*mut *mut usize>}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ StorageDead(_30); // scope 19 at $DIR/reference_prop.rs:+35:17: +35:18
+ StorageDead(_29); // scope 19 at $DIR/reference_prop.rs:+35:18: +35:19
+- _24 = const (); // scope 15 at $DIR/reference_prop.rs:+30:5: +36:6
+ StorageDead(_28); // scope 18 at $DIR/reference_prop.rs:+36:5: +36:6
+ StorageDead(_27); // scope 17 at $DIR/reference_prop.rs:+36:5: +36:6
+ StorageDead(_26); // scope 16 at $DIR/reference_prop.rs:+36:5: +36:6
+ StorageDead(_25); // scope 15 at $DIR/reference_prop.rs:+36:5: +36:6
+- StorageDead(_24); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
+- StorageLive(_31); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+ StorageLive(_32); // scope 20 at $DIR/reference_prop.rs:+40:13: +40:18
+ _32 = const 7_usize; // scope 20 at $DIR/reference_prop.rs:+40:21: +40:28
+ StorageLive(_33); // scope 21 at $DIR/reference_prop.rs:+41:13: +41:14
+ _33 = &raw mut _32; // scope 21 at $DIR/reference_prop.rs:+41:17: +41:27
+ StorageLive(_34); // scope 22 at $DIR/reference_prop.rs:+42:13: +42:14
+ _34 = (*_33); // scope 22 at $DIR/reference_prop.rs:+42:17: +42:19
+ StorageLive(_35); // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18
+ StorageLive(_36); // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17
+ _36 = _33; // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17
+ _35 = opaque::<*mut usize>(move _36) -> bb5; // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:341:9: 341:15
+ // + literal: Const { ty: fn(*mut usize) {opaque::<*mut usize>}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ StorageDead(_36); // scope 23 at $DIR/reference_prop.rs:+43:17: +43:18
+ StorageDead(_35); // scope 23 at $DIR/reference_prop.rs:+43:18: +43:19
+- _31 = const (); // scope 20 at $DIR/reference_prop.rs:+39:5: +44:6
+ StorageDead(_34); // scope 22 at $DIR/reference_prop.rs:+44:5: +44:6
+ StorageDead(_33); // scope 21 at $DIR/reference_prop.rs:+44:5: +44:6
+ StorageDead(_32); // scope 20 at $DIR/reference_prop.rs:+44:5: +44:6
+- StorageDead(_31); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
+- StorageLive(_37); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+ StorageLive(_38); // scope 24 at $DIR/reference_prop.rs:+48:13: +48:18
+ _38 = const 7_usize; // scope 24 at $DIR/reference_prop.rs:+48:21: +48:28
+ StorageLive(_39); // scope 25 at $DIR/reference_prop.rs:+49:13: +49:15
+ _39 = &raw mut _38; // scope 25 at $DIR/reference_prop.rs:+49:18: +49:28
+ StorageLive(_40); // scope 26 at $DIR/reference_prop.rs:+50:13: +50:14
+ _40 = (*_39); // scope 26 at $DIR/reference_prop.rs:+50:17: +50:20
+ StorageLive(_41); // scope 27 at $DIR/reference_prop.rs:+51:13: +51:15
+ _41 = _39; // scope 27 at $DIR/reference_prop.rs:+51:18: +51:20
+ StorageLive(_42); // scope 28 at $DIR/reference_prop.rs:+52:13: +52:15
+ _42 = (*_41); // scope 28 at $DIR/reference_prop.rs:+52:18: +52:21
+ StorageLive(_43); // scope 29 at $DIR/reference_prop.rs:+53:13: +53:15
+ _43 = _41; // scope 29 at $DIR/reference_prop.rs:+53:18: +53:20
+ StorageLive(_44); // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19
+ StorageLive(_45); // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18
+ _45 = _43; // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18
+ _44 = opaque::<*mut usize>(move _45) -> bb6; // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:354:9: 354:15
+ // + literal: Const { ty: fn(*mut usize) {opaque::<*mut usize>}, val: Value(<ZST>) }
+ }
+
+ bb6: {
+ StorageDead(_45); // scope 30 at $DIR/reference_prop.rs:+56:18: +56:19
+ StorageDead(_44); // scope 30 at $DIR/reference_prop.rs:+56:19: +56:20
+- _37 = const (); // scope 24 at $DIR/reference_prop.rs:+47:5: +57:6
+ StorageDead(_43); // scope 29 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_42); // scope 28 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_41); // scope 27 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_40); // scope 26 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_39); // scope 25 at $DIR/reference_prop.rs:+57:5: +57:6
+ StorageDead(_38); // scope 24 at $DIR/reference_prop.rs:+57:5: +57:6
+- StorageDead(_37); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
+- StorageLive(_46); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+- StorageLive(_47); // scope 31 at $DIR/reference_prop.rs:+61:13: +61:14
+- _47 = &raw mut (*_1); // scope 31 at $DIR/reference_prop.rs:+61:17: +61:33
+ StorageLive(_48); // scope 32 at $DIR/reference_prop.rs:+62:13: +62:14
+- _48 = (*_47); // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19
++ _48 = (*_1); // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19
+ StorageLive(_49); // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19
+ StorageLive(_50); // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18
+ _50 = (); // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18
+ _49 = opaque::<()>(move _50) -> bb7; // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:361:9: 361:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb7: {
+ StorageDead(_50); // scope 33 at $DIR/reference_prop.rs:+63:18: +63:19
+ StorageDead(_49); // scope 33 at $DIR/reference_prop.rs:+63:19: +63:20
+- _46 = const (); // scope 31 at $DIR/reference_prop.rs:+60:5: +64:6
+ StorageDead(_48); // scope 32 at $DIR/reference_prop.rs:+64:5: +64:6
+- StorageDead(_47); // scope 31 at $DIR/reference_prop.rs:+64:5: +64:6
+- StorageDead(_46); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
+- StorageLive(_51); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+ StorageLive(_52); // scope 34 at $DIR/reference_prop.rs:+68:13: +68:14
+ _52 = &raw mut (*_2); // scope 34 at $DIR/reference_prop.rs:+68:17: +68:35
+ StorageLive(_53); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:36
+ _53 = &raw mut (*_1); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:36
+ _2 = move _53; // scope 35 at $DIR/reference_prop.rs:+69:9: +69:36
+ StorageDead(_53); // scope 35 at $DIR/reference_prop.rs:+69:35: +69:36
+ StorageLive(_54); // scope 35 at $DIR/reference_prop.rs:+70:13: +70:14
+ _54 = (*_52); // scope 35 at $DIR/reference_prop.rs:+70:17: +70:19
+ StorageLive(_55); // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19
+ StorageLive(_56); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18
+ _56 = (); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18
+ _55 = opaque::<()>(move _56) -> bb8; // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:369:9: 369:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb8: {
+ StorageDead(_56); // scope 36 at $DIR/reference_prop.rs:+71:18: +71:19
+ StorageDead(_55); // scope 36 at $DIR/reference_prop.rs:+71:19: +71:20
+- _51 = const (); // scope 34 at $DIR/reference_prop.rs:+67:5: +72:6
+ StorageDead(_54); // scope 35 at $DIR/reference_prop.rs:+72:5: +72:6
+ StorageDead(_52); // scope 34 at $DIR/reference_prop.rs:+72:5: +72:6
+- StorageDead(_51); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6
+- StorageLive(_57); // scope 0 at $DIR/reference_prop.rs:+75:5: +81:6
+ StorageLive(_58); // scope 37 at $DIR/reference_prop.rs:+76:13: +76:18
+ _58 = const 5_usize; // scope 37 at $DIR/reference_prop.rs:+76:21: +76:28
+- StorageLive(_59); // scope 38 at $DIR/reference_prop.rs:+77:13: +77:14
+- _59 = &raw mut _58; // scope 38 at $DIR/reference_prop.rs:+77:17: +77:27
+- StorageLive(_60); // scope 39 at $DIR/reference_prop.rs:+78:13: +78:14
+- _60 = &_59; // scope 39 at $DIR/reference_prop.rs:+78:17: +78:19
+ StorageLive(_61); // scope 40 at $DIR/reference_prop.rs:+79:13: +79:14
+- _61 = (*_59); // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19
++ _61 = _58; // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19
+ StorageLive(_62); // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19
+ StorageLive(_63); // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18
+ _63 = (); // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18
+ _62 = opaque::<()>(move _63) -> bb9; // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:378:9: 378:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb9: {
+ StorageDead(_63); // scope 41 at $DIR/reference_prop.rs:+80:18: +80:19
+ StorageDead(_62); // scope 41 at $DIR/reference_prop.rs:+80:19: +80:20
+- _57 = const (); // scope 37 at $DIR/reference_prop.rs:+75:5: +81:6
+ StorageDead(_61); // scope 40 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageDead(_60); // scope 39 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageDead(_59); // scope 38 at $DIR/reference_prop.rs:+81:5: +81:6
+ StorageDead(_58); // scope 37 at $DIR/reference_prop.rs:+81:5: +81:6
+- StorageDead(_57); // scope 0 at $DIR/reference_prop.rs:+81:5: +81:6
+ StorageLive(_64); // scope 42 at $DIR/reference_prop.rs:+85:13: +85:18
+ _64 = const 5_usize; // scope 42 at $DIR/reference_prop.rs:+85:21: +85:28
+- StorageLive(_65); // scope 43 at $DIR/reference_prop.rs:+86:13: +86:18
+- _65 = &raw mut _64; // scope 43 at $DIR/reference_prop.rs:+86:21: +86:31
+- StorageLive(_66); // scope 44 at $DIR/reference_prop.rs:+87:13: +87:14
+- _66 = &mut _65; // scope 44 at $DIR/reference_prop.rs:+87:17: +87:23
+ StorageLive(_67); // scope 45 at $DIR/reference_prop.rs:+88:13: +88:14
+- _67 = (*_65); // scope 45 at $DIR/reference_prop.rs:+88:17: +88:19
++ _67 = _64; // scope 45 at $DIR/reference_prop.rs:+88:17: +88:19
+ StorageLive(_68); // scope 46 at $DIR/reference_prop.rs:+89:9: +89:19
+ StorageLive(_69); // scope 46 at $DIR/reference_prop.rs:+89:16: +89:18
+ _69 = (); // scope 46 at $DIR/reference_prop.rs:+89:16: +89:18
+ _68 = opaque::<()>(move _69) -> bb10; // scope 46 at $DIR/reference_prop.rs:+89:9: +89:19
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:387:9: 387:15
+ // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+ }
+
+ bb10: {
+ StorageDead(_69); // scope 46 at $DIR/reference_prop.rs:+89:18: +89:19
+ StorageDead(_68); // scope 46 at $DIR/reference_prop.rs:+89:19: +89:20
+ _0 = const (); // scope 42 at $DIR/reference_prop.rs:+84:5: +90:6
+ StorageDead(_67); // scope 45 at $DIR/reference_prop.rs:+90:5: +90:6
+- StorageDead(_66); // scope 44 at $DIR/reference_prop.rs:+90:5: +90:6
+- StorageDead(_65); // scope 43 at $DIR/reference_prop.rs:+90:5: +90:6
+ StorageDead(_64); // scope 42 at $DIR/reference_prop.rs:+90:5: +90:6
+ return; // scope 0 at $DIR/reference_prop.rs:+91:2: +91:2
+ }
+ }
+
diff --git a/tests/mir-opt/reference_prop.rs b/tests/mir-opt/reference_prop.rs
new file mode 100644
index 00000000000..4083b45470b
--- /dev/null
+++ b/tests/mir-opt/reference_prop.rs
@@ -0,0 +1,592 @@
+// unit-test: ReferencePropagation
+// needs-unwind
+
+#![feature(raw_ref_op)]
+#![feature(core_intrinsics, custom_mir)]
+
+#[inline(never)]
+fn opaque(_: impl Sized) {}
+
+fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) {
+ // Propagation through a reference.
+ {
+ let a = 5_usize;
+ let b = &a; // This borrow is only used once.
+ let c = *b; // This should be optimized.
+ opaque(()); // We use opaque to separate cases into basic blocks in the MIR.
+ }
+
+ // Propagation through a two references.
+ {
+ let a = 5_usize;
+ let a2 = 7_usize;
+ let mut b = &a;
+ b = &a2;
+ // `b` is assigned twice, so we cannot propagate it.
+ let c = *b;
+ opaque(());
+ }
+
+ // Propagation through a borrowed reference.
+ {
+ let a = 5_usize;
+ let b = &a;
+ let d = &b;
+ let c = *b; // `b` is immutably borrowed, we know its value, but do not propagate it
+ opaque(d); // prevent `d` from being removed.
+ }
+
+ // Propagation through a borrowed reference.
+ {
+ let a = 5_usize;
+ let mut b = &a;
+ let d = &raw mut b;
+ let c = *b; // `b` is mutably borrowed, we cannot know its value.
+ opaque(d); // prevent `d` from being removed.
+ }
+
+ // Propagation through an escaping borrow.
+ {
+ let a = 7_usize;
+ let b = &a;
+ let c = *b;
+ opaque(b); // `b` escapes here, but we can still replace immutable borrow
+ }
+
+ // Propagation through a transitively escaping borrow.
+ {
+ let a = 7_usize;
+ let b1 = &a;
+ let c = *b1;
+ let b2 = b1;
+ let c2 = *b2;
+ let b3 = b2;
+ // `b3` escapes here, so we can only replace immutable borrow,
+ // for either `b`, `b2` or `b3`.
+ opaque(b3);
+ }
+
+ // Propagation a reborrow of an argument.
+ {
+ let a = &*single;
+ let b = *a; // This should be optimized as `*single`.
+ opaque(());
+ }
+
+ // Propagation a reborrow of a mutated argument.
+ {
+ let a = &*multiple;
+ multiple = &*single;
+ let b = *a; // This should not be optimized.
+ opaque(());
+ }
+
+ // Fixed-point propagation through a borrowed reference.
+ {
+ let a = 5_usize;
+ let b = &a;
+ let d = &b; // first round promotes debuginfo for `d`
+ let c = *b; // second round propagates this dereference
+ opaque(());
+ }
+
+ // Fixed-point propagation through a borrowed reference.
+ {
+ let a = 5_usize;
+ let mut b = &a;
+ let d = &mut b; // first round promotes debuginfo for `d`
+ let c = *b; // second round propagates this dereference
+ opaque(());
+ }
+}
+
+fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a mut T) {
+ // Propagation through a reference.
+ {
+ let mut a = 5_usize;
+ let b = &mut a; // This borrow is only used once.
+ let c = *b; // This should be optimized.
+ opaque(());
+ }
+
+ // Propagation through a two references.
+ {
+ let mut a = 5_usize;
+ let mut a2 = 7_usize;
+ let mut b = &mut a;
+ b = &mut a2;
+ // `b` is assigned twice, so we cannot propagate it.
+ let c = *b;
+ opaque(());
+ }
+
+ // Propagation through a borrowed reference.
+ {
+ let mut a = 5_usize;
+ let b = &mut a;
+ let d = &b;
+ let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed.
+ opaque(d); // prevent `d` from being removed.
+ }
+
+ // Propagation through a borrowed reference.
+ {
+ let mut a = 5_usize;
+ let mut b = &mut a;
+ let d = &raw mut b;
+ let c = *b; // `b` is mutably borrowed, we cannot know its value.
+ opaque(d); // prevent `d` from being removed.
+ }
+
+ // Propagation through an escaping borrow.
+ {
+ let mut a = 7_usize;
+ let b = &mut a;
+ let c = *b;
+ opaque(b); // `b` escapes here, so we can only replace immutable borrow
+ }
+
+ // Propagation through a transitively escaping borrow.
+ {
+ let mut a = 7_usize;
+ let b1 = &mut a;
+ let c = *b1;
+ let b2 = b1;
+ let c2 = *b2;
+ let b3 = b2;
+ // `b3` escapes here, so we can only replace immutable borrow,
+ // for either `b`, `b2` or `b3`.
+ opaque(b3);
+ }
+
+ // Propagation a reborrow of an argument.
+ {
+ let a = &mut *single;
+ let b = *a; // This should be optimized as `*single`.
+ opaque(());
+ }
+
+ // Propagation a reborrow of a mutated argument.
+ {
+ let a = &mut *multiple;
+ multiple = &mut *single;
+ let b = *a; // This should not be optimized.
+ opaque(());
+ }
+
+ // Fixed-point propagation through a borrowed reference.
+ {
+ let mut a = 5_usize;
+ let b = &mut a;
+ let d = &b; // first round promotes debuginfo for `d`
+ let c = *b; // second round propagates this dereference
+ opaque(());
+ }
+
+ // Fixed-point propagation through a borrowed reference.
+ {
+ let mut a = 5_usize;
+ let mut b = &mut a;
+ let d = &mut b; // first round promotes debuginfo for `d`
+ let c = *b; // second round propagates this dereference
+ opaque(());
+ }
+}
+
+fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *const T) {
+ // Propagation through a reference.
+ unsafe {
+ let a = 5_usize;
+ let b = &raw const a; // This borrow is only used once.
+ let c = *b; // This should be optimized.
+ opaque(());
+ }
+
+ // Propagation through a two references.
+ unsafe {
+ let a = 5_usize;
+ let a2 = 7_usize;
+ let mut b = &raw const a;
+ b = &raw const a2;
+ // `b` is assigned twice, so we cannot propagate it.
+ let c = *b;
+ opaque(());
+ }
+
+ // Propagation through a borrowed reference.
+ unsafe {
+ let a = 5_usize;
+ let b = &raw const a;
+ let d = &b;
+ let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed.
+ opaque(d); // prevent `d` from being removed.
+ }
+
+ // Propagation through a borrowed reference.
+ unsafe {
+ let a = 5_usize;
+ let mut b = &raw const a;
+ let d = &raw mut b;
+ let c = *b; // `b` is mutably borrowed, we cannot know its value.
+ opaque(d); // prevent `d` from being removed.
+ }
+
+ // Propagation through an escaping borrow.
+ unsafe {
+ let a = 7_usize;
+ let b = &raw const a;
+ let c = *b;
+ opaque(b); // `b` escapes here, so we can only replace immutable borrow
+ }
+
+ // Propagation through a transitively escaping borrow.
+ unsafe {
+ let a = 7_usize;
+ let b1 = &raw const a;
+ let c = *b1;
+ let b2 = b1;
+ let c2 = *b2;
+ let b3 = b2;
+ // `b3` escapes here, so we can only replace immutable borrow,
+ // for either `b`, `b2` or `b3`.
+ opaque(b3);
+ }
+
+ // Propagation a reborrow of an argument.
+ unsafe {
+ let a = &raw const *single;
+ let b = *a; // This should be optimized as `*single`.
+ opaque(());
+ }
+
+ // Propagation a reborrow of a mutated argument.
+ unsafe {
+ let a = &raw const *multiple;
+ multiple = &raw const *single;
+ let b = *a; // This should not be optimized.
+ opaque(());
+ }
+
+ // Propagation through a reborrow.
+ unsafe {
+ let a = 13_usize;
+ let b = &raw const a;
+ let c = &raw const *b;
+ let e = *c;
+ opaque(());
+ }
+
+ // Fixed-point propagation through a borrowed reference.
+ unsafe {
+ let a = 5_usize;
+ let b = &raw const a;
+ let d = &b; // first round promotes debuginfo for `d`
+ let c = *b; // second round propagates this dereference
+ opaque(());
+ }
+
+ // Fixed-point propagation through a borrowed reference.
+ unsafe {
+ let a = 5_usize;
+ let mut b = &raw const a;
+ let d = &mut b; // first round promotes debuginfo for `d`
+ let c = *b; // second round propagates this dereference
+ opaque(());
+ }
+}
+
+fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T) {
+ // Propagation through a reference.
+ unsafe {
+ let mut a = 5_usize;
+ let b = &raw mut a; // This borrow is only used once.
+ let c = *b; // This should be optimized.
+ opaque(());
+ }
+
+ // Propagation through a two references.
+ unsafe {
+ let mut a = 5_usize;
+ let mut a2 = 7_usize;
+ let mut b = &raw mut a;
+ b = &raw mut a2;
+ // `b` is assigned twice, so we cannot propagate it.
+ let c = *b;
+ opaque(());
+ }
+
+ // Propagation through a borrowed reference.
+ unsafe {
+ let mut a = 5_usize;
+ let b = &raw mut a;
+ let d = &b;
+ let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed.
+ opaque(d); // prevent `d` from being removed.
+ }
+
+ // Propagation through a borrowed reference.
+ unsafe {
+ let mut a = 5_usize;
+ let mut b = &raw mut a;
+ let d = &raw mut b;
+ let c = *b; // `b` is mutably borrowed, we cannot know its value.
+ opaque(d); // prevent `d` from being removed.
+ }
+
+ // Propagation through an escaping borrow.
+ unsafe {
+ let mut a = 7_usize;
+ let b = &raw mut a;
+ let c = *b;
+ opaque(b); // `b` escapes here, so we can only replace immutable borrow
+ }
+
+ // Propagation through a transitively escaping borrow.
+ unsafe {
+ let mut a = 7_usize;
+ let b1 = &raw mut a;
+ let c = *b1;
+ let b2 = b1;
+ let c2 = *b2;
+ let b3 = b2;
+ // `b3` escapes here, so we can only replace immutable borrow,
+ // for either `b`, `b2` or `b3`.
+ opaque(b3);
+ }
+
+ // Propagation a reborrow of an argument.
+ unsafe {
+ let a = &raw mut *single;
+ let b = *a; // This should be optimized as `*single`.
+ opaque(());
+ }
+
+ // Propagation a reborrow of a mutated argument.
+ unsafe {
+ let a = &raw mut *multiple;
+ multiple = &raw mut *single;
+ let b = *a; // This should not be optimized.
+ opaque(());
+ }
+
+ // Fixed-point propagation through a borrowed reference.
+ unsafe {
+ let mut a = 5_usize;
+ let b = &raw mut a;
+ let d = &b; // first round promotes debuginfo for `d`
+ let c = *b; // second round propagates this dereference
+ opaque(());
+ }
+
+ // Fixed-point propagation through a borrowed reference.
+ unsafe {
+ let mut a = 5_usize;
+ let mut b = &raw mut a;
+ let d = &mut b; // first round promotes debuginfo for `d`
+ let c = *b; // second round propagates this dereference
+ opaque(());
+ }
+}
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn read_through_raw(x: &mut usize) -> usize {
+ use std::intrinsics::mir::*;
+
+ mir!(
+ let r1: &mut usize;
+ let r2: &mut usize;
+ let p1: *mut usize;
+ let p2: *mut usize;
+
+ {
+ r1 = &mut *x;
+ r2 = &mut *r1;
+ p1 = &raw mut *r1;
+ p2 = &raw mut *r2;
+
+ RET = *p1;
+ RET = *p2;
+ Return()
+ }
+ )
+}
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn multiple_storage() {
+ use std::intrinsics::mir::*;
+
+ mir!(
+ let x: i32;
+ {
+ StorageLive(x);
+ x = 5;
+ let z = &x;
+ StorageDead(x);
+ StorageLive(x);
+ // As there are multiple `StorageLive` statements for `x`, we cannot know if this `z`'s
+ // pointer address is the address of `x`, so do nothing.
+ let y = *z;
+ Call(RET, retblock, opaque(y))
+ }
+
+ retblock = {
+ Return()
+ }
+ )
+}
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn dominate_storage() {
+ use std::intrinsics::mir::*;
+
+ mir!(
+ let x: i32;
+ let r: &i32;
+ let c: i32;
+ let d: bool;
+ { Goto(bb0) }
+ bb0 = {
+ x = 5;
+ r = &x;
+ Goto(bb1)
+ }
+ bb1 = {
+ let c = *r;
+ Call(RET, bb2, opaque(c))
+ }
+ bb2 = {
+ StorageDead(x);
+ StorageLive(x);
+ let d = true;
+ match d { false => bb2, _ => bb0 }
+ }
+ )
+}
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn maybe_dead(m: bool) {
+ use std::intrinsics::mir::*;
+
+ mir!(
+ let x: i32;
+ let y: i32;
+ {
+ StorageLive(x);
+ StorageLive(y);
+ x = 5;
+ y = 5;
+ let a = &x;
+ let b = &mut y;
+ // As we don't replace `b` in `bb2`, we cannot replace it here either.
+ *b = 7;
+ // But this can still be replaced.
+ let u = *a;
+ match m { true => bb1, _ => bb2 }
+ }
+ bb1 = {
+ StorageDead(x);
+ StorageDead(y);
+ Call(RET, bb2, opaque(u))
+ }
+ bb2 = {
+ // As `x` may be `StorageDead`, `a` may be dangling, so we do nothing.
+ let z = *a;
+ Call(RET, bb3, opaque(z))
+ }
+ bb3 = {
+ // As `y` may be `StorageDead`, `b` may be dangling, so we do nothing.
+ // This implies that we also do not substitute `b` in `bb0`.
+ let t = *b;
+ Call(RET, retblock, opaque(t))
+ }
+ retblock = {
+ Return()
+ }
+ )
+}
+
+fn mut_raw_then_mut_shr() -> (i32, i32) {
+ let mut x = 2;
+ let xref = &mut x;
+ let xraw = &mut *xref as *mut _;
+ let xshr = &*xref;
+ // Verify that we completely replace with `x` in both cases.
+ let a = *xshr;
+ unsafe { *xraw = 4; }
+ (a, x)
+}
+
+fn unique_with_copies() {
+ let y = {
+ let mut a = 0;
+ let x = &raw mut a;
+ // `*y` is not replacable below, so we must not replace `*x`.
+ unsafe { opaque(*x) };
+ x
+ };
+ // But rewriting as `*x` is ok.
+ unsafe { opaque(*y) };
+}
+
+fn debuginfo() {
+ struct T(u8);
+
+ let ref_mut_u8 = &mut 5_u8;
+ let field = &T(0).0;
+
+ // Verify that we don't emit `&*` in debuginfo.
+ let reborrow = &*ref_mut_u8;
+
+ match Some(0) {
+ None => {}
+ Some(ref variant_field) => {}
+ }
+
+ // `constant_index_from_end` and `subslice` should not be promoted, as their value depends
+ // on the slice length.
+ if let [_, ref constant_index, subslice @ .., ref constant_index_from_end] = &[6; 10][..] {
+ }
+
+ let multiple_borrow = &&&mut T(6).0;
+}
+
+fn many_debuginfo() {
+ let a = 0;
+
+ // Verify that we do not ICE on deeply nested borrows.
+ let many_borrow =
+ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&a;
+}
+
+fn main() {
+ let mut x = 5_usize;
+ let mut y = 7_usize;
+ reference_propagation(&x, &y);
+ reference_propagation_mut(&mut x, &mut y);
+ reference_propagation_const_ptr(&raw const x, &raw const y);
+ reference_propagation_mut_ptr(&raw mut x, &raw mut y);
+ read_through_raw(&mut x);
+ multiple_storage();
+ dominate_storage();
+ maybe_dead(true);
+ mut_raw_then_mut_shr();
+ unique_with_copies();
+ debuginfo();
+ many_debuginfo();
+}
+
+// EMIT_MIR reference_prop.reference_propagation.ReferencePropagation.diff
+// EMIT_MIR reference_prop.reference_propagation_mut.ReferencePropagation.diff
+// EMIT_MIR reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
+// EMIT_MIR reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
+// EMIT_MIR reference_prop.read_through_raw.ReferencePropagation.diff
+// EMIT_MIR reference_prop.multiple_storage.ReferencePropagation.diff
+// EMIT_MIR reference_prop.dominate_storage.ReferencePropagation.diff
+// EMIT_MIR reference_prop.maybe_dead.ReferencePropagation.diff
+// EMIT_MIR reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff
+// EMIT_MIR reference_prop.unique_with_copies.ReferencePropagation.diff
+// EMIT_MIR reference_prop.debuginfo.ReferencePropagation.diff
diff --git a/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff b/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff
new file mode 100644
index 00000000000..b754aff4755
--- /dev/null
+++ b/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff
@@ -0,0 +1,67 @@
+- // MIR for `unique_with_copies` before ReferencePropagation
++ // MIR for `unique_with_copies` after ReferencePropagation
+
+ fn unique_with_copies() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:25: +0:25
+ let _1: *mut i32; // in scope 0 at $DIR/reference_prop.rs:+1:9: +1:10
+ let mut _2: i32; // in scope 0 at $DIR/reference_prop.rs:+2:13: +2:18
+ let _4: (); // in scope 0 at $DIR/reference_prop.rs:+5:18: +5:28
+ let mut _5: i32; // in scope 0 at $DIR/reference_prop.rs:+5:25: +5:27
+ let _6: (); // in scope 0 at $DIR/reference_prop.rs:+9:14: +9:24
+ let mut _7: i32; // in scope 0 at $DIR/reference_prop.rs:+9:21: +9:23
+ scope 1 {
+- debug y => _1; // in scope 1 at $DIR/reference_prop.rs:+1:9: +1:10
++ debug y => _3; // in scope 1 at $DIR/reference_prop.rs:+1:9: +1:10
+ scope 5 {
+ }
+ }
+ scope 2 {
+ debug a => _2; // in scope 2 at $DIR/reference_prop.rs:+2:13: +2:18
+ let _3: *mut i32; // in scope 2 at $DIR/reference_prop.rs:+3:13: +3:14
+ scope 3 {
+ debug x => _3; // in scope 3 at $DIR/reference_prop.rs:+3:13: +3:14
+ scope 4 {
+ }
+ }
+ }
+
+ bb0: {
+- StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/reference_prop.rs:+2:13: +2:18
+ _2 = const 0_i32; // scope 0 at $DIR/reference_prop.rs:+2:21: +2:22
+- StorageLive(_3); // scope 2 at $DIR/reference_prop.rs:+3:13: +3:14
+ _3 = &raw mut _2; // scope 2 at $DIR/reference_prop.rs:+3:17: +3:27
+ StorageLive(_4); // scope 3 at $DIR/reference_prop.rs:+5:9: +5:30
+ StorageLive(_5); // scope 4 at $DIR/reference_prop.rs:+5:25: +5:27
+ _5 = (*_3); // scope 4 at $DIR/reference_prop.rs:+5:25: +5:27
+ _4 = opaque::<i32>(move _5) -> bb1; // scope 4 at $DIR/reference_prop.rs:+5:18: +5:28
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:524:18: 524:24
+ // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_5); // scope 4 at $DIR/reference_prop.rs:+5:27: +5:28
+ StorageDead(_4); // scope 3 at $DIR/reference_prop.rs:+5:30: +5:31
+- _1 = _3; // scope 3 at $DIR/reference_prop.rs:+6:9: +6:10
+- StorageDead(_3); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
+ StorageDead(_2); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+ StorageLive(_6); // scope 1 at $DIR/reference_prop.rs:+9:5: +9:26
+ StorageLive(_7); // scope 5 at $DIR/reference_prop.rs:+9:21: +9:23
+- _7 = (*_1); // scope 5 at $DIR/reference_prop.rs:+9:21: +9:23
++ _7 = (*_3); // scope 5 at $DIR/reference_prop.rs:+9:21: +9:23
+ _6 = opaque::<i32>(move _7) -> bb2; // scope 5 at $DIR/reference_prop.rs:+9:14: +9:24
+ // mir::Constant
+ // + span: $DIR/reference_prop.rs:528:14: 528:20
+ // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_7); // scope 5 at $DIR/reference_prop.rs:+9:23: +9:24
+ StorageDead(_6); // scope 1 at $DIR/reference_prop.rs:+9:26: +9:27
+ _0 = const (); // scope 0 at $DIR/reference_prop.rs:+0:25: +10:2
+- StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+10:1: +10:2
+ return; // scope 0 at $DIR/reference_prop.rs:+10:2: +10:2
+ }
+ }
+
diff --git a/tests/mir-opt/slice_filter.rs b/tests/mir-opt/slice_filter.rs
index 97c18af31de..be32f40f132 100644
--- a/tests/mir-opt/slice_filter.rs
+++ b/tests/mir-opt/slice_filter.rs
@@ -12,7 +12,9 @@ pub fn variant_b(input: &[(usize, usize, usize, usize)]) -> usize {
input.iter().filter(|&&(a, b, c, d)| a <= c && d <= b || c <= a && b <= d).count()
}
+// EMIT_MIR slice_filter.variant_a-{closure#0}.ReferencePropagation.diff
// EMIT_MIR slice_filter.variant_a-{closure#0}.CopyProp.diff
// EMIT_MIR slice_filter.variant_a-{closure#0}.DestinationPropagation.diff
// EMIT_MIR slice_filter.variant_b-{closure#0}.CopyProp.diff
+// EMIT_MIR slice_filter.variant_b-{closure#0}.ReferencePropagation.diff
// EMIT_MIR slice_filter.variant_b-{closure#0}.DestinationPropagation.diff
diff --git a/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff b/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff
index 3bb0358ffe3..60e5056c7a9 100644
--- a/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff
+++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff
@@ -101,16 +101,16 @@
}
bb0: {
-- StorageLive(_3); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+ StorageLive(_3); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
_25 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
_3 = &((*_25).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
-- StorageLive(_4); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+ StorageLive(_4); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
_26 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
_4 = &((*_26).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
-- StorageLive(_5); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+ StorageLive(_5); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
_27 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
_5 = &((*_27).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
-- StorageLive(_6); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+ StorageLive(_6); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
_28 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
_6 = &((*_28).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
@@ -184,10 +184,10 @@
bb3: {
StorageDead(_16); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
-- StorageDead(_6); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
-- StorageDead(_5); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
-- StorageDead(_4); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
-- StorageDead(_3); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+ StorageDead(_6); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+ StorageDead(_5); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+ StorageDead(_4); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+ StorageDead(_3); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
return; // scope 0 at $DIR/slice_filter.rs:+0:76: +0:76
}
diff --git a/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff b/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff
index 294c3272f4f..afdcf57815f 100644
--- a/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff
+++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff
@@ -3,118 +3,79 @@
fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:8:25: 8:39], _2: &&(usize, usize, usize, usize)) -> bool {
let mut _0: bool; // return place in scope 0 at $DIR/slice_filter.rs:+0:40: +0:40
- let _3: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
- let _4: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
- let _5: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
- let _6: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
- let mut _7: bool; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:56
- let mut _8: bool; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:46
- let mut _9: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:41
- let mut _10: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:45: +0:46
- let _11: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:45: +0:46
- let mut _12: bool; // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:56
- let mut _13: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:51
- let mut _14: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:55: +0:56
- let _15: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:55: +0:56
- let mut _16: bool; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:76
- let mut _17: bool; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:66
- let mut _18: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:61
- let mut _19: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:65: +0:66
- let _20: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:65: +0:66
- let mut _21: bool; // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:76
- let mut _22: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:71
- let mut _23: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
- let _24: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
- let mut _25: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
- let mut _26: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
- let mut _27: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
- let mut _28: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+ let mut _3: bool; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:56
+ let mut _4: bool; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:46
+ let mut _5: bool; // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:56
+ let mut _6: bool; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:76
+ let mut _7: bool; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:66
+ let mut _8: bool; // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:76
+ let mut _9: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+ let mut _10: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+ let mut _11: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+ let mut _12: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
scope 1 {
- debug a => _3; // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28
- debug b => _4; // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31
- debug c => _5; // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34
- debug d => _6; // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37
+ debug a => &((*_9).0: usize); // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28
+ debug b => &((*_10).1: usize); // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31
+ debug c => &((*_11).2: usize); // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34
+ debug d => &((*_12).3: usize); // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37
scope 2 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:40: 8:46
- debug self => _9; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
- debug other => _10; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _29: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _30: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug self => &&((*_9).0: usize); // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug other => &&((*_11).2: usize); // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
scope 3 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
- debug self => _29; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
- debug other => _30; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _31: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _32: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug self => &((*_9).0: usize); // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug other => &((*_11).2: usize); // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _13: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _14: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
}
}
scope 4 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:60: 8:66
- debug self => _18; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
- debug other => _19; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _33: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _34: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug self => &&((*_11).2: usize); // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug other => &&((*_9).0: usize); // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
scope 5 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
- debug self => _33; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
- debug other => _34; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _35: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _36: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug self => &((*_11).2: usize); // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug other => &((*_9).0: usize); // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _15: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _16: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
}
}
scope 6 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:50: 8:56
- debug self => _13; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
- debug other => _14; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _37: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _38: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug self => &&((*_12).3: usize); // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug other => &&((*_10).1: usize); // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
scope 7 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
- debug self => _37; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
- debug other => _38; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _39: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _40: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug self => &((*_12).3: usize); // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug other => &((*_10).1: usize); // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _17: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _18: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
}
}
scope 8 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:70: 8:76
- debug self => _22; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
- debug other => _23; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _41: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _42: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug self => &&((*_10).1: usize); // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug other => &&((*_12).3: usize); // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
scope 9 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
- debug self => _41; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
- debug other => _42; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _43: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
- let mut _44: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug self => &((*_10).1: usize); // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ debug other => &((*_12).3: usize); // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _19: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _20: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
}
}
}
bb0: {
- _25 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
- _3 = &((*_25).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
- _26 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
- _4 = &((*_26).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
- _27 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
- _5 = &((*_27).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
- _28 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
- _6 = &((*_28).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
-- StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+ _9 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+ _10 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+ _11 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+ _12 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+- StorageLive(_3); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
- StorageLive(_8); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:46
- StorageLive(_9); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41
- _9 = &_3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41
- StorageLive(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
- StorageLive(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
- _11 = _5; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
- _10 = &_11; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
- _29 = deref_copy (*_9); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _30 = deref_copy (*_10); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageLive(_31); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _31 = (*_29); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageLive(_32); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _32 = (*_30); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _8 = Le(move _31, move _32); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageDead(_32); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageDead(_31); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
- StorageDead(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
- StorageDead(_9); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
- switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+ StorageLive(_4); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:46
+ StorageLive(_13); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _13 = ((*_9).0: usize); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageLive(_14); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _14 = ((*_11).2: usize); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _4 = Le(move _13, move _14); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_14); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_13); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ switchInt(move _4) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
}
bb1: {
@@ -123,113 +84,80 @@
}
bb2: {
-- StorageLive(_16); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+- StorageLive(_6); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
- StorageLive(_17); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:66
- StorageLive(_18); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61
- _18 = &_5; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61
- StorageLive(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
- StorageLive(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
- _20 = _3; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
- _19 = &_20; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
- _33 = deref_copy (*_18); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _34 = deref_copy (*_19); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageLive(_35); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _35 = (*_33); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageLive(_36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _36 = (*_34); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _17 = Le(move _35, move _36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageDead(_36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageDead(_35); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageDead(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
- StorageDead(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
- StorageDead(_18); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
- switchInt(move _17) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+ StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:66
+ StorageLive(_15); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _15 = ((*_11).2: usize); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageLive(_16); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _16 = ((*_9).0: usize); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _7 = Le(move _15, move _16); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_16); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_15); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ switchInt(move _7) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
}
bb3: {
-- StorageDead(_16); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
-- StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+- StorageDead(_6); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+- StorageDead(_3); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
return; // scope 0 at $DIR/slice_filter.rs:+0:76: +0:76
}
bb4: {
-- StorageDead(_12); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+- StorageDead(_5); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+ StorageDead(_4); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
goto -> bb2; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
}
bb5: {
-- StorageLive(_12); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56
+- StorageLive(_5); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56
- StorageLive(_13); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51
- _13 = &_6; // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51
- StorageLive(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- StorageLive(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- _15 = _4; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- _14 = &_15; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- _37 = deref_copy (*_13); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _38 = deref_copy (*_14); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageLive(_39); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _39 = (*_37); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageLive(_40); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _40 = (*_38); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _12 = Le(move _39, move _40); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageDead(_40); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageDead(_39); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageDead(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- StorageDead(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- StorageDead(_13); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
-- _7 = move _12; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
-- StorageDead(_12); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+ StorageLive(_17); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _17 = ((*_12).3: usize); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageLive(_18); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _18 = ((*_10).1: usize); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _5 = Le(move _17, move _18); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_18); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_17); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _3 = move _5; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+- StorageDead(_5); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
-- switchInt(move _7) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
-+ switchInt(move _12) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+ StorageDead(_4); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+- switchInt(move _3) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
++ switchInt(move _5) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
}
bb6: {
-- _16 = const false; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+- _6 = const false; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+ _0 = const false; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
}
bb7: {
-- StorageLive(_21); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76
+- StorageLive(_8); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76
- StorageLive(_22); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71
- _22 = &_4; // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71
- StorageLive(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageLive(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- _24 = _6; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- _23 = &_24; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- _41 = deref_copy (*_22); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _42 = deref_copy (*_23); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageLive(_43); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _43 = (*_41); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageLive(_44); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _44 = (*_42); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
-- _21 = Le(move _43, move _44); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
-+ _0 = Le(move _43, move _44); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageDead(_44); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageDead(_43); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageDead(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_22); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
-- _16 = move _21; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+ StorageLive(_19); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _19 = ((*_10).1: usize); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageLive(_20); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _20 = ((*_12).3: usize); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _8 = Le(move _19, move _20); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ _0 = Le(move _19, move _20); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_20); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_19); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _6 = move _8; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
}
bb8: {
-- StorageDead(_21); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+- StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_17); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
-- _0 = move _16; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+ StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+- _0 = move _6; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
}
diff --git a/tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff b/tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff
new file mode 100644
index 00000000000..2534eeef432
--- /dev/null
+++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff
@@ -0,0 +1,267 @@
+- // MIR for `variant_a::{closure#0}` before ReferencePropagation
++ // MIR for `variant_a::{closure#0}` after ReferencePropagation
+
+ fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:8:25: 8:39], _2: &&(usize, usize, usize, usize)) -> bool {
+ let mut _0: bool; // return place in scope 0 at $DIR/slice_filter.rs:+0:40: +0:40
+ let _3: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+ let _4: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+ let _5: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+ let _6: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+ let mut _7: bool; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:56
+ let mut _8: bool; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:46
+ let mut _9: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:41
+ let mut _10: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:45: +0:46
+ let _11: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:45: +0:46
+ let mut _12: bool; // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:56
+ let mut _13: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:51
+ let mut _14: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:55: +0:56
+ let _15: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:55: +0:56
+ let mut _16: bool; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:76
+ let mut _17: bool; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:66
+ let mut _18: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:61
+ let mut _19: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:65: +0:66
+ let _20: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:65: +0:66
+ let mut _21: bool; // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:76
+ let mut _22: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:71
+ let mut _23: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+ let _24: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+ let mut _25: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+ let mut _26: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+ let mut _27: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+ let mut _28: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+ let mut _31: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _32: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _37: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _38: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _43: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _44: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _49: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _50: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ scope 1 {
+- debug a => _3; // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28
+- debug b => _4; // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31
+- debug c => _5; // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34
+- debug d => _6; // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37
++ debug a => &((*_25).0: usize); // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28
++ debug b => &((*_26).1: usize); // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31
++ debug c => &((*_27).2: usize); // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34
++ debug d => &((*_28).3: usize); // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37
+ scope 2 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:40: 8:46
+- debug self => _9; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- debug other => _10; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug self => &&((*_25).0: usize); // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug other => &&((*_27).2: usize); // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _29: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _30: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ scope 3 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
+- debug self => _29; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- debug other => _30; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug self => &((*_25).0: usize); // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug other => &((*_27).2: usize); // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _33: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _34: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ }
+ }
+ scope 4 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:60: 8:66
+- debug self => _18; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- debug other => _19; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug self => &&((*_27).2: usize); // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug other => &&((*_25).0: usize); // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _35: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _36: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ scope 5 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
+- debug self => _35; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- debug other => _36; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug self => &((*_27).2: usize); // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug other => &((*_25).0: usize); // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _39: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _40: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ }
+ }
+ scope 6 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:50: 8:56
+- debug self => _13; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- debug other => _14; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug self => &&((*_28).3: usize); // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug other => &&((*_26).1: usize); // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _41: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _42: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ scope 7 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
+- debug self => _41; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- debug other => _42; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug self => &((*_28).3: usize); // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug other => &((*_26).1: usize); // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _45: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _46: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ }
+ }
+ scope 8 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:70: 8:76
+- debug self => _22; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- debug other => _23; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug self => &&((*_26).1: usize); // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug other => &&((*_28).3: usize); // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _47: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _48: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ scope 9 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
+- debug self => _47; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- debug other => _48; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug self => &((*_26).1: usize); // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ debug other => &((*_28).3: usize); // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _51: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ let mut _52: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ }
+ }
+ }
+
+ bb0: {
+- StorageLive(_3); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+ _25 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+- _3 = &((*_25).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+- StorageLive(_4); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+ _26 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+- _4 = &((*_26).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+- StorageLive(_5); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+ _27 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+- _5 = &((*_27).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+- StorageLive(_6); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+ _28 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+- _6 = &((*_28).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+ StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+ StorageLive(_8); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:46
+- StorageLive(_9); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41
+- _9 = &_3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41
+- StorageLive(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+- StorageLive(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+- _11 = _5; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+- _10 = &_11; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+- _29 = deref_copy (*_9); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _30 = deref_copy (*_10); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageLive(_33); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _33 = (*_29); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ _33 = ((*_25).0: usize); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageLive(_34); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _34 = (*_30); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ _34 = ((*_27).2: usize); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _8 = Le(move _33, move _34); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_34); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_33); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+- StorageDead(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+- StorageDead(_9); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+ switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+ }
+
+ bb1: {
+ _0 = const true; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+ goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+ }
+
+ bb2: {
+ StorageLive(_16); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+ StorageLive(_17); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:66
+- StorageLive(_18); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61
+- _18 = &_5; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61
+- StorageLive(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+- StorageLive(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+- _20 = _3; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+- _19 = &_20; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+- _35 = deref_copy (*_18); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _36 = deref_copy (*_19); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageLive(_39); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _39 = (*_35); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ _39 = ((*_27).2: usize); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageLive(_40); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _40 = (*_36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ _40 = ((*_25).0: usize); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _17 = Le(move _39, move _40); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_40); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_39); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- StorageDead(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+- StorageDead(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+- StorageDead(_18); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+ switchInt(move _17) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+ }
+
+ bb3: {
+ StorageDead(_16); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+ StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+- StorageDead(_6); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+- StorageDead(_5); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+- StorageDead(_4); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+- StorageDead(_3); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+ return; // scope 0 at $DIR/slice_filter.rs:+0:76: +0:76
+ }
+
+ bb4: {
+ _7 = const false; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+ StorageDead(_12); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+ StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+ goto -> bb2; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+ }
+
+ bb5: {
+ StorageLive(_12); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56
+- StorageLive(_13); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51
+- _13 = &_6; // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51
+- StorageLive(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+- StorageLive(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+- _15 = _4; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+- _14 = &_15; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+- _41 = deref_copy (*_13); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _42 = deref_copy (*_14); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageLive(_45); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _45 = (*_41); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ _45 = ((*_28).3: usize); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageLive(_46); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _46 = (*_42); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ _46 = ((*_26).1: usize); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _12 = Le(move _45, move _46); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_46); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_45); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- StorageDead(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+- StorageDead(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+- StorageDead(_13); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+ _7 = move _12; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+ StorageDead(_12); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+ StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+ switchInt(move _7) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+ }
+
+ bb6: {
+ _16 = const false; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+ goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+ }
+
+ bb7: {
+ StorageLive(_21); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76
+- StorageLive(_22); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71
+- _22 = &_4; // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71
+- StorageLive(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+- StorageLive(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+- _24 = _6; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+- _23 = &_24; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+- _47 = deref_copy (*_22); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _48 = deref_copy (*_23); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageLive(_51); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _51 = (*_47); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ _51 = ((*_26).1: usize); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageLive(_52); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- _52 = (*_48); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
++ _52 = ((*_28).3: usize); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _21 = Le(move _51, move _52); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_52); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ StorageDead(_51); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+- StorageDead(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+- StorageDead(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+- StorageDead(_22); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+ _16 = move _21; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+ goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+ }
+
+ bb8: {
+ StorageDead(_21); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+ StorageDead(_17); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+ _0 = move _16; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+ goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+ }
+ }
+
diff --git a/tests/mir-opt/slice_filter.variant_b-{closure#0}.ReferencePropagation.diff b/tests/mir-opt/slice_filter.variant_b-{closure#0}.ReferencePropagation.diff
new file mode 100644
index 00000000000..d1241c6b024
--- /dev/null
+++ b/tests/mir-opt/slice_filter.variant_b-{closure#0}.ReferencePropagation.diff
@@ -0,0 +1,103 @@
+- // MIR for `variant_b::{closure#0}` before ReferencePropagation
++ // MIR for `variant_b::{closure#0}` after ReferencePropagation
+
+ fn variant_b::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:12:25: 12:41], _2: &&(usize, usize, usize, usize)) -> bool {
+ let mut _0: bool; // return place in scope 0 at $DIR/slice_filter.rs:+0:42: +0:42
+ let _3: usize; // in scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
+ let _4: usize; // in scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
+ let _5: usize; // in scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
+ let _6: usize; // in scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
+ let mut _7: bool; // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:58
+ let mut _8: bool; // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:48
+ let mut _9: usize; // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:43
+ let mut _10: usize; // in scope 0 at $DIR/slice_filter.rs:+0:47: +0:48
+ let mut _11: bool; // in scope 0 at $DIR/slice_filter.rs:+0:52: +0:58
+ let mut _12: usize; // in scope 0 at $DIR/slice_filter.rs:+0:52: +0:53
+ let mut _13: usize; // in scope 0 at $DIR/slice_filter.rs:+0:57: +0:58
+ let mut _14: bool; // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:78
+ let mut _15: bool; // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:68
+ let mut _16: usize; // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:63
+ let mut _17: usize; // in scope 0 at $DIR/slice_filter.rs:+0:67: +0:68
+ let mut _18: bool; // in scope 0 at $DIR/slice_filter.rs:+0:72: +0:78
+ let mut _19: usize; // in scope 0 at $DIR/slice_filter.rs:+0:72: +0:73
+ let mut _20: usize; // in scope 0 at $DIR/slice_filter.rs:+0:77: +0:78
+ let mut _21: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
+ let mut _22: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
+ let mut _23: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
+ let mut _24: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
+ scope 1 {
+ debug a => _3; // in scope 1 at $DIR/slice_filter.rs:+0:29: +0:30
+ debug b => _4; // in scope 1 at $DIR/slice_filter.rs:+0:32: +0:33
+ debug c => _5; // in scope 1 at $DIR/slice_filter.rs:+0:35: +0:36
+ debug d => _6; // in scope 1 at $DIR/slice_filter.rs:+0:38: +0:39
+ }
+
+ bb0: {
+ _21 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
+ _3 = ((*_21).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
+ _22 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
+ _4 = ((*_22).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
+ _23 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
+ _5 = ((*_23).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
+ _24 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
+ _6 = ((*_24).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
+ StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+ StorageLive(_8); // scope 1 at $DIR/slice_filter.rs:+0:42: +0:48
+ _8 = Le(_3, _5); // scope 1 at $DIR/slice_filter.rs:+0:42: +0:48
+ switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+ }
+
+ bb1: {
+ _0 = const true; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+ goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+ }
+
+ bb2: {
+ StorageLive(_14); // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+ StorageLive(_15); // scope 1 at $DIR/slice_filter.rs:+0:62: +0:68
+ _15 = Le(_5, _3); // scope 1 at $DIR/slice_filter.rs:+0:62: +0:68
+ switchInt(move _15) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+ }
+
+ bb3: {
+ StorageDead(_14); // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+ StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+ return; // scope 0 at $DIR/slice_filter.rs:+0:78: +0:78
+ }
+
+ bb4: {
+ _7 = const false; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+ StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+ StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+ goto -> bb2; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+ }
+
+ bb5: {
+ StorageLive(_11); // scope 1 at $DIR/slice_filter.rs:+0:52: +0:58
+ _11 = Le(_6, _4); // scope 1 at $DIR/slice_filter.rs:+0:52: +0:58
+ _7 = move _11; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+ StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+ StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+ switchInt(move _7) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+ }
+
+ bb6: {
+ _14 = const false; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+ goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+ }
+
+ bb7: {
+ StorageLive(_18); // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78
+ _18 = Le(_4, _6); // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78
+ _14 = move _18; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+ goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+ }
+
+ bb8: {
+ StorageDead(_18); // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+ StorageDead(_15); // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+ _0 = move _14; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+ goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+ }
+ }
+
diff --git a/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir b/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir
index 2af864998cb..4b2a16b50b4 100644
--- a/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir
+++ b/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir
@@ -3,16 +3,13 @@
fn process_void(_1: *const Void) -> () {
debug input => _1; // in scope 0 at $DIR/uninhabited_enum.rs:+0:21: +0:26
let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum.rs:+0:41: +0:41
- let _2: &Void; // in scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14
scope 1 {
- debug _input => _2; // in scope 1 at $DIR/uninhabited_enum.rs:+1:8: +1:14
+ debug _input => _1; // in scope 1 at $DIR/uninhabited_enum.rs:+1:8: +1:14
}
scope 2 {
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14
- StorageDead(_2); // scope 0 at $DIR/uninhabited_enum.rs:+4:1: +4:2
return; // scope 0 at $DIR/uninhabited_enum.rs:+4:2: +4:2
}
}
diff --git a/tests/run-make-fulldeps/obtain-borrowck/driver.rs b/tests/run-make-fulldeps/obtain-borrowck/driver.rs
index 7bd7bb7c1ea..12cbb5a5f12 100644
--- a/tests/run-make-fulldeps/obtain-borrowck/driver.rs
+++ b/tests/run-make-fulldeps/obtain-borrowck/driver.rs
@@ -24,8 +24,8 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
use rustc_interface::interface::Compiler;
use rustc_interface::{Config, Queries};
-use rustc_middle::ty::query::query_values::mir_borrowck;
-use rustc_middle::ty::query::{ExternProviders, Providers};
+use rustc_middle::query::query_values::mir_borrowck;
+use rustc_middle::query::{ExternProviders, Providers};
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use std::cell::RefCell;
diff --git a/tests/run-make/branch-protection-check-IBT/Makefile b/tests/run-make/branch-protection-check-IBT/Makefile
new file mode 100644
index 00000000000..cabe951e1c5
--- /dev/null
+++ b/tests/run-make/branch-protection-check-IBT/Makefile
@@ -0,0 +1,15 @@
+# Check for GNU Property Note
+
+include ../tools.mk
+
+# How to run this
+# python3 x.py test --target x86_64-unknown-linux-gnu tests/run-make/branch-protection-check-IBT/
+
+# only-x86_64
+
+all:
+ifeq ($(filter x86,$(LLVM_COMPONENTS)),x86_64)
+ $(RUSTC) --target x86_64-unknown-linux-gnu -Z cf-protection=branch -L$(TMPDIR) -C link-args='-nostartfiles' -C save-temps ./main.rs -o $(TMPDIR)/rsmain
+ readelf -nW $(TMPDIR)/rsmain | $(CGREP) -e ".note.gnu.property"
+endif
+
diff --git a/tests/run-make/branch-protection-check-IBT/main.rs b/tests/run-make/branch-protection-check-IBT/main.rs
new file mode 100644
index 00000000000..ad379d6ea43
--- /dev/null
+++ b/tests/run-make/branch-protection-check-IBT/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!("hello world");
+}
diff --git a/tests/run-make/coverage-llvmir/filecheck.testprog.txt b/tests/run-make/coverage-llvmir/filecheck.testprog.txt
index c943261d799..b3a8808df05 100644
--- a/tests/run-make/coverage-llvmir/filecheck.testprog.txt
+++ b/tests/run-make/coverage-llvmir/filecheck.testprog.txt
@@ -36,7 +36,7 @@ CHECK-SAME: section "llvm.metadata"
CHECK: [[DEFINE_INTERNAL]] { {{.*}} } @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called() unnamed_addr #{{[0-9]+}} {
CHECK-NEXT: start:
CHECK-NOT: [[DEFINE_INTERNAL]]
-CHECK: %pgocount = load i64, {{i64\*|ptr}}
+CHECK: atomicrmw add ptr
CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called,
CHECK: declare void @llvm.instrprof.increment({{i8\*|ptr}}, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]]
diff --git a/tests/run-make/coverage-reports/Makefile b/tests/run-make/coverage-reports/Makefile
index d4ae03e590a..0ae409c4119 100644
--- a/tests/run-make/coverage-reports/Makefile
+++ b/tests/run-make/coverage-reports/Makefile
@@ -138,6 +138,7 @@ endif
) \
2> "$(TMPDIR)"/show_coverage_stderr.$@.txt \
| "$(PYTHON)" $(BASEDIR)/normalize_paths.py \
+ | "$(PYTHON)" $(BASEDIR)/sort_subviews.py \
> "$(TMPDIR)"/actual_show_coverage.$@.txt || \
( status=$$? ; \
>&2 cat "$(TMPDIR)"/show_coverage_stderr.$@.txt ; \
@@ -158,23 +159,15 @@ ifdef RUSTC_BLESS_TEST
else
# Compare the show coverage output (`--bless` refreshes `typical` files).
#
- # FIXME(richkadel): None of the Rust test source samples have the
- # `// 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` comparison.
+ # `llvm-cov show` normally prints instantiation groups in an unpredictable
+ # order, but we have used `sort_subviews.py` to sort them, so we can still
+ # check the output directly with `diff`.
#
- # A partial workaround is implemented below, with `diff --ignore-matching-lines=RE`
- # to ignore each line prefixing each generic instantiation coverage code region.
- #
- # This workaround only works if the coverage counts are identical across all reported
- # instantiations. If there is no way to ensure this, you may need to apply the
- # `// ignore-llvm-cov-show-diffs` directive, and check for differences using the
- # `.json` files to validate that results have not changed. (Until then, the JSON
- # files are redundant, so there is no need to generate `expected_*.json` files or
- # compare actual JSON results.)
-
- $(DIFF) --ignore-matching-lines='^ \| .*::<.*>.*:$$' --ignore-matching-lines='^ \| <.*>::.*:$$' \
+ # Some of the test cases are currently not working (since #110393) and have
+ # been marked with `// ignore-llvm-cov-show-diffs` so that they don't fail
+ # the build.
+
+ $(DIFF) \
expected_show_coverage.$@.txt "$(TMPDIR)"/actual_show_coverage.$@.txt || \
( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \
>&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.async.txt b/tests/run-make/coverage-reports/expected_show_coverage.async.txt
index 87ccb6c43ea..93c1535b06b 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.async.txt
+++ b/tests/run-make/coverage-reports/expected_show_coverage.async.txt
@@ -41,9 +41,9 @@
41| 1| // executed asynchronously.
42| 1| match x {
43| 1| y if c(x).await == y + 1 => { d().await; }
- ^0 ^0 ^0 ^0
+ ^0 ^0 ^0 ^0
44| 1| y if f().await == y + 1 => (),
- ^0 ^0 ^0
+ ^0 ^0 ^0
45| 1| _ => (),
46| | }
47| 1|}
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.sort_groups.txt b/tests/run-make/coverage-reports/expected_show_coverage.sort_groups.txt
new file mode 100644
index 00000000000..81468cb35da
--- /dev/null
+++ b/tests/run-make/coverage-reports/expected_show_coverage.sort_groups.txt
@@ -0,0 +1,49 @@
+ 1| |// compile-flags: --edition=2021
+ 2| |
+ 3| |// Demonstrate that `sort_subviews.py` can sort instantiation groups into a
+ 4| |// predictable order, while preserving their heterogeneous contents.
+ 5| |
+ 6| 1|fn main() {
+ 7| 1| let cond = std::env::args().len() > 1;
+ 8| 1| generic_fn::<()>(cond);
+ 9| 1| generic_fn::<&'static str>(!cond);
+ 10| 1| if false {
+ 11| 0| generic_fn::<char>(cond);
+ 12| 1| }
+ 13| 1| generic_fn::<i32>(cond);
+ 14| 1| other_fn();
+ 15| 1|}
+ 16| |
+ 17| 3|fn generic_fn<T>(cond: bool) {
+ 18| 3| if cond {
+ 19| 1| println!("{}", std::any::type_name::<T>());
+ 20| 2| }
+ 21| 3|}
+ ------------------
+ | Unexecuted instantiation: sort_groups::generic_fn::<char>
+ ------------------
+ | sort_groups::generic_fn::<&str>:
+ | 17| 1|fn generic_fn<T>(cond: bool) {
+ | 18| 1| if cond {
+ | 19| 1| println!("{}", std::any::type_name::<T>());
+ | 20| 1| }
+ | ^0
+ | 21| 1|}
+ ------------------
+ | sort_groups::generic_fn::<()>:
+ | 17| 1|fn generic_fn<T>(cond: bool) {
+ | 18| 1| if cond {
+ | 19| 0| println!("{}", std::any::type_name::<T>());
+ | 20| 1| }
+ | 21| 1|}
+ ------------------
+ | sort_groups::generic_fn::<i32>:
+ | 17| 1|fn generic_fn<T>(cond: bool) {
+ | 18| 1| if cond {
+ | 19| 0| println!("{}", std::any::type_name::<T>());
+ | 20| 1| }
+ | 21| 1|}
+ ------------------
+ 22| |
+ 23| 1|fn other_fn() {}
+
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.uses_crate.txt b/tests/run-make/coverage-reports/expected_show_coverage.uses_crate.txt
index 65eb1008dd8..412f4a93b9c 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.uses_crate.txt
+++ b/tests/run-make/coverage-reports/expected_show_coverage.uses_crate.txt
@@ -19,29 +19,29 @@
18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
19| 2|}
------------------
- | used_crate::used_only_from_bin_crate_generic_function::<&str>:
+ | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
+ ------------------
+ | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 19| 1|}
------------------
- | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
+ | used_crate::used_only_from_bin_crate_generic_function::<&str>:
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 19| 1|}
------------------
- | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
- ------------------
20| |// Expect for above function: `Unexecuted instantiation` (see below)
21| 2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
22| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
23| 2|}
------------------
- | used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+ | used_crate::used_only_from_this_lib_crate_generic_function::<&str>:
| 21| 1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
| 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
| 23| 1|}
------------------
- | used_crate::used_only_from_this_lib_crate_generic_function::<&str>:
+ | used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
| 21| 1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
| 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
| 23| 1|}
@@ -51,12 +51,12 @@
26| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
27| 2|}
------------------
- | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+ | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
| 25| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 26| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 27| 1|}
------------------
- | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
+ | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
| 25| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 26| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 27| 1|}
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt b/tests/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt
index 748343885de..66ca9e80a32 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt
+++ b/tests/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt
@@ -42,6 +42,8 @@
40| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
41| 2|}
------------------
+ | Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_>
+ ------------------
| used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
| 39| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
@@ -52,8 +54,6 @@
| 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 41| 1|}
------------------
- | Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_>
- ------------------
42| |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
43| |
44| |#[inline(always)]
@@ -77,16 +77,16 @@
51| 3| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
52| 3|}
------------------
- | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
- | 50| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
- | 51| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
- | 52| 1|}
- ------------------
| used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
| 50| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 51| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 52| 2|}
------------------
+ | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+ | 50| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+ | 51| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+ | 52| 1|}
+ ------------------
53| |
54| |#[inline(always)]
55| 3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
diff --git a/tests/run-make/coverage-reports/sort_subviews.py b/tests/run-make/coverage-reports/sort_subviews.py
new file mode 100644
index 00000000000..10cfc51d447
--- /dev/null
+++ b/tests/run-make/coverage-reports/sort_subviews.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+
+# `llvm-cov show` prints grouped subviews (e.g. for generic functions) in an
+# unstable order, which is inconvenient when checking output snapshots with
+# `diff`. To work around that, this script detects consecutive subviews in its
+# piped input, and sorts them while preserving their contents.
+
+from __future__ import print_function
+
+import sys
+
+
+def main():
+ subviews = []
+
+ def flush_subviews():
+ if not subviews:
+ return
+
+ # The last "subview" should be just a boundary line on its own, so
+ # temporarily remove it before sorting the accumulated subviews.
+ terminator = subviews.pop()
+ subviews.sort()
+ subviews.append(terminator)
+
+ for view in subviews:
+ for line in view:
+ print(line, end="")
+
+ subviews.clear()
+
+ for line in sys.stdin:
+ if line.startswith(" ------------------"):
+ # This is a subview boundary line, so start a new subview.
+ subviews.append([line])
+ elif line.startswith(" |"):
+ # Add this line to the current subview.
+ subviews[-1].append(line)
+ else:
+ # This line is not part of a subview, so sort and print any
+ # accumulated subviews, and then print the line as-is.
+ flush_subviews()
+ print(line, end="")
+
+ flush_subviews()
+ assert not subviews
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/run-make/coverage/sort_groups.rs b/tests/run-make/coverage/sort_groups.rs
new file mode 100644
index 00000000000..f89f9f3ec61
--- /dev/null
+++ b/tests/run-make/coverage/sort_groups.rs
@@ -0,0 +1,23 @@
+// compile-flags: --edition=2021
+
+// Demonstrate that `sort_subviews.py` can sort instantiation groups into a
+// predictable order, while preserving their heterogeneous contents.
+
+fn main() {
+ let cond = std::env::args().len() > 1;
+ generic_fn::<()>(cond);
+ generic_fn::<&'static str>(!cond);
+ if false {
+ generic_fn::<char>(cond);
+ }
+ generic_fn::<i32>(cond);
+ other_fn();
+}
+
+fn generic_fn<T>(cond: bool) {
+ if cond {
+ println!("{}", std::any::type_name::<T>());
+ }
+}
+
+fn other_fn() {}
diff --git a/tests/run-make/forced-unwind-terminate-pof/Makefile b/tests/run-make/forced-unwind-terminate-pof/Makefile
new file mode 100644
index 00000000000..871621520b9
--- /dev/null
+++ b/tests/run-make/forced-unwind-terminate-pof/Makefile
@@ -0,0 +1,9 @@
+# ignore-cross-compile
+# only-linux
+include ../tools.mk
+
+all: foo
+ $(call RUN,foo) | $(CGREP) -v "cannot unwind"
+
+foo: foo.rs
+ $(RUSTC) $<
diff --git a/tests/run-make/forced-unwind-terminate-pof/foo.rs b/tests/run-make/forced-unwind-terminate-pof/foo.rs
new file mode 100644
index 00000000000..0a51287313f
--- /dev/null
+++ b/tests/run-make/forced-unwind-terminate-pof/foo.rs
@@ -0,0 +1,17 @@
+// Tests that forced unwind through POF Rust frames wouldn't trigger our terminating guards.
+
+#![feature(c_unwind)]
+#![no_main]
+
+extern "C-unwind" {
+ fn pthread_exit(v: *mut core::ffi::c_void) -> !;
+}
+
+unsafe extern "C" fn call_pthread_exit() {
+ pthread_exit(core::ptr::null_mut());
+}
+
+#[no_mangle]
+unsafe extern "C-unwind" fn main(_argc: core::ffi::c_int, _argv: *mut *mut core::ffi::c_char) {
+ call_pthread_exit();
+}
diff --git a/tests/run-make/staticlib-dylib-linkage/Makefile b/tests/run-make/staticlib-dylib-linkage/Makefile
new file mode 100644
index 00000000000..a1e86a7ce4b
--- /dev/null
+++ b/tests/run-make/staticlib-dylib-linkage/Makefile
@@ -0,0 +1,21 @@
+include ../tools.mk
+
+# ignore-cross-compile
+# ignore-msvc FIXME(bjorn3) can't figure out how to link with the MSVC toolchain
+# ignore-wasm wasm doesn't support dynamic libraries
+
+all:
+ $(RUSTC) -C prefer-dynamic bar.rs
+ $(RUSTC) foo.rs --crate-type staticlib --print native-static-libs \
+ -Z staticlib-allow-rdylib-deps 2>&1 | grep 'note: native-static-libs: ' \
+ | sed 's/note: native-static-libs: \(.*\)/\1/' > $(TMPDIR)/libs.txt
+ cat $(TMPDIR)/libs.txt
+
+ifdef IS_MSVC
+ $(CC) $(CFLAGS) /c foo.c /Fo:$(TMPDIR)/foo.o
+ $(RUSTC_LINKER) $(TMPDIR)/foo.o $(TMPDIR)/foo.lib $$(cat $(TMPDIR)/libs.txt) $(call OUT_EXE,foo)
+else
+ $(CC) $(CFLAGS) foo.c -L $(TMPDIR) -lfoo $$(cat $(TMPDIR)/libs.txt) -o $(call RUN_BINFILE,foo)
+endif
+
+ $(call RUN,foo)
diff --git a/tests/run-make/staticlib-dylib-linkage/bar.rs b/tests/run-make/staticlib-dylib-linkage/bar.rs
new file mode 100644
index 00000000000..b3a7539abae
--- /dev/null
+++ b/tests/run-make/staticlib-dylib-linkage/bar.rs
@@ -0,0 +1,5 @@
+#![crate_type = "dylib"]
+
+pub fn bar() {
+ println!("hello!");
+}
diff --git a/tests/run-make/staticlib-dylib-linkage/foo.c b/tests/run-make/staticlib-dylib-linkage/foo.c
new file mode 100644
index 00000000000..154f9682ef8
--- /dev/null
+++ b/tests/run-make/staticlib-dylib-linkage/foo.c
@@ -0,0 +1,10 @@
+#include <assert.h>
+
+extern void foo();
+extern unsigned bar(unsigned a, unsigned b);
+
+int main() {
+ foo();
+ assert(bar(1, 2) == 3);
+ return 0;
+}
diff --git a/tests/run-make/staticlib-dylib-linkage/foo.rs b/tests/run-make/staticlib-dylib-linkage/foo.rs
new file mode 100644
index 00000000000..af439391c75
--- /dev/null
+++ b/tests/run-make/staticlib-dylib-linkage/foo.rs
@@ -0,0 +1,13 @@
+#![crate_type = "staticlib"]
+
+extern crate bar;
+
+#[no_mangle]
+pub extern "C" fn foo() {
+ bar::bar();
+}
+
+#[no_mangle]
+pub extern "C" fn bar(a: u32, b: u32) -> u32 {
+ a + b
+}
diff --git a/tests/rustdoc-gui/check-stab-in-docblock.goml b/tests/rustdoc-gui/check-stab-in-docblock.goml
index 2f62636211b..f25c88690e5 100644
--- a/tests/rustdoc-gui/check-stab-in-docblock.goml
+++ b/tests/rustdoc-gui/check-stab-in-docblock.goml
@@ -7,20 +7,26 @@ set-window-size: (786, 600)
// Confirms that there 3 paragraphs.
assert-count: (".top-doc .docblock p", 3)
// Checking that there is no scrollable content.
-store-property: (clientHeight, ".top-doc .docblock p:nth-of-type(1)", "clientHeight")
-store-property: (clientWidth, ".top-doc .docblock p:nth-of-type(1)", "clientWidth")
+store-property: (".top-doc .docblock p:nth-of-type(1)", {
+ "clientHeight": clientHeight,
+ "clientWidth": clientWidth,
+})
assert-property: (
".top-doc .docblock p:nth-of-type(1)",
{"scrollHeight": |clientHeight|, "scrollWidth": |clientWidth|},
)
-store-property: (clientHeight, ".top-doc .docblock p:nth-of-type(2)", "clientHeight")
-store-property: (clientWidth, ".top-doc .docblock p:nth-of-type(2)", "clientWidth")
+store-property: (".top-doc .docblock p:nth-of-type(2)", {
+ "clientHeight": clientHeight,
+ "clientWidth": clientWidth,
+})
assert-property: (
".top-doc .docblock p:nth-of-type(2)",
{"scrollHeight": |clientHeight|, "scrollWidth": |clientWidth|},
)
-store-property: (clientHeight, ".top-doc .docblock p:nth-of-type(3)", "clientHeight")
-store-property: (clientWidth, ".top-doc .docblock p:nth-of-type(3)", "clientWidth")
+store-property: (".top-doc .docblock p:nth-of-type(3)", {
+ "clientHeight": clientHeight,
+ "clientWidth": clientWidth,
+})
assert-property: (
".top-doc .docblock p:nth-of-type(3)",
{"scrollHeight": |clientHeight|, "scrollWidth": |clientWidth|},
diff --git a/tests/rustdoc-gui/codeblock-sub.goml b/tests/rustdoc-gui/codeblock-sub.goml
index 03575cc6aaa..a4b0558765a 100644
--- a/tests/rustdoc-gui/codeblock-sub.goml
+++ b/tests/rustdoc-gui/codeblock-sub.goml
@@ -1,5 +1,5 @@
// Test that code blocks nested within <sub> do not have a line height of 0.
go-to: "file://" + |DOC_PATH| + "/test_docs/codeblock_sub/index.html"
-store-property: (codeblock_sub_1, "#codeblock-sub-1", "offsetHeight")
+store-property: ("#codeblock-sub-1", {"offsetHeight": codeblock_sub_1})
assert-property-false: ("#codeblock-sub-3", { "offsetHeight": |codeblock_sub_1| })
diff --git a/tests/rustdoc-gui/docblock-details.goml b/tests/rustdoc-gui/docblock-details.goml
index 58ff17619f6..8e6d2ba824f 100644
--- a/tests/rustdoc-gui/docblock-details.goml
+++ b/tests/rustdoc-gui/docblock-details.goml
@@ -9,7 +9,7 @@ reload:
assert-text: (".top-doc .docblock > h3", "Hello")
assert-css: (
".top-doc .docblock > h3",
- {"border-bottom": "1px solid rgb(210, 210, 210)"},
+ {"border-bottom": "1px solid #d2d2d2"},
)
// We now check that the `<summary>` doesn't have a bottom border and has the correct display.
assert-css: (
diff --git a/tests/rustdoc-gui/item-info.goml b/tests/rustdoc-gui/item-info.goml
index 60fd7c4e198..030ff8f8a3e 100644
--- a/tests/rustdoc-gui/item-info.goml
+++ b/tests/rustdoc-gui/item-info.goml
@@ -4,8 +4,8 @@ go-to: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html"
// We set a fixed size so there is no chance of "random" resize.
set-window-size: (1100, 800)
// We check that ".item-info" is bigger than its content.
-assert-css: (".item-info", {"width": "840px"})
-assert-css: (".item-info .stab", {"width": "289px"})
+assert-size: (".item-info", {"width": 840})
+assert-size: (".item-info .stab", {"width": 289})
assert-position: (".item-info .stab", {"x": 245})
// Now we ensure that they're not rendered on the same line.
diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml
index f65da577478..ecb57c274a5 100644
--- a/tests/rustdoc-gui/notable-trait.goml
+++ b/tests/rustdoc-gui/notable-trait.goml
@@ -225,12 +225,12 @@ assert: "#method\.create_an_iterator_from_read .tooltip:focus"
// Now we check that the focus isn't given back to the wrong item when opening
// another popover.
-store-window-property: (scroll, "scrollY")
+store-window-property: {"scrollY": scroll}
click: "#method\.create_an_iterator_from_read .fn"
// We ensure that the scroll position changed.
assert-window-property-false: {"scrollY": |scroll|}
// Store the new position.
-store-window-property: (scroll, "scrollY")
+store-window-property: {"scrollY": scroll}
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']"
wait-for: "//*[@class='tooltip popover']"
click: "#settings-menu a"
@@ -239,12 +239,12 @@ click: ".search-input"
assert-window-property-false: {"scrollY": |scroll|}
// Same but with Escape handling.
-store-window-property: (scroll, "scrollY")
+store-window-property: {"scrollY": scroll}
click: "#method\.create_an_iterator_from_read .fn"
// We ensure that the scroll position changed.
assert-window-property-false: {"scrollY": |scroll|}
// Store the new position.
-store-window-property: (scroll, "scrollY")
+store-window-property: {"scrollY": scroll}
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']"
wait-for: "//*[@class='tooltip popover']"
click: "#settings-menu a"
diff --git a/tests/rustdoc-gui/scrape-examples-button-focus.goml b/tests/rustdoc-gui/scrape-examples-button-focus.goml
index 77061ea2a3f..af4293dfc00 100644
--- a/tests/rustdoc-gui/scrape-examples-button-focus.goml
+++ b/tests/rustdoc-gui/scrape-examples-button-focus.goml
@@ -3,7 +3,7 @@
go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test.html"
// The next/prev buttons vertically scroll the code viewport between examples
-store-property: (initialScrollTop, ".scraped-example-list > .scraped-example pre", "scrollTop")
+store-property: (".scraped-example-list > .scraped-example pre", {"scrollTop": initialScrollTop})
focus: ".scraped-example-list > .scraped-example .next"
press-key: "Enter"
assert-property-false: (".scraped-example-list > .scraped-example pre", {
@@ -16,7 +16,7 @@ assert-property: (".scraped-example-list > .scraped-example pre", {
}, NEAR)
// The expand button increases the scrollHeight of the minimized code viewport
-store-property: (smallOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight")
+store-property: (".scraped-example-list > .scraped-example pre", {"offsetHeight": smallOffsetHeight})
assert-property-false: (".scraped-example-list > .scraped-example pre", {
"scrollHeight": |smallOffsetHeight|
}, NEAR)
@@ -25,7 +25,7 @@ press-key: "Enter"
assert-property-false: (".scraped-example-list > .scraped-example pre", {
"offsetHeight": |smallOffsetHeight|
}, NEAR)
-store-property: (fullOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight")
+store-property: (".scraped-example-list > .scraped-example pre", {"offsetHeight": fullOffsetHeight})
assert-property: (".scraped-example-list > .scraped-example pre", {
"scrollHeight": |fullOffsetHeight|
}, NEAR)
diff --git a/tests/rustdoc-gui/scrape-examples-layout.goml b/tests/rustdoc-gui/scrape-examples-layout.goml
index 160056d6d05..4fc1c1ac065 100644
--- a/tests/rustdoc-gui/scrape-examples-layout.goml
+++ b/tests/rustdoc-gui/scrape-examples-layout.goml
@@ -9,9 +9,8 @@ assert-property-false: (
// Check that examples with very long lines have the same width as ones that don't.
store-property: (
- clientWidth,
".more-scraped-examples .scraped-example:nth-child(2) .code-wrapper .src-line-numbers",
- "clientWidth"
+ {"clientWidth": clientWidth},
)
assert-property: (
@@ -40,8 +39,8 @@ assert-property: (
store-value: (offset_y, 4)
// First with desktop
-assert-position: (".scraped-example .code-wrapper", {"y": 253})
-assert-position: (".scraped-example .code-wrapper .prev", {"y": 253 + |offset_y|})
+assert-position: (".scraped-example .code-wrapper", {"y": 226})
+assert-position: (".scraped-example .code-wrapper .prev", {"y": 226 + |offset_y|})
// Then with mobile
set-window-size: (600, 600)
diff --git a/tests/rustdoc-gui/search-result-color.goml b/tests/rustdoc-gui/search-result-color.goml
index da46a90df90..90f7160b724 100644
--- a/tests/rustdoc-gui/search-result-color.goml
+++ b/tests/rustdoc-gui/search-result-color.goml
@@ -47,89 +47,89 @@ reload:
wait-for: "#search-tabs"
assert-css: (
"#search-tabs > button > .count",
- {"color": "rgb(136, 136, 136)"},
+ {"color": "#888"},
ALL,
)
assert-css: (
"//*[@class='desc'][text()='Just a normal struct.']",
- {"color": "rgb(197, 197, 197)"},
+ {"color": "#c5c5c5"},
)
assert-css: (
"//*[@class='result-name']/*[text()='test_docs::']",
- {"color": "rgb(0, 150, 207)"},
+ {"color": "#0096cf"},
)
// Checking the color of the bottom border.
assert-css: (
".search-results > a",
- {"border-bottom-color": "rgba(170, 170, 170, 0.2)"}
+ {"border-bottom-color": "#aaa3"}
)
// Checking the color of "keyword" text.
assert-css: (
"//*[@class='result-name']//*[text()='(keyword)']",
- {"color": "rgb(120, 135, 151)"},
+ {"color": "#788797"},
)
-store-value: (entry_color, "rgb(0, 150, 207)") // color of the search entry
-store-value: (hover_entry_color, "rgb(255, 255, 255)") // color of the hovered/focused search entry
-store-value: (background_color, "rgba(0, 0, 0, 0)") // background color
-store-value: (hover_background_color, "rgb(60, 60, 60)") // hover background color
+store-value: (entry_color, "#0096cf") // color of the search entry
+store-value: (hover_entry_color, "#fff") // color of the hovered/focused search entry
+store-value: (background_color, "transparent") // background color
+store-value: (hover_background_color, "#3c3c3c") // hover background color
call-function: (
"check-result-color", (
"keyword", // item kind
- "rgb(57, 175, 215)", // color of item kind
- "rgb(57, 175, 215)", // color of hovered/focused item kind
+ "#39afd7", // color of item kind
+ "#39afd7", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"struct", // item kind
- "rgb(255, 160, 165)", // color of item kind
- "rgb(255, 160, 165)", // color of hovered/focused item kind
+ "#ffa0a5", // color of item kind
+ "#ffa0a5", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"associatedtype", // item kind
- "rgb(57, 175, 215)", // color of item kind
- "rgb(57, 175, 215)", // color of hovered/focused item kind
+ "#39afd7", // color of item kind
+ "#39afd7", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"tymethod", // item kind
- "rgb(253, 214, 135)", // color of item kind
- "rgb(253, 214, 135)", // color of hovered/focused item kind
+ "#fdd687", // color of item kind
+ "#fdd687", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"method", // item kind
- "rgb(253, 214, 135)", // color of item kind
- "rgb(253, 214, 135)", // color of hovered/focused item kind
+ "#fdd687", // color of item kind
+ "#fdd687", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"structfield", // item kind
- "rgb(0, 150, 207)", // color of item kind
- "rgb(255, 255, 255)", // color of hovered/focused item kind
+ "#0096cf", // color of item kind
+ "#fff", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"macro", // item kind
- "rgb(163, 122, 204)", // color of item kind
- "rgb(163, 122, 204)", // color of hovered/focused item kind
+ "#a37acc", // color of item kind
+ "#a37acc", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"fn", // item kind
- "rgb(253, 214, 135)", // color of item kind
- "rgb(253, 214, 135)", // color of hovered/focused item kind
+ "#fdd687", // color of item kind
+ "#fdd687", // color of hovered/focused item kind
),
)
@@ -138,7 +138,7 @@ move-cursor-to: ".search-input"
focus: ".search-input" // To ensure the `<a>` container isnt focus or hover.
assert-css: (
"//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
- {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
+ {"color": "#0096cf", "background-color": "transparent"},
ALL,
)
@@ -146,11 +146,11 @@ assert-css: (
move-cursor-to: "//*[@class='desc'][text()='Just a normal struct.']"
assert-css: (
"//*[@class='result-name']/*[text()='test_docs::']",
- {"color": "rgb(255, 255, 255)"},
+ {"color": "#fff"},
)
assert-css: (
"//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
- {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+ {"color": "#fff", "background-color": "rgb(60, 60, 60)"},
)
// Dark theme
@@ -164,89 +164,89 @@ reload:
wait-for: "#search-tabs"
assert-css: (
"#search-tabs > button > .count",
- {"color": "rgb(136, 136, 136)"},
+ {"color": "#888"},
ALL,
)
assert-css: (
"//*[@class='desc'][text()='Just a normal struct.']",
- {"color": "rgb(221, 221, 221)"},
+ {"color": "#ddd"},
)
assert-css: (
"//*[@class='result-name']/*[text()='test_docs::']",
- {"color": "rgb(221, 221, 221)"},
+ {"color": "#ddd"},
)
// Checking the color of the bottom border.
assert-css: (
".search-results > a",
- {"border-bottom-color": "rgba(170, 170, 170, 0.2)"}
+ {"border-bottom-color": "#aaa3"}
)
// Checking the color for "keyword" text.
assert-css: (
"//*[@class='result-name']//*[text()='(keyword)']",
- {"color": "rgb(221, 221, 221)"},
+ {"color": "#ddd"},
)
-store-value: (entry_color, "rgb(221, 221, 221)") // color of the search entry
-store-value: (hover_entry_color, "rgb(221, 221, 221)") // color of the hovered/focused search entry
-store-value: (background_color, "rgba(0, 0, 0, 0)") // background color
-store-value: (hover_background_color, "rgb(97, 97, 97)") // hover background color
+store-value: (entry_color, "#ddd") // color of the search entry
+store-value: (hover_entry_color, "#ddd") // color of the hovered/focused search entry
+store-value: (background_color, "transparent") // background color
+store-value: (hover_background_color, "#616161") // hover background color
call-function: (
"check-result-color", (
"keyword", // item kind
- "rgb(210, 153, 29)", // color of item kind
- "rgb(210, 153, 29)", // color of hovered/focused item kind
+ "#d2991d", // color of item kind
+ "#d2991d", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"struct", // item kind
- "rgb(45, 191, 184)", // color of item kind
- "rgb(45, 191, 184)", // color of hovered/focused item kind
+ "#2dbfb8", // color of item kind
+ "#2dbfb8", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"associatedtype", // item kind
- "rgb(210, 153, 29)", // color of item kind
- "rgb(210, 153, 29)", // color of hovered/focused item kind
+ "#d2991d", // color of item kind
+ "#d2991d", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"tymethod", // item kind
- "rgb(43, 171, 99)", // color of item kind
- "rgb(43, 171, 99)", // color of hovered/focused item kind
+ "#2bab63", // color of item kind
+ "#2bab63", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"method", // item kind
- "rgb(43, 171, 99)", // color of item kind
- "rgb(43, 171, 99)", // color of hovered/focused item kind
+ "#2bab63", // color of item kind
+ "#2bab63", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"structfield", // item kind
- "rgb(221, 221, 221)", // color of item kind
- "rgb(221, 221, 221)", // color of hovered/focused item kind
+ "#ddd", // color of item kind
+ "#ddd", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"macro", // item kind
- "rgb(9, 189, 0)", // color of item kind
- "rgb(9, 189, 0)", // color of hovered/focused item kind
+ "#09bd00", // color of item kind
+ "#09bd00", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"fn", // item kind
- "rgb(43, 171, 99)", // color of item kind
- "rgb(43, 171, 99)", // color of hovered/focused item kind
+ "#2bab63", // color of item kind
+ "#2bab63", // color of hovered/focused item kind
),
)
@@ -255,7 +255,7 @@ move-cursor-to: ".search-input"
focus: ".search-input" // To ensure the `<a>` container isnt focus or hover.
assert-css: (
"//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
- {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
+ {"color": "#ddd", "background-color": "transparent"},
)
// Light theme
@@ -266,89 +266,89 @@ reload:
wait-for: "#search-tabs"
assert-css: (
"#search-tabs > button > .count",
- {"color": "rgb(136, 136, 136)"},
+ {"color": "#888"},
ALL,
)
assert-css: (
"//*[@class='desc'][text()='Just a normal struct.']",
- {"color": "rgb(0, 0, 0)"},
+ {"color": "#000"},
)
assert-css: (
"//*[@class='result-name']/*[text()='test_docs::']",
- {"color": "rgb(0, 0, 0)"},
+ {"color": "#000"},
)
// Checking the color of the bottom border.
assert-css: (
".search-results > a",
- {"border-bottom-color": "rgba(170, 170, 170, 0.2)"}
+ {"border-bottom-color": "#aaa3"}
)
// Checking the color for "keyword" text.
assert-css: (
"//*[@class='result-name']//*[text()='(keyword)']",
- {"color": "rgb(0, 0, 0)"},
+ {"color": "#000"},
)
-store-value: (entry_color, "rgb(0, 0, 0)") // color of the search entry
-store-value: (hover_entry_color, "rgb(0, 0, 0)") // color of the hovered/focused search entry
-store-value: (background_color, "rgba(0, 0, 0, 0)") // background color
-store-value: (hover_background_color, "rgb(204, 204, 204)") // hover background color
+store-value: (entry_color, "#000") // color of the search entry
+store-value: (hover_entry_color, "#000") // color of the hovered/focused search entry
+store-value: (background_color, "transparent") // background color
+store-value: (hover_background_color, "#ccc") // hover background color
call-function: (
"check-result-color", (
"keyword", // item kind
- "rgb(56, 115, 173)", // color of item kind
- "rgb(56, 115, 173)", // color of hovered/focused item kind
+ "#3873ad", // color of item kind
+ "#3873ad", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"struct", // item kind
- "rgb(173, 55, 138)", // color of item kind
- "rgb(173, 55, 138)", // color of hovered/focused item kind
+ "#ad378a", // color of item kind
+ "#ad378a", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"associatedtype", // item kind
- "rgb(56, 115, 173)", // color of item kind
- "rgb(56, 115, 173)", // color of hovered/focused item kind
+ "#3873ad", // color of item kind
+ "#3873ad", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"tymethod", // item kind
- "rgb(173, 124, 55)", // color of item kind
- "rgb(173, 124, 55)", // color of hovered/focused item kind
+ "#ad7c37", // color of item kind
+ "#ad7c37", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"method", // item kind
- "rgb(173, 124, 55)", // color of item kind
- "rgb(173, 124, 55)", // color of hovered/focused item kind
+ "#ad7c37", // color of item kind
+ "#ad7c37", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"structfield", // item kind
- "rgb(0, 0, 0)", // color of item kind
- "rgb(0, 0, 0)", // color of hovered/focused item kind
+ "#000", // color of item kind
+ "#000", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"macro", // item kind
- "rgb(6, 128, 0)", // color of item kind
- "rgb(6, 128, 0)", // color of hovered/focused item kind
+ "#068000", // color of item kind
+ "#068000", // color of hovered/focused item kind
),
)
call-function: (
"check-result-color", (
"fn", // item kind
- "rgb(173, 124, 55)", // color of item kind
- "rgb(173, 124, 55)", // color of hovered/focused item kind
+ "#ad7c37", // color of item kind
+ "#ad7c37", // color of hovered/focused item kind
),
)
@@ -357,7 +357,7 @@ move-cursor-to: ".search-input"
focus: ".search-input" // To ensure the `<a>` container isnt focus or hover.
assert-css: (
"//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
- {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
+ {"color": "#000", "background-color": "transparent"},
)
// Check the alias.
@@ -386,16 +386,16 @@ define-function: (
call-function: ("check-alias", {
"theme": "ayu",
- "alias": "rgb(197, 197, 197)",
- "grey": "rgb(153, 153, 153)",
+ "alias": "#c5c5c5",
+ "grey": "#999",
})
call-function: ("check-alias", {
"theme": "dark",
- "alias": "rgb(255, 255, 255)",
- "grey": "rgb(204, 204, 204)",
+ "alias": "#fff",
+ "grey": "#ccc",
})
call-function: ("check-alias", {
"theme": "light",
- "alias": "rgb(0, 0, 0)",
- "grey": "rgb(153, 153, 153)",
+ "alias": "#000",
+ "grey": "#999",
})
diff --git a/tests/rustdoc-gui/search-result-display.goml b/tests/rustdoc-gui/search-result-display.goml
index 93c71f23f24..ee5598e4b21 100644
--- a/tests/rustdoc-gui/search-result-display.goml
+++ b/tests/rustdoc-gui/search-result-display.goml
@@ -32,8 +32,8 @@ set-text: (
)
// Then we compare again to confirm the height didn't change.
-assert-css: ("#crate-search", {"width": "527px"})
-assert-css: (".search-results-title", {"height": "50px", "width": "640px"})
+assert-size: ("#crate-search", {"width": 527})
+assert-size: (".search-results-title", {"height": 50, "width": 640})
// And we check that the `<select>` isn't bigger than its container (".search-results-title").
assert-css: ("#search", {"width": "640px"})
diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml
index a44ff9d3e4a..bf1fe7be910 100644
--- a/tests/rustdoc-gui/settings.goml
+++ b/tests/rustdoc-gui/settings.goml
@@ -10,7 +10,7 @@ wait-for: "#settings"
assert-css: ("#settings", {"display": "block"})
// Store the line margin to compare with the settings.html later.
-store-css: (setting_line_margin, ".setting-line", "margin")
+store-css: (".setting-line", {"margin": setting_line_margin})
// Let's close it by clicking on the same button.
click: "#settings-menu"
diff --git a/tests/rustdoc-gui/sidebar-source-code-display.goml b/tests/rustdoc-gui/sidebar-source-code-display.goml
index 20bf0596f95..0c680bcc9fb 100644
--- a/tests/rustdoc-gui/sidebar-source-code-display.goml
+++ b/tests/rustdoc-gui/sidebar-source-code-display.goml
@@ -121,28 +121,28 @@ define-function: (
call-function: ("check-colors", {
"theme": "light",
- "color": "rgb(0, 0, 0)",
- "color_hover": "rgb(0, 0, 0)",
- "background": "rgb(255, 255, 255)",
- "background_hover": "rgb(224, 224, 224)",
+ "color": "black",
+ "color_hover": "#000",
+ "background": "#fff",
+ "background_hover": "#e0e0e0",
"background_toggle": "rgba(0, 0, 0, 0)",
- "background_toggle_hover": "rgb(224, 224, 224)",
+ "background_toggle_hover": "#e0e0e0",
})
call-function: ("check-colors", {
"theme": "dark",
- "color": "rgb(221, 221, 221)",
- "color_hover": "rgb(221, 221, 221)",
- "background": "rgb(51, 51, 51)",
- "background_hover": "rgb(68, 68, 68)",
+ "color": "#ddd",
+ "color_hover": "#ddd",
+ "background": "#333",
+ "background_hover": "#444",
"background_toggle": "rgba(0, 0, 0, 0)",
- "background_toggle_hover": "rgb(103, 103, 103)",
+ "background_toggle_hover": "#676767",
})
call-function: ("check-colors", {
"theme": "ayu",
- "color": "rgb(197, 197, 197)",
- "color_hover": "rgb(255, 180, 76)",
+ "color": "#c5c5c5",
+ "color_hover": "#ffb44c",
"background": "rgb(20, 25, 31)",
- "background_hover": "rgb(20, 25, 31)",
+ "background_hover": "#14191f",
"background_toggle": "rgba(0, 0, 0, 0)",
"background_toggle_hover": "rgba(70, 70, 70, 0.33)",
})
diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml
index 3c1ed009a33..574cc629a04 100644
--- a/tests/rustdoc-gui/sidebar.goml
+++ b/tests/rustdoc-gui/sidebar.goml
@@ -152,14 +152,16 @@ assert-property: (".sidebar", {"clientWidth": "200"})
// Checks that all.html and index.html have their sidebar link in the same place.
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-store-property: (index_sidebar_width, ".sidebar .location a", "clientWidth")
-store-property: (index_sidebar_height, ".sidebar .location a", "clientHeight")
-store-property: (index_sidebar_x, ".sidebar .location a", "offsetTop")
-store-property: (index_sidebar_y, ".sidebar .location a", "offsetLeft")
+store-property: (".sidebar .location a", {
+ "clientWidth": index_sidebar_width,
+ "clientHeight": index_sidebar_height,
+ "offsetTop": index_sidebar_y,
+ "offsetLeft": index_sidebar_x,
+})
go-to: "file://" + |DOC_PATH| + "/test_docs/all.html"
assert-property: (".sidebar .location a", {
"clientWidth": |index_sidebar_width|,
"clientHeight": |index_sidebar_height|,
- "offsetTop": |index_sidebar_x|,
- "offsetLeft": |index_sidebar_y|,
+ "offsetTop": |index_sidebar_y|,
+ "offsetLeft": |index_sidebar_x|,
})
diff --git a/tests/rustdoc-gui/source-code-page.goml b/tests/rustdoc-gui/source-code-page.goml
index 42f3200e967..5c795928bdc 100644
--- a/tests/rustdoc-gui/source-code-page.goml
+++ b/tests/rustdoc-gui/source-code-page.goml
@@ -117,9 +117,8 @@ assert-property: ("#source-sidebar details:first-of-type", {"open": "true"})
// Check the sidebar directory entries have a marker and spacing (desktop).
store-property: (
- link_height,
"#source-sidebar > details:first-of-type.dir-entry[open] > .files > a",
- "offsetHeight"
+ {"offsetHeight": link_height},
)
define-function: (
"check-sidebar-dir-entry",
@@ -147,16 +146,10 @@ define-function: (
)
}
)
-store-property: (
- source_sidebar_title_height,
- "#source-sidebar > .title",
- "offsetHeight"
-)
-store-property: (
- source_sidebar_title_y,
- "#source-sidebar > .title",
- "offsetTop"
-)
+store-property: ("#source-sidebar > .title", {
+ "offsetHeight": source_sidebar_title_height,
+ "offsetTop": source_sidebar_title_y,
+})
call-function: ("check-sidebar-dir-entry", {
"x": 0,
// border + margin = 6
@@ -182,16 +175,10 @@ assert-property: ("#main-content", {"offsetTop": 76})
// 21 = 76 - 34 - 21
// Check the sidebar directory entries have a marker and spacing (tablet).
-store-property: (
- source_sidebar_title_height,
- "#source-sidebar > .title",
- "offsetHeight"
-)
-store-property: (
- source_sidebar_title_y,
- "#source-sidebar > .title",
- "offsetTop"
-)
+store-property: ("#source-sidebar > .title", {
+ "offsetHeight": source_sidebar_title_height,
+ "offsetTop": source_sidebar_title_y,
+})
call-function: ("check-sidebar-dir-entry", {
"x": 0,
"y": |source_sidebar_title_y| + |source_sidebar_title_height| + 6,
@@ -202,16 +189,10 @@ set-window-size: (450, 700)
assert-css: ("nav.sub", {"flex-direction": "column"})
// Check the sidebar directory entries have a marker and spacing (phone).
-store-property: (
- source_sidebar_title_height,
- "#source-sidebar > .title",
- "offsetHeight"
-)
-store-property: (
- source_sidebar_title_y,
- "#source-sidebar > .title",
- "offsetTop"
-)
+store-property: ("#source-sidebar > .title", {
+ "offsetHeight": source_sidebar_title_height,
+ "offsetTop": source_sidebar_title_y,
+})
call-function: ("check-sidebar-dir-entry", {
"x": 0,
"y": |source_sidebar_title_y| + |source_sidebar_title_height| + 6,
@@ -219,5 +200,5 @@ call-function: ("check-sidebar-dir-entry", {
// Now we check that the logo has a bottom margin so it's not stuck to the search input.
assert-css: (".sub-logo-container > img", {"margin-bottom": "8px"})
-store-property: (logo_height, ".sub-logo-container", "clientHeight")
+store-property: (".sub-logo-container", {"clientHeight": logo_height})
assert-position: (".search-form", {"y": |logo_height| + 8})
diff --git a/tests/rustdoc-gui/src-font-size.goml b/tests/rustdoc-gui/src-font-size.goml
index 790aeba529c..ff30bcdf2a2 100644
--- a/tests/rustdoc-gui/src-font-size.goml
+++ b/tests/rustdoc-gui/src-font-size.goml
@@ -11,6 +11,6 @@ assert-css: (".impl-items .srclink", {"font-size": "16px", "font-weight": 400},
assert-css: (".impl-items .code-header", {"font-size": "16px", "font-weight": 600}, ALL)
// Check that we can click on source link
-store-document-property: (url, "URL")
+store-document-property: {"URL": url}
click: ".impl-items .srclink"
assert-document-property-false: {"URL": |url|}
diff --git a/tests/rustdoc-gui/struct-fields.goml b/tests/rustdoc-gui/struct-fields.goml
index da0467de13a..3c87a4cd654 100644
--- a/tests/rustdoc-gui/struct-fields.goml
+++ b/tests/rustdoc-gui/struct-fields.goml
@@ -1,5 +1,5 @@
// This test ensures that each field is on its own line (In other words, they have display: block).
go-to: "file://" + |DOC_PATH| + "/test_docs/struct.StructWithPublicUndocumentedFields.html"
-store-property: (first_top, "//*[@id='structfield.first']", "offsetTop")
+store-property: ("//*[@id='structfield.first']", {"offsetTop": first_top})
assert-property-false: ("//*[@id='structfield.second']", { "offsetTop": |first_top| })
diff --git a/tests/rustdoc-gui/type-declation-overflow.goml b/tests/rustdoc-gui/type-declation-overflow.goml
index e8e42e4004b..f212781e9b3 100644
--- a/tests/rustdoc-gui/type-declation-overflow.goml
+++ b/tests/rustdoc-gui/type-declation-overflow.goml
@@ -39,7 +39,7 @@ assert-property: ("pre.item-decl", {"scrollWidth": "950"})
set-window-size: (600, 600)
go-to: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html"
// It shouldn't have an overflow in the topbar either.
-store-property: (scrollWidth, ".mobile-topbar h2", "scrollWidth")
+store-property: (".mobile-topbar h2", {"scrollWidth": scrollWidth})
assert-property: (".mobile-topbar h2", {"clientWidth": |scrollWidth|})
assert-css: (".mobile-topbar h2", {"overflow-x": "hidden"})
diff --git a/tests/rustdoc-json/impls/impl_item_visibility.rs b/tests/rustdoc-json/impls/impl_item_visibility.rs
new file mode 100644
index 00000000000..efa54d91dca
--- /dev/null
+++ b/tests/rustdoc-json/impls/impl_item_visibility.rs
@@ -0,0 +1,26 @@
+#![feature(no_core)]
+#![no_core]
+
+pub struct Foo;
+
+/// impl Foo priv
+impl Foo {
+ fn baz() {}
+}
+// @!has '$.index[*][?(@.docs=="impl Foo priv")]'
+
+
+/// impl Foo pub
+impl Foo {
+ pub fn qux() {}
+}
+// @is '$.index[*][?(@.docs=="impl Foo pub")].visibility' '"default"'
+
+
+/// impl Foo hidden
+impl Foo {
+ #[doc(hidden)]
+ pub fn __quazl(){}
+}
+// FIXME(#111564): Is this the right behaviour?
+// @is '$.index[*][?(@.docs=="impl Foo hidden")].visibility' '"default"'
diff --git a/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs b/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs
new file mode 100644
index 00000000000..3c6fefc4ca2
--- /dev/null
+++ b/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs
@@ -0,0 +1,28 @@
+// compile-flags: --document-hidden-items
+#![feature(no_core)]
+#![no_core]
+
+pub struct Foo;
+
+/// impl Foo priv
+impl Foo {
+ fn baz() {}
+}
+// FIXME(#111564): Is this the right behaviour?
+// @is '$.index[*][?(@.docs=="impl Foo priv")].visibility' '"default"'
+
+
+/// impl Foo pub
+impl Foo {
+ pub fn qux() {}
+}
+// @is '$.index[*][?(@.docs=="impl Foo pub")].visibility' '"default"'
+
+
+/// impl Foo hidden
+impl Foo {
+ #[doc(hidden)]
+ pub fn __quazl(){}
+}
+// FIXME(#111564): Is this the right behaviour?
+// @is '$.index[*][?(@.docs=="impl Foo hidden")].visibility' '"default"'
diff --git a/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs b/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs
new file mode 100644
index 00000000000..b98d1e4167c
--- /dev/null
+++ b/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs
@@ -0,0 +1,27 @@
+// compile-flags: --document-private-items
+#![feature(no_core)]
+#![no_core]
+
+pub struct Foo;
+
+/// impl Foo priv
+impl Foo {
+ fn baz() {}
+}
+// @is '$.index[*][?(@.docs=="impl Foo priv")].visibility' '"default"'
+
+
+/// impl Foo pub
+impl Foo {
+ pub fn qux() {}
+}
+// @is '$.index[*][?(@.docs=="impl Foo pub")].visibility' '"default"'
+
+
+/// impl Foo hidden
+impl Foo {
+ #[doc(hidden)]
+ pub fn __quazl(){}
+}
+// FIXME(#111564): Is this the right behaviour?
+// @is '$.index[*][?(@.docs=="impl Foo hidden")].visibility' '"default"'
diff --git a/tests/rustdoc-json/type/inherent_associated_type.rs b/tests/rustdoc-json/type/inherent_associated_type.rs
new file mode 100644
index 00000000000..ed63def93df
--- /dev/null
+++ b/tests/rustdoc-json/type/inherent_associated_type.rs
@@ -0,0 +1,29 @@
+// ignore-tidy-linelength
+#![feature(inherent_associated_types)]
+#![feature(no_core)]
+#![allow(incomplete_features)]
+#![no_core]
+
+// @set OwnerMetadata = '$.index[*][?(@.name=="OwnerMetadata")].id'
+pub struct OwnerMetadata;
+// @set Owner = '$.index[*][?(@.name=="Owner")].id'
+pub struct Owner;
+
+pub fn create() -> Owner::Metadata {
+ OwnerMetadata
+}
+// @is '$.index[*][?(@.name=="create")].inner.decl.output.kind' '"qualified_path"'
+// @is '$.index[*][?(@.name=="create")].inner.decl.output.inner.name' '"Metadata"'
+// @is '$.index[*][?(@.name=="create")].inner.decl.output.inner.trait' null
+// @is '$.index[*][?(@.name=="create")].inner.decl.output.inner.self_type.kind' '"resolved_path"'
+// @is '$.index[*][?(@.name=="create")].inner.decl.output.inner.self_type.inner.id' $Owner
+
+/// impl
+impl Owner {
+ /// iat
+ pub type Metadata = OwnerMetadata;
+}
+// @set iat = '$.index[*][?(@.docs=="iat")].id'
+// @is '$.index[*][?(@.docs=="impl")].inner.items[*]' $iat
+// @is '$.index[*][?(@.docs=="iat")].kind' '"assoc_type"'
+// @is '$.index[*][?(@.docs=="iat")].inner.default.inner.id' $OwnerMetadata
diff --git a/tests/rustdoc-json/type/inherent_associated_type_bound.rs b/tests/rustdoc-json/type/inherent_associated_type_bound.rs
new file mode 100644
index 00000000000..a089600b692
--- /dev/null
+++ b/tests/rustdoc-json/type/inherent_associated_type_bound.rs
@@ -0,0 +1,21 @@
+// ignore-tidy-linelength
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// @set Carrier = '$.index[*][?(@.name=="Carrier")].id'
+pub struct Carrier<'a>(&'a ());
+
+// @is '$.index[*][?(@.name=="User")].inner.type.kind' '"function_pointer"'
+// @is '$.index[*][?(@.name=="User")].inner.type.inner.generic_params[*].name' \""'b"\"
+// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].kind' '"qualified_path"'
+// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.self_type.inner.id' $Carrier
+// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.self_type.inner.args.angle_bracketed.args[0].lifetime' \""'b"\"
+// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.name' '"Focus"'
+// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.trait' null
+// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.args.angle_bracketed.args[0].type.inner' '"i32"'
+
+pub type User = for<'b> fn(Carrier<'b>::Focus<i32>);
+
+impl<'a> Carrier<'a> {
+ pub type Focus<T> = &'a mut T;
+}
diff --git a/tests/rustdoc-json/type/inherent_associated_type_projections.rs b/tests/rustdoc-json/type/inherent_associated_type_projections.rs
new file mode 100644
index 00000000000..30c68bfe56c
--- /dev/null
+++ b/tests/rustdoc-json/type/inherent_associated_type_projections.rs
@@ -0,0 +1,33 @@
+// ignore-tidy-linelength
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// @set Parametrized = '$.index[*][?(@.name=="Parametrized")].id'
+pub struct Parametrized<T>(T);
+
+// @is '$.index[*][?(@.name=="Test")].inner.type.kind' '"qualified_path"'
+// @is '$.index[*][?(@.name=="Test")].inner.type.inner.self_type.inner.id' $Parametrized
+// @is '$.index[*][?(@.name=="Test")].inner.type.inner.self_type.inner.args.angle_bracketed.args[0].type' '{"inner": "i32", "kind": "primitive"}'
+// @is '$.index[*][?(@.name=="Test")].inner.type.inner.name' '"Proj"'
+// @is '$.index[*][?(@.name=="Test")].inner.type.inner.trait' null
+pub type Test = Parametrized<i32>::Proj;
+
+/// param_bool
+impl Parametrized<bool> {
+ /// param_bool_proj
+ pub type Proj = ();
+}
+
+/// param_i32
+impl Parametrized<i32> {
+ /// param_i32_proj
+ pub type Proj = String;
+}
+
+// @set param_bool = '$.index[*][?(@.docs=="param_bool")].id'
+// @set param_i32 = '$.index[*][?(@.docs=="param_i32")].id'
+// @set param_bool_proj = '$.index[*][?(@.docs=="param_bool_proj")].id'
+// @set param_i32_proj = '$.index[*][?(@.docs=="param_i32_proj")].id'
+
+// @is '$.index[*][?(@.docs=="param_bool")].inner.items[*]' $param_bool_proj
+// @is '$.index[*][?(@.docs=="param_i32")].inner.items[*]' $param_i32_proj
diff --git a/tests/rustdoc-ui/ice-bug-report-url.rs b/tests/rustdoc-ui/ice-bug-report-url.rs
index cc066447d31..8ede91cf8f4 100644
--- a/tests/rustdoc-ui/ice-bug-report-url.rs
+++ b/tests/rustdoc-ui/ice-bug-report-url.rs
@@ -6,8 +6,8 @@
// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
// normalize-stderr-test "note: rustc.*running on.*" -> "note: rustc {version} running on {platform}"
// normalize-stderr-test "thread.*panicked at .*, compiler.*" -> "thread panicked at 'aborting due to `-Z treat-err-as-bug`'"
-// normalize-stderr-test "\s*\d{1,}: .*\n" -> ""
-// normalize-stderr-test "\s at .*\n" -> ""
+// normalize-stderr-test " +\d{1,}: .*\n" -> ""
+// normalize-stderr-test " + at .*\n" -> ""
// normalize-stderr-test ".*note: Some details are omitted.*\n" -> ""
fn wrong()
diff --git a/tests/rustdoc-ui/ice-bug-report-url.stderr b/tests/rustdoc-ui/ice-bug-report-url.stderr
index cfb73a9b919..98c08b9a894 100644
--- a/tests/rustdoc-ui/ice-bug-report-url.stderr
+++ b/tests/rustdoc-ui/ice-bug-report-url.stderr
@@ -6,6 +6,7 @@ LL | fn wrong()
thread panicked at 'aborting due to `-Z treat-err-as-bug`'
stack backtrace:
+
error: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md
diff --git a/tests/rustdoc/impl-alias-substituted.rs b/tests/rustdoc/impl-alias-substituted.rs
new file mode 100644
index 00000000000..82dfffe5f1c
--- /dev/null
+++ b/tests/rustdoc/impl-alias-substituted.rs
@@ -0,0 +1,9 @@
+pub struct Matrix<T, const N: usize, const M: usize>([[T; N]; M]);
+
+pub type Vector<T, const N: usize> = Matrix<T, N, 1>;
+
+// @has "impl_alias_substituted/struct.Matrix.html" '//*[@class="impl"]//h3[@class="code-header"]' \
+// "impl<T: Copy> Matrix<T, 3, 1>"
+impl<T: Copy> Vector<T, 3> {
+ pub fn test() {}
+}
diff --git a/tests/rustdoc/inherent-projections.rs b/tests/rustdoc/inherent-projections.rs
new file mode 100644
index 00000000000..9bda0acaf83
--- /dev/null
+++ b/tests/rustdoc/inherent-projections.rs
@@ -0,0 +1,44 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// @has 'inherent_projections/fn.create.html'
+// @has - '//pre[@class="rust item-decl"]' "create() -> Owner::Metadata"
+// @has - '//pre[@class="rust item-decl"]//a[@class="associatedtype"]/@href' 'struct.Owner.html#associatedtype.Metadata'
+pub fn create() -> Owner::Metadata {}
+
+pub struct Owner;
+
+impl Owner {
+ pub type Metadata = ();
+}
+
+// Make sure we handle bound vars correctly.
+// @has 'inherent_projections/type.User.html' '//pre[@class="rust item-decl"]' "for<'a> fn(_: Carrier<'a>::Focus)"
+pub type User = for<'a> fn(Carrier<'a>::Focus);
+
+pub struct Carrier<'a>(&'a ());
+
+impl<'a> Carrier<'a> {
+ pub type Focus = &'a mut i32;
+}
+
+////////////////////////////////////////
+
+// FIXME(inherent_associated_types): Below we link to `Proj` but we should link to `Proj-1`.
+// The current test checks for the buggy behavior for demonstration purposes.
+
+// @has 'inherent_projections/type.Test.html'
+// @has - '//pre[@class="rust item-decl"]' "Parametrized<i32>"
+// @has - '//pre[@class="rust item-decl"]//a[@class="associatedtype"]/@href' 'struct.Parametrized.html#associatedtype.Proj'
+// @!has - '//pre[@class="rust item-decl"]//a[@class="associatedtype"]/@href' 'struct.Parametrized.html#associatedtype.Proj-1'
+pub type Test = Parametrized<i32>::Proj;
+
+pub struct Parametrized<T>(T);
+
+impl Parametrized<bool> {
+ pub type Proj = ();
+}
+
+impl Parametrized<i32> {
+ pub type Proj = String;
+}
diff --git a/tests/rustdoc/intra-doc/inherent-associated-types.rs b/tests/rustdoc/intra-doc/inherent-associated-types.rs
new file mode 100644
index 00000000000..2b28d2ae60b
--- /dev/null
+++ b/tests/rustdoc/intra-doc/inherent-associated-types.rs
@@ -0,0 +1,45 @@
+#![feature(inherent_associated_types)]
+
+#![allow(incomplete_features)]
+#![deny(rustdoc::broken_intra_doc_links)]
+
+// @has inherent_associated_types/index.html
+
+// @has - '//a/@href' 'enum.Simple.html#associatedtype.Type'
+//! [`Simple::Type`]
+
+pub enum Simple {}
+
+impl Simple {
+ pub type Type = ();
+}
+
+////////////////////////////////////////
+
+// @has 'inherent_associated_types/type.Test0.html' '//a/@href' \
+// 'struct.Parametrized.html#associatedtype.Proj'
+/// [`Parametrized<bool>::Proj`]
+pub type Test0 = ();
+
+// FIXME(inherent_associated_types): The intra-doc link below should point to `Proj-1` not `Proj`.
+// The current test checks for the buggy behavior for demonstration purposes.
+// The same bug happens for inherent associated functions and constants (see #85960, #93398).
+//
+// Further, at some point we should reject the intra-doc link `Parametrized::Proj`.
+// It currently links to `Parametrized<bool>::Proj`.
+
+// @has 'inherent_associated_types/type.Test1.html'
+// @has - '//a/@href' 'struct.Parametrized.html#associatedtype.Proj'
+// @!has - '//a/@href' 'struct.Parametrized.html#associatedtype.Proj-1'
+/// [`Parametrized<i32>::Proj`]
+pub type Test1 = ();
+
+pub struct Parametrized<T>(T);
+
+impl Parametrized<bool> {
+ pub type Proj = ();
+}
+
+impl Parametrized<i32> {
+ pub type Proj = String;
+}
diff --git a/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs b/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs
new file mode 100644
index 00000000000..8e1029a1ca3
--- /dev/null
+++ b/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs
@@ -0,0 +1,31 @@
+#![feature(no_core)]
+#![no_core]
+#![crate_name = "foo"]
+
+// @!has 'foo/hidden/index.html'
+// FIXME: add missing `@` for the two next tests once issue is fixed!
+// To be done in <https://github.com/rust-lang/rust/issues/111249>.
+// !has 'foo/hidden/inner/index.html'
+// !has 'foo/hidden/inner/trait.Foo.html'
+#[doc(hidden)]
+pub mod hidden {
+ pub mod inner {
+ pub trait Foo {
+ /// Hello, world!
+ fn test();
+ }
+ }
+}
+
+// @has 'foo/visible/index.html'
+// @has 'foo/visible/trait.Foo.html'
+#[doc(inline)]
+pub use hidden::inner as visible;
+
+// @has 'foo/struct.Bar.html'
+// @count - '//*[@id="impl-Foo-for-Bar"]' 1
+pub struct Bar;
+
+impl visible::Foo for Bar {
+ fn test() {}
+}
diff --git a/tests/rustdoc/issue-111064-reexport-trait-from-hidden.rs b/tests/rustdoc/issue-111064-reexport-trait-from-hidden.rs
new file mode 100644
index 00000000000..a9ce4a34507
--- /dev/null
+++ b/tests/rustdoc/issue-111064-reexport-trait-from-hidden.rs
@@ -0,0 +1,21 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/111064>.
+// Methods from a re-exported trait inside a `#[doc(hidden)]` item should
+// be visible.
+
+#![crate_name = "foo"]
+
+// @has 'foo/index.html'
+// @has - '//*[@id="main-content"]//*[@class="item-name"]/a[@href="trait.Foo.html"]' 'Foo'
+
+// @has 'foo/trait.Foo.html'
+// @has - '//*[@id="main-content"]//*[@class="code-header"]' 'fn test()'
+
+#[doc(hidden)]
+mod hidden {
+ pub trait Foo {
+ /// Hello, world!
+ fn test();
+ }
+}
+
+pub use hidden::Foo;
diff --git a/tests/rustdoc/nested-items-issue-111415.rs b/tests/rustdoc/nested-items-issue-111415.rs
new file mode 100644
index 00000000000..9b7688c332c
--- /dev/null
+++ b/tests/rustdoc/nested-items-issue-111415.rs
@@ -0,0 +1,36 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/111415>.
+// This test ensures that only impl blocks are documented in bodies.
+
+#![crate_name = "foo"]
+
+// @has 'foo/index.html'
+// Checking there are only three sections.
+// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3
+// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs'
+// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions'
+// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits'
+// Checking that there are only three items.
+// @count - '//*[@id="main-content"]//*[@class="item-name"]' 3
+// @has - '//*[@id="main-content"]//a[@href="struct.Bar.html"]' 'Bar'
+// @has - '//*[@id="main-content"]//a[@href="fn.foo.html"]' 'foo'
+// @has - '//*[@id="main-content"]//a[@href="trait.Foo.html"]' 'Foo'
+
+// Now checking that the `foo` method is visible in `Bar` page.
+// @has 'foo/struct.Bar.html'
+// @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'pub fn foo()'
+// @has - '//*[@id="method.bar"]/*[@class="code-header"]' 'fn bar()'
+pub struct Bar;
+
+pub trait Foo {
+ fn bar() {}
+}
+
+pub fn foo() {
+ pub mod inaccessible {}
+ pub fn inner() {}
+ pub const BAR: u32 = 0;
+ impl Bar {
+ pub fn foo() {}
+ }
+ impl Foo for Bar {}
+}
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs
new file mode 100644
index 00000000000..642b58b0753
--- /dev/null
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs
@@ -0,0 +1,49 @@
+// check-fail
+// Tests that a doc comment will not preclude a field from being considered a diagnostic argument
+// 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 Subdiagnostic is strictly internal to the compiler
+// the test is just ignored on stable and beta:
+// ignore-stage1
+// ignore-beta
+// ignore-stable
+
+#![feature(rustc_private)]
+#![crate_type = "lib"]
+
+extern crate rustc_errors;
+extern crate rustc_fluent_macro;
+extern crate rustc_macros;
+extern crate rustc_session;
+extern crate rustc_span;
+
+use rustc_errors::{Applicability, DiagnosticMessage, SubdiagnosticMessage};
+use rustc_fluent_macro::fluent_messages;
+use rustc_macros::{Diagnostic, Subdiagnostic};
+use rustc_span::Span;
+
+fluent_messages! { "./example.ftl" }
+
+struct NotIntoDiagnosticArg;
+
+#[derive(Diagnostic)]
+#[diag(no_crate_example)]
+struct Test {
+ #[primary_span]
+ span: Span,
+ /// A doc comment
+ arg: NotIntoDiagnosticArg,
+ //~^ ERROR the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
+}
+
+#[derive(Subdiagnostic)]
+#[label(no_crate_example)]
+struct SubTest {
+ #[primary_span]
+ span: Span,
+ /// A doc comment
+ arg: NotIntoDiagnosticArg,
+ //~^ ERROR the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
+}
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr
new file mode 100644
index 00000000000..e4b8958b4fa
--- /dev/null
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr
@@ -0,0 +1,30 @@
+error[E0277]: the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
+ --> $DIR/diagnostic-derive-doc-comment-field.rs:37:10
+ |
+LL | #[derive(Diagnostic)]
+ | ---------- required by a bound introduced by this call
+...
+LL | arg: NotIntoDiagnosticArg,
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `NotIntoDiagnosticArg`
+ |
+ = help: normalized in stderr
+note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg`
+ --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC
+ = note: this error originates in the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
+ --> $DIR/diagnostic-derive-doc-comment-field.rs:47:10
+ |
+LL | #[derive(Subdiagnostic)]
+ | ------------- required by a bound introduced by this call
+...
+LL | arg: NotIntoDiagnosticArg,
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `NotIntoDiagnosticArg`
+ |
+ = help: normalized in stderr
+note: required by a bound in `Diagnostic::set_arg`
+ --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:964:5
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
index 80ab03ab24c..39e34d73f9a 100644
--- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -339,12 +339,12 @@ struct ErrorWithDefaultLabelAttr<'a> {
}
#[derive(Diagnostic)]
-//~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied
#[diag(no_crate_example, code = "E0123")]
struct ArgFieldWithoutSkip {
#[primary_span]
span: Span,
other: Hello,
+ //~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied
}
#[derive(Diagnostic)]
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
index 5e1bea4e38c..801e4b5793c 100644
--- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -641,15 +641,18 @@ LL | #[derive(Diagnostic)]
= note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied
- --> $DIR/diagnostic-derive.rs:341:10
+ --> $DIR/diagnostic-derive.rs:346:12
|
LL | #[derive(Diagnostic)]
- | ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello`
+ | ---------- required by a bound introduced by this call
+...
+LL | other: Hello,
+ | ^^^^^ 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:LL:CC
- = note: this error originates in the derive macro `Diagnostic` which comes from the expansion of the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 84 previous errors
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index 1454d6dde6c..a3db2e9ef24 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -40,6 +40,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) {
let bar = get_item(tcx, &items, (DefKind::Fn, "bar")).unwrap();
let body = bar.body();
+ assert_eq!(body.locals.len(), 2);
assert_eq!(body.blocks.len(), 1);
let block = &body.blocks[0];
assert_eq!(block.statements.len(), 1);
@@ -54,6 +55,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) {
let foo_bar = get_item(tcx, &items, (DefKind::Fn, "foo_bar")).unwrap();
let body = foo_bar.body();
+ assert_eq!(body.locals.len(), 7);
assert_eq!(body.blocks.len(), 4);
let block = &body.blocks[0];
match &block.terminator {
@@ -123,7 +125,7 @@ impl Callbacks for SMirCalls {
queries: &'tcx Queries<'tcx>,
) -> Compilation {
queries.global_ctxt().unwrap().enter(|tcx| {
- test_stable_mir(tcx);
+ rustc_smir::rustc_internal::run(tcx, || test_stable_mir(tcx));
});
// No need to keep going.
Compilation::Stop
diff --git a/tests/ui/argument-suggestions/issue-97484.stderr b/tests/ui/argument-suggestions/issue-97484.stderr
index a86cbbf1802..082564fbc7f 100644
--- a/tests/ui/argument-suggestions/issue-97484.stderr
+++ b/tests/ui/argument-suggestions/issue-97484.stderr
@@ -16,7 +16,7 @@ LL | fn foo(a: &A, d: D, e: &E, g: G) {}
help: consider borrowing here
|
LL | foo(&&A, B, C, D, &E, F, G);
- | ~~
+ | +
help: remove the extra arguments
|
LL - foo(&&A, B, C, D, E, F, G);
diff --git a/tests/ui/array-slice-vec/slice-mut-2.stderr b/tests/ui/array-slice-vec/slice-mut-2.stderr
index 5b040d3e4d3..c33919c41cd 100644
--- a/tests/ui/array-slice-vec/slice-mut-2.stderr
+++ b/tests/ui/array-slice-vec/slice-mut-2.stderr
@@ -7,7 +7,7 @@ LL | let _ = &mut x[2..4];
help: consider changing this to be a mutable reference
|
LL | let x: &[isize] = &mut [1, 2, 3, 4, 5];
- | ~~~~~~~~~~~~~~~~~~~~
+ | +++
error: aborting due to previous error
diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs
new file mode 100644
index 00000000000..f41574403d8
--- /dev/null
+++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs
@@ -0,0 +1,10 @@
+// known-bug: #108491
+
+// FIXME(inherent_associated_types): This should pass.
+
+struct Foo {
+ bar: Self::Bar,
+}
+impl Foo {
+ pub type Bar = usize;
+}
diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr
new file mode 100644
index 00000000000..f313c494671
--- /dev/null
+++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr
@@ -0,0 +1,49 @@
+error[E0601]: `main` function not found in crate `cycle_iat_inside_of_adt`
+ --> $DIR/cycle-iat-inside-of-adt.rs:10:2
+ |
+LL | }
+ | ^ consider adding a `main` function to `$DIR/cycle-iat-inside-of-adt.rs`
+
+error[E0391]: cycle detected when computing predicates of `Foo`
+ --> $DIR/cycle-iat-inside-of-adt.rs:5:1
+ |
+LL | struct Foo {
+ | ^^^^^^^^^^
+ |
+note: ...which requires computing predicates of `Foo`...
+ --> $DIR/cycle-iat-inside-of-adt.rs:5:1
+ |
+LL | struct Foo {
+ | ^^^^^^^^^^
+note: ...which requires computing inferred outlives predicates of `Foo`...
+ --> $DIR/cycle-iat-inside-of-adt.rs:5:1
+ |
+LL | struct Foo {
+ | ^^^^^^^^^^
+ = note: ...which requires computing the inferred outlives predicates for items in this crate...
+note: ...which requires computing type of `Foo::bar`...
+ --> $DIR/cycle-iat-inside-of-adt.rs:6:5
+ |
+LL | bar: Self::Bar,
+ | ^^^^^^^^^^^^^^
+note: ...which requires computing normalized predicates of `Foo`...
+ --> $DIR/cycle-iat-inside-of-adt.rs:5:1
+ |
+LL | struct Foo {
+ | ^^^^^^^^^^
+ = note: ...which again requires computing predicates of `Foo`, completing the cycle
+note: cycle used when collecting item types in top-level module
+ --> $DIR/cycle-iat-inside-of-adt.rs:5:1
+ |
+LL | / struct Foo {
+LL | | bar: Self::Bar,
+LL | | }
+LL | | impl Foo {
+LL | | pub type Bar = usize;
+LL | | }
+ | |_^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0391, E0601.
+For more information about an error, try `rustc --explain E0391`.
diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.rs b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.rs
new file mode 100644
index 00000000000..0c2a38b1173
--- /dev/null
+++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.rs
@@ -0,0 +1,16 @@
+// known-bug: unknown
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// FIXME(inherent_associated_types): This shouldn't lead to a cycle error.
+
+fn user<T>() where S<T>::P: std::fmt::Debug {}
+
+struct S<T>;
+
+impl<T: Copy> S<T> {
+ type P = ();
+}
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr
new file mode 100644
index 00000000000..aaa9a39ea0f
--- /dev/null
+++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr
@@ -0,0 +1,37 @@
+error[E0391]: cycle detected when computing predicates of `user`
+ --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1
+ |
+LL | fn user<T>() where S<T>::P: std::fmt::Debug {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: ...which requires computing predicates of `user`...
+ --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1
+ |
+LL | fn user<T>() where S<T>::P: std::fmt::Debug {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires computing explicit predicates of `user`...
+ --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1
+ |
+LL | fn user<T>() where S<T>::P: std::fmt::Debug {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires computing normalized predicates of `user`...
+ --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1
+ |
+LL | fn user<T>() where S<T>::P: std::fmt::Debug {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: ...which again requires computing predicates of `user`, completing the cycle
+note: cycle used when collecting item types in top-level module
+ --> $DIR/cycle-iat-inside-of-where-predicate.rs:3:1
+ |
+LL | / #![feature(inherent_associated_types)]
+LL | | #![allow(incomplete_features)]
+LL | |
+LL | | // FIXME(inherent_associated_types): This shouldn't lead to a cycle error.
+... |
+LL | |
+LL | | fn main() {}
+ | |____________^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/associated-inherent-types/bugs/ice-substitution.rs b/tests/ui/associated-inherent-types/bugs/ice-substitution.rs
deleted file mode 100644
index 53ac79e0561..00000000000
--- a/tests/ui/associated-inherent-types/bugs/ice-substitution.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-// known-bug: unknown
-// failure-status: 101
-// normalize-stderr-test "note: .*\n\n" -> ""
-// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
-// rustc-env:RUST_BACKTRACE=0
-
-// FIXME: I presume a type variable that couldn't be solved by `resolve_vars_if_possible`
-// escapes the InferCtxt snapshot.
-
-#![feature(inherent_associated_types)]
-#![allow(incomplete_features)]
-
-struct Cont<T>(T);
-
-impl<T: Copy> Cont<T> {
- type Out = Vec<T>;
-}
-
-pub fn weird<T: Copy>(x: T) {
- let _: Cont<_>::Out = vec![true];
-}
-
-fn main() {}
diff --git a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr b/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr
deleted file mode 100644
index 1648cfb266b..00000000000
--- a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr
+++ /dev/null
@@ -1,6 +0,0 @@
-error: the compiler unexpectedly panicked. this is a bug.
-
-query stack during panic:
-#0 [typeck] type-checking `weird`
-#1 [used_trait_imports] finding used_trait_imports `weird`
-end of query stack
diff --git a/tests/ui/associated-inherent-types/bugs/inference-fail.rs b/tests/ui/associated-inherent-types/bugs/inference-fail.rs
deleted file mode 100644
index a920b412b1a..00000000000
--- a/tests/ui/associated-inherent-types/bugs/inference-fail.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// known-bug: unknown
-
-#![feature(inherent_associated_types)]
-#![allow(incomplete_features)]
-
-struct S<T>(T);
-
-impl S<()> {
- type P = i128;
-}
-
-fn main() {
- // We fail to infer `_ == ()` here.
- let _: S<_>::P;
-}
diff --git a/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs b/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs
deleted file mode 100644
index 632dbf3854b..00000000000
--- a/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// known-bug: unknown
-// check-pass
-
-// We currently don't region-check inherent associated type projections at all.
-
-#![feature(inherent_associated_types)]
-#![allow(incomplete_features, dead_code)]
-
-struct S<T>(T);
-
-impl S<&'static ()> {
- type T = ();
-}
-
-fn usr<'a>() {
- let _: S::<&'a ()>::T; // this should *fail* but it doesn't!
-}
-
-fn main() {}
diff --git a/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs b/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs
new file mode 100644
index 00000000000..c7f66e645bb
--- /dev/null
+++ b/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs
@@ -0,0 +1,15 @@
+// known-bug: #100041
+// check-pass
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// FIXME(inherent_associated_types): This should fail.
+
+struct Foo;
+
+impl Foo {
+ type Bar<T> = ();
+}
+
+fn main() -> Foo::Bar::<Vec<[u32]>> {}
diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs
index f846bfa4168..83be4f43b5e 100644
--- a/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs
+++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs
@@ -31,7 +31,7 @@ fn main() {
let _: Select<u8>::Projection = ();
let _: Choose<NonCopy>::Result = ();
- let _: Choose<bool>::Result = vec![true];
+ let _: Choose<&str>::Result = vec!["…"]; // regression test for issue #108957
}
// Test if we use the correct `ParamEnv` when proving obligations.
diff --git a/tests/ui/associated-inherent-types/former-subst-ice.rs b/tests/ui/associated-inherent-types/former-subst-ice.rs
new file mode 100644
index 00000000000..48390b9430b
--- /dev/null
+++ b/tests/ui/associated-inherent-types/former-subst-ice.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Cont<T>(T);
+
+impl<T: Copy> Cont<T> {
+ type Out = Vec<T>;
+}
+
+pub fn weird<T: Copy>(x: T) {
+ let _: Cont<_>::Out = vec![true];
+}
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/generic-associated-types-bad.item.stderr b/tests/ui/associated-inherent-types/generic-associated-types-bad.item.stderr
new file mode 100644
index 00000000000..464b59c249f
--- /dev/null
+++ b/tests/ui/associated-inherent-types/generic-associated-types-bad.item.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `String: Copy` is not satisfied
+ --> $DIR/generic-associated-types-bad.rs:16:10
+ |
+LL | const _: Ty::Pr<String> = String::new();
+ | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+ |
+note: required by a bound in `Ty::Pr`
+ --> $DIR/generic-associated-types-bad.rs:10:16
+ |
+LL | type Pr<T: Copy> = T;
+ | ^^^^ required by this bound in `Ty::Pr`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-inherent-types/generic-associated-types-bad.local.stderr b/tests/ui/associated-inherent-types/generic-associated-types-bad.local.stderr
new file mode 100644
index 00000000000..4f371b24e80
--- /dev/null
+++ b/tests/ui/associated-inherent-types/generic-associated-types-bad.local.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `Vec<()>: Copy` is not satisfied
+ --> $DIR/generic-associated-types-bad.rs:20:12
+ |
+LL | let _: Ty::Pr<Vec<()>>;
+ | ^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Vec<()>`
+ |
+note: required by a bound in `Ty::Pr`
+ --> $DIR/generic-associated-types-bad.rs:10:16
+ |
+LL | type Pr<T: Copy> = T;
+ | ^^^^ required by this bound in `Ty::Pr`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-inherent-types/generic-associated-types-bad.region.stderr b/tests/ui/associated-inherent-types/generic-associated-types-bad.region.stderr
new file mode 100644
index 00000000000..74ec39424ed
--- /dev/null
+++ b/tests/ui/associated-inherent-types/generic-associated-types-bad.region.stderr
@@ -0,0 +1,11 @@
+error: lifetime may not live long enough
+ --> $DIR/generic-associated-types-bad.rs:25:12
+ |
+LL | fn user<'a>() {
+ | -- lifetime `'a` defined here
+LL | #[cfg(region)]
+LL | let _: Ty::Static<&'a str> = "";
+ | ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/associated-inherent-types/generic-associated-types-bad.rs b/tests/ui/associated-inherent-types/generic-associated-types-bad.rs
new file mode 100644
index 00000000000..e66392a0a94
--- /dev/null
+++ b/tests/ui/associated-inherent-types/generic-associated-types-bad.rs
@@ -0,0 +1,26 @@
+// revisions: item local region
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+#[derive(Clone, Copy)]
+pub enum Ty {}
+
+impl Ty {
+ type Pr<T: Copy> = T;
+
+ type Static<Q: 'static> = Q;
+}
+
+#[cfg(item)]
+const _: Ty::Pr<String> = String::new(); //[item]~ the trait bound `String: Copy` is not satisfied
+
+fn main() {
+ #[cfg(local)]
+ let _: Ty::Pr<Vec<()>>; //[local]~ ERROR the trait bound `Vec<()>: Copy` is not satisfied
+}
+
+fn user<'a>() {
+ #[cfg(region)]
+ let _: Ty::Static<&'a str> = ""; //[region]~ ERROR lifetime may not live long enough
+}
diff --git a/tests/ui/associated-inherent-types/inference-fail.rs b/tests/ui/associated-inherent-types/inference-fail.rs
new file mode 100644
index 00000000000..939a4ff60f2
--- /dev/null
+++ b/tests/ui/associated-inherent-types/inference-fail.rs
@@ -0,0 +1,11 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct S<T>(T);
+
+impl<T> S<T> { type P = (); }
+
+fn main() {
+ // There is no way to infer this type.
+ let _: S<_>::P = (); //~ ERROR type annotations needed
+}
diff --git a/tests/ui/associated-inherent-types/bugs/inference-fail.stderr b/tests/ui/associated-inherent-types/inference-fail.stderr
index 425691bd6c4..f29144e4aa7 100644
--- a/tests/ui/associated-inherent-types/bugs/inference-fail.stderr
+++ b/tests/ui/associated-inherent-types/inference-fail.stderr
@@ -1,8 +1,8 @@
error[E0282]: type annotations needed
- --> $DIR/inference-fail.rs:14:14
+ --> $DIR/inference-fail.rs:10:12
|
-LL | let _: S<_>::P;
- | ^ cannot infer type
+LL | let _: S<_>::P = ();
+ | ^^^^^^^ cannot infer type for type parameter `T`
error: aborting due to previous error
diff --git a/tests/ui/associated-inherent-types/inference.rs b/tests/ui/associated-inherent-types/inference.rs
new file mode 100644
index 00000000000..7d6d26003f6
--- /dev/null
+++ b/tests/ui/associated-inherent-types/inference.rs
@@ -0,0 +1,40 @@
+// Testing inference capabilities.
+// check-pass
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+#![allow(drop_copy)]
+
+use std::convert::identity;
+
+struct Container<T>(T);
+
+impl Container<u32> {
+ type Sink = ();
+}
+
+impl<Any> Container<Any> {
+ type Thing = Any;
+}
+
+impl<T> Container<(T, ())> {
+ type Output = ((), Wrapped<T>);
+}
+
+fn main() {
+ // Inferred via the Self type of the impl.
+ let _: Container<_>::Sink;
+
+ // Inferred via the RHS:
+
+ let _: Container<_>::Thing = 0;
+
+ let _: Container<Wrapped<_>>::Thing = Wrapped(false);
+
+ let _: Container<_>::Output = (drop(1), Wrapped("..."));
+
+ let binding: Container<_>::Thing = Default::default(); // unsolved at this point
+ identity::<String>(binding); // constrained and solved here
+}
+
+struct Wrapped<T>(T);
diff --git a/tests/ui/associated-inherent-types/issue-109768.rs b/tests/ui/associated-inherent-types/issue-109768.rs
new file mode 100644
index 00000000000..a3ae2e2ab44
--- /dev/null
+++ b/tests/ui/associated-inherent-types/issue-109768.rs
@@ -0,0 +1,12 @@
+// incremental
+
+struct Wrapper<T>(T);
+
+struct Local<T, U>(T, U);
+
+impl<T> Local { //~ ERROR missing generics for struct `Local`
+ type AssocType3 = T; //~ ERROR inherent associated types are unstable
+
+ const WRAPPED_ASSOC_3: Wrapper<Self::AssocType3> = Wrapper();
+}
+//~^ ERROR `main` function not found
diff --git a/tests/ui/associated-inherent-types/issue-109768.stderr b/tests/ui/associated-inherent-types/issue-109768.stderr
new file mode 100644
index 00000000000..97706d4062a
--- /dev/null
+++ b/tests/ui/associated-inherent-types/issue-109768.stderr
@@ -0,0 +1,35 @@
+error[E0601]: `main` function not found in crate `issue_109768`
+ --> $DIR/issue-109768.rs:11:2
+ |
+LL | }
+ | ^ consider adding a `main` function to `$DIR/issue-109768.rs`
+
+error[E0107]: missing generics for struct `Local`
+ --> $DIR/issue-109768.rs:7:9
+ |
+LL | impl<T> Local {
+ | ^^^^^ expected 2 generic arguments
+ |
+note: struct defined here, with 2 generic parameters: `T`, `U`
+ --> $DIR/issue-109768.rs:5:8
+ |
+LL | struct Local<T, U>(T, U);
+ | ^^^^^ - -
+help: add missing generic arguments
+ |
+LL | impl<T> Local<T, U> {
+ | ++++++
+
+error[E0658]: inherent associated types are unstable
+ --> $DIR/issue-109768.rs:8:5
+ |
+LL | type AssocType3 = T;
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
+ = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0107, E0601, E0658.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/associated-inherent-types/issue-109789.rs b/tests/ui/associated-inherent-types/issue-109789.rs
new file mode 100644
index 00000000000..0b5ba7d1fb5
--- /dev/null
+++ b/tests/ui/associated-inherent-types/issue-109789.rs
@@ -0,0 +1,22 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Foo<T>(T);
+
+impl Foo<fn(&'static ())> {
+ type Assoc = u32;
+}
+
+trait Other {}
+impl Other for u32 {}
+
+// FIXME(inherent_associated_types): Avoid emitting two diagnostics (they only differ in span).
+// FIXME(inherent_associated_types): Enhancement: Spruce up the diagnostic by saying something like
+// "implementation is not general enough" as is done for traits via
+// `try_report_trait_placeholder_mismatch`.
+
+fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
+//~^ ERROR mismatched types
+//~| ERROR mismatched types
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/issue-109789.stderr b/tests/ui/associated-inherent-types/issue-109789.stderr
new file mode 100644
index 00000000000..7af338274a1
--- /dev/null
+++ b/tests/ui/associated-inherent-types/issue-109789.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-109789.rs:18:1
+ |
+LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+ |
+ = note: expected struct `Foo<fn(&'static ())>`
+ found struct `Foo<for<'a> fn(&'a ())>`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-109789.rs:18:11
+ |
+LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+ |
+ = note: expected struct `Foo<fn(&'static ())>`
+ found struct `Foo<for<'a> fn(&'a ())>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/associated-inherent-types/issue-109790.rs b/tests/ui/associated-inherent-types/issue-109790.rs
new file mode 100644
index 00000000000..88327f86423
--- /dev/null
+++ b/tests/ui/associated-inherent-types/issue-109790.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+#![deny(single_use_lifetimes)]
+
+struct Foo<T>(T);
+
+impl<'a> Foo<fn(&'a ())> {
+ type Assoc = &'a ();
+}
+
+trait Other {}
+impl Other for u32 {}
+
+fn bar(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/late-bound-regions.rs b/tests/ui/associated-inherent-types/late-bound-regions.rs
new file mode 100644
index 00000000000..488a2cda649
--- /dev/null
+++ b/tests/ui/associated-inherent-types/late-bound-regions.rs
@@ -0,0 +1,25 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// Test if we correctly normalize `S<'a>::P` with respect to late-bound regions.
+
+type Function = for<'a> fn(&'a i32) -> S<'a>::P;
+
+struct S<'a>(&'a ());
+
+trait Inter {
+ type P;
+}
+
+impl<'a> S<'a> {
+ type P = &'a i32;
+}
+
+fn ret_ref_local<'e>() -> &'e i32 {
+ let f: Function = |x| x;
+
+ let local = 0;
+ f(&local) //~ ERROR cannot return value referencing local variable `local`
+}
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/late-bound-regions.stderr b/tests/ui/associated-inherent-types/late-bound-regions.stderr
new file mode 100644
index 00000000000..4706fcca91d
--- /dev/null
+++ b/tests/ui/associated-inherent-types/late-bound-regions.stderr
@@ -0,0 +1,12 @@
+error[E0515]: cannot return value referencing local variable `local`
+ --> $DIR/late-bound-regions.rs:22:5
+ |
+LL | f(&local)
+ | ^^------^
+ | | |
+ | | `local` is borrowed here
+ | returns a value referencing data owned by the current function
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0515`.
diff --git a/tests/ui/associated-inherent-types/normalization-overflow.rs b/tests/ui/associated-inherent-types/normalization-overflow.rs
new file mode 100644
index 00000000000..4228238aa7b
--- /dev/null
+++ b/tests/ui/associated-inherent-types/normalization-overflow.rs
@@ -0,0 +1,12 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// FIXME(fmease): I'd prefer to report a cycle error here instead of an overflow one.
+
+struct T;
+
+impl T {
+ type This = Self::This; //~ ERROR overflow evaluating associated type `T::This`
+}
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/normalization-overflow.stderr b/tests/ui/associated-inherent-types/normalization-overflow.stderr
new file mode 100644
index 00000000000..16bb64281e3
--- /dev/null
+++ b/tests/ui/associated-inherent-types/normalization-overflow.stderr
@@ -0,0 +1,8 @@
+error: overflow evaluating associated type `T::This`
+ --> $DIR/normalization-overflow.rs:9:17
+ |
+LL | type This = Self::This;
+ | ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/associated-inherent-types/private-in-public.rs b/tests/ui/associated-inherent-types/private-in-public.rs
new file mode 100644
index 00000000000..a4b372537c7
--- /dev/null
+++ b/tests/ui/associated-inherent-types/private-in-public.rs
@@ -0,0 +1,26 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+#![crate_type = "lib"]
+
+#![deny(private_in_public)]
+
+pub type PubAlias0 = PubTy::PrivAssocTy;
+//~^ ERROR private associated type `PubTy::PrivAssocTy` in public interface (error E0446)
+//~| WARNING this was previously accepted
+pub type PubAlias1 = PrivTy::PubAssocTy;
+//~^ ERROR private type `PrivTy` in public interface (error E0446)
+//~| WARNING this was previously accepted
+pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
+//~^ ERROR private type `PrivTy` in public interface (error E0446)
+//~| WARNING this was previously accepted
+
+pub struct PubTy;
+impl PubTy {
+ type PrivAssocTy = ();
+ pub type PubAssocTy<T> = T;
+}
+
+struct PrivTy;
+impl PrivTy {
+ pub type PubAssocTy = ();
+}
diff --git a/tests/ui/associated-inherent-types/private-in-public.stderr b/tests/ui/associated-inherent-types/private-in-public.stderr
new file mode 100644
index 00000000000..f0a64e96179
--- /dev/null
+++ b/tests/ui/associated-inherent-types/private-in-public.stderr
@@ -0,0 +1,34 @@
+error: private associated type `PubTy::PrivAssocTy` in public interface (error E0446)
+ --> $DIR/private-in-public.rs:7:1
+ |
+LL | pub type PubAlias0 = PubTy::PrivAssocTy;
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = 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 #34537 <https://github.com/rust-lang/rust/issues/34537>
+note: the lint level is defined here
+ --> $DIR/private-in-public.rs:5:9
+ |
+LL | #![deny(private_in_public)]
+ | ^^^^^^^^^^^^^^^^^
+
+error: private type `PrivTy` in public interface (error E0446)
+ --> $DIR/private-in-public.rs:10:1
+ |
+LL | pub type PubAlias1 = PrivTy::PubAssocTy;
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = 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 #34537 <https://github.com/rust-lang/rust/issues/34537>
+
+error: private type `PrivTy` in public interface (error E0446)
+ --> $DIR/private-in-public.rs:13:1
+ |
+LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = 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 #34537 <https://github.com/rust-lang/rust/issues/34537>
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/associated-inherent-types/regionck-0.rs b/tests/ui/associated-inherent-types/regionck-0.rs
new file mode 100644
index 00000000000..7c94539ace1
--- /dev/null
+++ b/tests/ui/associated-inherent-types/regionck-0.rs
@@ -0,0 +1,14 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct S<T>(T);
+
+impl S<&'static ()> {
+ type T = ();
+}
+
+fn user<'a>() {
+ let _: S::<&'a ()>::T; //~ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/regionck-0.stderr b/tests/ui/associated-inherent-types/regionck-0.stderr
new file mode 100644
index 00000000000..3a438ee630e
--- /dev/null
+++ b/tests/ui/associated-inherent-types/regionck-0.stderr
@@ -0,0 +1,10 @@
+error: lifetime may not live long enough
+ --> $DIR/regionck-0.rs:11:12
+ |
+LL | fn user<'a>() {
+ | -- lifetime `'a` defined here
+LL | let _: S::<&'a ()>::T;
+ | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/associated-inherent-types/regionck-1.rs b/tests/ui/associated-inherent-types/regionck-1.rs
new file mode 100644
index 00000000000..ec663cd0f77
--- /dev/null
+++ b/tests/ui/associated-inherent-types/regionck-1.rs
@@ -0,0 +1,13 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct U;
+
+impl U {
+ // Don't imply any bounds here.
+
+ type NoTyOutliv<'a, T> = &'a T; //~ ERROR the parameter type `T` may not live long enough
+ type NoReOutliv<'a, 'b> = &'a &'b (); //~ ERROR reference has a longer lifetime than the data it references
+}
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/regionck-1.stderr b/tests/ui/associated-inherent-types/regionck-1.stderr
new file mode 100644
index 00000000000..b17d89ca306
--- /dev/null
+++ b/tests/ui/associated-inherent-types/regionck-1.stderr
@@ -0,0 +1,29 @@
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/regionck-1.rs:9:30
+ |
+LL | type NoTyOutliv<'a, T> = &'a T;
+ | ^^^^^- help: consider adding a where clause: `where T: 'a`
+ | |
+ | ...so that the reference type `&'a T` does not outlive the data it points at
+
+error[E0491]: in type `&'a &'b ()`, reference has a longer lifetime than the data it references
+ --> $DIR/regionck-1.rs:10:31
+ |
+LL | type NoReOutliv<'a, 'b> = &'a &'b ();
+ | ^^^^^^^^^^
+ |
+note: the pointer is valid for the lifetime `'a` as defined here
+ --> $DIR/regionck-1.rs:10:21
+ |
+LL | type NoReOutliv<'a, 'b> = &'a &'b ();
+ | ^^
+note: but the referenced data is only valid for the lifetime `'b` as defined here
+ --> $DIR/regionck-1.rs:10:25
+ |
+LL | type NoReOutliv<'a, 'b> = &'a &'b ();
+ | ^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0309, E0491.
+For more information about an error, try `rustc --explain E0309`.
diff --git a/tests/ui/associated-inherent-types/regionck-2.rs b/tests/ui/associated-inherent-types/regionck-2.rs
new file mode 100644
index 00000000000..7a0b8b08300
--- /dev/null
+++ b/tests/ui/associated-inherent-types/regionck-2.rs
@@ -0,0 +1,14 @@
+// Regression test for issue #109299.
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Lexer<'d>(&'d ());
+
+impl Lexer<'static> {
+ type Cursor = ();
+}
+
+fn test(_: Lexer::Cursor) {} //~ ERROR mismatched types
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/regionck-2.stderr b/tests/ui/associated-inherent-types/regionck-2.stderr
new file mode 100644
index 00000000000..b0a4ed35d56
--- /dev/null
+++ b/tests/ui/associated-inherent-types/regionck-2.stderr
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+ --> $DIR/regionck-2.rs:12:12
+ |
+LL | fn test(_: Lexer::Cursor) {}
+ | ^^^^^^^^^^^^^ lifetime mismatch
+ |
+ = note: expected struct `Lexer<'static>`
+ found struct `Lexer<'_>`
+note: the anonymous lifetime defined here...
+ --> $DIR/regionck-2.rs:12:12
+ |
+LL | fn test(_: Lexer::Cursor) {}
+ | ^^^^^
+ = note: ...does not necessarily outlive the static lifetime
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs
new file mode 100644
index 00000000000..b32b4288ac9
--- /dev/null
+++ b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs
@@ -0,0 +1,26 @@
+// check-pass
+// compile-flags: --crate-type=lib
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// Bounds on the self type play a major role in the resolution of inherent associated types (*).
+// As a result of that, if a type alias contains any then its bounds have to be respected and the
+// lint `type_alias_bounds` should not fire.
+//
+// FIXME(inherent_associated_types): In the current implementation that is. We might move the
+// selection phase of IATs from hir_typeck to trait_selection resulting in us not requiring the
+// ParamEnv that early allowing us to ignore bounds on type aliases again.
+// Triage this before stabilization.
+
+#![deny(type_alias_bounds)]
+
+pub type Alias<T: Bound> = (Source<T>::Assoc,);
+
+
+pub struct Source<T>(T);
+pub trait Bound {}
+
+impl<T: Bound> Source<T> {
+ pub type Assoc = ();
+}
diff --git a/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.rs b/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.rs
new file mode 100644
index 00000000000..d081c4d5b78
--- /dev/null
+++ b/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.rs
@@ -0,0 +1,12 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct S<T>(T);
+
+impl<T: Copy> S<T> {
+ type T = T;
+}
+
+fn main() {
+ let _: S<_>::T = String::new(); //~ ERROR the trait bound `String: Copy` is not satisfied
+}
diff --git a/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.stderr b/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.stderr
new file mode 100644
index 00000000000..ecf30f4cdec
--- /dev/null
+++ b/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `String: Copy` is not satisfied
+ --> $DIR/unsatisfied-bounds-inferred-type.rs:11:12
+ |
+LL | let _: S<_>::T = String::new();
+ | ^^^^^^^ the trait `Copy` is not implemented for `String`
+ |
+note: required by a bound in `S<T>::T`
+ --> $DIR/unsatisfied-bounds-inferred-type.rs:6:9
+ |
+LL | impl<T: Copy> S<T> {
+ | ^^^^ required by this bound in `S<T>::T`
+LL | type T = T;
+ | - required by a bound in this associated type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.rs b/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.rs
new file mode 100644
index 00000000000..97bd2c42160
--- /dev/null
+++ b/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.rs
@@ -0,0 +1,14 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct S<T>(T);
+
+impl<T> S<T> {
+ type X = ()
+ where
+ T: Copy;
+}
+
+fn main() {
+ let _: S::<String>::X; //~ ERROR the trait bound `String: Copy` is not satisfied
+}
diff --git a/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.stderr b/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.stderr
new file mode 100644
index 00000000000..d4968cd05dc
--- /dev/null
+++ b/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `String: Copy` is not satisfied
+ --> $DIR/unsatisfied-bounds-where-clause-on-assoc-ty.rs:13:12
+ |
+LL | let _: S::<String>::X;
+ | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+ |
+note: required by a bound in `S<T>::X`
+ --> $DIR/unsatisfied-bounds-where-clause-on-assoc-ty.rs:9:12
+ |
+LL | type X = ()
+ | - required by a bound in this associated type
+LL | where
+LL | T: Copy;
+ | ^^^^ required by this bound in `S<T>::X`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/associated-types-eq-3.stderr b/tests/ui/associated-types/associated-types-eq-3.stderr
index 15ce4fc91cb..c3377eed20a 100644
--- a/tests/ui/associated-types/associated-types-eq-3.stderr
+++ b/tests/ui/associated-types/associated-types-eq-3.stderr
@@ -43,7 +43,7 @@ note: expected this to be `Bar`
|
LL | type A = usize;
| ^^^^^
- = note: required for the cast from `isize` to the object type `dyn Foo<A = Bar>`
+ = note: required for the cast from `&isize` to `&dyn Foo<A = Bar>`
error: aborting due to 3 previous errors
diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr
index a28a0b74e4a..fdec01b95e3 100644
--- a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr
+++ b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr
@@ -4,7 +4,7 @@ error[E0271]: expected `IntoIter<u32>` to be an iterator that yields `i32`, but
LL | let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
| ^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32`
|
- = note: required for the cast from `std::vec::IntoIter<u32>` to the object type `dyn Iterator<Item = u32, Item = i32>`
+ = note: required for the cast from `&std::vec::IntoIter<u32>` to `&dyn Iterator<Item = u32, Item = i32>`
error: aborting due to previous error
diff --git a/tests/ui/associated-types/issue-65774-1.stderr b/tests/ui/associated-types/issue-65774-1.stderr
index 91b557555d5..9c77a25c432 100644
--- a/tests/ui/associated-types/issue-65774-1.stderr
+++ b/tests/ui/associated-types/issue-65774-1.stderr
@@ -25,7 +25,7 @@ LL | impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
| --------- ^^^^^^^^^ ^^^^^^^^^
| |
| unsatisfied trait bound introduced here
- = note: required for the cast from `&mut T` to the object type `dyn MyDisplay`
+ = note: required for the cast from `&&mut T` to `&dyn MyDisplay`
error: aborting due to 2 previous errors
diff --git a/tests/ui/associated-types/issue-65774-2.stderr b/tests/ui/associated-types/issue-65774-2.stderr
index c22302cdc26..ca8a727f0fe 100644
--- a/tests/ui/associated-types/issue-65774-2.stderr
+++ b/tests/ui/associated-types/issue-65774-2.stderr
@@ -18,7 +18,7 @@ LL | writer.my_write(valref)
| ^^^^^^ the trait `MyDisplay` is not implemented for `T`
|
= help: the trait `MyDisplay` is implemented for `&'a mut T`
- = note: required for the cast from `T` to the object type `dyn MyDisplay`
+ = note: required for the cast from `&mut T` to `&dyn MyDisplay`
error: aborting due to 2 previous errors
diff --git a/tests/ui/async-await/async-block-control-flow-static-semantics.stderr b/tests/ui/async-await/async-block-control-flow-static-semantics.stderr
index a6dbb071614..bbd5a822d8d 100644
--- a/tests/ui/async-await/async-block-control-flow-static-semantics.stderr
+++ b/tests/ui/async-await/async-block-control-flow-static-semantics.stderr
@@ -35,7 +35,7 @@ error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semant
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected `()`, found `u8`
|
- = note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to the object type `dyn Future<Output = ()>`
+ = note: required for the cast from `&[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to `&dyn Future<Output = ()>`
error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:12:43
@@ -51,7 +51,7 @@ error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semant
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected `()`, found `u8`
|
- = note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to the object type `dyn Future<Output = ()>`
+ = note: required for the cast from `&[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to `&dyn Future<Output = ()>`
error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:49:44
diff --git a/tests/ui/async-await/issue-86507.drop_tracking.stderr b/tests/ui/async-await/issue-86507.drop_tracking.stderr
index 5c8b7ef1b71..adb7b9bf4bf 100644
--- a/tests/ui/async-await/issue-86507.drop_tracking.stderr
+++ b/tests/ui/async-await/issue-86507.drop_tracking.stderr
@@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
|
LL | let x = x;
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
- = note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future<Output = ()> + Send`
+ = note: required for the cast from `Pin<Box<[async block@$DIR/issue-86507.rs:21:17: 23:18]>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
help: consider further restricting this bound
|
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
diff --git a/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr b/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr
index 5c8b7ef1b71..adb7b9bf4bf 100644
--- a/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr
@@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
|
LL | let x = x;
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
- = note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future<Output = ()> + Send`
+ = note: required for the cast from `Pin<Box<[async block@$DIR/issue-86507.rs:21:17: 23:18]>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
help: consider further restricting this bound
|
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
diff --git a/tests/ui/async-await/issue-86507.no_drop_tracking.stderr b/tests/ui/async-await/issue-86507.no_drop_tracking.stderr
index 5c8b7ef1b71..adb7b9bf4bf 100644
--- a/tests/ui/async-await/issue-86507.no_drop_tracking.stderr
+++ b/tests/ui/async-await/issue-86507.no_drop_tracking.stderr
@@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
|
LL | let x = x;
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
- = note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future<Output = ()> + Send`
+ = note: required for the cast from `Pin<Box<[async block@$DIR/issue-86507.rs:21:17: 23:18]>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
help: consider further restricting this bound
|
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
diff --git a/tests/ui/async-await/issues/issue-102206.stderr b/tests/ui/async-await/issues/issue-102206.stderr
index 750b7a886ef..cd845056805 100644
--- a/tests/ui/async-await/issues/issue-102206.stderr
+++ b/tests/ui/async-await/issues/issue-102206.stderr
@@ -2,14 +2,16 @@ error[E0308]: mismatched types
--> $DIR/issue-102206.rs:6:27
|
LL | std::mem::size_of_val(foo());
- | --------------------- ^^^^^
- | | |
- | | expected `&_`, found future
- | | help: consider borrowing here: `&foo()`
+ | --------------------- ^^^^^ expected `&_`, found future
+ | |
| arguments to this function are incorrect
|
note: function defined here
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+help: consider borrowing here
+ |
+LL | std::mem::size_of_val(&foo());
+ | +
error: aborting due to previous error
diff --git a/tests/ui/async-await/multiple-lifetimes/partial-relation.rs b/tests/ui/async-await/multiple-lifetimes/partial-relation.rs
index 02b105999f5..7375cb6d3a0 100644
--- a/tests/ui/async-await/multiple-lifetimes/partial-relation.rs
+++ b/tests/ui/async-await/multiple-lifetimes/partial-relation.rs
@@ -4,7 +4,7 @@
async fn lotsa_lifetimes<'a, 'b, 'c>(a: &'a u32, b: &'b u32, c: &'c u32) -> (&'a u32, &'b u32)
where 'b: 'a
{
- drop((a, c));
+ let _ = (a, c);
(b, b)
}
diff --git a/tests/ui/attr-bad-crate-attr.rc b/tests/ui/attr-bad-crate-attr.rs
index 89ba26dfd6f..89ba26dfd6f 100644
--- a/tests/ui/attr-bad-crate-attr.rc
+++ b/tests/ui/attr-bad-crate-attr.rs
diff --git a/tests/ui/attr-bad-crate-attr.stderr b/tests/ui/attr-bad-crate-attr.stderr
new file mode 100644
index 00000000000..ff420eeea4a
--- /dev/null
+++ b/tests/ui/attr-bad-crate-attr.stderr
@@ -0,0 +1,8 @@
+error: expected item after attributes
+ --> $DIR/attr-bad-crate-attr.rs:4:1
+ |
+LL | #[attr = "val"] // Unterminated
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr b/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr
index 4cc1d821d0a..cfc86ff0dc1 100644
--- a/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr
+++ b/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr
@@ -7,7 +7,7 @@ LL | let q = &raw mut *x;
help: consider changing this to be a mutable reference
|
LL | let x = &mut 0;
- | ~~~~~~
+ | +++
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer
--> $DIR/borrow-raw-address-of-deref-mutability.rs:14:13
@@ -18,7 +18,7 @@ LL | let q = &raw mut *x;
help: consider changing this to be a mutable pointer
|
LL | let x = &mut 0 as *const i32;
- | ~~~~~~
+ | +++
error: aborting due to 2 previous errors
diff --git a/tests/ui/borrowck/borrowck-access-permissions.stderr b/tests/ui/borrowck/borrowck-access-permissions.stderr
index 26f3e2bbdb7..c161e2d95b4 100644
--- a/tests/ui/borrowck/borrowck-access-permissions.stderr
+++ b/tests/ui/borrowck/borrowck-access-permissions.stderr
@@ -35,7 +35,7 @@ LL | let _y1 = &mut *ref_x;
help: consider changing this to be a mutable reference
|
LL | let ref_x = &mut x;
- | ~~~~~~
+ | +++
error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` pointer
--> $DIR/borrowck-access-permissions.rs:39:23
@@ -46,7 +46,7 @@ LL | let _y1 = &mut *ptr_x;
help: consider changing this to be a mutable pointer
|
LL | let ptr_x : *const _ = &mut x;
- | ~~~~~~
+ | +++
error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-access-permissions.rs:48:18
@@ -57,7 +57,7 @@ LL | let _y = &mut *foo_ref.f;
help: consider changing this to be a mutable reference
|
LL | let foo_ref = &mut foo;
- | ~~~~~~~~
+ | +++
error: aborting due to 6 previous errors
diff --git a/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr b/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr
index cbacc87a0e8..cf0c4127d82 100644
--- a/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr
+++ b/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr
@@ -6,8 +6,8 @@ LL | *s.pointer += 1;
|
help: consider changing this to be a mutable reference
|
-LL | fn a(s: &mut S<'_>) {
- | ~~~~~~~~~~
+LL | fn a(s: &mut S) {
+ | +++
error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference
--> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:17:5
@@ -17,8 +17,8 @@ LL | *s.pointer += 1;
|
help: consider changing this to be a mutable reference
|
-LL | fn c(s: &mut &mut S<'_>) {
- | ~~~~~~~~~~~~~~~
+LL | fn c(s: &mut &mut S) {
+ | +++
error: aborting due to 2 previous errors
diff --git a/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr b/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr
index dd0817ff233..59ef61b19d5 100644
--- a/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr
+++ b/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr
@@ -27,8 +27,8 @@ LL | let x: &mut isize = &mut **t0;
|
help: consider changing this to be a mutable reference
|
-LL | fn foo4(t0: &mut &mut isize) {
- | ~~~~~~~~~~~~~~~
+LL | fn foo4(t0: &mut &mut isize) {
+ | +++
error: aborting due to 3 previous errors
diff --git a/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs b/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs
index 0229ca37a69..9163c8ed6fb 100644
--- a/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs
+++ b/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs
@@ -1,6 +1,7 @@
// Check that closure captures for slice patterns are inferred correctly
#![allow(unused_variables)]
+#![allow(drop_ref)]
// run-pass
diff --git a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs
index dd6708582c1..a88b323e0bf 100644
--- a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs
+++ b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs
@@ -1,6 +1,7 @@
// run-pass
#![allow(unused_mut)]
#![allow(unused_variables)]
+#![allow(drop_copy)]
// pretty-expanded FIXME #23616
struct A { a: isize, b: Box<isize> }
diff --git a/tests/ui/borrowck/borrowck-issue-14498.stderr b/tests/ui/borrowck/borrowck-issue-14498.stderr
index 374c5ee3ed2..12d67d536d9 100644
--- a/tests/ui/borrowck/borrowck-issue-14498.stderr
+++ b/tests/ui/borrowck/borrowck-issue-14498.stderr
@@ -7,7 +7,7 @@ LL | ***p = 2;
help: consider changing this to be a mutable reference
|
LL | let p = &mut y;
- | ~~~~~~
+ | +++
error[E0506]: cannot assign to `**y` because it is borrowed
--> $DIR/borrowck-issue-14498.rs:25:5
diff --git a/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr b/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr
index d9590e446c7..fb3db4e1446 100644
--- a/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr
+++ b/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr
@@ -111,7 +111,7 @@ LL | let _bar1 = &mut foo.bar1;
help: consider changing this to be a mutable reference
|
LL | fn borrow_mut_from_imm(foo: &mut Foo) {
- | ~~~~~~~~
+ | +++
error: aborting due to 11 previous errors
diff --git a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
index 1cf763f66fd..40c6bfeeb43 100644
--- a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
+++ b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
@@ -1,6 +1,8 @@
// run-pass
// pretty-expanded FIXME #23616
+#![allow(drop_copy)]
+
struct A { a: isize, b: Box<isize> }
fn field_copy_after_field_borrow() {
diff --git a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs
new file mode 100644
index 00000000000..addbe5d658a
--- /dev/null
+++ b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs
@@ -0,0 +1,23 @@
+// compile-flags: -Zdrop-tracking-mir
+// edition:2021
+
+use std::future::Future;
+
+trait Client {
+ type Connecting<'a>: Future + Send
+ where
+ Self: 'a;
+
+ fn connect(&'_ self) -> Self::Connecting<'a>;
+ //~^ ERROR use of undeclared lifetime name `'a`
+}
+
+fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
+where
+ C: Client + Send + Sync,
+{
+ async move { c.connect().await }
+ //~^ ERROR `C` does not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr
new file mode 100644
index 00000000000..53abe3dc952
--- /dev/null
+++ b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr
@@ -0,0 +1,24 @@
+error[E0261]: use of undeclared lifetime name `'a`
+ --> $DIR/erase-error-in-mir-drop-tracking.rs:11:46
+ |
+LL | fn connect(&'_ self) -> Self::Connecting<'a>;
+ | ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'a` here
+ |
+LL | fn connect<'a>(&'_ self) -> Self::Connecting<'a>;
+ | ++++
+help: consider introducing lifetime `'a` here
+ |
+LL | trait Client<'a> {
+ | ++++
+
+error: `C` does not live long enough
+ --> $DIR/erase-error-in-mir-drop-tracking.rs:19:5
+ |
+LL | async move { c.connect().await }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/borrowck/issue-85765.stderr b/tests/ui/borrowck/issue-85765.stderr
index b4bb128cbb4..2985a658fdd 100644
--- a/tests/ui/borrowck/issue-85765.stderr
+++ b/tests/ui/borrowck/issue-85765.stderr
@@ -18,7 +18,7 @@ LL | *r = 0;
help: consider changing this to be a mutable reference
|
LL | let r = &mut mutvar;
- | ~~~~~~~~~~~
+ | +++
error[E0594]: cannot assign to `*x`, which is behind a `&` reference
--> $DIR/issue-85765.rs:19:5
diff --git a/tests/ui/borrowck/mutability-errors.stderr b/tests/ui/borrowck/mutability-errors.stderr
index d7c602718f1..b39e57d70ec 100644
--- a/tests/ui/borrowck/mutability-errors.stderr
+++ b/tests/ui/borrowck/mutability-errors.stderr
@@ -7,7 +7,7 @@ LL | *x = (1,);
help: consider changing this to be a mutable reference
|
LL | fn named_ref(x: &mut (i32,)) {
- | ~~~~~~~~~~~
+ | +++
error[E0594]: cannot assign to `x.0`, which is behind a `&` reference
--> $DIR/mutability-errors.rs:10:5
@@ -18,7 +18,7 @@ LL | x.0 = 1;
help: consider changing this to be a mutable reference
|
LL | fn named_ref(x: &mut (i32,)) {
- | ~~~~~~~~~~~
+ | +++
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/mutability-errors.rs:11:5
@@ -29,7 +29,7 @@ LL | &mut *x;
help: consider changing this to be a mutable reference
|
LL | fn named_ref(x: &mut (i32,)) {
- | ~~~~~~~~~~~
+ | +++
error[E0596]: cannot borrow `x.0` as mutable, as it is behind a `&` reference
--> $DIR/mutability-errors.rs:12:5
@@ -40,7 +40,7 @@ LL | &mut x.0;
help: consider changing this to be a mutable reference
|
LL | fn named_ref(x: &mut (i32,)) {
- | ~~~~~~~~~~~
+ | +++
error[E0594]: cannot assign to data in a `&` reference
--> $DIR/mutability-errors.rs:16:5
@@ -74,8 +74,8 @@ LL | *x = (1,);
|
help: consider changing this to be a mutable pointer
|
-LL | unsafe fn named_ptr(x: *mut (i32,)) {
- | ~~~~~~~~~~~
+LL | unsafe fn named_ptr(x: *mut const (i32,)) {
+ | +++
error[E0594]: cannot assign to `x.0`, which is behind a `*const` pointer
--> $DIR/mutability-errors.rs:24:5
@@ -85,8 +85,8 @@ LL | (*x).0 = 1;
|
help: consider changing this to be a mutable pointer
|
-LL | unsafe fn named_ptr(x: *mut (i32,)) {
- | ~~~~~~~~~~~
+LL | unsafe fn named_ptr(x: *mut const (i32,)) {
+ | +++
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer
--> $DIR/mutability-errors.rs:25:5
@@ -96,8 +96,8 @@ LL | &mut *x;
|
help: consider changing this to be a mutable pointer
|
-LL | unsafe fn named_ptr(x: *mut (i32,)) {
- | ~~~~~~~~~~~
+LL | unsafe fn named_ptr(x: *mut const (i32,)) {
+ | +++
error[E0596]: cannot borrow `x.0` as mutable, as it is behind a `*const` pointer
--> $DIR/mutability-errors.rs:26:5
@@ -107,8 +107,8 @@ LL | &mut (*x).0;
|
help: consider changing this to be a mutable pointer
|
-LL | unsafe fn named_ptr(x: *mut (i32,)) {
- | ~~~~~~~~~~~
+LL | unsafe fn named_ptr(x: *mut const (i32,)) {
+ | +++
error[E0594]: cannot assign to data in a `*const` pointer
--> $DIR/mutability-errors.rs:30:5
diff --git a/tests/ui/check-cfg/order-independant.names_after.stderr b/tests/ui/check-cfg/order-independant.names_after.stderr
new file mode 100644
index 00000000000..91b81428b38
--- /dev/null
+++ b/tests/ui/check-cfg/order-independant.names_after.stderr
@@ -0,0 +1,19 @@
+warning: unexpected `cfg` condition value
+ --> $DIR/order-independant.rs:8:7
+ |
+LL | #[cfg(a)]
+ | ^- help: specify a config value: `= "b"`
+ |
+ = note: expected values for `a` are: `b`
+ = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: unexpected `cfg` condition value
+ --> $DIR/order-independant.rs:12:7
+ |
+LL | #[cfg(a = "unk")]
+ | ^^^^^^^^^
+ |
+ = note: expected values for `a` are: `b`
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/check-cfg/order-independant.names_before.stderr b/tests/ui/check-cfg/order-independant.names_before.stderr
new file mode 100644
index 00000000000..91b81428b38
--- /dev/null
+++ b/tests/ui/check-cfg/order-independant.names_before.stderr
@@ -0,0 +1,19 @@
+warning: unexpected `cfg` condition value
+ --> $DIR/order-independant.rs:8:7
+ |
+LL | #[cfg(a)]
+ | ^- help: specify a config value: `= "b"`
+ |
+ = note: expected values for `a` are: `b`
+ = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: unexpected `cfg` condition value
+ --> $DIR/order-independant.rs:12:7
+ |
+LL | #[cfg(a = "unk")]
+ | ^^^^^^^^^
+ |
+ = note: expected values for `a` are: `b`
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/check-cfg/order-independant.rs b/tests/ui/check-cfg/order-independant.rs
new file mode 100644
index 00000000000..ce056b8dcd6
--- /dev/null
+++ b/tests/ui/check-cfg/order-independant.rs
@@ -0,0 +1,16 @@
+// check-pass
+// revisions: names_before names_after
+// compile-flags: -Z unstable-options
+// compile-flags: --check-cfg=names(names_before,names_after)
+// [names_before]compile-flags: --check-cfg=names(a) --check-cfg=values(a,"b")
+// [names_after]compile-flags: --check-cfg=values(a,"b") --check-cfg=names(a)
+
+#[cfg(a)]
+//~^ WARNING unexpected `cfg` condition value
+fn my_cfg() {}
+
+#[cfg(a = "unk")]
+//~^ WARNING unexpected `cfg` condition value
+fn my_cfg() {}
+
+fn main() {}
diff --git a/tests/ui/closure_context/issue-26046-fn-mut.stderr b/tests/ui/closure_context/issue-26046-fn-mut.stderr
index f744b71c284..e468f6be791 100644
--- a/tests/ui/closure_context/issue-26046-fn-mut.stderr
+++ b/tests/ui/closure_context/issue-26046-fn-mut.stderr
@@ -9,7 +9,7 @@ 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()`
+ = note: required for the cast from `Box<[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]>` to `Box<(dyn Fn() + 'static)>`
error: aborting due to previous error
diff --git a/tests/ui/closure_context/issue-26046-fn-once.stderr b/tests/ui/closure_context/issue-26046-fn-once.stderr
index 34f94f9dca6..41f60327ce0 100644
--- a/tests/ui/closure_context/issue-26046-fn-once.stderr
+++ b/tests/ui/closure_context/issue-26046-fn-once.stderr
@@ -9,7 +9,7 @@ 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>`
+ = note: required for the cast from `Box<[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]>` to `Box<(dyn Fn() -> Vec<u8> + 'static)>`
error: aborting due to previous error
diff --git a/tests/ui/closures/2229_closure_analysis/bad-pattern.rs b/tests/ui/closures/2229_closure_analysis/bad-pattern.rs
new file mode 100644
index 00000000000..a7bf9b67d45
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/bad-pattern.rs
@@ -0,0 +1,23 @@
+// regression test for #108683
+// edition:2021
+
+enum Refutable {
+ A,
+ B,
+}
+
+fn example(v1: u32, v2: [u32; 4], v3: Refutable) {
+ const PAT: u32 = 0;
+ let v4 = &v2[..];
+ || {
+ let 0 = v1; //~ ERROR refutable pattern in local binding
+ let (0 | 1) = v1; //~ ERROR refutable pattern in local binding
+ let 1.. = v1; //~ ERROR refutable pattern in local binding
+ let [0, 0, 0, 0] = v2; //~ ERROR refutable pattern in local binding
+ let [0] = v4; //~ ERROR refutable pattern in local binding
+ let Refutable::A = v3; //~ ERROR refutable pattern in local binding
+ let PAT = v1; //~ ERROR refutable pattern in local binding
+ };
+}
+
+fn main() {}
diff --git a/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr b/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr
new file mode 100644
index 00000000000..ca8c2a16d32
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr
@@ -0,0 +1,113 @@
+error[E0005]: refutable pattern in local binding
+ --> $DIR/bad-pattern.rs:13:13
+ |
+LL | let 0 = v1;
+ | ^ pattern `1_u32..=u32::MAX` 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
+ = note: the matched value is of type `u32`
+help: you might want to use `if let` to ignore the variant that isn't matched
+ |
+LL | if let 0 = v1 { todo!() };
+ | ++ +++++++++++
+help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
+ |
+LL | let _0 = v1;
+ | +
+
+error[E0005]: refutable pattern in local binding
+ --> $DIR/bad-pattern.rs:14:14
+ |
+LL | let (0 | 1) = v1;
+ | ^^^^^ pattern `2_u32..=u32::MAX` 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
+ = note: the matched value is of type `u32`
+help: you might want to use `if let` to ignore the variant that isn't matched
+ |
+LL | if let (0 | 1) = v1 { todo!() };
+ | ++ +++++++++++
+
+error[E0005]: refutable pattern in local binding
+ --> $DIR/bad-pattern.rs:15:13
+ |
+LL | let 1.. = v1;
+ | ^^^ pattern `0_u32` 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
+ = note: the matched value is of type `u32`
+help: you might want to use `if let` to ignore the variant that isn't matched
+ |
+LL | if let 1.. = v1 { todo!() };
+ | ++ +++++++++++
+
+error[E0005]: refutable pattern in local binding
+ --> $DIR/bad-pattern.rs:16:13
+ |
+LL | let [0, 0, 0, 0] = v2;
+ | ^^^^^^^^^^^^ pattern `[1_u32..=u32::MAX, _, _, _]` 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
+ = note: the matched value is of type `[u32; 4]`
+help: you might want to use `if let` to ignore the variant that isn't matched
+ |
+LL | if let [0, 0, 0, 0] = v2 { todo!() };
+ | ++ +++++++++++
+
+error[E0005]: refutable pattern in local binding
+ --> $DIR/bad-pattern.rs:17:13
+ |
+LL | let [0] = v4;
+ | ^^^ patterns `&[]` and `&[_, _, ..]` 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
+ = note: the matched value is of type `&[u32]`
+help: you might want to use `if let` to ignore the variants that aren't matched
+ |
+LL | if let [0] = v4 { todo!() };
+ | ++ +++++++++++
+
+error[E0005]: refutable pattern in local binding
+ --> $DIR/bad-pattern.rs:18:13
+ |
+LL | let Refutable::A = v3;
+ | ^^^^^^^^^^^^ pattern `Refutable::B` 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
+note: `Refutable` defined here
+ --> $DIR/bad-pattern.rs:4:6
+ |
+LL | enum Refutable {
+ | ^^^^^^^^^
+LL | A,
+LL | B,
+ | - not covered
+ = note: the matched value is of type `Refutable`
+help: you might want to use `if let` to ignore the variant that isn't matched
+ |
+LL | if let Refutable::A = v3 { todo!() };
+ | ++ +++++++++++
+
+error[E0005]: refutable pattern in local binding
+ --> $DIR/bad-pattern.rs:19:13
+ |
+LL | let PAT = v1;
+ | ^^^
+ | |
+ | pattern `1_u32..=u32::MAX` not covered
+ | missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable
+ | help: introduce a variable instead: `PAT_var`
+ |
+ = 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
+ = note: the matched value is of type `u32`
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0005`.
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr
index 95f36fc042c..1904faa9598 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr
@@ -10,7 +10,7 @@ LL | **ref_mref_x = y;
help: consider changing this to be a mutable reference
|
LL | let ref_mref_x = &mut mref_x;
- | ~~~~~~~~~~~
+ | +++
error[E0596]: cannot borrow `**mref_ref_x` as mutable, as it is behind a `&` reference
--> $DIR/mut_ref.rs:26:13
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs
index ff5d284614b..bc7295a0826 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs
+++ b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs
@@ -1,6 +1,7 @@
// run-pass
#![warn(rust_2021_incompatible_closure_captures)]
+#![allow(drop_ref, drop_copy)]
fn main() {
if let a = "" {
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr
index 36a80e694e8..2609e2951ec 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr
@@ -1,5 +1,5 @@
warning: irrefutable `if let` pattern
- --> $DIR/issue-78720.rs:6:8
+ --> $DIR/issue-78720.rs:7:8
|
LL | if let a = "" {
| ^^^^^^^^^^
diff --git a/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs b/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs
index 033fd6f1775..0f15f664e75 100644
--- a/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs
+++ b/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs
@@ -3,6 +3,7 @@
#![allow(unused)]
#![allow(dead_code)]
+#![allow(drop_ref)]
struct Int(i32);
struct B<'a>(&'a i32);
diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs b/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs
index 477fdd613f5..a097424a021 100644
--- a/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs
+++ b/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs
@@ -1,6 +1,8 @@
// edition:2021
// check-pass
+
#![feature(rustc_attrs)]
+#![allow(drop_ref)]
fn main() {
let mut x = 1;
diff --git a/tests/ui/issues/issue-868.rs b/tests/ui/closures/issue-868.rs
index ce0a3c7ca52..ce0a3c7ca52 100644
--- a/tests/ui/issues/issue-868.rs
+++ b/tests/ui/closures/issue-868.rs
diff --git a/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr
index 980da536034..b976f70acf7 100644
--- a/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr
+++ b/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
LL | /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
- = note: required for the cast from `()` to the object type `dyn std::error::Error`
+ = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
--> $DIR/coerce-issue-49593-box-never-windows.rs:23:49
@@ -12,7 +12,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
- = note: required for the cast from `()` to the object type `(dyn std::error::Error + 'static)`
+ = note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)`
error: aborting due to 2 previous errors
diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
index 322681b97bc..0d98fa93e5a 100644
--- a/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
+++ b/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
LL | /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
- = note: required for the cast from `()` to the object type `dyn std::error::Error`
+ = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
--> $DIR/coerce-issue-49593-box-never.rs:23:49
@@ -12,7 +12,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
- = note: required for the cast from `()` to the object type `(dyn std::error::Error + 'static)`
+ = note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)`
error: aborting due to 2 previous errors
diff --git a/tests/ui/coercion/coercion-slice.stderr b/tests/ui/coercion/coercion-slice.stderr
index c7b856a57eb..17bbca7a0bd 100644
--- a/tests/ui/coercion/coercion-slice.stderr
+++ b/tests/ui/coercion/coercion-slice.stderr
@@ -2,11 +2,14 @@ error[E0308]: mismatched types
--> $DIR/coercion-slice.rs:4:21
|
LL | let _: &[i32] = [0];
- | ------ ^^^
- | | |
- | | expected `&[i32]`, found `[{integer}; 1]`
- | | help: consider borrowing here: `&[0]`
+ | ------ ^^^ expected `&[i32]`, found `[{integer}; 1]`
+ | |
| expected due to this
+ |
+help: consider borrowing here
+ |
+LL | let _: &[i32] = &[0];
+ | +
error: aborting due to previous error
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs
index a1b711a3024..87ae83dd966 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs
@@ -11,6 +11,13 @@ struct S<T> {
impl<T: ConstParamTy> ConstParamTy for S<T> {}
+#[derive(PartialEq, Eq, ConstParamTy)]
+struct D<T> {
+ field: u8,
+ gen: T,
+}
+
+
fn check<T: ConstParamTy + ?Sized>() {}
fn main() {
@@ -39,5 +46,8 @@ fn main() {
check::<S<u8>>();
check::<S<[&[bool]; 8]>>();
+ check::<D<u8>>();
+ check::<D<[&[bool]; 8]>>();
+
// FIXME: test tuples
}
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs
index 07fd243737e..74283a37afc 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs
@@ -10,4 +10,8 @@ struct CantParam(NotParam);
impl std::marker::ConstParamTy for CantParam {}
//~^ error: the trait `ConstParamTy` cannot be implemented for this type
+#[derive(std::marker::ConstParamTy, Eq, PartialEq)]
+//~^ error: the trait `ConstParamTy` cannot be implemented for this type
+struct CantParamDerive(NotParam);
+
fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr
index c8e065848b1..52b65d6061a 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr
@@ -7,6 +7,17 @@ LL |
LL | impl std::marker::ConstParamTy for CantParam {}
| ^^^^^^^^^
-error: aborting due to previous error
+error[E0204]: the trait `ConstParamTy` cannot be implemented for this type
+ --> $DIR/const_param_ty_impl_bad_field.rs:13:10
+ |
+LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | struct CantParamDerive(NotParam);
+ | -------- this field does not implement `ConstParamTy`
+ |
+ = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0204`.
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs
index 17ef396164e..37986de481f 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs
@@ -10,6 +10,10 @@ struct CantParam(ImplementsConstParamTy);
impl std::marker::ConstParamTy for CantParam {}
//~^ error: the type `CantParam` does not `#[derive(Eq)]`
+#[derive(std::marker::ConstParamTy)]
+//~^ error: the type `CantParamDerive` does not `#[derive(Eq)]`
+struct CantParamDerive(ImplementsConstParamTy);
+
fn check<T: std::marker::ConstParamTy>() {}
fn main() {
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
index ca5abf5e254..52701d55914 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
@@ -7,6 +7,16 @@ LL | impl std::marker::ConstParamTy for CantParam {}
note: required by a bound in `ConstParamTy`
--> $SRC_DIR/core/src/marker.rs:LL:COL
-error: aborting due to previous error
+error[E0277]: the type `CantParamDerive` does not `#[derive(Eq)]`
+ --> $DIR/const_param_ty_impl_no_structural_eq.rs:13:10
+ |
+LL | #[derive(std::marker::ConstParamTy)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralEq` is not implemented for `CantParamDerive`
+ |
+note: required by a bound in `ConstParamTy`
+ --> $SRC_DIR/core/src/marker.rs:LL:COL
+ = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs
new file mode 100644
index 00000000000..d70377a20c1
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs
@@ -0,0 +1,33 @@
+#![allow(incomplete_features)]
+#![feature(adt_const_params, structural_match)]
+
+union Union {
+ a: u8,
+}
+
+impl PartialEq for Union {
+ fn eq(&self, other: &Union) -> bool {
+ true
+ }
+}
+impl Eq for Union {}
+impl std::marker::StructuralEq for Union {}
+
+impl std::marker::ConstParamTy for Union {}
+
+#[derive(std::marker::ConstParamTy)]
+//~^ ERROR this trait cannot be derived for unions
+union UnionDerive {
+ a: u8,
+}
+
+impl PartialEq for UnionDerive {
+ fn eq(&self, other: &UnionDerive) -> bool {
+ true
+ }
+}
+impl Eq for UnionDerive {}
+impl std::marker::StructuralEq for UnionDerive {}
+
+
+fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr
new file mode 100644
index 00000000000..29370304605
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr
@@ -0,0 +1,8 @@
+error: this trait cannot be derived for unions
+ --> $DIR/const_param_ty_impl_union.rs:18:10
+ |
+LL | #[derive(std::marker::ConstParamTy)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/const-generics/assoc_const_as_type_argument.rs b/tests/ui/const-generics/assoc_const_as_type_argument.rs
new file mode 100644
index 00000000000..ffc7f116a94
--- /dev/null
+++ b/tests/ui/const-generics/assoc_const_as_type_argument.rs
@@ -0,0 +1,13 @@
+trait Trait {
+ const ASSOC: usize;
+}
+
+fn bar<const N: usize>() {}
+
+fn foo<T: Trait>() {
+ bar::<<T as Trait>::ASSOC>();
+ //~^ ERROR: expected associated type, found associated constant `Trait::ASSOC`
+ //~| ERROR: unresolved item provided when a constant was expected
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/assoc_const_as_type_argument.stderr b/tests/ui/const-generics/assoc_const_as_type_argument.stderr
new file mode 100644
index 00000000000..ac009546135
--- /dev/null
+++ b/tests/ui/const-generics/assoc_const_as_type_argument.stderr
@@ -0,0 +1,21 @@
+error[E0575]: expected associated type, found associated constant `Trait::ASSOC`
+ --> $DIR/assoc_const_as_type_argument.rs:8:11
+ |
+LL | bar::<<T as Trait>::ASSOC>();
+ | ^^^^^^^^^^^^^^^^^^^ not a associated type
+
+error[E0747]: unresolved item provided when a constant was expected
+ --> $DIR/assoc_const_as_type_argument.rs:8:11
+ |
+LL | bar::<<T as Trait>::ASSOC>();
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+help: if this generic argument was intended as a const parameter, surround it with braces
+ |
+LL | bar::<{ <T as Trait>::ASSOC }>();
+ | + +
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0575, E0747.
+For more information about an error, try `rustc --explain E0575`.
diff --git a/tests/ui/const-generics/const-arg-in-const-arg.full.stderr b/tests/ui/const-generics/const-arg-in-const-arg.full.stderr
deleted file mode 100644
index 463a37d7e3d..00000000000
--- a/tests/ui/const-generics/const-arg-in-const-arg.full.stderr
+++ /dev/null
@@ -1,163 +0,0 @@
-error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:18:23
- |
-LL | let _: [u8; faz::<'a>(&())];
- | ^^
- |
-note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
- |
-LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
- | ^^
-
-error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:21:23
- |
-LL | let _: [u8; faz::<'b>(&())];
- | ^^
- |
-note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
- |
-LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
- | ^^
-
-error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:41:24
- |
-LL | let _: Foo<{ faz::<'a>(&()) }>;
- | ^^
- |
-note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
- |
-LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
- | ^^
-
-error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:44:24
- |
-LL | let _: Foo<{ faz::<'b>(&()) }>;
- | ^^
- |
-note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
- |
-LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
- | ^^
-
-error: unconstrained generic constant
- --> $DIR/const-arg-in-const-arg.rs:13:12
- |
-LL | let _: [u8; foo::<T>()];
- | ^^^^^^^^^^^^^^^^
- |
- = help: try adding a `where` bound using this expression: `where [(); foo::<T>()]:`
-
-error: unconstrained generic constant
- --> $DIR/const-arg-in-const-arg.rs:15:12
- |
-LL | let _: [u8; bar::<N>()];
- | ^^^^^^^^^^^^^^^^
- |
- = help: try adding a `where` bound using this expression: `where [(); bar::<N>()]:`
-
-error: unconstrained generic constant
- --> $DIR/const-arg-in-const-arg.rs:36:12
- |
-LL | let _: Foo<{ foo::<T>() }>;
- | ^^^^^^^^^^^^^^^^^^^
- |
- = help: try adding a `where` bound using this expression: `where [(); { foo::<T>() }]:`
-
-error: unconstrained generic constant
- --> $DIR/const-arg-in-const-arg.rs:38:12
- |
-LL | let _: Foo<{ bar::<N>() }>;
- | ^^^^^^^^^^^^^^^^^^^
- |
- = help: try adding a `where` bound using this expression: `where [(); { bar::<N>() }]:`
-
-error: unconstrained generic constant
- --> $DIR/const-arg-in-const-arg.rs:25:17
- |
-LL | let _ = [0; foo::<T>()];
- | ^^^^^^^^^^
- |
- = help: try adding a `where` bound using this expression: `where [(); foo::<T>()]:`
-
-error: unconstrained generic constant
- --> $DIR/const-arg-in-const-arg.rs:27:17
- |
-LL | let _ = [0; bar::<N>()];
- | ^^^^^^^^^^
- |
- = help: try adding a `where` bound using this expression: `where [(); bar::<N>()]:`
-
-error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:30:23
- |
-LL | let _ = [0; faz::<'a>(&())];
- | ^^
- |
-note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
- |
-LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
- | ^^
-
-error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:33:23
- |
-LL | let _ = [0; faz::<'b>(&())];
- | ^^
- |
-note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
- |
-LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
- | ^^
-
-error: unconstrained generic constant
- --> $DIR/const-arg-in-const-arg.rs:47:19
- |
-LL | let _ = Foo::<{ foo::<T>() }>;
- | ^^^^^^^^^^^^^^
- |
- = help: try adding a `where` bound using this expression: `where [(); { foo::<T>() }]:`
-
-error: unconstrained generic constant
- --> $DIR/const-arg-in-const-arg.rs:49:19
- |
-LL | let _ = Foo::<{ bar::<N>() }>;
- | ^^^^^^^^^^^^^^
- |
- = help: try adding a `where` bound using this expression: `where [(); { bar::<N>() }]:`
-
-error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:52:27
- |
-LL | let _ = Foo::<{ faz::<'a>(&()) }>;
- | ^^
- |
-note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
- |
-LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
- | ^^
-
-error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:55:27
- |
-LL | let _ = Foo::<{ faz::<'b>(&()) }>;
- | ^^
- |
-note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
- |
-LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
- | ^^
-
-error: aborting due to 16 previous errors
-
-For more information about this error, try `rustc --explain E0794`.
diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
index a7bd9c62b0e..f1f22e2342d 100644
--- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
+++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
@@ -1,5 +1,5 @@
error: generic parameters may not be used in const operations
- --> $DIR/const-arg-in-const-arg.rs:13:23
+ --> $DIR/const-arg-in-const-arg.rs:15:23
|
LL | let _: [u8; foo::<T>()];
| ^ cannot perform const operation using `T`
@@ -8,7 +8,7 @@ LL | let _: [u8; foo::<T>()];
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations
- --> $DIR/const-arg-in-const-arg.rs:15:23
+ --> $DIR/const-arg-in-const-arg.rs:16:23
|
LL | let _: [u8; bar::<N>()];
| ^ cannot perform const operation using `N`
@@ -16,44 +16,44 @@ LL | let _: [u8; bar::<N>()];
= help: const parameters may only be used as standalone arguments, i.e. `N`
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
+error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:18:23
|
LL | let _: [u8; faz::<'a>(&())];
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
+error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:20:23
|
LL | let _: [u8; baz::<'a>(&())];
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
+error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:21:23
|
LL | let _: [u8; faz::<'b>(&())];
- | ^^
+ | ^^ cannot perform const operation using `'b`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
+error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:23:23
|
LL | let _: [u8; baz::<'b>(&())];
- | ^^
+ | ^^ cannot perform const operation using `'b`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations
- --> $DIR/const-arg-in-const-arg.rs:27:23
+ --> $DIR/const-arg-in-const-arg.rs:26:23
|
LL | let _ = [0; bar::<N>()];
| ^ cannot perform const operation using `N`
@@ -61,44 +61,44 @@ LL | let _ = [0; bar::<N>()];
= help: const parameters may only be used as standalone arguments, i.e. `N`
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
- --> $DIR/const-arg-in-const-arg.rs:30:23
+error: generic parameters may not be used in const operations
+ --> $DIR/const-arg-in-const-arg.rs:28:23
|
LL | let _ = [0; faz::<'a>(&())];
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
- --> $DIR/const-arg-in-const-arg.rs:32:23
+error: generic parameters may not be used in const operations
+ --> $DIR/const-arg-in-const-arg.rs:30:23
|
LL | let _ = [0; baz::<'a>(&())];
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
- --> $DIR/const-arg-in-const-arg.rs:33:23
+error: generic parameters may not be used in const operations
+ --> $DIR/const-arg-in-const-arg.rs:31:23
|
LL | let _ = [0; faz::<'b>(&())];
- | ^^
+ | ^^ cannot perform const operation using `'b`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
- --> $DIR/const-arg-in-const-arg.rs:35:23
+error: generic parameters may not be used in const operations
+ --> $DIR/const-arg-in-const-arg.rs:33:23
|
LL | let _ = [0; baz::<'b>(&())];
- | ^^
+ | ^^ cannot perform const operation using `'b`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations
- --> $DIR/const-arg-in-const-arg.rs:36:24
+ --> $DIR/const-arg-in-const-arg.rs:34:24
|
LL | let _: Foo<{ foo::<T>() }>;
| ^ cannot perform const operation using `T`
@@ -107,7 +107,7 @@ LL | let _: Foo<{ foo::<T>() }>;
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations
- --> $DIR/const-arg-in-const-arg.rs:38:24
+ --> $DIR/const-arg-in-const-arg.rs:35:24
|
LL | let _: Foo<{ bar::<N>() }>;
| ^ cannot perform const operation using `N`
@@ -115,44 +115,44 @@ LL | let _: Foo<{ bar::<N>() }>;
= help: const parameters may only be used as standalone arguments, i.e. `N`
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
- --> $DIR/const-arg-in-const-arg.rs:41:24
+error: generic parameters may not be used in const operations
+ --> $DIR/const-arg-in-const-arg.rs:37:24
|
LL | let _: Foo<{ faz::<'a>(&()) }>;
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
- --> $DIR/const-arg-in-const-arg.rs:43:24
+error: generic parameters may not be used in const operations
+ --> $DIR/const-arg-in-const-arg.rs:39:24
|
LL | let _: Foo<{ baz::<'a>(&()) }>;
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
- --> $DIR/const-arg-in-const-arg.rs:44:24
+error: generic parameters may not be used in const operations
+ --> $DIR/const-arg-in-const-arg.rs:40:24
|
LL | let _: Foo<{ faz::<'b>(&()) }>;
- | ^^
+ | ^^ cannot perform const operation using `'b`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
- --> $DIR/const-arg-in-const-arg.rs:46:24
+error: generic parameters may not be used in const operations
+ --> $DIR/const-arg-in-const-arg.rs:42:24
|
LL | let _: Foo<{ baz::<'b>(&()) }>;
- | ^^
+ | ^^ cannot perform const operation using `'b`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations
- --> $DIR/const-arg-in-const-arg.rs:47:27
+ --> $DIR/const-arg-in-const-arg.rs:43:27
|
LL | let _ = Foo::<{ foo::<T>() }>;
| ^ cannot perform const operation using `T`
@@ -161,7 +161,7 @@ LL | let _ = Foo::<{ foo::<T>() }>;
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations
- --> $DIR/const-arg-in-const-arg.rs:49:27
+ --> $DIR/const-arg-in-const-arg.rs:44:27
|
LL | let _ = Foo::<{ bar::<N>() }>;
| ^ cannot perform const operation using `N`
@@ -169,44 +169,44 @@ LL | let _ = Foo::<{ bar::<N>() }>;
= help: const parameters may only be used as standalone arguments, i.e. `N`
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
- --> $DIR/const-arg-in-const-arg.rs:52:27
+error: generic parameters may not be used in const operations
+ --> $DIR/const-arg-in-const-arg.rs:46:27
|
LL | let _ = Foo::<{ faz::<'a>(&()) }>;
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
- --> $DIR/const-arg-in-const-arg.rs:54:27
+error: generic parameters may not be used in const operations
+ --> $DIR/const-arg-in-const-arg.rs:48:27
|
LL | let _ = Foo::<{ baz::<'a>(&()) }>;
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
- --> $DIR/const-arg-in-const-arg.rs:55:27
+error: generic parameters may not be used in const operations
+ --> $DIR/const-arg-in-const-arg.rs:49:27
|
LL | let _ = Foo::<{ faz::<'b>(&()) }>;
- | ^^
+ | ^^ cannot perform const operation using `'b`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
- --> $DIR/const-arg-in-const-arg.rs:57:27
+error: generic parameters may not be used in const operations
+ --> $DIR/const-arg-in-const-arg.rs:51:27
|
LL | let _ = Foo::<{ baz::<'b>(&()) }>;
- | ^^
+ | ^^ cannot perform const operation using `'b`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error[E0747]: unresolved item provided when a constant was expected
- --> $DIR/const-arg-in-const-arg.rs:15:23
+ --> $DIR/const-arg-in-const-arg.rs:16:23
|
LL | let _: [u8; bar::<N>()];
| ^
@@ -223,7 +223,7 @@ LL | let _: [u8; faz::<'a>(&())];
| ^^
|
note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
+ --> $DIR/const-arg-in-const-arg.rs:10:14
|
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
@@ -235,13 +235,13 @@ LL | let _: [u8; faz::<'b>(&())];
| ^^
|
note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
+ --> $DIR/const-arg-in-const-arg.rs:10:14
|
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error[E0747]: unresolved item provided when a constant was expected
- --> $DIR/const-arg-in-const-arg.rs:38:24
+ --> $DIR/const-arg-in-const-arg.rs:35:24
|
LL | let _: Foo<{ bar::<N>() }>;
| ^
@@ -252,25 +252,25 @@ LL | let _: Foo<{ bar::<{ N }>() }>;
| + +
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:41:24
+ --> $DIR/const-arg-in-const-arg.rs:37:24
|
LL | let _: Foo<{ faz::<'a>(&()) }>;
| ^^
|
note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
+ --> $DIR/const-arg-in-const-arg.rs:10:14
|
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:44:24
+ --> $DIR/const-arg-in-const-arg.rs:40:24
|
LL | let _: Foo<{ faz::<'b>(&()) }>;
| ^^
|
note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
+ --> $DIR/const-arg-in-const-arg.rs:10:14
|
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
@@ -284,7 +284,7 @@ LL | let _ = [0; foo::<T>()];
= note: this may fail depending on what value the parameter takes
error[E0747]: unresolved item provided when a constant was expected
- --> $DIR/const-arg-in-const-arg.rs:27:23
+ --> $DIR/const-arg-in-const-arg.rs:26:23
|
LL | let _ = [0; bar::<N>()];
| ^
@@ -295,31 +295,31 @@ LL | let _ = [0; bar::<{ N }>()];
| + +
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:30:23
+ --> $DIR/const-arg-in-const-arg.rs:28:23
|
LL | let _ = [0; faz::<'a>(&())];
| ^^
|
note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
+ --> $DIR/const-arg-in-const-arg.rs:10:14
|
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:33:23
+ --> $DIR/const-arg-in-const-arg.rs:31:23
|
LL | let _ = [0; faz::<'b>(&())];
| ^^
|
note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
+ --> $DIR/const-arg-in-const-arg.rs:10:14
|
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error[E0747]: unresolved item provided when a constant was expected
- --> $DIR/const-arg-in-const-arg.rs:49:27
+ --> $DIR/const-arg-in-const-arg.rs:44:27
|
LL | let _ = Foo::<{ bar::<N>() }>;
| ^
@@ -330,30 +330,30 @@ LL | let _ = Foo::<{ bar::<{ N }>() }>;
| + +
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:52:27
+ --> $DIR/const-arg-in-const-arg.rs:46:27
|
LL | let _ = Foo::<{ faz::<'a>(&()) }>;
| ^^
|
note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
+ --> $DIR/const-arg-in-const-arg.rs:10:14
|
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- --> $DIR/const-arg-in-const-arg.rs:55:27
+ --> $DIR/const-arg-in-const-arg.rs:49:27
|
LL | let _ = Foo::<{ faz::<'b>(&()) }>;
| ^^
|
note: the late bound lifetime parameter is introduced here
- --> $DIR/const-arg-in-const-arg.rs:8:14
+ --> $DIR/const-arg-in-const-arg.rs:10:14
|
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^
error: aborting due to 36 previous errors
-Some errors have detailed explanations: E0658, E0747, E0794.
-For more information about an error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0747, E0794.
+For more information about an error, try `rustc --explain E0747`.
diff --git a/tests/ui/const-generics/const-arg-in-const-arg.rs b/tests/ui/const-generics/const-arg-in-const-arg.rs
index 44a4f560a24..9eaa54347f1 100644
--- a/tests/ui/const-generics/const-arg-in-const-arg.rs
+++ b/tests/ui/const-generics/const-arg-in-const-arg.rs
@@ -1,4 +1,6 @@
-// revisions: full min
+// revisions: min
+// we use a single revision because t his shoudl have a `full` revision
+// but right now that ICEs and I(@BoxyUwU) could not get stderr normalization to work
#![cfg_attr(full, feature(generic_const_exprs))]
#![cfg_attr(full, allow(incomplete_features))]
@@ -11,50 +13,42 @@ const fn baz<'a>(_: &'a ()) -> usize where &'a (): Sized { 13 }
struct Foo<const N: usize>;
fn test<'a, 'b, T, const N: usize>() where &'b (): Sized {
let _: [u8; foo::<T>()]; //[min]~ ERROR generic parameters may not
- //[full]~^ ERROR unconstrained generic constant
let _: [u8; bar::<N>()]; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR unresolved item provided when a constant was expected
- //[full]~^^ ERROR unconstrained generic constant
- let _: [u8; faz::<'a>(&())]; //[min]~ ERROR a non-static lifetime
- //~^ ERROR cannot specify lifetime arguments
- let _: [u8; baz::<'a>(&())]; //[min]~ ERROR a non-static lifetime
- let _: [u8; faz::<'b>(&())]; //[min]~ ERROR a non-static lifetime
- //~^ ERROR cannot specify lifetime arguments
- let _: [u8; baz::<'b>(&())]; //[min]~ ERROR a non-static lifetime
+ let _: [u8; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not
+ //[min]~^ ERROR cannot specify lifetime arguments
+ let _: [u8; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not
+ let _: [u8; faz::<'b>(&())]; //[min]~ ERROR generic parameters may not
+ //[min]~^ ERROR cannot specify lifetime arguments
+ let _: [u8; baz::<'b>(&())]; //[min]~ ERROR generic parameters may not
let _ = [0; foo::<T>()]; //[min]~ ERROR constant expression depends on a generic parameter
- //[full]~^ ERROR unconstrained generic constant
let _ = [0; bar::<N>()]; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR unresolved item provided when a constant was expected
- //[full]~^^ ERROR unconstrained generic constant
- let _ = [0; faz::<'a>(&())]; //[min]~ ERROR a non-static lifetime
- //~^ ERROR cannot specify lifetime arguments
- let _ = [0; baz::<'a>(&())]; //[min]~ ERROR a non-static lifetime
- let _ = [0; faz::<'b>(&())]; //[min]~ ERROR a non-static lifetime
- //~^ ERROR cannot specify lifetime arguments
- let _ = [0; baz::<'b>(&())]; //[min]~ ERROR a non-static lifetime
+ let _ = [0; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not
+ //[min]~^ ERROR cannot specify lifetime arguments
+ let _ = [0; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not
+ let _ = [0; faz::<'b>(&())]; //[min]~ ERROR generic parameters may not
+ //[min]~^ ERROR cannot specify lifetime arguments
+ let _ = [0; baz::<'b>(&())]; //[min]~ ERROR generic parameters may not
let _: Foo<{ foo::<T>() }>; //[min]~ ERROR generic parameters may not
- //[full]~^ ERROR unconstrained generic constant
let _: Foo<{ bar::<N>() }>; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR unresolved item provided when a constant was expected
- //[full]~^^ ERROR unconstrained generic constant
- let _: Foo<{ faz::<'a>(&()) }>; //[min]~ ERROR a non-static lifetime
- //~^ ERROR cannot specify lifetime arguments
- let _: Foo<{ baz::<'a>(&()) }>; //[min]~ ERROR a non-static lifetime
- let _: Foo<{ faz::<'b>(&()) }>; //[min]~ ERROR a non-static lifetime
- //~^ ERROR cannot specify lifetime arguments
- let _: Foo<{ baz::<'b>(&()) }>; //[min]~ ERROR a non-static lifetime
+ let _: Foo<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not
+ //[min]~^ ERROR cannot specify lifetime arguments
+ let _: Foo<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not
+ let _: Foo<{ faz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not
+ //[min]~^ ERROR cannot specify lifetime arguments
+ let _: Foo<{ baz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not
let _ = Foo::<{ foo::<T>() }>; //[min]~ ERROR generic parameters may not
- //[full]~^ ERROR unconstrained generic constant
let _ = Foo::<{ bar::<N>() }>; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR unresolved item provided when a constant was expected
- //[full]~^^ ERROR unconstrained generic constant
- let _ = Foo::<{ faz::<'a>(&()) }>; //[min]~ ERROR a non-static lifetime
- //~^ ERROR cannot specify lifetime arguments
- let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR a non-static lifetime
- let _ = Foo::<{ faz::<'b>(&()) }>; //[min]~ ERROR a non-static lifetime
- //~^ ERROR cannot specify lifetime arguments
- let _ = Foo::<{ baz::<'b>(&()) }>; //[min]~ ERROR a non-static lifetime
+ let _ = Foo::<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not
+ //[min]~^ ERROR cannot specify lifetime arguments
+ let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not
+ let _ = Foo::<{ faz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not
+ //[min]~^ ERROR cannot specify lifetime arguments
+ let _ = Foo::<{ baz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not
}
fn main() {}
diff --git a/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr b/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr
index 82030731cc1..310ca75fdc9 100644
--- a/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr
+++ b/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr
@@ -1,12 +1,11 @@
-error[E0658]: a non-static lifetime is not allowed in a `const`
+error: generic parameters may not be used in const operations
--> $DIR/const-argument-non-static-lifetime.rs:14:17
|
LL | let _: &'a ();
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/const-generics/const-argument-non-static-lifetime.rs b/tests/ui/const-generics/const-argument-non-static-lifetime.rs
index 0357e4ed59f..df2f3b7918c 100644
--- a/tests/ui/const-generics/const-argument-non-static-lifetime.rs
+++ b/tests/ui/const-generics/const-argument-non-static-lifetime.rs
@@ -11,7 +11,7 @@ fn test<const N: usize>() {}
fn wow<'a>() -> &'a () {
test::<{
- let _: &'a (); //[min]~ ERROR a non-static lifetime
+ let _: &'a (); //[min]~ ERROR generic parameters may not be used in const operations
3
}>();
&()
diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr
index f639e276f46..539d840f0a8 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr
@@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
| ^ the type must not depend on the parameter `N`
+ |
+ = note: const parameters may not be used in the type of const parameters
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/const-param-type-depends-on-const-param.rs:15:40
|
LL | pub struct SelfDependent<const N: [u8; N]>;
| ^ the type must not depend on the parameter `N`
+ |
+ = note: const parameters may not be used in the type of const parameters
error: aborting due to 2 previous errors
diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr
index 24aa405211f..f829526ca1d 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr
@@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
| ^ the type must not depend on the parameter `N`
+ |
+ = note: const parameters may not be used in the type of const parameters
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/const-param-type-depends-on-const-param.rs:15:40
|
LL | pub struct SelfDependent<const N: [u8; N]>;
| ^ the type must not depend on the parameter `N`
+ |
+ = note: const parameters may not be used in the type of const parameters
error: `[u8; N]` is forbidden as the type of a const generic parameter
--> $DIR/const-param-type-depends-on-const-param.rs:11:47
diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
index 9c5c97befd8..c5160d1c384 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
@@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | struct B<T, const N: T>(PhantomData<[T; N]>);
| ^ the type must not depend on the parameter `T`
+ |
+ = note: type parameters may not be used in the type of const parameters
error: aborting due to previous error
diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr
index 32f7dea8263..938fb08b795 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr
@@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | pub struct Dependent<T, const X: T>([(); X]);
| ^ the type must not depend on the parameter `T`
+ |
+ = note: type parameters may not be used in the type of const parameters
error[E0392]: parameter `T` is never used
--> $DIR/const-param-type-depends-on-type-param.rs:11:22
diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr
index 32f7dea8263..938fb08b795 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr
@@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | pub struct Dependent<T, const X: T>([(); X]);
| ^ the type must not depend on the parameter `T`
+ |
+ = note: type parameters may not be used in the type of const parameters
error[E0392]: parameter `T` is never used
--> $DIR/const-param-type-depends-on-type-param.rs:11:22
diff --git a/tests/ui/const-generics/defaults/trait_objects_fail.stderr b/tests/ui/const-generics/defaults/trait_objects_fail.stderr
index 0e8334d0338..481d77728b9 100644
--- a/tests/ui/const-generics/defaults/trait_objects_fail.stderr
+++ b/tests/ui/const-generics/defaults/trait_objects_fail.stderr
@@ -5,7 +5,7 @@ LL | foo(&10_u32);
| ^^^^^^^ 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`
+ = note: required for the cast from `&u32` to `&dyn Trait`
error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied
--> $DIR/trait_objects_fail.rs:28:9
@@ -14,7 +14,7 @@ LL | bar(&true);
| ^^^^^ 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<_>`
+ = note: required for the cast from `&bool` to `&dyn Traitor<_>`
error: aborting due to 2 previous errors
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-74713.rs b/tests/ui/const-generics/generic_const_exprs/issue-74713.rs
index 0bcb997d96c..205d031d4a3 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-74713.rs
+++ b/tests/ui/const-generics/generic_const_exprs/issue-74713.rs
@@ -1,7 +1,7 @@
fn bug<'a>()
where
[(); { //~ ERROR mismatched types
- let _: &'a (); //~ ERROR a non-static lifetime is not allowed in a `const`
+ let _: &'a (); //~ ERROR generic parameters may not be used in const operations
}]:
{}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr b/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr
index e7673df0a02..f0e0a4b9711 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr
@@ -1,11 +1,11 @@
-error[E0658]: a non-static lifetime is not allowed in a `const`
+error: generic parameters may not be used in const operations
--> $DIR/issue-74713.rs:4:17
|
LL | let _: &'a ();
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error[E0308]: mismatched types
--> $DIR/issue-74713.rs:3:10
@@ -18,5 +18,4 @@ LL | | }]:
error: aborting due to 2 previous errors
-Some errors have detailed explanations: E0308, E0658.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.rs b/tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.rs
new file mode 100644
index 00000000000..96aeec77c13
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.rs
@@ -0,0 +1,12 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn foo() -> [(); {
+ let a: &'a ();
+ //~^ ERROR: use of undeclared lifetime name `'a`
+ 10_usize
+}] {
+ loop {}
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.stderr b/tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.stderr
new file mode 100644
index 00000000000..976f037062d
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.stderr
@@ -0,0 +1,11 @@
+error[E0261]: use of undeclared lifetime name `'a`
+ --> $DIR/unresolved_lifetimes_error.rs:5:13
+ |
+LL | fn foo() -> [(); {
+ | - help: consider introducing lifetime `'a` here: `<'a>`
+LL | let a: &'a ();
+ | ^^ undeclared lifetime
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/const-generics/issue-46511.rs b/tests/ui/const-generics/issue-46511.rs
index 71c50e2f3f7..78baba818ad 100644
--- a/tests/ui/const-generics/issue-46511.rs
+++ b/tests/ui/const-generics/issue-46511.rs
@@ -2,7 +2,7 @@
struct Foo<'a> //~ ERROR parameter `'a` is never used [E0392]
{
- _a: [u8; std::mem::size_of::<&'a mut u8>()] //~ ERROR a non-static lifetime is not allowed in a `const`
+ _a: [u8; std::mem::size_of::<&'a mut u8>()] //~ ERROR generic parameters may not be used in const operations
}
pub fn main() {}
diff --git a/tests/ui/const-generics/issue-46511.stderr b/tests/ui/const-generics/issue-46511.stderr
index b21afa56dcb..58c93a1fab4 100644
--- a/tests/ui/const-generics/issue-46511.stderr
+++ b/tests/ui/const-generics/issue-46511.stderr
@@ -1,11 +1,11 @@
-error[E0658]: a non-static lifetime is not allowed in a `const`
+error: generic parameters may not be used in const operations
--> $DIR/issue-46511.rs:5:35
|
LL | _a: [u8; std::mem::size_of::<&'a mut u8>()]
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error[E0392]: parameter `'a` is never used
--> $DIR/issue-46511.rs:3:12
@@ -17,5 +17,4 @@ LL | struct Foo<'a>
error: aborting due to 2 previous errors
-Some errors have detailed explanations: E0392, E0658.
-For more information about an error, try `rustc --explain E0392`.
+For more information about this error, try `rustc --explain E0392`.
diff --git a/tests/ui/const-generics/issues/issue-105821.rs b/tests/ui/const-generics/issues/issue-105821.rs
index cba2e22c460..6cfabb65efb 100644
--- a/tests/ui/const-generics/issues/issue-105821.rs
+++ b/tests/ui/const-generics/issues/issue-105821.rs
@@ -1,7 +1,7 @@
// check-pass
#![allow(incomplete_features)]
-#![feature(adt_const_params, const_ptr_read, generic_const_exprs)]
+#![feature(adt_const_params, generic_const_exprs)]
#![allow(dead_code)]
const fn catone<const M: usize>(_a: &[u8; M]) -> [u8; M + 1]
diff --git a/tests/ui/const-generics/issues/issue-56445-1.full.stderr b/tests/ui/const-generics/issues/issue-56445-1.full.stderr
index 179643a7552..5fc0ec26047 100644
--- a/tests/ui/const-generics/issues/issue-56445-1.full.stderr
+++ b/tests/ui/const-generics/issues/issue-56445-1.full.stderr
@@ -1,11 +1,11 @@
-error[E0771]: use of non-static lifetime `'a` in const generic
+error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/issue-56445-1.rs:9:26
|
LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
- | ^^
+ | ^^ the type must not depend on the parameter `'a`
|
- = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
+ = note: lifetime parameters may not be used in the type of const parameters
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0771`.
+For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/const-generics/issues/issue-56445-1.min.stderr b/tests/ui/const-generics/issues/issue-56445-1.min.stderr
index 9f880134162..71a7051f25b 100644
--- a/tests/ui/const-generics/issues/issue-56445-1.min.stderr
+++ b/tests/ui/const-generics/issues/issue-56445-1.min.stderr
@@ -1,10 +1,10 @@
-error[E0771]: use of non-static lifetime `'a` in const generic
+error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/issue-56445-1.rs:9:26
|
LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
- | ^^
+ | ^^ the type must not depend on the parameter `'a`
|
- = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
+ = note: lifetime parameters may not be used in the type of const parameters
error: `&str` is forbidden as the type of a const generic parameter
--> $DIR/issue-56445-1.rs:9:25
@@ -17,4 +17,4 @@ LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0771`.
+For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/const-generics/issues/issue-56445-1.rs b/tests/ui/const-generics/issues/issue-56445-1.rs
index 0741c3796ad..d862bf24aef 100644
--- a/tests/ui/const-generics/issues/issue-56445-1.rs
+++ b/tests/ui/const-generics/issues/issue-56445-1.rs
@@ -7,7 +7,7 @@
use std::marker::PhantomData;
struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
-//~^ ERROR: use of non-static lifetime `'a` in const generic
+//~^ ERROR: the type of const parameters must not depend on other generic parameters
//[min]~| ERROR: `&str` is forbidden as the type of a const generic parameter
impl Bug<'_, ""> {}
diff --git a/tests/ui/const-generics/issues/issue-62878.full.stderr b/tests/ui/const-generics/issues/issue-62878.full.stderr
index 3a2b291d7ba..c658b5a6e68 100644
--- a/tests/ui/const-generics/issues/issue-62878.full.stderr
+++ b/tests/ui/const-generics/issues/issue-62878.full.stderr
@@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | fn foo<const N: usize, const A: [u8; N]>() {}
| ^ the type must not depend on the parameter `N`
+ |
+ = note: const parameters may not be used in the type of const parameters
error: aborting due to previous error
diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr
index 5a721720d78..9c0e5179cc4 100644
--- a/tests/ui/const-generics/issues/issue-62878.min.stderr
+++ b/tests/ui/const-generics/issues/issue-62878.min.stderr
@@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | fn foo<const N: usize, const A: [u8; N]>() {}
| ^ the type must not depend on the parameter `N`
+ |
+ = note: const parameters may not be used in the type of const parameters
error: `[u8; N]` is forbidden as the type of a const generic parameter
--> $DIR/issue-62878.rs:5:33
diff --git a/tests/ui/const-generics/issues/issue-71169.full.stderr b/tests/ui/const-generics/issues/issue-71169.full.stderr
index 1f5880f368e..ccdfbbd54cf 100644
--- a/tests/ui/const-generics/issues/issue-71169.full.stderr
+++ b/tests/ui/const-generics/issues/issue-71169.full.stderr
@@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
| ^^^ the type must not depend on the parameter `LEN`
+ |
+ = note: const parameters may not be used in the type of const parameters
error: aborting due to previous error
diff --git a/tests/ui/const-generics/issues/issue-71169.min.stderr b/tests/ui/const-generics/issues/issue-71169.min.stderr
index 998b16a79e6..ebfb24bec28 100644
--- a/tests/ui/const-generics/issues/issue-71169.min.stderr
+++ b/tests/ui/const-generics/issues/issue-71169.min.stderr
@@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
| ^^^ the type must not depend on the parameter `LEN`
+ |
+ = note: const parameters may not be used in the type of const parameters
error: `[u8; LEN]` is forbidden as the type of a const generic parameter
--> $DIR/issue-71169.rs:5:38
diff --git a/tests/ui/const-generics/issues/issue-71381.full.stderr b/tests/ui/const-generics/issues/issue-71381.full.stderr
index e17cf96aa3e..962eaf75b98 100644
--- a/tests/ui/const-generics/issues/issue-71381.full.stderr
+++ b/tests/ui/const-generics/issues/issue-71381.full.stderr
@@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
| ^^^^ the type must not depend on the parameter `Args`
+ |
+ = note: type parameters may not be used in the type of const parameters
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/issue-71381.rs:23:40
|
LL | const FN: unsafe extern "C" fn(Args),
| ^^^^ the type must not depend on the parameter `Args`
+ |
+ = note: type parameters may not be used in the type of const parameters
error[E0741]: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71381.rs:14:61
diff --git a/tests/ui/const-generics/issues/issue-71381.min.stderr b/tests/ui/const-generics/issues/issue-71381.min.stderr
index 3950317b370..e1e140071fc 100644
--- a/tests/ui/const-generics/issues/issue-71381.min.stderr
+++ b/tests/ui/const-generics/issues/issue-71381.min.stderr
@@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
| ^^^^ the type must not depend on the parameter `Args`
+ |
+ = note: type parameters may not be used in the type of const parameters
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/issue-71381.rs:23:40
|
LL | const FN: unsafe extern "C" fn(Args),
| ^^^^ the type must not depend on the parameter `Args`
+ |
+ = note: type parameters may not be used in the type of const parameters
error: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71381.rs:14:61
diff --git a/tests/ui/const-generics/issues/issue-71611.full.stderr b/tests/ui/const-generics/issues/issue-71611.full.stderr
index 656aa29e19b..e109459f2be 100644
--- a/tests/ui/const-generics/issues/issue-71611.full.stderr
+++ b/tests/ui/const-generics/issues/issue-71611.full.stderr
@@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | fn func<A, const F: fn(inner: A)>(outer: A) {
| ^ the type must not depend on the parameter `A`
+ |
+ = note: type parameters may not be used in the type of const parameters
error[E0741]: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71611.rs:5:21
diff --git a/tests/ui/const-generics/issues/issue-71611.min.stderr b/tests/ui/const-generics/issues/issue-71611.min.stderr
index 01a85b745ce..b33d7cf9850 100644
--- a/tests/ui/const-generics/issues/issue-71611.min.stderr
+++ b/tests/ui/const-generics/issues/issue-71611.min.stderr
@@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | fn func<A, const F: fn(inner: A)>(outer: A) {
| ^ the type must not depend on the parameter `A`
+ |
+ = note: type parameters may not be used in the type of const parameters
error: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71611.rs:5:21
diff --git a/tests/ui/const-generics/issues/issue-77357.rs b/tests/ui/const-generics/issues/issue-77357.rs
deleted file mode 100644
index 3cb8d3846ab..00000000000
--- a/tests/ui/const-generics/issues/issue-77357.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-#![feature(generic_const_exprs)]
-#![allow(incomplete_features)]
-
-trait MyTrait<T> {}
-
-fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> {
- //~^ ERROR overly complex generic constant
- todo!()
-}
-
-fn main() {}
diff --git a/tests/ui/const-generics/issues/issue-77357.stderr b/tests/ui/const-generics/issues/issue-77357.stderr
deleted file mode 100644
index 68b35a38b0f..00000000000
--- a/tests/ui/const-generics/issues/issue-77357.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: overly complex generic constant
- --> $DIR/issue-77357.rs:6:46
- |
-LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ blocks are not supported in generic constants
- |
- = help: consider moving this anonymous constant into a `const` function
- = note: this operation may be supported in the future
-
-error: aborting due to previous error
-
diff --git a/tests/ui/const-generics/issues/issue-83993.rs b/tests/ui/const-generics/issues/issue-83993.rs
deleted file mode 100644
index f2f05d9526b..00000000000
--- a/tests/ui/const-generics/issues/issue-83993.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-// check-pass
-
-#![feature(generic_const_exprs)]
-#![allow(incomplete_features)]
-
-fn bug<'a>()
-where
- for<'b> [(); {
- let x: &'b ();
- 0
- }]:
-{}
-
-fn main() {}
diff --git a/tests/ui/const-generics/issues/issue-88997.stderr b/tests/ui/const-generics/issues/issue-88997.stderr
index 505ba0da232..b49d52dd0ba 100644
--- a/tests/ui/const-generics/issues/issue-88997.stderr
+++ b/tests/ui/const-generics/issues/issue-88997.stderr
@@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | struct Range<T: PartialOrd, const MIN: T, const MAX: T>(T)
| ^ the type must not depend on the parameter `T`
+ |
+ = note: type parameters may not be used in the type of const parameters
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/issue-88997.rs:8:54
|
LL | struct Range<T: PartialOrd, const MIN: T, const MAX: T>(T)
| ^ the type must not depend on the parameter `T`
+ |
+ = note: type parameters may not be used in the type of const parameters
error: aborting due to 2 previous errors
diff --git a/tests/ui/const-generics/issues/issue-90364.stderr b/tests/ui/const-generics/issues/issue-90364.stderr
index e85bd136ef6..23424d7b919 100644
--- a/tests/ui/const-generics/issues/issue-90364.stderr
+++ b/tests/ui/const-generics/issues/issue-90364.stderr
@@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
LL | pub struct Foo<T, const H: T>(T)
| ^ the type must not depend on the parameter `T`
+ |
+ = note: type parameters may not be used in the type of const parameters
error: aborting due to previous error
diff --git a/tests/ui/const-generics/late-bound-vars/in_closure.rs b/tests/ui/const-generics/late-bound-vars/in_closure.rs
index 5294cc3b5f4..00fb535f048 100644
--- a/tests/ui/const-generics/late-bound-vars/in_closure.rs
+++ b/tests/ui/const-generics/late-bound-vars/in_closure.rs
@@ -1,4 +1,22 @@
-// run-pass
+// failure-status: 101
+// known-bug: unknown
+// error-pattern:internal compiler error
+// normalize-stderr-test "internal compiler error.*" -> ""
+// normalize-stderr-test "DefId\([^)]*\)" -> "..."
+// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
+// normalize-stderr-test "thread.*panicked.*\n" -> ""
+// normalize-stderr-test "stack backtrace:\n" -> ""
+// normalize-stderr-test "\s\d{1,}: .*\n" -> ""
+// normalize-stderr-test "\s at .*\n" -> ""
+// normalize-stderr-test ".*note: Some details.*\n" -> ""
+// normalize-stderr-test "\n\n[ ]*\n" -> ""
+// normalize-stderr-test "compiler/.*: projection" -> "projection"
+// this should run-pass
+
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
diff --git a/tests/ui/const-generics/late-bound-vars/in_closure.stderr b/tests/ui/const-generics/late-bound-vars/in_closure.stderr
new file mode 100644
index 00000000000..557fbea2e05
--- /dev/null
+++ b/tests/ui/const-generics/late-bound-vars/in_closure.stderr
@@ -0,0 +1,13 @@
+error: query stack during panic:
+#0 [mir_borrowck] borrow-checking `test::{closure#0}::{constant#1}`
+#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{closure#0}::{constant#1}`
+#2 [mir_for_ctfe] caching mir of `test::{closure#0}::{constant#1}` for CTFE
+#3 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}`
+#4 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}`
+#5 [eval_to_valtree] evaluating type-level constant
+#6 [typeck] type-checking `test`
+#7 [used_trait_imports] finding used_trait_imports `test`
+#8 [analysis] running analysis passes on this crate
+end of query stack
+error: aborting due to previous error
+
diff --git a/tests/ui/const-generics/late-bound-vars/simple.rs b/tests/ui/const-generics/late-bound-vars/simple.rs
index 6da5395ef83..5d19aaf0b95 100644
--- a/tests/ui/const-generics/late-bound-vars/simple.rs
+++ b/tests/ui/const-generics/late-bound-vars/simple.rs
@@ -1,4 +1,21 @@
-// run-pass
+// failure-status: 101
+// known-bug: unknown
+// error-pattern:internal compiler error
+// normalize-stderr-test "internal compiler error.*" -> ""
+// normalize-stderr-test "DefId\([^)]*\)" -> "..."
+// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
+// normalize-stderr-test "thread.*panicked.*\n" -> ""
+// normalize-stderr-test "stack backtrace:\n" -> ""
+// normalize-stderr-test "\s\d{1,}: .*\n" -> ""
+// normalize-stderr-test "\s at .*\n" -> ""
+// normalize-stderr-test ".*note: Some details.*\n" -> ""
+// normalize-stderr-test "\n\n[ ]*\n" -> ""
+// normalize-stderr-test "compiler/.*: projection" -> "projection"
+
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
diff --git a/tests/ui/const-generics/late-bound-vars/simple.stderr b/tests/ui/const-generics/late-bound-vars/simple.stderr
new file mode 100644
index 00000000000..c0568f5a5cf
--- /dev/null
+++ b/tests/ui/const-generics/late-bound-vars/simple.stderr
@@ -0,0 +1,13 @@
+error: query stack during panic:
+#0 [mir_borrowck] borrow-checking `test::{constant#1}`
+#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{constant#1}`
+#2 [mir_for_ctfe] caching mir of `test::{constant#1}` for CTFE
+#3 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}`
+#4 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}`
+#5 [eval_to_valtree] evaluating type-level constant
+#6 [typeck] type-checking `test`
+#7 [used_trait_imports] finding used_trait_imports `test`
+#8 [analysis] running analysis passes on this crate
+end of query stack
+error: aborting due to previous error
+
diff --git a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs
index 6215b7d936c..86f2bc9c74b 100644
--- a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs
+++ b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs
@@ -5,7 +5,7 @@ fn test<const N: usize>() {}
fn issue_75323_and_74447_1<'a>() -> &'a () {
test::<{ let _: &'a (); 3 },>();
- //~^ ERROR a non-static lifetime is not allowed in a `const`
+ //~^ ERROR generic parameters may not be used in const operations
&()
}
@@ -19,7 +19,7 @@ fn issue_75323_and_74447_3() {
fn issue_73375<'a>() {
[(); (|_: &'a u8| (), 0).1];
- //~^ ERROR a non-static lifetime is not allowed in a `const`
+ //~^ ERROR generic parameters may not be used in const operations
}
fn main() {}
diff --git a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr
index 5f641b07095..7726016eb83 100644
--- a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr
+++ b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr
@@ -1,21 +1,20 @@
-error[E0658]: a non-static lifetime is not allowed in a `const`
+error: generic parameters may not be used in const operations
--> $DIR/forbid-non-static-lifetimes.rs:7:22
|
LL | test::<{ let _: &'a (); 3 },>();
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-error[E0658]: a non-static lifetime is not allowed in a `const`
+error: generic parameters may not be used in const operations
--> $DIR/forbid-non-static-lifetimes.rs:21:16
|
LL | [(); (|_: &'a u8| (), 0).1];
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.rs b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.rs
index 3018439afa7..de710b0e37d 100644
--- a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.rs
+++ b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.rs
@@ -2,7 +2,7 @@ struct Foo<
'a,
const N: usize = {
let x: &'a ();
- //~^ ERROR use of non-static lifetime `'a` in const generic
+ //~^ ERROR generic parameters may not be used in const operations
3
},
>(&'a ());
diff --git a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr
index 9d9555d3f64..6b0d18f1989 100644
--- a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr
+++ b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr
@@ -1,11 +1,11 @@
-error[E0771]: use of non-static lifetime `'a` in const generic
+error: generic parameters may not be used in const operations
--> $DIR/outer-lifetime-in-const-generic-default.rs:4:17
|
LL | let x: &'a ();
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0771`.
diff --git a/tests/ui/const-generics/variant-discrimiant-no-generics.full.stderr b/tests/ui/const-generics/variant-discrimiant-no-generics.full.stderr
new file mode 100644
index 00000000000..2f03b8e1f66
--- /dev/null
+++ b/tests/ui/const-generics/variant-discrimiant-no-generics.full.stderr
@@ -0,0 +1,34 @@
+error: generic parameters may not be used in enum discriminant values
+ --> $DIR/variant-discrimiant-no-generics.rs:7:15
+ |
+LL | Variant = N,
+ | ^ cannot perform const operation using `N`
+ |
+ = note: const parameters may not be used in enum discriminant values
+
+error: generic parameters may not be used in enum discriminant values
+ --> $DIR/variant-discrimiant-no-generics.rs:12:17
+ |
+LL | Variant = { N + 1 },
+ | ^ cannot perform const operation using `N`
+ |
+ = note: const parameters may not be used in enum discriminant values
+
+error: generic parameters may not be used in enum discriminant values
+ --> $DIR/variant-discrimiant-no-generics.rs:18:37
+ |
+LL | Variant = { std::mem::size_of::<T>() as isize },
+ | ^ cannot perform const operation using `T`
+ |
+ = note: type parameters may not be used in enum discriminant values
+
+error: generic parameters may not be used in enum discriminant values
+ --> $DIR/variant-discrimiant-no-generics.rs:25:17
+ |
+LL | let a: &'a ();
+ | ^^ cannot perform const operation using `'a`
+ |
+ = note: lifetime parameters may not be used in enum discriminant values
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/const-generics/variant-discrimiant-no-generics.min.stderr b/tests/ui/const-generics/variant-discrimiant-no-generics.min.stderr
new file mode 100644
index 00000000000..2f03b8e1f66
--- /dev/null
+++ b/tests/ui/const-generics/variant-discrimiant-no-generics.min.stderr
@@ -0,0 +1,34 @@
+error: generic parameters may not be used in enum discriminant values
+ --> $DIR/variant-discrimiant-no-generics.rs:7:15
+ |
+LL | Variant = N,
+ | ^ cannot perform const operation using `N`
+ |
+ = note: const parameters may not be used in enum discriminant values
+
+error: generic parameters may not be used in enum discriminant values
+ --> $DIR/variant-discrimiant-no-generics.rs:12:17
+ |
+LL | Variant = { N + 1 },
+ | ^ cannot perform const operation using `N`
+ |
+ = note: const parameters may not be used in enum discriminant values
+
+error: generic parameters may not be used in enum discriminant values
+ --> $DIR/variant-discrimiant-no-generics.rs:18:37
+ |
+LL | Variant = { std::mem::size_of::<T>() as isize },
+ | ^ cannot perform const operation using `T`
+ |
+ = note: type parameters may not be used in enum discriminant values
+
+error: generic parameters may not be used in enum discriminant values
+ --> $DIR/variant-discrimiant-no-generics.rs:25:17
+ |
+LL | let a: &'a ();
+ | ^^ cannot perform const operation using `'a`
+ |
+ = note: lifetime parameters may not be used in enum discriminant values
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/const-generics/variant-discrimiant-no-generics.rs b/tests/ui/const-generics/variant-discrimiant-no-generics.rs
new file mode 100644
index 00000000000..e286aa9a613
--- /dev/null
+++ b/tests/ui/const-generics/variant-discrimiant-no-generics.rs
@@ -0,0 +1,32 @@
+// revisions: full min
+
+#![cfg_attr(full, feature(generic_const_exprs))]
+#![cfg_attr(full, allow(incomplete_features))]
+
+enum Foo<const N: isize> {
+ Variant = N,
+ //~^ ERROR: generic parameters may not be used in enum discriminant values
+}
+
+enum Owo<const N: isize> {
+ Variant = { N + 1 },
+ //~^ ERROR: generic parameters may not be used in enum discriminant values
+}
+
+#[repr(isize)]
+enum Bar<T> {
+ Variant = { std::mem::size_of::<T>() as isize },
+ Other(T), //~^ ERROR: generic parameters may not be used in enum discriminant values
+}
+
+#[repr(isize)]
+enum UwU<'a> {
+ Variant = {
+ let a: &'a ();
+ //~^ ERROR: generic parameters may not be used in enum discriminant values
+ 10_isize
+ },
+ Other(&'a ()),
+}
+
+fn main() {}
diff --git a/tests/ui/const-ptr/out_of_bounds_read.rs b/tests/ui/const-ptr/out_of_bounds_read.rs
index 9dd669180da..a371aa93c5e 100644
--- a/tests/ui/const-ptr/out_of_bounds_read.rs
+++ b/tests/ui/const-ptr/out_of_bounds_read.rs
@@ -1,7 +1,5 @@
// error-pattern: evaluation of constant value failed
-#![feature(const_ptr_read)]
-
fn main() {
use std::ptr;
diff --git a/tests/ui/const-ptr/out_of_bounds_read.stderr b/tests/ui/const-ptr/out_of_bounds_read.stderr
index 89536f53f08..c5c0a1cdefc 100644
--- a/tests/ui/const-ptr/out_of_bounds_read.stderr
+++ b/tests/ui/const-ptr/out_of_bounds_read.stderr
@@ -6,7 +6,7 @@ error[E0080]: evaluation of constant value failed
note: inside `std::ptr::read::<u32>`
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
note: inside `_READ`
- --> $DIR/out_of_bounds_read.rs:12:33
+ --> $DIR/out_of_bounds_read.rs:10:33
|
LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -21,7 +21,7 @@ note: inside `std::ptr::read::<u32>`
note: inside `ptr::const_ptr::<impl *const u32>::read`
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
note: inside `_CONST_READ`
- --> $DIR/out_of_bounds_read.rs:13:39
+ --> $DIR/out_of_bounds_read.rs:11:39
|
LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
| ^^^^^^^^^^^^^^^^^^^
@@ -36,7 +36,7 @@ note: inside `std::ptr::read::<u32>`
note: inside `ptr::mut_ptr::<impl *mut u32>::read`
--> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
note: inside `_MUT_READ`
- --> $DIR/out_of_bounds_read.rs:14:37
+ --> $DIR/out_of_bounds_read.rs:12:37
|
LL | const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr
index 70a1abb0a95..434b0744304 100644
--- a/tests/ui/consts/const-eval/format.stderr
+++ b/tests/ui/consts/const-eval/format.stderr
@@ -43,62 +43,6 @@ LL | println!("{:?}", 0);
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
-note: erroneous constant used
- --> $DIR/format.rs:2:12
- |
-LL | panic!("{:?}", 0);
- | ^^^^^^
-
-note: erroneous constant used
- --> $DIR/format.rs:2:12
- |
-LL | panic!("{:?}", 0);
- | ^^^^^^
-
-note: erroneous constant used
- --> $DIR/format.rs:2:20
- |
-LL | panic!("{:?}", 0);
- | ^
- |
- = note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-note: erroneous constant used
- --> $DIR/format.rs:2:20
- |
-LL | panic!("{:?}", 0);
- | ^
- |
- = note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-note: erroneous constant used
- --> $DIR/format.rs:8:14
- |
-LL | println!("{:?}", 0);
- | ^^^^^^
-
-note: erroneous constant used
- --> $DIR/format.rs:8:14
- |
-LL | println!("{:?}", 0);
- | ^^^^^^
-
-note: erroneous constant used
- --> $DIR/format.rs:8:22
- |
-LL | println!("{:?}", 0);
- | ^
- |
- = note: this note 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)
-
-note: erroneous constant used
- --> $DIR/format.rs:8:22
- |
-LL | println!("{:?}", 0);
- | ^
- |
- = note: this note 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 5 previous errors
For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.rs b/tests/ui/consts/const-eval/ub-ref-ptr.rs
index 369e4519407..a5d2ea01486 100644
--- a/tests/ui/consts/const-eval/ub-ref-ptr.rs
+++ b/tests/ui/consts/const-eval/ub-ref-ptr.rs
@@ -3,7 +3,6 @@
// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP"
#![allow(invalid_value)]
-#![feature(const_ptr_read)]
use std::mem;
diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr
index 080568b51ef..1d19dfff50b 100644
--- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr
+++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr
@@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:16:1
+ --> $DIR/ub-ref-ptr.rs:15:1
|
LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1)
@@ -10,7 +10,7 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:20:1
+ --> $DIR/ub-ref-ptr.rs:19:1
|
LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1)
@@ -21,7 +21,7 @@ LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:24:1
+ --> $DIR/ub-ref-ptr.rs:23:1
|
LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference
@@ -32,7 +32,7 @@ LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:27:1
+ --> $DIR/ub-ref-ptr.rs:26:1
|
LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null box
@@ -43,7 +43,7 @@ LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
}
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:34:1
+ --> $DIR/ub-ref-ptr.rs:33:1
|
LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -52,7 +52,7 @@ LL | const REF_AS_USIZE: usize = 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]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:37:39
+ --> $DIR/ub-ref-ptr.rs:36:39
|
LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -61,13 +61,13 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
note: erroneous constant used
- --> $DIR/ub-ref-ptr.rs:37:38
+ --> $DIR/ub-ref-ptr.rs:36:38
|
LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:40:86
+ --> $DIR/ub-ref-ptr.rs:39:86
|
LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
| ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -76,13 +76,13 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
note: erroneous constant used
- --> $DIR/ub-ref-ptr.rs:40:85
+ --> $DIR/ub-ref-ptr.rs:39:85
|
LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
| ^^^^^^^^^^^^^^^^^^^^^
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:43:1
+ --> $DIR/ub-ref-ptr.rs:42:1
|
LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (0x539[noalloc] has no provenance)
@@ -93,7 +93,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:46:1
+ --> $DIR/ub-ref-ptr.rs:45:1
|
LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (0x539[noalloc] has no provenance)
@@ -104,13 +104,13 @@ LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
}
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:49:41
+ --> $DIR/ub-ref-ptr.rs:48:41
|
LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:53:1
+ --> $DIR/ub-ref-ptr.rs:52:1
|
LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer
@@ -121,13 +121,13 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
}
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:55:38
+ --> $DIR/ub-ref-ptr.rs:54:38
|
LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:58:1
+ --> $DIR/ub-ref-ptr.rs:57:1
|
LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer
@@ -138,7 +138,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:60:1
+ --> $DIR/ub-ref-ptr.rs:59:1
|
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer
@@ -158,7 +158,7 @@ note: inside `std::ptr::read::<u32>`
note: inside `ptr::const_ptr::<impl *const u32>::read`
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
note: inside `UNALIGNED_READ`
- --> $DIR/ub-ref-ptr.rs:67:5
+ --> $DIR/ub-ref-ptr.rs:66:5
|
LL | ptr.read();
| ^^^^^^^^^^
diff --git a/tests/ui/consts/const-integer-bool-ops.rs b/tests/ui/consts/const-integer-bool-ops.rs
index 4110ae3e456..35915a7a606 100644
--- a/tests/ui/consts/const-integer-bool-ops.rs
+++ b/tests/ui/consts/const-integer-bool-ops.rs
@@ -6,7 +6,6 @@ const X: usize = 42 && 39;
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR: [i32; X] = [99; 34];
-//~^ constant
const X1: usize = 42 || 39;
//~^ ERROR mismatched types
@@ -16,7 +15,6 @@ const X1: usize = 42 || 39;
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR1: [i32; X1] = [99; 47];
-//~^ constant
const X2: usize = -42 || -39;
//~^ ERROR mismatched types
@@ -26,7 +24,6 @@ const X2: usize = -42 || -39;
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR2: [i32; X2] = [99; 18446744073709551607];
-//~^ constant
const X3: usize = -42 && -39;
//~^ ERROR mismatched types
@@ -36,43 +33,36 @@ const X3: usize = -42 && -39;
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR3: [i32; X3] = [99; 6];
-//~^ constant
const Y: usize = 42.0 == 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR: [i32; Y] = [99; 1];
-//~^ constant
const Y1: usize = 42.0 >= 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR1: [i32; Y1] = [99; 1];
-//~^ constant
const Y2: usize = 42.0 <= 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR2: [i32; Y2] = [99; 1];
-//~^ constant
const Y3: usize = 42.0 > 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR3: [i32; Y3] = [99; 0];
-//~^ constant
const Y4: usize = 42.0 < 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR4: [i32; Y4] = [99; 0];
-//~^ constant
const Y5: usize = 42.0 != 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR5: [i32; Y5] = [99; 0];
-//~^ constant
fn main() {
let _ = ARR;
diff --git a/tests/ui/consts/const-integer-bool-ops.stderr b/tests/ui/consts/const-integer-bool-ops.stderr
index b5c3b22fdbe..4e503e5a5c0 100644
--- a/tests/ui/consts/const-integer-bool-ops.stderr
+++ b/tests/ui/consts/const-integer-bool-ops.stderr
@@ -16,156 +16,96 @@ error[E0308]: mismatched types
LL | const X: usize = 42 && 39;
| ^^^^^^^^ expected `usize`, found `bool`
-note: erroneous constant used
- --> $DIR/const-integer-bool-ops.rs:8:18
- |
-LL | const ARR: [i32; X] = [99; 34];
- | ^
-
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:11:19
+ --> $DIR/const-integer-bool-ops.rs:10:19
|
LL | const X1: usize = 42 || 39;
| ^^ expected `bool`, found integer
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:11:25
+ --> $DIR/const-integer-bool-ops.rs:10:25
|
LL | const X1: usize = 42 || 39;
| ^^ expected `bool`, found integer
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:11:19
+ --> $DIR/const-integer-bool-ops.rs:10:19
|
LL | const X1: usize = 42 || 39;
| ^^^^^^^^ expected `usize`, found `bool`
-note: erroneous constant used
- --> $DIR/const-integer-bool-ops.rs:18:19
- |
-LL | const ARR1: [i32; X1] = [99; 47];
- | ^^
-
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:21:19
+ --> $DIR/const-integer-bool-ops.rs:19:19
|
LL | const X2: usize = -42 || -39;
| ^^^ expected `bool`, found integer
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:21:26
+ --> $DIR/const-integer-bool-ops.rs:19:26
|
LL | const X2: usize = -42 || -39;
| ^^^ expected `bool`, found integer
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:21:19
+ --> $DIR/const-integer-bool-ops.rs:19:19
|
LL | const X2: usize = -42 || -39;
| ^^^^^^^^^^ expected `usize`, found `bool`
-note: erroneous constant used
- --> $DIR/const-integer-bool-ops.rs:28:19
- |
-LL | const ARR2: [i32; X2] = [99; 18446744073709551607];
- | ^^
-
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:31:19
+ --> $DIR/const-integer-bool-ops.rs:28:19
|
LL | const X3: usize = -42 && -39;
| ^^^ expected `bool`, found integer
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:31:26
+ --> $DIR/const-integer-bool-ops.rs:28:26
|
LL | const X3: usize = -42 && -39;
| ^^^ expected `bool`, found integer
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:31:19
+ --> $DIR/const-integer-bool-ops.rs:28:19
|
LL | const X3: usize = -42 && -39;
| ^^^^^^^^^^ expected `usize`, found `bool`
-note: erroneous constant used
- --> $DIR/const-integer-bool-ops.rs:38:19
- |
-LL | const ARR3: [i32; X3] = [99; 6];
- | ^^
-
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:41:18
+ --> $DIR/const-integer-bool-ops.rs:37:18
|
LL | const Y: usize = 42.0 == 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`
-note: erroneous constant used
- --> $DIR/const-integer-bool-ops.rs:44:19
- |
-LL | const ARRR: [i32; Y] = [99; 1];
- | ^
-
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:47:19
+ --> $DIR/const-integer-bool-ops.rs:42:19
|
LL | const Y1: usize = 42.0 >= 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`
-note: erroneous constant used
- --> $DIR/const-integer-bool-ops.rs:50:20
- |
-LL | const ARRR1: [i32; Y1] = [99; 1];
- | ^^
-
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:53:19
+ --> $DIR/const-integer-bool-ops.rs:47:19
|
LL | const Y2: usize = 42.0 <= 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`
-note: erroneous constant used
- --> $DIR/const-integer-bool-ops.rs:56:20
- |
-LL | const ARRR2: [i32; Y2] = [99; 1];
- | ^^
-
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:59:19
+ --> $DIR/const-integer-bool-ops.rs:52:19
|
LL | const Y3: usize = 42.0 > 42.0;
| ^^^^^^^^^^^ expected `usize`, found `bool`
-note: erroneous constant used
- --> $DIR/const-integer-bool-ops.rs:62:20
- |
-LL | const ARRR3: [i32; Y3] = [99; 0];
- | ^^
-
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:65:19
+ --> $DIR/const-integer-bool-ops.rs:57:19
|
LL | const Y4: usize = 42.0 < 42.0;
| ^^^^^^^^^^^ expected `usize`, found `bool`
-note: erroneous constant used
- --> $DIR/const-integer-bool-ops.rs:68:20
- |
-LL | const ARRR4: [i32; Y4] = [99; 0];
- | ^^
-
error[E0308]: mismatched types
- --> $DIR/const-integer-bool-ops.rs:71:19
+ --> $DIR/const-integer-bool-ops.rs:62:19
|
LL | const Y5: usize = 42.0 != 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`
-note: erroneous constant used
- --> $DIR/const-integer-bool-ops.rs:74:20
- |
-LL | const ARRR5: [i32; Y5] = [99; 0];
- | ^^
-
error: aborting due to 18 previous errors
For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr b/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr
index 109d15a8e4d..61b00be345f 100644
--- a/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr
+++ b/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr
@@ -19,12 +19,6 @@ error[E0596]: cannot borrow data in a `&` reference as mutable
LL | const S: &'static mut str = &mut " hello ";
| ^^^^^^^^^^^^^^ cannot borrow as mutable
-note: erroneous constant used
- --> $DIR/issue-76510.rs:11:70
- |
-LL | let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3));
- | ^
-
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0596, E0658, E0764.
diff --git a/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr b/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr
index 109d15a8e4d..61b00be345f 100644
--- a/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr
+++ b/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr
@@ -19,12 +19,6 @@ error[E0596]: cannot borrow data in a `&` reference as mutable
LL | const S: &'static mut str = &mut " hello ";
| ^^^^^^^^^^^^^^ cannot borrow as mutable
-note: erroneous constant used
- --> $DIR/issue-76510.rs:11:70
- |
-LL | let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3));
- | ^
-
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0596, E0658, E0764.
diff --git a/tests/ui/consts/const-mut-refs/issue-76510.rs b/tests/ui/consts/const-mut-refs/issue-76510.rs
index b853e2737f1..143d2fb6b9a 100644
--- a/tests/ui/consts/const-mut-refs/issue-76510.rs
+++ b/tests/ui/consts/const-mut-refs/issue-76510.rs
@@ -9,7 +9,6 @@ const S: &'static mut str = &mut " hello ";
const fn trigger() -> [(); unsafe {
let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3));
- //~^ constant
0
}] {
[(); 0]
diff --git a/tests/ui/consts/const-tup-index-span.rs b/tests/ui/consts/const-tup-index-span.rs
index 18f4f59d378..e77d392e694 100644
--- a/tests/ui/consts/const-tup-index-span.rs
+++ b/tests/ui/consts/const-tup-index-span.rs
@@ -4,7 +4,6 @@ const TUP: (usize,) = 5usize << 64;
//~^ ERROR mismatched types
//~| expected `(usize,)`, found `usize`
const ARR: [i32; TUP.0] = [];
-//~^ constant
fn main() {
}
diff --git a/tests/ui/consts/const-tup-index-span.stderr b/tests/ui/consts/const-tup-index-span.stderr
index 65f0520f8a4..d5df0df9525 100644
--- a/tests/ui/consts/const-tup-index-span.stderr
+++ b/tests/ui/consts/const-tup-index-span.stderr
@@ -11,12 +11,6 @@ help: use a trailing comma to create a tuple with one element
LL | const TUP: (usize,) = (5usize << 64,);
| + ++
-note: erroneous constant used
- --> $DIR/const-tup-index-span.rs:6:18
- |
-LL | const ARR: [i32; TUP.0] = [];
- | ^^^
-
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/consts/const_forget.rs b/tests/ui/consts/const_forget.rs
index ec7dde8c9ec..acdd6a54cf4 100644
--- a/tests/ui/consts/const_forget.rs
+++ b/tests/ui/consts/const_forget.rs
@@ -1,5 +1,7 @@
// check-pass
+#![allow(forget_copy)]
+
use std::mem::forget;
const _: () = forget(0i32);
diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.rs b/tests/ui/consts/extra-const-ub/detect-extra-ub.rs
index e2f8149883b..6a3c93ce7a6 100644
--- a/tests/ui/consts/extra-const-ub/detect-extra-ub.rs
+++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.rs
@@ -1,7 +1,6 @@
// 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;
diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
index b2a5fd90149..3970baefcb3 100644
--- a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
+++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
@@ -1,11 +1,11 @@
error[E0080]: evaluation of constant value failed
- --> $DIR/detect-extra-ub.rs:9:20
+ --> $DIR/detect-extra-ub.rs:8:20
|
LL | let _x: bool = transmute(3u8);
| ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean
error[E0080]: evaluation of constant value failed
- --> $DIR/detect-extra-ub.rs:15:21
+ --> $DIR/detect-extra-ub.rs:14:21
|
LL | let _x: usize = transmute(&3u8);
| ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -14,7 +14,7 @@ LL | let _x: usize = transmute(&3u8);
= 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:21:30
+ --> $DIR/detect-extra-ub.rs:20:30
|
LL | let _x: (usize, usize) = transmute(x);
| ^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -23,7 +23,7 @@ LL | let _x: (usize, usize) = transmute(x);
= 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:26:20
+ --> $DIR/detect-extra-ub.rs:25:20
|
LL | let _x: &u32 = transmute(&[0u8; 4]);
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1)
diff --git a/tests/ui/consts/issue-104155.rs b/tests/ui/consts/issue-104155.rs
index 1cc8f81b0d2..b3821f467b6 100644
--- a/tests/ui/consts/issue-104155.rs
+++ b/tests/ui/consts/issue-104155.rs
@@ -1,4 +1,7 @@
// check-pass
+
+#![allow(forget_copy)]
+
const _: () = core::mem::forget(Box::<u32>::default);
const _: () = core::mem::forget(|| Box::<u32>::default());
diff --git a/tests/ui/consts/issue-54954.rs b/tests/ui/consts/issue-54954.rs
index 520bf508ff3..7bcfa057019 100644
--- a/tests/ui/consts/issue-54954.rs
+++ b/tests/ui/consts/issue-54954.rs
@@ -9,8 +9,6 @@ trait Tt {
}
fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
- //~^ constant
- //~| constant
z
}
diff --git a/tests/ui/consts/issue-54954.stderr b/tests/ui/consts/issue-54954.stderr
index 85055828737..b0701bab793 100644
--- a/tests/ui/consts/issue-54954.stderr
+++ b/tests/ui/consts/issue-54954.stderr
@@ -16,18 +16,6 @@ LL | | core::mem::size_of::<T>()
LL | | }
| |_____- `Tt::const_val` defined here
-note: erroneous constant used
- --> $DIR/issue-54954.rs:11:15
- |
-LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
- | ^^^^^^^
-
-note: erroneous constant used
- --> $DIR/issue-54954.rs:11:34
- |
-LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
- | ^^^^^^^
-
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0379, E0790.
diff --git a/tests/ui/consts/issue-56164.stderr b/tests/ui/consts/issue-56164.stderr
index 003f8474463..e46c649faf0 100644
--- a/tests/ui/consts/issue-56164.stderr
+++ b/tests/ui/consts/issue-56164.stderr
@@ -28,18 +28,6 @@ error: function pointer calls are not allowed in constant functions
LL | input()
| ^^^^^^^
-note: erroneous constant used
- --> $DIR/issue-56164.rs:1:18
- |
-LL | const fn foo() { (||{})() }
- | ^^^^^^
-
-note: erroneous constant used
- --> $DIR/issue-56164.rs:1:18
- |
-LL | const fn foo() { (||{})() }
- | ^^^^^^
-
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0015, E0277.
diff --git a/tests/ui/consts/issue-66693.stderr b/tests/ui/consts/issue-66693.stderr
index e9a3fced61c..f4898fd9732 100644
--- a/tests/ui/consts/issue-66693.stderr
+++ b/tests/ui/consts/issue-66693.stderr
@@ -22,17 +22,5 @@ LL | panic!(&1);
|
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
-note: erroneous constant used
- --> $DIR/issue-66693.rs:11:12
- |
-LL | panic!(&1);
- | ^^
-
-note: erroneous constant used
- --> $DIR/issue-66693.rs:11:12
- |
-LL | panic!(&1);
- | ^^
-
error: aborting due to 3 previous errors
diff --git a/tests/ui/consts/issue-miri-1910.rs b/tests/ui/consts/issue-miri-1910.rs
index 29e0ea95026..3798332dfd7 100644
--- a/tests/ui/consts/issue-miri-1910.rs
+++ b/tests/ui/consts/issue-miri-1910.rs
@@ -1,6 +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 {
let foo = Some(&42 as *const i32);
diff --git a/tests/ui/consts/issue-miri-1910.stderr b/tests/ui/consts/issue-miri-1910.stderr
index a10eea9de11..fb758d406b5 100644
--- a/tests/ui/consts/issue-miri-1910.stderr
+++ b/tests/ui/consts/issue-miri-1910.stderr
@@ -10,7 +10,7 @@ note: inside `std::ptr::read::<u8>`
note: inside `ptr::const_ptr::<impl *const u8>::read`
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
note: inside `C`
- --> $DIR/issue-miri-1910.rs:8:5
+ --> $DIR/issue-miri-1910.rs:7:5
|
LL | (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/crate-leading-sep.rs b/tests/ui/crate-leading-sep.rs
index ca5905fab41..8d1d0b4fcdf 100644
--- a/tests/ui/crate-leading-sep.rs
+++ b/tests/ui/crate-leading-sep.rs
@@ -1,6 +1,8 @@
// run-pass
// pretty-expanded FIXME #23616
+#![allow(drop_copy)]
+
fn main() {
use ::std::mem;
mem::drop(2_usize);
diff --git a/tests/ui/custom_test_frameworks/mismatch.stderr b/tests/ui/custom_test_frameworks/mismatch.stderr
index 61061ae529d..31b18b2df98 100644
--- a/tests/ui/custom_test_frameworks/mismatch.stderr
+++ b/tests/ui/custom_test_frameworks/mismatch.stderr
@@ -6,7 +6,7 @@ LL | #[test]
LL | fn wrong_kind(){}
| ^^^^^^^^^^^^^^^^^ the trait `Testable` is not implemented for `TestDescAndFn`
|
- = note: required for the cast from `TestDescAndFn` to the object type `dyn Testable`
+ = note: required for the cast from `&TestDescAndFn` to `&dyn Testable`
= note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
diff --git a/tests/ui/issues/issue-12511.rs b/tests/ui/cycle-trait/issue-12511.rs
index ea83e3fd9dc..ea83e3fd9dc 100644
--- a/tests/ui/issues/issue-12511.rs
+++ b/tests/ui/cycle-trait/issue-12511.rs
diff --git a/tests/ui/issues/issue-12511.stderr b/tests/ui/cycle-trait/issue-12511.stderr
index 558aad10946..558aad10946 100644
--- a/tests/ui/issues/issue-12511.stderr
+++ b/tests/ui/cycle-trait/issue-12511.stderr
diff --git a/tests/ui/issues/issue-15689-1.rs b/tests/ui/deriving/issue-15689-1.rs
index d143926b281..d143926b281 100644
--- a/tests/ui/issues/issue-15689-1.rs
+++ b/tests/ui/deriving/issue-15689-1.rs
diff --git a/tests/ui/issues/issue-15689-2.rs b/tests/ui/deriving/issue-15689-2.rs
index 83dcb1406f8..83dcb1406f8 100644
--- a/tests/ui/issues/issue-15689-2.rs
+++ b/tests/ui/deriving/issue-15689-2.rs
diff --git a/tests/ui/diagnostic-width/E0271.stderr b/tests/ui/diagnostic-width/E0271.stderr
index ed7b6651d01..52f415037d3 100644
--- a/tests/ui/diagnostic-width/E0271.stderr
+++ b/tests/ui/diagnostic-width/E0271.stderr
@@ -15,8 +15,8 @@ note: expected this to be `Foo`
|
LL | type Error = E;
| ^
- = note: required for the cast from `Result<Result<..., ...>, ...>` to the object type `dyn Future<Error = Foo>`
- = note: the full name for the casted type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271/E0271.long-type-hash.txt'
+ = note: required for the cast from `Box<Result<..., ...>>` to `Box<(dyn Future<Error = Foo> + 'static)>`
+ = note: the full name for the source type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271/E0271.long-type-hash.txt'
error: aborting due to previous error
diff --git a/tests/ui/did_you_mean/issue-38147-4.stderr b/tests/ui/did_you_mean/issue-38147-4.stderr
index d3339989361..43647fa562b 100644
--- a/tests/ui/did_you_mean/issue-38147-4.stderr
+++ b/tests/ui/did_you_mean/issue-38147-4.stderr
@@ -6,8 +6,8 @@ LL | f.s.push('x');
|
help: consider changing this to be a mutable reference
|
-LL | fn f(x: usize, f: &mut Foo<'_>) {
- | ~~~~~~~~~~~~
+LL | fn f(x: usize, f: &mut Foo) {
+ | +++
error: aborting due to previous error
diff --git a/tests/ui/did_you_mean/issue-39544.stderr b/tests/ui/did_you_mean/issue-39544.stderr
index 8dc0512a945..8ccb4cbb0c1 100644
--- a/tests/ui/did_you_mean/issue-39544.stderr
+++ b/tests/ui/did_you_mean/issue-39544.stderr
@@ -40,7 +40,7 @@ LL | let _ = &mut other.x;
help: consider changing this to be a mutable reference
|
LL | fn foo1(&self, other: &mut Z) {
- | ~~~~~~
+ | +++
error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:25:17
@@ -62,7 +62,7 @@ LL | let _ = &mut other.x;
help: consider changing this to be a mutable reference
|
LL | fn foo2<'a>(&'a self, other: &mut Z) {
- | ~~~~~~
+ | +++
error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:30:17
@@ -73,7 +73,7 @@ LL | let _ = &mut self.x;
help: consider changing this to be a mutable reference
|
LL | fn foo3<'a>(self: &'a mut Self, other: &Z) {
- | ~~~~~~~~~~~~
+ | +++
error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:31:17
@@ -84,7 +84,7 @@ LL | let _ = &mut other.x;
help: consider changing this to be a mutable reference
|
LL | fn foo3<'a>(self: &'a Self, other: &mut Z) {
- | ~~~~~~
+ | +++
error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:35:17
@@ -95,7 +95,7 @@ LL | let _ = &mut other.x;
help: consider changing this to be a mutable reference
|
LL | fn foo4(other: &mut Z) {
- | ~~~~~~
+ | +++
error[E0596]: cannot borrow `z.x` as mutable, as `z` is not declared as mutable
--> $DIR/issue-39544.rs:41:13
@@ -117,7 +117,7 @@ LL | let _ = &mut w.x;
help: consider changing this to be a mutable reference
|
LL | pub fn with_arg(z: Z, w: &mut Z) {
- | ~~~~~~
+ | +++
error[E0594]: cannot assign to `*x.0`, which is behind a `&` reference
--> $DIR/issue-39544.rs:48:5
diff --git a/tests/ui/did_you_mean/issue-40823.stderr b/tests/ui/did_you_mean/issue-40823.stderr
index aadd698891e..ba94a570256 100644
--- a/tests/ui/did_you_mean/issue-40823.stderr
+++ b/tests/ui/did_you_mean/issue-40823.stderr
@@ -7,7 +7,7 @@ LL | buf.iter_mut();
help: consider changing this to be a mutable reference
|
LL | let mut buf = &mut [1, 2, 3, 4];
- | ~~~~~~~~~~~~~~~~~
+ | +++
error: aborting due to previous error
diff --git a/tests/ui/drop/dropck-eyepatch-manuallydrop.rs b/tests/ui/drop/dropck-eyepatch-manuallydrop.rs
new file mode 100644
index 00000000000..ff100cd941f
--- /dev/null
+++ b/tests/ui/drop/dropck-eyepatch-manuallydrop.rs
@@ -0,0 +1,22 @@
+// check-pass
+//! This test checks that dropck knows that ManuallyDrop does not drop its field.
+#![feature(dropck_eyepatch)]
+
+use std::mem::ManuallyDrop;
+
+struct S<T>(ManuallyDrop<T>);
+
+unsafe impl<#[may_dangle] T> Drop for S<T> {
+ fn drop(&mut self) {}
+}
+
+struct NonTrivialDrop<'a>(&'a str);
+impl<'a> Drop for NonTrivialDrop<'a> {
+ fn drop(&mut self) {}
+}
+
+fn main() {
+ let s = String::from("string");
+ let _t = S(ManuallyDrop::new(NonTrivialDrop(&s)));
+ drop(s);
+}
diff --git a/tests/ui/drop/issue-110682.rs b/tests/ui/drop/issue-110682.rs
new file mode 100644
index 00000000000..35f9c7e8d9b
--- /dev/null
+++ b/tests/ui/drop/issue-110682.rs
@@ -0,0 +1,92 @@
+// build-pass
+// compile-flags: -Zmir-opt-level=3
+
+use std::fmt::Debug;
+use std::mem::ManuallyDrop;
+use std::ptr;
+
+pub trait BitRegister {}
+
+macro_rules! register {
+ ($($t:ty),+ $(,)?) => { $(
+ impl BitRegister for $t {
+ }
+ )* };
+}
+
+register!(u8, u16, u32);
+
+pub trait BitStore: Sized + Debug {
+ /// The register type that the implementor describes.
+ type Mem: BitRegister + Into<Self>;
+}
+
+macro_rules! store {
+ ($($t:ty),+ $(,)?) => { $(
+ impl BitStore for $t {
+ type Mem = Self;
+ }
+ )+ };
+}
+
+store!(u8, u16, u32,);
+
+#[repr(C)]
+pub struct BitVec<T>
+where
+ T: BitStore,
+{
+ /// Region pointer describing the live portion of the owned buffer.
+ pointer: ptr::NonNull<T>,
+ /// Allocated capacity, in elements `T`, of the owned buffer.
+ capacity: usize,
+}
+
+impl<T> BitVec<T>
+where
+ T: BitStore,
+{
+ pub fn new() -> Self {
+ let pointer = ptr::NonNull::<T>::new(ptr::null_mut()).unwrap();
+
+ BitVec { pointer, capacity: 10 }
+ }
+
+ pub fn clear(&mut self) {
+ unsafe {
+ self.set_len(0);
+ }
+ }
+
+ #[inline]
+ pub unsafe fn set_len(&mut self, new_len: usize) {}
+
+ fn with_vec<F, R>(&mut self, func: F) -> R
+ where
+ F: FnOnce(&mut ManuallyDrop<Vec<T::Mem>>) -> R,
+ {
+ let cap = self.capacity;
+ let elts = 10;
+ let mut vec = ManuallyDrop::new(unsafe { Vec::from_raw_parts(ptr::null_mut(), elts, cap) });
+ let out = func(&mut vec);
+
+ out
+ }
+}
+
+impl<T> Drop for BitVec<T>
+where
+ T: BitStore,
+{
+ #[inline]
+ fn drop(&mut self) {
+ // The buffer elements do not have destructors.
+ self.clear();
+ // Run the `Vec` destructor to deällocate the buffer.
+ self.with_vec(|vec| unsafe { ManuallyDrop::drop(vec) });
+ }
+}
+
+fn main() {
+ let bitvec = BitVec::<u32>::new();
+}
diff --git a/tests/ui/issues/issue-979.rs b/tests/ui/drop/issue-979.rs
index 57a99b325ad..57a99b325ad 100644
--- a/tests/ui/issues/issue-979.rs
+++ b/tests/ui/drop/issue-979.rs
diff --git a/tests/ui/drop/repeat-drop.rs b/tests/ui/drop/repeat-drop.rs
index 8fd46ecaf44..659d35db657 100644
--- a/tests/ui/drop/repeat-drop.rs
+++ b/tests/ui/drop/repeat-drop.rs
@@ -1,6 +1,8 @@
// run-pass
// needs-unwind
+#![allow(drop_ref, drop_copy)]
+
static mut CHECK: usize = 0;
struct DropChecker(usize);
diff --git a/tests/ui/dst/dst-bad-coerce1.stderr b/tests/ui/dst/dst-bad-coerce1.stderr
index ff77bd4cef8..2c75518c298 100644
--- a/tests/ui/dst/dst-bad-coerce1.stderr
+++ b/tests/ui/dst/dst-bad-coerce1.stderr
@@ -15,7 +15,7 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied
LL | let f3: &Fat<dyn Bar> = f2;
| ^^ the trait `Bar` is not implemented for `Foo`
|
- = note: required for the cast from `Foo` to the object type `dyn Bar`
+ = note: required for the cast from `&Fat<Foo>` to `&Fat<dyn Bar>`
error[E0308]: mismatched types
--> $DIR/dst-bad-coerce1.rs:28:27
@@ -34,7 +34,7 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied
LL | let f3: &(dyn Bar,) = f2;
| ^^ the trait `Bar` is not implemented for `Foo`
|
- = note: required for the cast from `Foo` to the object type `dyn Bar`
+ = note: required for the cast from `&(Foo,)` to `&(dyn Bar,)`
error: aborting due to 4 previous errors
diff --git a/tests/ui/dst/dst-object-from-unsized-type.stderr b/tests/ui/dst/dst-object-from-unsized-type.stderr
index e24c96ebed6..d5e464aed4b 100644
--- a/tests/ui/dst/dst-object-from-unsized-type.stderr
+++ b/tests/ui/dst/dst-object-from-unsized-type.stderr
@@ -6,7 +6,7 @@ LL | fn test1<T: ?Sized + Foo>(t: &T) {
LL | let u: &dyn Foo = t;
| ^ doesn't have a size known at compile-time
|
- = note: required for the cast from `T` to the object type `dyn Foo`
+ = note: required for the cast from `&T` to `&dyn Foo`
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - fn test1<T: ?Sized + Foo>(t: &T) {
@@ -21,7 +21,7 @@ LL | fn test2<T: ?Sized + Foo>(t: &T) {
LL | let v: &dyn Foo = t as &dyn Foo;
| ^ doesn't have a size known at compile-time
|
- = note: required for the cast from `T` to the object type `dyn Foo`
+ = note: required for the cast from `&T` to `&dyn Foo`
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - fn test2<T: ?Sized + Foo>(t: &T) {
@@ -35,7 +35,7 @@ LL | let _: &[&dyn Foo] = &["hi"];
| ^^^^ 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 Foo`
+ = note: required for the cast from `&'static str` to `&dyn Foo`
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/dst-object-from-unsized-type.rs:23:23
@@ -44,7 +44,7 @@ LL | let _: &dyn Foo = x as &dyn Foo;
| ^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
- = note: required for the cast from `[u8]` to the object type `dyn Foo`
+ = note: required for the cast from `&[u8]` to `&dyn Foo`
error: aborting due to 4 previous errors
diff --git a/tests/ui/dupe-first-attr.rc b/tests/ui/dupe-first-attr.rs
index 8b7025b7be7..d950743b41c 100644
--- a/tests/ui/dupe-first-attr.rc
+++ b/tests/ui/dupe-first-attr.rs
@@ -1,24 +1,26 @@
+// run-pass
+
// Regression test for a problem with the first mod attribute
// being applied to every mod
// pretty-expanded FIXME #23616
#[cfg(target_os = "linux")]
-mod hello;
+mod hello {}
#[cfg(target_os = "macos")]
-mod hello;
+mod hello {}
#[cfg(target_os = "windows")]
-mod hello;
+mod hello {}
#[cfg(target_os = "freebsd")]
-mod hello;
+mod hello {}
#[cfg(target_os = "dragonfly")]
-mod hello;
+mod hello {}
#[cfg(target_os = "android")]
-mod hello;
+mod hello {}
-pub fn main() { }
+fn main() {}
diff --git a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.stderr b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.current.stderr
index 8726fae79a0..ba42f619a54 100644
--- a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.stderr
+++ b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.current.stderr
@@ -1,5 +1,5 @@
error[E0277]: `&T` needs to have the same ABI as a pointer
- --> $DIR/check-size-at-cast-polymorphic-bad.rs:11:15
+ --> $DIR/check-size-at-cast-polymorphic-bad.rs:14:15
|
LL | dyn_debug(t);
| ^ `&T` needs to be a pointer-like type
diff --git a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.next.stderr b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.next.stderr
new file mode 100644
index 00000000000..ba42f619a54
--- /dev/null
+++ b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.next.stderr
@@ -0,0 +1,15 @@
+error[E0277]: `&T` needs to have the same ABI as a pointer
+ --> $DIR/check-size-at-cast-polymorphic-bad.rs:14:15
+ |
+LL | dyn_debug(t);
+ | ^ `&T` needs to be a pointer-like type
+ |
+ = help: the trait `PointerLike` is not implemented for `&T`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+ |
+LL | fn polymorphic<T: Debug + ?Sized>(t: &T) where &T: PointerLike {
+ | +++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs
index 913c2faacbd..9846f871424 100644
--- a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs
+++ b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs
@@ -1,3 +1,6 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
#![feature(dyn_star)]
#![allow(incomplete_features)]
diff --git a/tests/ui/enum-discriminant/auxiliary/discr-foreign-dep.rs b/tests/ui/enum-discriminant/auxiliary/discr-foreign-dep.rs
new file mode 100644
index 00000000000..a2cc10a4b22
--- /dev/null
+++ b/tests/ui/enum-discriminant/auxiliary/discr-foreign-dep.rs
@@ -0,0 +1,7 @@
+#[derive(Default)]
+pub enum Foo {
+ A(u32),
+ #[default]
+ B,
+ C(u32),
+}
diff --git a/tests/ui/enum-discriminant/discr-foreign.rs b/tests/ui/enum-discriminant/discr-foreign.rs
new file mode 100644
index 00000000000..e7123b34452
--- /dev/null
+++ b/tests/ui/enum-discriminant/discr-foreign.rs
@@ -0,0 +1,11 @@
+// aux-build:discr-foreign-dep.rs
+// build-pass
+
+extern crate discr_foreign_dep;
+
+fn main() {
+ match Default::default() {
+ discr_foreign_dep::Foo::A(_) => {}
+ _ => {}
+ }
+}
diff --git a/tests/ui/enum-discriminant/issue-41394.rs b/tests/ui/enum-discriminant/issue-41394.rs
index 07cad8796e1..06a33081340 100644
--- a/tests/ui/enum-discriminant/issue-41394.rs
+++ b/tests/ui/enum-discriminant/issue-41394.rs
@@ -5,7 +5,6 @@ enum Foo {
enum Bar {
A = Foo::A as isize
- //~^ const
}
fn main() {}
diff --git a/tests/ui/enum-discriminant/issue-41394.stderr b/tests/ui/enum-discriminant/issue-41394.stderr
index 1b5c64628a1..fa95ca9c18a 100644
--- a/tests/ui/enum-discriminant/issue-41394.stderr
+++ b/tests/ui/enum-discriminant/issue-41394.stderr
@@ -6,12 +6,6 @@ LL | A = "" + 1
| |
| &str
-note: erroneous constant used
- --> $DIR/issue-41394.rs:7:9
- |
-LL | A = Foo::A as isize
- | ^^^^^^^^^^^^^^^
-
error: aborting due to previous error
For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs
index ad9fcc25b41..62137c0c8d3 100644
--- a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs
+++ b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs
@@ -7,7 +7,7 @@ use core::intrinsics::discriminant_value;
enum MyWeirdOption<T> {
None = 0,
Some(T) = std::mem::size_of::<T>(),
- //~^ ERROR generic parameters may not be used in const operations
+ //~^ ERROR generic parameters may not be used in enum discriminant values
}
fn main() {
diff --git a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr
index e4e10468d53..2cb159ee291 100644
--- a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr
+++ b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr
@@ -1,11 +1,10 @@
-error: generic parameters may not be used in const operations
+error: generic parameters may not be used in enum discriminant values
--> $DIR/issue-70453-generics-in-discr-ice-2.rs:9:35
|
LL | Some(T) = std::mem::size_of::<T>(),
| ^ cannot perform const operation using `T`
|
- = note: type parameters may not be used in const expressions
- = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+ = note: type parameters may not be used in enum discriminant values
error: aborting due to previous error
diff --git a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs
index a0fb788a510..093c57534a4 100644
--- a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs
+++ b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs
@@ -8,7 +8,7 @@ enum MyWeirdOption<T> {
//~^ ERROR parameter `T` is never used
None = 0,
Some = std::mem::size_of::<T>(),
- //~^ ERROR generic parameters may not be used in const operations
+ //~^ ERROR generic parameters may not be used in enum discriminant values
}
fn main() {
diff --git a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr
index 7ea8a39129e..fac3ce07aeb 100644
--- a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr
+++ b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr
@@ -1,11 +1,10 @@
-error: generic parameters may not be used in const operations
+error: generic parameters may not be used in enum discriminant values
--> $DIR/issue-70453-generics-in-discr-ice.rs:10:32
|
LL | Some = std::mem::size_of::<T>(),
| ^ cannot perform const operation using `T`
|
- = note: type parameters may not be used in const expressions
- = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+ = note: type parameters may not be used in enum discriminant values
error[E0392]: parameter `T` is never used
--> $DIR/issue-70453-generics-in-discr-ice.rs:7:20
diff --git a/tests/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr b/tests/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr
index 0a7a631606e..15cd6d30364 100644
--- a/tests/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr
+++ b/tests/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr
@@ -1,11 +1,10 @@
-error: generic parameters may not be used in const operations
+error: generic parameters may not be used in enum discriminant values
--> $DIR/issue-70453-polymorphic-ctfe.rs:9:41
|
LL | Some(T) = core::mem::size_of::<*mut T>(),
| ^ cannot perform const operation using `T`
|
- = note: type parameters may not be used in const expressions
- = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+ = note: type parameters may not be used in enum discriminant values
error: aborting due to previous error
diff --git a/tests/ui/issues/issue-1821.rs b/tests/ui/enum/issue-1821.rs
index 76ee9c3edb0..76ee9c3edb0 100644
--- a/tests/ui/issues/issue-1821.rs
+++ b/tests/ui/enum/issue-1821.rs
diff --git a/tests/ui/enum/issue-67945-1.stderr b/tests/ui/enum/issue-67945-1.stderr
index 8f1b5b38e4c..878fa322f02 100644
--- a/tests/ui/enum/issue-67945-1.stderr
+++ b/tests/ui/enum/issue-67945-1.stderr
@@ -1,11 +1,10 @@
-error: generic parameters may not be used in const operations
+error: generic parameters may not be used in enum discriminant values
--> $DIR/issue-67945-1.rs:3:16
|
LL | let x: S = 0;
| ^ cannot perform const operation using `S`
|
- = note: type parameters may not be used in const expressions
- = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+ = note: type parameters may not be used in enum discriminant values
error[E0392]: parameter `S` is never used
--> $DIR/issue-67945-1.rs:1:10
diff --git a/tests/ui/enum/issue-67945-2.stderr b/tests/ui/enum/issue-67945-2.stderr
index 63d3521afe4..f8ec12d470a 100644
--- a/tests/ui/enum/issue-67945-2.stderr
+++ b/tests/ui/enum/issue-67945-2.stderr
@@ -1,11 +1,10 @@
-error: generic parameters may not be used in const operations
+error: generic parameters may not be used in enum discriminant values
--> $DIR/issue-67945-2.rs:4:28
|
LL | Var = type_ascribe!(0, S),
| ^ cannot perform const operation using `S`
|
- = note: type parameters may not be used in const expressions
- = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+ = note: type parameters may not be used in enum discriminant values
error[E0392]: parameter `S` is never used
--> $DIR/issue-67945-2.rs:3:10
diff --git a/tests/ui/error-codes/E0389.stderr b/tests/ui/error-codes/E0389.stderr
index 51c4c92addf..e4001856c38 100644
--- a/tests/ui/error-codes/E0389.stderr
+++ b/tests/ui/error-codes/E0389.stderr
@@ -7,7 +7,7 @@ LL | fancy_ref.num = 6;
help: consider changing this to be a mutable reference
|
LL | let fancy_ref = &mut (&mut fancy);
- | ~~~~~~~~~~~~~~~~~
+ | +++
error: aborting due to previous error
diff --git a/tests/ui/error-codes/E0771.rs b/tests/ui/error-codes/E0771.rs
index 67e7d106a1f..c0a2e98a7df 100644
--- a/tests/ui/error-codes/E0771.rs
+++ b/tests/ui/error-codes/E0771.rs
@@ -1,7 +1,7 @@
#![feature(adt_const_params)]
//~^ WARN the feature `adt_const_params` is incomplete
-fn function_with_str<'a, const STRING: &'a str>() {} //~ ERROR E0771
+fn function_with_str<'a, const STRING: &'a str>() {} //~ ERROR E0770
fn main() {
function_with_str::<"Hello, world!">()
diff --git a/tests/ui/error-codes/E0771.stderr b/tests/ui/error-codes/E0771.stderr
index b759399a940..9450c61c27b 100644
--- a/tests/ui/error-codes/E0771.stderr
+++ b/tests/ui/error-codes/E0771.stderr
@@ -1,10 +1,10 @@
-error[E0771]: use of non-static lifetime `'a` in const generic
+error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/E0771.rs:4:41
|
LL | fn function_with_str<'a, const STRING: &'a str>() {}
- | ^^
+ | ^^ the type must not depend on the parameter `'a`
|
- = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
+ = note: lifetime parameters may not be used in the type of const parameters
warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/E0771.rs:1:12
@@ -17,4 +17,4 @@ LL | #![feature(adt_const_params)]
error: aborting due to previous error; 1 warning emitted
-For more information about this error, try `rustc --explain E0771`.
+For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed b/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed
index 47c4c9f67b6..0bc4feed329 100644
--- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed
+++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed
@@ -1,4 +1,7 @@
// run-rustfix
+
+#![allow(drop_ref)]
+
struct Foo {
x: isize
}
diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs b/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs
index c698de50c75..26ae6698d66 100644
--- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs
+++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs
@@ -1,4 +1,7 @@
// run-rustfix
+
+#![allow(drop_ref)]
+
struct Foo {
x: isize
}
diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr
index 7f5106eb57e..c7067117349 100644
--- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr
+++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr
@@ -1,5 +1,5 @@
error[E0040]: explicit use of destructor method
- --> $DIR/explicit-call-to-supertrait-dtor.rs:19:14
+ --> $DIR/explicit-call-to-supertrait-dtor.rs:22:14
|
LL | self.drop();
| -----^^^^--
diff --git a/tests/ui/extenv/extenv-escaped-var.rs b/tests/ui/extenv/extenv-escaped-var.rs
new file mode 100644
index 00000000000..d898feb78c6
--- /dev/null
+++ b/tests/ui/extenv/extenv-escaped-var.rs
@@ -0,0 +1,3 @@
+fn main() {
+ env!("\t"); //~ERROR environment variable `\t` not defined at compile time
+}
diff --git a/tests/ui/extenv/extenv-escaped-var.stderr b/tests/ui/extenv/extenv-escaped-var.stderr
new file mode 100644
index 00000000000..25e218c63f3
--- /dev/null
+++ b/tests/ui/extenv/extenv-escaped-var.stderr
@@ -0,0 +1,11 @@
+error: environment variable `\t` not defined at compile time
+ --> $DIR/extenv-escaped-var.rs:2:5
+ |
+LL | env!("\t");
+ | ^^^^^^^^^^
+ |
+ = help: use `std::env::var("\t")` to read the variable at run time
+ = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/tests/ui/extenv/issue-110547.stderr b/tests/ui/extenv/issue-110547.stderr
index 1219630d346..10589ec2f54 100644
--- a/tests/ui/extenv/issue-110547.stderr
+++ b/tests/ui/extenv/issue-110547.stderr
@@ -1,28 +1,28 @@
-error: environment variable ` ` not defined at compile time
+error: environment variable `\t` not defined at compile time
--> $DIR/issue-110547.rs:4:5
|
LL | env!{"\t"};
| ^^^^^^^^^^
|
- = help: use `std::env::var(" ")` to read the variable at run time
+ = help: use `std::env::var("\t")` to read the variable at run time
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: environment variable ` ` not defined at compile time
+error: environment variable `\t` not defined at compile time
--> $DIR/issue-110547.rs:5:5
|
LL | env!("\t");
| ^^^^^^^^^^
|
- = help: use `std::env::var(" ")` to read the variable at run time
+ = help: use `std::env::var("\t")` to read the variable at run time
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: environment variable `` not defined at compile time
+error: environment variable `\u{2069}` not defined at compile time
--> $DIR/issue-110547.rs:6:5
|
LL | env!("\u{2069}");
| ^^^^^^^^^^^^^^^^
|
- = help: use `std::env::var("")` to read the variable at run time
+ = help: use `std::env::var("\u{2069}")` to read the variable at run time
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 3 previous errors
diff --git a/tests/ui/extern/auxiliary/invalid-utf8.txt b/tests/ui/extern/auxiliary/invalid-utf8.txt
deleted file mode 100644
index dc1115b82db..00000000000
--- a/tests/ui/extern/auxiliary/invalid-utf8.txt
+++ /dev/null
@@ -1 +0,0 @@
-Ã( \ No newline at end of file
diff --git a/tests/ui/feature-gates/auxiliary/debugger-visualizer.natvis b/tests/ui/feature-gates/auxiliary/debugger-visualizer.natvis
deleted file mode 100644
index 6eb47e3d85b..00000000000
--- a/tests/ui/feature-gates/auxiliary/debugger-visualizer.natvis
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
-</AutoVisualizer>
diff --git a/tests/ui/feature-gates/feature-gate-builtin_syntax.rs b/tests/ui/feature-gates/feature-gate-builtin_syntax.rs
new file mode 100644
index 00000000000..832bb5a96bc
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-builtin_syntax.rs
@@ -0,0 +1,7 @@
+struct Foo {
+ v: u8,
+ w: u8,
+}
+fn main() {
+ builtin # offset_of(Foo, v); //~ ERROR `builtin #` syntax is unstable
+}
diff --git a/tests/ui/feature-gates/feature-gate-builtin_syntax.stderr b/tests/ui/feature-gates/feature-gate-builtin_syntax.stderr
new file mode 100644
index 00000000000..3bc7848f66d
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-builtin_syntax.stderr
@@ -0,0 +1,12 @@
+error[E0658]: `builtin #` syntax is unstable
+ --> $DIR/feature-gate-builtin_syntax.rs:6:15
+ |
+LL | builtin # offset_of(Foo, v);
+ | ^^^^^^^^^
+ |
+ = note: see issue #110680 <https://github.com/rust-lang/rust/issues/110680> for more information
+ = help: add `#![feature(builtin_syntax)]` 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/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.rs b/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.rs
new file mode 100644
index 00000000000..cb265aa7f25
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.rs
@@ -0,0 +1,6 @@
+#![crate_type = "lib"]
+
+#[cfg(overflow_checks)] //~ ERROR `cfg(overflow_checks)` is experimental
+pub fn cast(v: i64)->u32{
+ todo!()
+}
diff --git a/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.stderr b/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.stderr
new file mode 100644
index 00000000000..79aba7945f6
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.stderr
@@ -0,0 +1,12 @@
+error[E0658]: `cfg(overflow_checks)` is experimental and subject to change
+ --> $DIR/feature-gate-cfg_overflow_checks.rs:3:7
+ |
+LL | #[cfg(overflow_checks)]
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: see issue #111466 <https://github.com/rust-lang/rust/issues/111466> for more information
+ = help: add `#![feature(cfg_overflow_checks)]` 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/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr
index d81eade8e9b..303700c7ab4 100644
--- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr
+++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr
@@ -31,14 +31,7 @@ LL | trait Trait {
| ----- this trait cannot be made into an object...
LL | fn ptr(self: Ptr<Self>);
| ^^^^^^^^^ ...because method `ptr`'s `self` parameter cannot be dispatched on
-note: required for `Ptr<{integer}>` to implement `CoerceUnsized<Ptr<dyn Trait>>`
- --> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:20:40
- |
-LL | impl<T: Unsize<U> + ?Sized, U: ?Sized> CoerceUnsized<Ptr<U>> for Ptr<T> {}
- | --------- ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^
- | |
- | unsatisfied trait bound introduced here
- = note: required by cast to type `Ptr<dyn Trait>`
+ = note: required for the cast from `Ptr<{integer}>` to `Ptr<dyn Trait>`
error: aborting due to 2 previous errors
diff --git a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs
index 0680d234403..dce94c9eab2 100644
--- a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs
+++ b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs
@@ -13,5 +13,4 @@ fn non_unsafe_pin_new_unchecked<T>(pointer: &mut T) -> Pin<&mut T> {
fn main() {
let mut self_referential = PhantomPinned;
let _: Pin<&mut PhantomPinned> = non_unsafe_pin_new_unchecked(&mut self_referential);
- core::mem::forget(self_referential); // move and disable drop glue!
}
diff --git a/tests/ui/fmt/ifmt-unimpl.stderr b/tests/ui/fmt/ifmt-unimpl.stderr
index cc316e55f5c..b0dddd3b1e8 100644
--- a/tests/ui/fmt/ifmt-unimpl.stderr
+++ b/tests/ui/fmt/ifmt-unimpl.stderr
@@ -15,7 +15,7 @@ LL | format!("{:X}", "3");
NonZeroI64
NonZeroI8
NonZeroIsize
- and 21 others
+ and 20 others
= note: required for `&str` to implement `UpperHex`
note: required by a bound in `core::fmt::rt::Argument::<'a>::new_upper_hex`
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
diff --git a/tests/ui/issues/issue-3099.rs b/tests/ui/fn/issue-3099.rs
index ee75b359388..ee75b359388 100644
--- a/tests/ui/issues/issue-3099.rs
+++ b/tests/ui/fn/issue-3099.rs
diff --git a/tests/ui/issues/issue-3099.stderr b/tests/ui/fn/issue-3099.stderr
index 32ee2e1d207..32ee2e1d207 100644
--- a/tests/ui/issues/issue-3099.stderr
+++ b/tests/ui/fn/issue-3099.stderr
diff --git a/tests/ui/generator/drop-env.rs b/tests/ui/generator/drop-env.rs
index 66dfb8c2c09..cb46953dac3 100644
--- a/tests/ui/generator/drop-env.rs
+++ b/tests/ui/generator/drop-env.rs
@@ -4,6 +4,7 @@
//[nomiropt]compile-flags: -Z mir-opt-level=0
#![feature(generators, generator_trait)]
+#![allow(drop_copy)]
use std::ops::Generator;
use std::pin::Pin;
diff --git a/tests/ui/generator/drop-tracking-error-body.rs b/tests/ui/generator/drop-tracking-error-body.rs
new file mode 100644
index 00000000000..f99d9ab6bf8
--- /dev/null
+++ b/tests/ui/generator/drop-tracking-error-body.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Zdrop-tracking-mir --edition=2021
+
+#![feature(generators)]
+
+pub async fn async_bad_body() {
+ match true {} //~ ERROR non-exhaustive patterns: type `bool` is non-empty
+}
+
+pub fn generator_bad_body() {
+ || {
+ // 'non-exhaustive pattern' only seems to be reported once, so this annotation doesn't work
+ // keep the function around so we can make sure it doesn't ICE
+ match true {}; // ERROR non-exhaustive patterns: type `bool` is non-empty
+ yield ();
+ };
+}
+
+fn main() {}
diff --git a/tests/ui/generator/drop-tracking-error-body.stderr b/tests/ui/generator/drop-tracking-error-body.stderr
new file mode 100644
index 00000000000..28a6892336f
--- /dev/null
+++ b/tests/ui/generator/drop-tracking-error-body.stderr
@@ -0,0 +1,17 @@
+error[E0004]: non-exhaustive patterns: type `bool` is non-empty
+ --> $DIR/drop-tracking-error-body.rs:6:11
+ |
+LL | match true {}
+ | ^^^^
+ |
+ = note: the matched value is of type `bool`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match true {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/generator/issue-57017.no_drop_tracking.stderr b/tests/ui/generator/issue-57017.no_drop_tracking.stderr
index 06d2d23b9ef..f7b8e198cc4 100644
--- a/tests/ui/generator/issue-57017.no_drop_tracking.stderr
+++ b/tests/ui/generator/issue-57017.no_drop_tracking.stderr
@@ -1,5 +1,5 @@
error: generator cannot be sent between threads safely
- --> $DIR/issue-57017.rs:31:25
+ --> $DIR/issue-57017.rs:32:25
|
LL | assert_send(g);
| ^ generator is not `Send`
@@ -15,7 +15,7 @@ LL | | );
|
= help: the trait `Sync` is not implemented for `copy::unsync::Client`
note: generator is not `Send` as this value is used across a yield
- --> $DIR/issue-57017.rs:29:28
+ --> $DIR/issue-57017.rs:30:28
|
LL | let g = move || match drop(&$name::unsync::Client::default()) {
| --------------------------------- has type `&copy::unsync::Client` which is not `Send`
@@ -33,14 +33,14 @@ LL | | }
LL | | );
| |_____- in this macro invocation
note: required by a bound in `assert_send`
- --> $DIR/issue-57017.rs:51:19
+ --> $DIR/issue-57017.rs:52:19
|
LL | fn assert_send<T: Send>(_thing: T) {}
| ^^^^ required by this bound in `assert_send`
= 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/issue-57017.rs:43:25
+ --> $DIR/issue-57017.rs:44:25
|
LL | assert_send(g);
| ^ generator is not `Send`
@@ -54,9 +54,9 @@ LL | | }
LL | | );
| |_____- in this macro invocation
|
- = help: within `[generator@$DIR/issue-57017.rs:40:21: 40:28]`, the trait `Send` is not implemented for `copy::unsend::Client`
+ = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `copy::unsend::Client`
note: generator is not `Send` as this value is used across a yield
- --> $DIR/issue-57017.rs:41:28
+ --> $DIR/issue-57017.rs:42:28
|
LL | let g = move || match drop($name::unsend::Client::default()) {
| -------------------------------- has type `copy::unsend::Client` which is not `Send`
@@ -74,14 +74,14 @@ LL | | }
LL | | );
| |_____- in this macro invocation
note: required by a bound in `assert_send`
- --> $DIR/issue-57017.rs:51:19
+ --> $DIR/issue-57017.rs:52:19
|
LL | fn assert_send<T: Send>(_thing: T) {}
| ^^^^ required by this bound in `assert_send`
= 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/issue-57017.rs:31:25
+ --> $DIR/issue-57017.rs:32:25
|
LL | assert_send(g);
| ^ generator is not `Send`
@@ -97,7 +97,7 @@ LL | | );
|
= help: the trait `Sync` is not implemented for `derived_drop::unsync::Client`
note: generator is not `Send` as this value is used across a yield
- --> $DIR/issue-57017.rs:29:28
+ --> $DIR/issue-57017.rs:30:28
|
LL | let g = move || match drop(&$name::unsync::Client::default()) {
| --------------------------------- has type `&derived_drop::unsync::Client` which is not `Send`
@@ -115,14 +115,14 @@ LL | | }
LL | | );
| |_____- in this macro invocation
note: required by a bound in `assert_send`
- --> $DIR/issue-57017.rs:51:19
+ --> $DIR/issue-57017.rs:52:19
|
LL | fn assert_send<T: Send>(_thing: T) {}
| ^^^^ required by this bound in `assert_send`
= 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/issue-57017.rs:43:25
+ --> $DIR/issue-57017.rs:44:25
|
LL | assert_send(g);
| ^ generator is not `Send`
@@ -136,9 +136,9 @@ LL | | }
LL | | );
| |_____- in this macro invocation
|
- = help: within `[generator@$DIR/issue-57017.rs:40:21: 40:28]`, the trait `Send` is not implemented for `derived_drop::unsend::Client`
+ = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `derived_drop::unsend::Client`
note: generator is not `Send` as this value is used across a yield
- --> $DIR/issue-57017.rs:41:28
+ --> $DIR/issue-57017.rs:42:28
|
LL | let g = move || match drop($name::unsend::Client::default()) {
| -------------------------------- has type `derived_drop::unsend::Client` which is not `Send`
@@ -156,14 +156,14 @@ LL | | }
LL | | );
| |_____- in this macro invocation
note: required by a bound in `assert_send`
- --> $DIR/issue-57017.rs:51:19
+ --> $DIR/issue-57017.rs:52:19
|
LL | fn assert_send<T: Send>(_thing: T) {}
| ^^^^ required by this bound in `assert_send`
= 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/issue-57017.rs:31:25
+ --> $DIR/issue-57017.rs:32:25
|
LL | assert_send(g);
| ^ generator is not `Send`
@@ -179,7 +179,7 @@ LL | | );
|
= help: the trait `Sync` is not implemented for `significant_drop::unsync::Client`
note: generator is not `Send` as this value is used across a yield
- --> $DIR/issue-57017.rs:29:28
+ --> $DIR/issue-57017.rs:30:28
|
LL | let g = move || match drop(&$name::unsync::Client::default()) {
| --------------------------------- has type `&significant_drop::unsync::Client` which is not `Send`
@@ -197,14 +197,14 @@ LL | | }
LL | | );
| |_____- in this macro invocation
note: required by a bound in `assert_send`
- --> $DIR/issue-57017.rs:51:19
+ --> $DIR/issue-57017.rs:52:19
|
LL | fn assert_send<T: Send>(_thing: T) {}
| ^^^^ required by this bound in `assert_send`
= 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/issue-57017.rs:43:25
+ --> $DIR/issue-57017.rs:44:25
|
LL | assert_send(g);
| ^ generator is not `Send`
@@ -218,9 +218,9 @@ LL | | }
LL | | );
| |_____- in this macro invocation
|
- = help: within `[generator@$DIR/issue-57017.rs:40:21: 40:28]`, the trait `Send` is not implemented for `significant_drop::unsend::Client`
+ = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `significant_drop::unsend::Client`
note: generator is not `Send` as this value is used across a yield
- --> $DIR/issue-57017.rs:41:28
+ --> $DIR/issue-57017.rs:42:28
|
LL | let g = move || match drop($name::unsend::Client::default()) {
| -------------------------------- has type `significant_drop::unsend::Client` which is not `Send`
@@ -238,7 +238,7 @@ LL | | }
LL | | );
| |_____- in this macro invocation
note: required by a bound in `assert_send`
- --> $DIR/issue-57017.rs:51:19
+ --> $DIR/issue-57017.rs:52:19
|
LL | fn assert_send<T: Send>(_thing: T) {}
| ^^^^ required by this bound in `assert_send`
diff --git a/tests/ui/generator/issue-57017.rs b/tests/ui/generator/issue-57017.rs
index 03b00ac99ad..918d233bf4e 100644
--- a/tests/ui/generator/issue-57017.rs
+++ b/tests/ui/generator/issue-57017.rs
@@ -5,6 +5,7 @@
// [drop_tracking_mir] build-pass
#![feature(generators, negative_impls)]
+#![allow(drop_ref, drop_copy)]
macro_rules! type_combinations {
(
diff --git a/tests/ui/generator/non-static-is-unpin.rs b/tests/ui/generator/non-static-is-unpin.rs
index 17e23f5bcd2..adba800e25a 100644
--- a/tests/ui/generator/non-static-is-unpin.rs
+++ b/tests/ui/generator/non-static-is-unpin.rs
@@ -3,6 +3,7 @@
// run-pass
#![feature(generators, generator_trait)]
+#![allow(drop_copy)]
use std::marker::{PhantomPinned, Unpin};
diff --git a/tests/ui/generator/resume-arg-size.rs b/tests/ui/generator/resume-arg-size.rs
index b93dc54f7a9..19618f8d0aa 100644
--- a/tests/ui/generator/resume-arg-size.rs
+++ b/tests/ui/generator/resume-arg-size.rs
@@ -1,4 +1,5 @@
#![feature(generators)]
+#![allow(drop_copy)]
// run-pass
diff --git a/tests/ui/generic-associated-types/equality-bound.stderr b/tests/ui/generic-associated-types/equality-bound.stderr
index d78f7a7fbce..b21ff30a27d 100644
--- a/tests/ui/generic-associated-types/equality-bound.stderr
+++ b/tests/ui/generic-associated-types/equality-bound.stderr
@@ -36,7 +36,10 @@ error[E0433]: failed to resolve: use of undeclared type `I`
--> $DIR/equality-bound.rs:9:41
|
LL | fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
- | ^ use of undeclared type `I`
+ | ^
+ | |
+ | use of undeclared type `I`
+ | help: a type parameter with a similar name exists: `J`
error: aborting due to 4 previous errors
diff --git a/tests/ui/generic-associated-types/issue-76535.base.stderr b/tests/ui/generic-associated-types/issue-76535.base.stderr
index 52c6e3eec60..370329b9f83 100644
--- a/tests/ui/generic-associated-types/issue-76535.base.stderr
+++ b/tests/ui/generic-associated-types/issue-76535.base.stderr
@@ -43,8 +43,7 @@ LL | pub trait SuperTrait {
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 for `Box<SuperStruct>` to implement `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>`
- = note: required by cast to type `Box<dyn SuperTrait<SubType = SubStruct<'_>>>`
+ = note: required for the cast from `Box<SuperStruct>` to `Box<dyn SuperTrait<SubType = SubStruct<'_>>>`
error: aborting due to 3 previous errors
diff --git a/tests/ui/generic-associated-types/issue-79422.base.stderr b/tests/ui/generic-associated-types/issue-79422.base.stderr
index f1de77bc3c0..ad704f5e9f0 100644
--- a/tests/ui/generic-associated-types/issue-79422.base.stderr
+++ b/tests/ui/generic-associated-types/issue-79422.base.stderr
@@ -43,8 +43,7 @@ LL | trait MapLike<K, V> {
LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
= help: consider moving `VRefCont` to another trait
- = note: required 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)>>`
+ = note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
error: aborting due to 3 previous errors
diff --git a/tests/ui/generic-associated-types/issue-79422.extended.stderr b/tests/ui/generic-associated-types/issue-79422.extended.stderr
index 04184fce921..14492266cda 100644
--- a/tests/ui/generic-associated-types/issue-79422.extended.stderr
+++ b/tests/ui/generic-associated-types/issue-79422.extended.stderr
@@ -27,7 +27,7 @@ LL | type VRefCont<'a> = &'a V where Self: 'a;
| ^^^^^
= note: expected trait object `(dyn RefCont<'_, u8> + 'static)`
found reference `&u8`
- = note: required for the cast from `BTreeMap<u8, u8>` to the object type `dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>`
+ = note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
error: aborting due to 2 previous errors
diff --git a/tests/ui/generic-associated-types/issue-88595.rs b/tests/ui/generic-associated-types/issue-88595.rs
index 5a40a612972..7de906e7ef3 100644
--- a/tests/ui/generic-associated-types/issue-88595.rs
+++ b/tests/ui/generic-associated-types/issue-88595.rs
@@ -19,4 +19,5 @@ impl<'a> A<'a> for C {
type B<'b> = impl Clone;
fn a(&'a self) -> Self::B<'a> {} //~ ERROR: non-defining opaque type use in defining scope
+ //~^ ERROR: mismatched types
}
diff --git a/tests/ui/generic-associated-types/issue-88595.stderr b/tests/ui/generic-associated-types/issue-88595.stderr
index 79d3479af8c..d6caed85459 100644
--- a/tests/ui/generic-associated-types/issue-88595.stderr
+++ b/tests/ui/generic-associated-types/issue-88595.stderr
@@ -1,16 +1,34 @@
error: non-defining opaque type use in defining scope
- --> $DIR/issue-88595.rs:21:35
+ --> $DIR/issue-88595.rs:21:5
|
LL | fn a(&'a self) -> Self::B<'a> {}
- | ^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ generic argument `'a` used twice
|
-note: lifetime used multiple times
- --> $DIR/issue-88595.rs:18:6
+note: for this opaque type
+ --> $DIR/issue-88595.rs:19:18
|
-LL | impl<'a> A<'a> for C {
- | ^^
LL | type B<'b> = impl Clone;
- | ^^
+ | ^^^^^^^^^^
-error: aborting due to previous error
+error[E0308]: mismatched types
+ --> $DIR/issue-88595.rs:21:23
+ |
+LL | type B<'b> = impl Clone;
+ | ---------- the expected opaque type
+LL |
+LL | fn a(&'a self) -> Self::B<'a> {}
+ | - ^^^^^^^^^^^ expected opaque type, found `()`
+ | |
+ | implicitly returns `()` as its body has no tail or `return` expression
+ |
+ = note: expected opaque type `<C as A<'a>>::B<'a>`
+ found unit type `()`
+note: this item must have the opaque type in its signature in order to be able to register hidden types
+ --> $DIR/issue-88595.rs:21:5
+ |
+LL | fn a(&'a self) -> Self::B<'a> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs b/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs
index cf65de2bc23..214267372bf 100644
--- a/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs
+++ b/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs
@@ -1,6 +1,7 @@
// check-pass
#![feature(decl_macro)]
+#![allow(drop_copy)]
macro mac() {
mod m {
diff --git a/tests/ui/illegal-ufcs-drop.fixed b/tests/ui/illegal-ufcs-drop.fixed
index d73b391be06..8783682dec4 100644
--- a/tests/ui/illegal-ufcs-drop.fixed
+++ b/tests/ui/illegal-ufcs-drop.fixed
@@ -1,4 +1,7 @@
// run-rustfix
+
+#![allow(drop_ref)]
+
struct Foo;
impl Drop for Foo {
diff --git a/tests/ui/illegal-ufcs-drop.rs b/tests/ui/illegal-ufcs-drop.rs
index 11411f55494..29774306ec6 100644
--- a/tests/ui/illegal-ufcs-drop.rs
+++ b/tests/ui/illegal-ufcs-drop.rs
@@ -1,4 +1,7 @@
// run-rustfix
+
+#![allow(drop_ref)]
+
struct Foo;
impl Drop for Foo {
diff --git a/tests/ui/illegal-ufcs-drop.stderr b/tests/ui/illegal-ufcs-drop.stderr
index 91f47d5e456..7a5c0612c07 100644
--- a/tests/ui/illegal-ufcs-drop.stderr
+++ b/tests/ui/illegal-ufcs-drop.stderr
@@ -1,5 +1,5 @@
error[E0040]: explicit use of destructor method
- --> $DIR/illegal-ufcs-drop.rs:9:5
+ --> $DIR/illegal-ufcs-drop.rs:12:5
|
LL | Drop::drop(&mut Foo)
| ^^^^^^^^^^
diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed b/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed
new file mode 100644
index 00000000000..cd4f2610d3f
--- /dev/null
+++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed
@@ -0,0 +1,19 @@
+// run-rustfix
+
+struct S<T>(T);
+struct S2;
+
+impl<T: Default> Default for S<T> {
+ //~^ ERROR: unexpected `impl` keyword
+ //~| HELP: remove the extra `impl`
+ fn default() -> Self { todo!() }
+}
+
+impl Default for S2 {
+ //~^ ERROR: unexpected `impl` keyword
+ //~| HELP: remove the extra `impl`
+ fn default() -> Self { todo!() }
+}
+
+
+fn main() {}
diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.rs b/tests/ui/impl-trait/extra-impl-in-trait-impl.rs
new file mode 100644
index 00000000000..024b703e6f2
--- /dev/null
+++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.rs
@@ -0,0 +1,19 @@
+// run-rustfix
+
+struct S<T>(T);
+struct S2;
+
+impl<T: Default> impl Default for S<T> {
+ //~^ ERROR: unexpected `impl` keyword
+ //~| HELP: remove the extra `impl`
+ fn default() -> Self { todo!() }
+}
+
+impl impl Default for S2 {
+ //~^ ERROR: unexpected `impl` keyword
+ //~| HELP: remove the extra `impl`
+ fn default() -> Self { todo!() }
+}
+
+
+fn main() {}
diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr b/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr
new file mode 100644
index 00000000000..5aafc8b64d4
--- /dev/null
+++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr
@@ -0,0 +1,26 @@
+error: unexpected `impl` keyword
+ --> $DIR/extra-impl-in-trait-impl.rs:6:18
+ |
+LL | impl<T: Default> impl Default for S<T> {
+ | ^^^^^ help: remove the extra `impl`
+ |
+note: this is parsed as an `impl Trait` type, but a trait is expected at this position
+ --> $DIR/extra-impl-in-trait-impl.rs:6:18
+ |
+LL | impl<T: Default> impl Default for S<T> {
+ | ^^^^^^^^^^^^
+
+error: unexpected `impl` keyword
+ --> $DIR/extra-impl-in-trait-impl.rs:12:6
+ |
+LL | impl impl Default for S2 {
+ | ^^^^^ help: remove the extra `impl`
+ |
+note: this is parsed as an `impl Trait` type, but a trait is expected at this position
+ --> $DIR/extra-impl-in-trait-impl.rs:12:6
+ |
+LL | impl impl Default for S2 {
+ | ^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.rs b/tests/ui/impl-trait/in-assoc-type-unconstrained.rs
new file mode 100644
index 00000000000..c395b4195a0
--- /dev/null
+++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.rs
@@ -0,0 +1,27 @@
+#![feature(impl_trait_in_assoc_type)]
+
+mod compare_ty {
+ trait Trait {
+ type Ty: IntoIterator<Item = ()>;
+ }
+ impl Trait for () {
+ type Ty = Option<impl Sized>;
+ //~^ ERROR: unconstrained opaque type
+ //~| ERROR: type mismatch resolving `<Option<<() as Trait>::Ty::{opaque#0}> as IntoIterator>::Item == ()`
+ }
+}
+
+mod compare_method {
+ trait Trait {
+ type Ty;
+ fn method() -> Self::Ty;
+ }
+ impl Trait for () {
+ type Ty = impl Sized;
+ //~^ ERROR: unconstrained opaque type
+ fn method() -> () {}
+ //~^ ERROR: method `method` has an incompatible type for trait
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
new file mode 100644
index 00000000000..1097cd0f452
--- /dev/null
+++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
@@ -0,0 +1,59 @@
+error[E0271]: type mismatch resolving `<Option<<() as Trait>::Ty::{opaque#0}> as IntoIterator>::Item == ()`
+ --> $DIR/in-assoc-type-unconstrained.rs:8:19
+ |
+LL | type Ty = Option<impl Sized>;
+ | ^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type
+ |
+ = note: expected unit type `()`
+ found opaque type `<() as compare_ty::Trait>::Ty::{opaque#0}`
+note: required by a bound in `compare_ty::Trait::Ty`
+ --> $DIR/in-assoc-type-unconstrained.rs:5:31
+ |
+LL | type Ty: IntoIterator<Item = ()>;
+ | ^^^^^^^^^ required by this bound in `Trait::Ty`
+
+error: unconstrained opaque type
+ --> $DIR/in-assoc-type-unconstrained.rs:8:26
+ |
+LL | type Ty = Option<impl Sized>;
+ | ^^^^^^^^^^
+ |
+ = note: `Ty` must be used in combination with a concrete type within the same impl
+
+error[E0053]: method `method` has an incompatible type for trait
+ --> $DIR/in-assoc-type-unconstrained.rs:22:24
+ |
+LL | type Ty = impl Sized;
+ | ---------- the expected opaque type
+LL |
+LL | fn method() -> () {}
+ | ^^
+ | |
+ | expected opaque type, found `()`
+ | help: change the output type to match the trait: `<() as compare_method::Trait>::Ty`
+ |
+note: type in trait
+ --> $DIR/in-assoc-type-unconstrained.rs:17:24
+ |
+LL | fn method() -> Self::Ty;
+ | ^^^^^^^^
+ = note: expected signature `fn() -> <() as compare_method::Trait>::Ty`
+ found signature `fn()`
+note: this item must have the opaque type in its signature in order to be able to register hidden types
+ --> $DIR/in-assoc-type-unconstrained.rs:22:9
+ |
+LL | fn method() -> () {}
+ | ^^^^^^^^^^^^^^^^^
+
+error: unconstrained opaque type
+ --> $DIR/in-assoc-type-unconstrained.rs:20:19
+ |
+LL | type Ty = impl Sized;
+ | ^^^^^^^^^^
+ |
+ = note: `Ty` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0053, E0271.
+For more information about an error, try `rustc --explain E0053`.
diff --git a/tests/ui/impl-trait/in-assoc-type.rs b/tests/ui/impl-trait/in-assoc-type.rs
new file mode 100644
index 00000000000..36c54bdd6de
--- /dev/null
+++ b/tests/ui/impl-trait/in-assoc-type.rs
@@ -0,0 +1,21 @@
+#![feature(impl_trait_in_assoc_type)]
+
+trait Foo<T> {
+ type Bar;
+ fn foo(&self) -> <Self as Foo<()>>::Bar
+ where
+ Self: Foo<()>;
+}
+
+impl Foo<()> for () {
+ type Bar = impl std::fmt::Debug;
+ fn foo(&self) -> Self::Bar {}
+}
+
+impl Foo<i32> for () {
+ type Bar = u32;
+ fn foo(&self) -> <Self as Foo<()>>::Bar {}
+ //~^ ERROR: mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-assoc-type.stderr b/tests/ui/impl-trait/in-assoc-type.stderr
new file mode 100644
index 00000000000..f0a272dc2d5
--- /dev/null
+++ b/tests/ui/impl-trait/in-assoc-type.stderr
@@ -0,0 +1,22 @@
+error[E0308]: mismatched types
+ --> $DIR/in-assoc-type.rs:17:22
+ |
+LL | type Bar = impl std::fmt::Debug;
+ | -------------------- the expected opaque type
+...
+LL | fn foo(&self) -> <Self as Foo<()>>::Bar {}
+ | --- ^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `()`
+ | |
+ | implicitly returns `()` as its body has no tail or `return` expression
+ |
+ = note: expected opaque type `<() as Foo<()>>::Bar`
+ found unit type `()`
+note: this item must have the opaque type in its signature in order to be able to register hidden types
+ --> $DIR/in-assoc-type.rs:17:5
+ |
+LL | fn foo(&self) -> <Self as Foo<()>>::Bar {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/in-trait/object-safety.current.stderr b/tests/ui/impl-trait/in-trait/object-safety.current.stderr
index b7f2b019a77..2c340a02319 100644
--- a/tests/ui/impl-trait/in-trait/object-safety.current.stderr
+++ b/tests/ui/impl-trait/in-trait/object-safety.current.stderr
@@ -42,8 +42,7 @@ LL | trait Foo {
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>`
+ = note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
error: aborting due to 3 previous errors
diff --git a/tests/ui/impl-trait/in-trait/object-safety.next.stderr b/tests/ui/impl-trait/in-trait/object-safety.next.stderr
index b7f2b019a77..2c340a02319 100644
--- a/tests/ui/impl-trait/in-trait/object-safety.next.stderr
+++ b/tests/ui/impl-trait/in-trait/object-safety.next.stderr
@@ -42,8 +42,7 @@ LL | trait Foo {
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>`
+ = note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
error: aborting due to 3 previous errors
diff --git a/tests/ui/impl-trait/issue-103181-1.stderr b/tests/ui/impl-trait/issue-103181-1.current.stderr
index cd026607d52..e87a9d28ae1 100644
--- a/tests/ui/impl-trait/issue-103181-1.stderr
+++ b/tests/ui/impl-trait/issue-103181-1.current.stderr
@@ -1,5 +1,5 @@
error[E0046]: not all trait items implemented, missing: `Error`
- --> $DIR/issue-103181-1.rs:9:5
+ --> $DIR/issue-103181-1.rs:11:5
|
LL | type Error;
| ---------- `Error` from trait
diff --git a/tests/ui/impl-trait/issue-103181-1.next.stderr b/tests/ui/impl-trait/issue-103181-1.next.stderr
new file mode 100644
index 00000000000..e87a9d28ae1
--- /dev/null
+++ b/tests/ui/impl-trait/issue-103181-1.next.stderr
@@ -0,0 +1,12 @@
+error[E0046]: not all trait items implemented, missing: `Error`
+ --> $DIR/issue-103181-1.rs:11:5
+ |
+LL | type Error;
+ | ---------- `Error` from trait
+LL | }
+LL | impl HttpBody for () {
+ | ^^^^^^^^^^^^^^^^^^^^ missing `Error` in implementation
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/impl-trait/issue-103181-1.rs b/tests/ui/impl-trait/issue-103181-1.rs
index 197aedf9d98..5154abcd690 100644
--- a/tests/ui/impl-trait/issue-103181-1.rs
+++ b/tests/ui/impl-trait/issue-103181-1.rs
@@ -1,3 +1,5 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
// edition:2021
mod hyper {
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
index f7aff419544..fe62a8f3288 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
@@ -43,6 +43,11 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
|
= note: expected signature `fn(&b::Bar, &(b::Foo, i32)) -> _`
found signature `fn(&b::Bar, &(b::Bar, i32)) -> _`
+note: this item must have the opaque type in its signature in order to be able to register hidden types
+ --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:9
+ |
+LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
diff --git a/tests/ui/inference/deref-suggestion.stderr b/tests/ui/inference/deref-suggestion.stderr
index 6f5aacacfc1..c58aab42269 100644
--- a/tests/ui/inference/deref-suggestion.stderr
+++ b/tests/ui/inference/deref-suggestion.stderr
@@ -98,19 +98,23 @@ error[E0308]: mismatched types
--> $DIR/deref-suggestion.rs:40:17
|
LL | let s = S { u };
- | ^
- | |
- | expected `&u32`, found integer
- | help: consider borrowing here: `u: &u`
+ | ^ expected `&u32`, found integer
+ |
+help: consider borrowing here
+ |
+LL | let s = S { u: &u };
+ | ++++
error[E0308]: mismatched types
--> $DIR/deref-suggestion.rs:42:20
|
LL | let s = S { u: u };
- | ^
- | |
- | expected `&u32`, found integer
- | help: consider borrowing here: `&u`
+ | ^ expected `&u32`, found integer
+ |
+help: consider borrowing here
+ |
+LL | let s = S { u: &u };
+ | +
error[E0308]: mismatched types
--> $DIR/deref-suggestion.rs:45:17
diff --git a/tests/ui/issues/issue-71584.rs b/tests/ui/inference/issue-71584.rs
index 7bf3ed60ec1..7bf3ed60ec1 100644
--- a/tests/ui/issues/issue-71584.rs
+++ b/tests/ui/inference/issue-71584.rs
diff --git a/tests/ui/issues/issue-71584.stderr b/tests/ui/inference/issue-71584.stderr
index 6ddb7657301..6ddb7657301 100644
--- a/tests/ui/issues/issue-71584.stderr
+++ b/tests/ui/inference/issue-71584.stderr
diff --git a/tests/ui/issues/auxiliary/issue-3136-a.rc b/tests/ui/issues/auxiliary/issue-3136-a.rc
deleted file mode 100644
index cd5fd314505..00000000000
--- a/tests/ui/issues/auxiliary/issue-3136-a.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-#![crate_type = "lib"]
-
-#[path = "issue-3136-a.rs"]
-pub mod issue_3136_a;
diff --git a/tests/ui/issues/auxiliary/issue-3136-a.rs b/tests/ui/issues/auxiliary/issue-3136-a.rs
index 9bb546ab393..22bb1c8f977 100644
--- a/tests/ui/issues/auxiliary/issue-3136-a.rs
+++ b/tests/ui/issues/auxiliary/issue-3136-a.rs
@@ -1,11 +1,14 @@
+#![crate_type = "lib"]
+
trait x {
fn use_x<T>(&self);
}
struct y(());
impl x for y {
fn use_x<T>(&self) {
- struct foo { //~ ERROR quux
- i: ()
+ struct foo {
+ //~ ERROR quux
+ i: (),
}
fn new_foo<T>(i: ()) -> foo {
foo { i: i }
diff --git a/tests/ui/issues/issue-11374.stderr b/tests/ui/issues/issue-11374.stderr
index 6e1fb1540bb..879dc5b76c5 100644
--- a/tests/ui/issues/issue-11374.stderr
+++ b/tests/ui/issues/issue-11374.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
--> $DIR/issue-11374.rs:26:15
|
LL | c.read_to(v);
- | ------- ^
- | | |
- | | expected `&mut [u8]`, found `Vec<_>`
- | | help: consider mutably borrowing here: `&mut v`
+ | ------- ^ expected `&mut [u8]`, found `Vec<_>`
+ | |
| arguments to this method are incorrect
|
= note: expected mutable reference `&mut [u8]`
@@ -15,6 +13,10 @@ note: method defined here
|
LL | pub fn read_to(&mut self, vec: &mut [u8]) {
| ^^^^^^^ --------------
+help: consider mutably borrowing here
+ |
+LL | c.read_to(&mut v);
+ | ++++
error: aborting due to previous error
diff --git a/tests/ui/issues/issue-14366.stderr b/tests/ui/issues/issue-14366.stderr
index 10a73b245ac..df61aabf00a 100644
--- a/tests/ui/issues/issue-14366.stderr
+++ b/tests/ui/issues/issue-14366.stderr
@@ -5,8 +5,8 @@ LL | let _x = "test" as &dyn (::std::any::Any);
| ^^^^^^ 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 Any`
-help: consider borrowing the value, since `&str` can be coerced into `dyn Any`
+ = note: required for the cast from `&'static str` to `&(dyn Any + 'static)`
+help: consider borrowing the value, since `&&'static str` can be coerced into `&(dyn Any + 'static)`
|
LL | let _x = &"test" as &dyn (::std::any::Any);
| +
diff --git a/tests/ui/issues/issue-17033.stderr b/tests/ui/issues/issue-17033.stderr
index f26bee5ff45..3419c079859 100644
--- a/tests/ui/issues/issue-17033.stderr
+++ b/tests/ui/issues/issue-17033.stderr
@@ -2,11 +2,14 @@ error[E0308]: mismatched types
--> $DIR/issue-17033.rs:2:10
|
LL | (*p)(())
- | ---- ^^
- | | |
- | | expected `&mut ()`, found `()`
- | | help: consider mutably borrowing here: `&mut ()`
+ | ---- ^^ expected `&mut ()`, found `()`
+ | |
| arguments to this function are incorrect
+ |
+help: consider mutably borrowing here
+ |
+LL | (*p)(&mut ())
+ | ++++
error: aborting due to previous error
diff --git a/tests/ui/issues/issue-18819.stderr b/tests/ui/issues/issue-18819.stderr
index 1fc974b609c..40098f9622f 100644
--- a/tests/ui/issues/issue-18819.stderr
+++ b/tests/ui/issues/issue-18819.stderr
@@ -19,7 +19,7 @@ LL | fn print_x(_: &dyn Foo<Item=bool>, extra: &str) {
help: consider borrowing here
|
LL | print_x(&X);
- | ~~
+ | +
help: provide the argument
|
LL | print_x(/* &dyn Foo<Item = bool> */, /* &str */);
diff --git a/tests/ui/issues/issue-22034.stderr b/tests/ui/issues/issue-22034.stderr
index b32de5b24b9..9833e559cbc 100644
--- a/tests/ui/issues/issue-22034.stderr
+++ b/tests/ui/issues/issue-22034.stderr
@@ -6,7 +6,7 @@ LL | &mut *(ptr as *mut dyn Fn())
|
= help: the trait `Fn<()>` is not implemented for `()`
= note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
- = note: required for the cast from `()` to the object type `dyn Fn()`
+ = note: required for the cast from `*mut ()` to `*mut dyn Fn()`
error: aborting due to previous error
diff --git a/tests/ui/issues/issue-22872.stderr b/tests/ui/issues/issue-22872.stderr
index 9510197197a..63222d25c01 100644
--- a/tests/ui/issues/issue-22872.stderr
+++ b/tests/ui/issues/issue-22872.stderr
@@ -13,7 +13,7 @@ LL | impl<'b, P> Wrap<'b> for Wrapper<P>
LL | where P: Process<'b>,
LL | <P as Process<'b>>::Item: Iterator {
| -------- unsatisfied trait bound introduced here
- = note: required for the cast from `Wrapper<P>` to the object type `dyn for<'b> Wrap<'b>`
+ = note: required for the cast from `Box<Wrapper<P>>` to `Box<dyn for<'b> Wrap<'b>>`
help: consider further restricting the associated type
|
LL | fn push_process<P>(process: P) where P: Process<'static>, <P as Process<'_>>::Item: Iterator {
diff --git a/tests/ui/issues/issue-2748-a.rs b/tests/ui/issues/issue-2748-a.rs
deleted file mode 100644
index cbb9bcc28ac..00000000000
--- a/tests/ui/issues/issue-2748-a.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// build-pass
-#![allow(dead_code)]
-#![allow(non_snake_case)]
-
-// pretty-expanded FIXME #23616
-
-struct CMap<'a> {
- buf: &'a [u8],
-}
-
-fn CMap(buf: &[u8]) -> CMap {
- CMap {
- buf: buf
- }
-}
-
-pub fn main() { }
diff --git a/tests/ui/issues/issue-3136-b.rs b/tests/ui/issues/issue-3136-b.rs
index c4ca7236e76..33d97fe7c83 100644
--- a/tests/ui/issues/issue-3136-b.rs
+++ b/tests/ui/issues/issue-3136-b.rs
@@ -1,5 +1,5 @@
// run-pass
-// aux-build:issue-3136-a.rc
+// aux-build:issue-3136-a.rs
// pretty-expanded FIXME #23616
diff --git a/tests/ui/issues/issue-46302.stderr b/tests/ui/issues/issue-46302.stderr
index a6f97c3c9af..6e126038cc9 100644
--- a/tests/ui/issues/issue-46302.stderr
+++ b/tests/ui/issues/issue-46302.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
--> $DIR/issue-46302.rs:3:27
|
LL | let u: &str = if true { s[..2] } else { s };
- | ^^^^^^
- | |
- | expected `&str`, found `str`
- | help: consider borrowing here: `&s[..2]`
+ | ^^^^^^ expected `&str`, found `str`
+ |
+help: consider borrowing here
+ |
+LL | let u: &str = if true { &s[..2] } else { s };
+ | +
error: aborting due to previous error
diff --git a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr b/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr
index e874ded8ec5..211dd512895 100644
--- a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr
+++ b/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
--> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:12:42
|
LL | light_flows_our_war_of_mocking_words(behold as usize);
- | ------------------------------------ ^^^^^^^^^^^^^^^
- | | |
- | | expected `&usize`, found `usize`
- | | help: consider borrowing here: `&(behold as usize)`
+ | ------------------------------------ ^^^^^^^^^^^^^^^ expected `&usize`, found `usize`
+ | |
| arguments to this function are incorrect
|
note: function defined here
@@ -13,15 +11,17 @@ note: function defined here
|
LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------
+help: consider borrowing here
+ |
+LL | light_flows_our_war_of_mocking_words(&(behold as usize));
+ | ++ +
error[E0308]: mismatched types
--> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:14:42
|
LL | light_flows_our_war_of_mocking_words(with_tears + 4);
- | ------------------------------------ ^^^^^^^^^^^^^^
- | | |
- | | expected `&usize`, found `usize`
- | | help: consider borrowing here: `&(with_tears + 4)`
+ | ------------------------------------ ^^^^^^^^^^^^^^ expected `&usize`, found `usize`
+ | |
| arguments to this function are incorrect
|
note: function defined here
@@ -29,6 +29,10 @@ note: function defined here
|
LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------
+help: consider borrowing here
+ |
+LL | light_flows_our_war_of_mocking_words(&(with_tears + 4));
+ | ++ +
error: aborting due to 2 previous errors
diff --git a/tests/ui/issues/issue-51515.rs b/tests/ui/issues/issue-51515.rs
index 84e09afac0a..33a9bf85e23 100644
--- a/tests/ui/issues/issue-51515.rs
+++ b/tests/ui/issues/issue-51515.rs
@@ -1,7 +1,6 @@
fn main() {
let foo = &16;
//~^ HELP consider changing this to be a mutable reference
- //~| SUGGESTION &mut 16
*foo = 32;
//~^ ERROR cannot assign to `*foo`, which is behind a `&` reference
let bar = foo;
diff --git a/tests/ui/issues/issue-51515.stderr b/tests/ui/issues/issue-51515.stderr
index 94e5c9f1b83..88b8d210908 100644
--- a/tests/ui/issues/issue-51515.stderr
+++ b/tests/ui/issues/issue-51515.stderr
@@ -1,5 +1,5 @@
error[E0594]: cannot assign to `*foo`, which is behind a `&` reference
- --> $DIR/issue-51515.rs:5:5
+ --> $DIR/issue-51515.rs:4:5
|
LL | *foo = 32;
| ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
@@ -7,10 +7,10 @@ LL | *foo = 32;
help: consider changing this to be a mutable reference
|
LL | let foo = &mut 16;
- | ~~~~~~~
+ | +++
error[E0594]: cannot assign to `*bar`, which is behind a `&` reference
- --> $DIR/issue-51515.rs:9:5
+ --> $DIR/issue-51515.rs:8:5
|
LL | *bar = 64;
| ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written
diff --git a/tests/ui/issues/issue-61106.stderr b/tests/ui/issues/issue-61106.stderr
index eff3e6e7849..aa922e2682d 100644
--- a/tests/ui/issues/issue-61106.stderr
+++ b/tests/ui/issues/issue-61106.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
--> $DIR/issue-61106.rs:3:9
|
LL | foo(x.clone());
- | --- ^^^^^^^^^
- | | |
- | | expected `&str`, found `String`
- | | help: consider borrowing here: `&x`
+ | --- ^^^^^^^^^ expected `&str`, found `String`
+ | |
| arguments to this function are incorrect
|
note: function defined here
@@ -13,6 +11,10 @@ note: function defined here
|
LL | fn foo(_: &str) {}
| ^^^ -------
+help: consider borrowing here
+ |
+LL | foo(&x.clone());
+ | +
error: aborting due to previous error
diff --git a/tests/ui/issues/issue-61623.stderr b/tests/ui/issues/issue-61623.stderr
index 5fcc338557c..bedea3890a3 100644
--- a/tests/ui/issues/issue-61623.stderr
+++ b/tests/ui/issues/issue-61623.stderr
@@ -7,7 +7,7 @@ LL | f2(|| x.0, f1(x.1))
help: consider changing this to be a mutable reference
|
LL | fn f3<'a>(x: &'a mut ((), &'a mut ())) {
- | ~~~~~~~~~~~~~~~~~~~~~~~~
+ | +++
error: aborting due to previous error
diff --git a/tests/ui/kindck/kindck-impl-type-params.stderr b/tests/ui/kindck/kindck-impl-type-params.stderr
index efb25bf83e1..53c1940491f 100644
--- a/tests/ui/kindck/kindck-impl-type-params.stderr
+++ b/tests/ui/kindck/kindck-impl-type-params.stderr
@@ -11,7 +11,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
| ---- ^^^^^^^^^^^ ^^^^
| |
| unsatisfied trait bound introduced here
- = note: required for the cast from `S<T>` to the object type `dyn Gettable<T>`
+ = note: required for the cast from `&S<T>` to `&dyn Gettable<T>`
help: consider restricting type parameter `T`
|
LL | fn f<T: std::marker::Send>(val: T) {
@@ -30,7 +30,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
| ---- ^^^^^^^^^^^ ^^^^
| |
| unsatisfied trait bound introduced here
- = note: required for the cast from `S<T>` to the object type `dyn Gettable<T>`
+ = note: required for the cast from `&S<T>` to `&dyn Gettable<T>`
help: consider restricting type parameter `T`
|
LL | fn f<T: std::marker::Copy>(val: T) {
@@ -49,7 +49,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
| ---- ^^^^^^^^^^^ ^^^^
| |
| unsatisfied trait bound introduced here
- = note: required for the cast from `S<T>` to the object type `dyn Gettable<T>`
+ = note: required for the cast from `&S<T>` to `&dyn Gettable<T>`
help: consider restricting type parameter `T`
|
LL | fn g<T: std::marker::Send>(val: T) {
@@ -68,7 +68,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
| ---- ^^^^^^^^^^^ ^^^^
| |
| unsatisfied trait bound introduced here
- = note: required for the cast from `S<T>` to the object type `dyn Gettable<T>`
+ = note: required for the cast from `&S<T>` to `&dyn Gettable<T>`
help: consider restricting type parameter `T`
|
LL | fn g<T: std::marker::Copy>(val: T) {
@@ -88,7 +88,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
| ---- ^^^^^^^^^^^ ^^^^
| |
| unsatisfied trait bound introduced here
- = note: required for the cast from `S<String>` to the object type `dyn Gettable<String>`
+ = note: required for the cast from `Box<S<String>>` to `Box<dyn Gettable<String>>`
error[E0277]: the trait bound `Foo: Copy` is not satisfied
--> $DIR/kindck-impl-type-params.rs:43:37
@@ -104,7 +104,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
| ---- ^^^^^^^^^^^ ^^^^
| |
| unsatisfied trait bound introduced here
- = note: required for the cast from `S<Foo>` to the object type `dyn Gettable<Foo>`
+ = note: required for the cast from `Box<S<Foo>>` to `Box<dyn Gettable<Foo>>`
help: consider annotating `Foo` with `#[derive(Copy)]`
|
LL + #[derive(Copy)]
diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr
index 8d45748a6c4..29495176556 100644
--- a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr
+++ b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr
@@ -46,8 +46,7 @@ LL | trait Foo : Copy {
| --- ^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required for `&Box<{integer}>` to implement `CoerceUnsized<&dyn Foo>`
- = note: required by cast to type `&dyn Foo`
+ = note: required for the cast from `&Box<{integer}>` to `&dyn Foo`
error: aborting due to 3 previous errors
diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
index 2fbb5a98a8d..3e164ebf514 100644
--- a/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
+++ b/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
@@ -32,8 +32,7 @@ LL | trait Foo : Copy {
| --- ^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required for `&Box<i32>` to implement `CoerceUnsized<&dyn Foo>`
- = note: required by cast to type `&dyn Foo`
+ = note: required for the cast from `&Box<i32>` to `&dyn Foo`
error: aborting due to 2 previous errors
diff --git a/tests/ui/kindck/kindck-send-unsafe.rs b/tests/ui/kindck/kindck-send-unsafe.rs
index 4ef30a71fa3..eb1f2a549b1 100644
--- a/tests/ui/kindck/kindck-send-unsafe.rs
+++ b/tests/ui/kindck/kindck-send-unsafe.rs
@@ -1,11 +1,15 @@
extern crate core;
-fn assert_send<T:Send>() { }
+fn assert_send<T: Send>() {}
+
+fn test70() {
+ assert_send::<*mut isize>();
+ //~^ ERROR `*mut isize` cannot be sent between threads safely
+}
fn test71<'a>() {
assert_send::<*mut &'a isize>();
//~^ ERROR `*mut &'a isize` cannot be sent between threads safely
}
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/kindck/kindck-send-unsafe.rs~rust-lang_master b/tests/ui/kindck/kindck-send-unsafe.rs~rust-lang_master
deleted file mode 100644
index 3f0444ec9c8..00000000000
--- a/tests/ui/kindck/kindck-send-unsafe.rs~rust-lang_master
+++ /dev/null
@@ -1,12 +0,0 @@
-fn assert_send<T:Send>() { }
-
-// unsafe ptrs are ok unless they point at unsendable things
-fn test70() {
- assert_send::<*mut int>();
-}
-fn test71<'a>() {
- assert_send::<*mut &'a int>(); //~ ERROR does not fulfill the required lifetime
-}
-
-fn main() {
-}
diff --git a/tests/ui/kindck/kindck-send-unsafe.stderr b/tests/ui/kindck/kindck-send-unsafe.stderr
index ceed0053caa..f1a5054abbc 100644
--- a/tests/ui/kindck/kindck-send-unsafe.stderr
+++ b/tests/ui/kindck/kindck-send-unsafe.stderr
@@ -1,16 +1,29 @@
-error[E0277]: `*mut &'a isize` cannot be sent between threads safely
+error[E0277]: `*mut isize` cannot be sent between threads safely
--> $DIR/kindck-send-unsafe.rs:6:19
|
+LL | assert_send::<*mut isize>();
+ | ^^^^^^^^^^ `*mut isize` cannot be sent between threads safely
+ |
+ = help: the trait `Send` is not implemented for `*mut isize`
+note: required by a bound in `assert_send`
+ --> $DIR/kindck-send-unsafe.rs:3:19
+ |
+LL | fn assert_send<T: Send>() {}
+ | ^^^^ required by this bound in `assert_send`
+
+error[E0277]: `*mut &'a isize` cannot be sent between threads safely
+ --> $DIR/kindck-send-unsafe.rs:11:19
+ |
LL | assert_send::<*mut &'a isize>();
| ^^^^^^^^^^^^^^ `*mut &'a isize` cannot be sent between threads safely
|
= help: the trait `Send` is not implemented for `*mut &'a isize`
note: required by a bound in `assert_send`
- --> $DIR/kindck-send-unsafe.rs:3:18
+ --> $DIR/kindck-send-unsafe.rs:3:19
|
-LL | fn assert_send<T:Send>() { }
- | ^^^^ required by this bound in `assert_send`
+LL | fn assert_send<T: Send>() {}
+ | ^^^^ required by this bound in `assert_send`
-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/tests/ui/lifetimes/issue-64173-unused-lifetimes.rs b/tests/ui/lifetimes/issue-64173-unused-lifetimes.rs
index 8080dd7dc34..3879784d0b0 100644
--- a/tests/ui/lifetimes/issue-64173-unused-lifetimes.rs
+++ b/tests/ui/lifetimes/issue-64173-unused-lifetimes.rs
@@ -13,7 +13,7 @@ const fn foo<T>() -> usize {
}
struct Bar<'a> { //~ ERROR: parameter `'a` is never used
- beta: [(); foo::<&'a ()>()], //~ ERROR: a non-static lifetime is not allowed in a `const`
+ beta: [(); foo::<&'a ()>()], //~ ERROR: generic parameters may not be used in const operations
}
fn main() {}
diff --git a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr
index a487cbea537..02ca10b2eb6 100644
--- a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr
+++ b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr
@@ -1,11 +1,11 @@
-error[E0658]: a non-static lifetime is not allowed in a `const`
+error: generic parameters may not be used in const operations
--> $DIR/issue-64173-unused-lifetimes.rs:16:23
|
LL | beta: [(); foo::<&'a ()>()],
- | ^^
+ | ^^ cannot perform const operation using `'a`
|
- = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
- = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+ = note: lifetime parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic `Self` types are currently not permitted in anonymous constants
--> $DIR/issue-64173-unused-lifetimes.rs:4:28
@@ -31,5 +31,4 @@ LL | struct Bar<'a> {
error: aborting due to 4 previous errors
-Some errors have detailed explanations: E0392, E0658.
-For more information about an error, try `rustc --explain E0392`.
+For more information about this error, try `rustc --explain E0392`.
diff --git a/tests/ui/lifetimes/unusual-rib-combinations.rs b/tests/ui/lifetimes/unusual-rib-combinations.rs
index 0ae68ad04f7..2f5ba98445b 100644
--- a/tests/ui/lifetimes/unusual-rib-combinations.rs
+++ b/tests/ui/lifetimes/unusual-rib-combinations.rs
@@ -27,7 +27,7 @@ fn d<const C: S>() {}
trait Foo<'a> {}
struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>;
-//~^ ERROR use of non-static lifetime `'a` in const generic
+//~^ ERROR the type of const parameters must not depend on other generic parameters
//~| ERROR `&dyn for<'a> Foo<'a>` is forbidden as the type of a const generic parameter
fn main() {}
diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr
index 20163d289b1..4994e4dc444 100644
--- a/tests/ui/lifetimes/unusual-rib-combinations.stderr
+++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr
@@ -9,13 +9,13 @@ help: consider introducing a named lifetime parameter
LL | fn d<'a, const C: S<'a>>() {}
| +++ ++++
-error[E0771]: use of non-static lifetime `'a` in const generic
+error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/unusual-rib-combinations.rs:29:22
|
LL | struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>;
- | ^^
+ | ^^ the type must not depend on the parameter `'a`
|
- = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
+ = note: lifetime parameters may not be used in the type of const parameters
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/unusual-rib-combinations.rs:7:16
@@ -74,5 +74,5 @@ LL | struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>;
error: aborting due to 9 previous errors
-Some errors have detailed explanations: E0106, E0214, E0308, E0771.
+Some errors have detailed explanations: E0106, E0214, E0308, E0770.
For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/lint/drop_copy.rs b/tests/ui/lint/drop_copy.rs
new file mode 100644
index 00000000000..0adcd34505f
--- /dev/null
+++ b/tests/ui/lint/drop_copy.rs
@@ -0,0 +1,79 @@
+// check-pass
+
+#![warn(drop_copy)]
+
+use std::mem::drop;
+use std::vec::Vec;
+
+#[derive(Copy, Clone)]
+struct SomeStruct;
+
+struct AnotherStruct {
+ x: u8,
+ y: u8,
+ z: Vec<u8>,
+}
+
+impl Clone for AnotherStruct {
+ fn clone(&self) -> AnotherStruct {
+ AnotherStruct {
+ x: self.x,
+ y: self.y,
+ z: self.z.clone(),
+ }
+ }
+}
+
+fn main() {
+ let s1 = SomeStruct {};
+ let s2 = s1;
+ let s3 = &s1;
+ let mut s4 = s1;
+ let ref s5 = s1;
+
+ drop(s1); //~ WARN calls to `std::mem::drop`
+ drop(s2); //~ WARN calls to `std::mem::drop`
+ drop(s3); //~ WARN calls to `std::mem::drop`
+ drop(s4); //~ WARN calls to `std::mem::drop`
+ drop(s5); //~ WARN calls to `std::mem::drop`
+
+ let a1 = AnotherStruct {
+ x: 255,
+ y: 0,
+ z: vec![1, 2, 3],
+ };
+ let a2 = &a1;
+ let mut a3 = a1.clone();
+ let ref a4 = a1;
+ let a5 = a1.clone();
+
+ drop(a2); //~ WARN calls to `std::mem::drop`
+ drop(a3);
+ drop(a4); //~ WARN calls to `std::mem::drop`
+ drop(a5);
+}
+
+#[allow(unused)]
+#[allow(clippy::unit_cmp)]
+fn issue9482(x: u8) {
+ fn println_and<T>(t: T) -> T {
+ println!("foo");
+ t
+ }
+
+ match x {
+ // Don't lint (copy type), we only care about side-effects
+ 0 => drop(println_and(12)),
+ // Don't lint (no copy type), we only care about side-effects
+ 1 => drop(println_and(String::new())),
+ 2 => {
+ // Lint, even if we only care about the side-effect, it's already in a block
+ drop(println_and(13)); //~ WARN calls to `std::mem::drop`
+ },
+ // Lint, idiomatic use is only in body of `Arm`
+ 3 if drop(println_and(14)) == () => (), //~ WARN calls to `std::mem::drop`
+ // Lint, not a fn/method call
+ 4 => drop(2),//~ WARN calls to `std::mem::drop`
+ _ => (),
+ }
+}
diff --git a/tests/ui/lint/drop_copy.stderr b/tests/ui/lint/drop_copy.stderr
new file mode 100644
index 00000000000..db8e89ad295
--- /dev/null
+++ b/tests/ui/lint/drop_copy.stderr
@@ -0,0 +1,108 @@
+warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+ --> $DIR/drop_copy.rs:34:5
+ |
+LL | drop(s1);
+ | ^^^^^--^
+ | |
+ | argument has type `SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+note: the lint level is defined here
+ --> $DIR/drop_copy.rs:3:9
+ |
+LL | #![warn(drop_copy)]
+ | ^^^^^^^^^
+
+warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+ --> $DIR/drop_copy.rs:35:5
+ |
+LL | drop(s2);
+ | ^^^^^--^
+ | |
+ | argument has type `SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_copy.rs:36:5
+ |
+LL | drop(s3);
+ | ^^^^^--^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+ = note: `#[warn(drop_ref)]` on by default
+
+warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+ --> $DIR/drop_copy.rs:37:5
+ |
+LL | drop(s4);
+ | ^^^^^--^
+ | |
+ | argument has type `SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_copy.rs:38:5
+ |
+LL | drop(s5);
+ | ^^^^^--^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_copy.rs:50:5
+ |
+LL | drop(a2);
+ | ^^^^^--^
+ | |
+ | argument has type `&AnotherStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_copy.rs:52:5
+ |
+LL | drop(a4);
+ | ^^^^^--^
+ | |
+ | argument has type `&AnotherStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+ --> $DIR/drop_copy.rs:71:13
+ |
+LL | drop(println_and(13));
+ | ^^^^^---------------^
+ | |
+ | argument has type `i32`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+ --> $DIR/drop_copy.rs:74:14
+ |
+LL | 3 if drop(println_and(14)) == () => (),
+ | ^^^^^---------------^
+ | |
+ | argument has type `i32`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+ --> $DIR/drop_copy.rs:76:14
+ |
+LL | 4 => drop(2),
+ | ^^^^^-^
+ | |
+ | argument has type `i32`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: 10 warnings emitted
+
diff --git a/src/tools/clippy/tests/ui/drop_ref.rs b/tests/ui/lint/drop_ref.rs
index 10044e65f11..db4f7569f6f 100644
--- a/src/tools/clippy/tests/ui/drop_ref.rs
+++ b/tests/ui/lint/drop_ref.rs
@@ -1,42 +1,39 @@
-#![warn(clippy::drop_ref)]
-#![allow(clippy::toplevel_ref_arg)]
-#![allow(clippy::map_err_ignore)]
-#![allow(clippy::unnecessary_wraps, clippy::drop_non_drop)]
+// check-pass
-use std::mem::drop;
+#![warn(drop_ref)]
struct SomeStruct;
fn main() {
- drop(&SomeStruct);
+ drop(&SomeStruct); //~ WARN calls to `std::mem::drop`
let mut owned1 = SomeStruct;
- drop(&owned1);
- drop(&&owned1);
- drop(&mut owned1);
- drop(owned1); //OK
+ drop(&owned1); //~ WARN calls to `std::mem::drop`
+ drop(&&owned1); //~ WARN calls to `std::mem::drop`
+ drop(&mut owned1); //~ WARN calls to `std::mem::drop`
+ drop(owned1);
let reference1 = &SomeStruct;
- drop(reference1);
+ drop(reference1); //~ WARN calls to `std::mem::drop`
let reference2 = &mut SomeStruct;
- drop(reference2);
+ drop(reference2); //~ WARN calls to `std::mem::drop`
let ref reference3 = SomeStruct;
- drop(reference3);
+ drop(reference3); //~ WARN calls to `std::mem::drop`
}
#[allow(dead_code)]
fn test_generic_fn_drop<T>(val: T) {
- drop(&val);
- drop(val); //OK
+ drop(&val); //~ WARN calls to `std::mem::drop`
+ drop(val);
}
#[allow(dead_code)]
fn test_similarly_named_function() {
fn drop<T>(_val: T) {}
drop(&SomeStruct); //OK; call to unrelated function which happens to have the same name
- std::mem::drop(&SomeStruct);
+ std::mem::drop(&SomeStruct); //~ WARN calls to `std::mem::drop`
}
#[derive(Copy, Clone)]
@@ -77,21 +74,26 @@ fn test_owl_result_2() -> Result<u8, ()> {
#[allow(clippy::unit_cmp)]
fn issue10122(x: u8) {
// This is a function which returns a reference and has a side-effect, which means
- // that calling drop() on the function is considered an idiomatic way of achieving the side-effect
- // in a match arm.
+ // that calling drop() on the function is considered an idiomatic way of achieving
+ // the side-effect in a match arm.
fn println_and<T>(t: &T) -> &T {
println!("foo");
t
}
match x {
- 0 => drop(println_and(&12)), // Don't lint (copy type), we only care about side-effects
- 1 => drop(println_and(&String::new())), // Don't lint (no copy type), we only care about side-effects
+ // Don't lint (copy type), we only care about side-effects
+ 0 => drop(println_and(&12)),
+ // Don't lint (no copy type), we only care about side-effects
+ 1 => drop(println_and(&String::new())),
2 => {
- drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block
+ // Lint, even if we only care about the side-effect, it's already in a block
+ drop(println_and(&13)); //~ WARN calls to `std::mem::drop`
},
- 3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm`
- 4 => drop(&2), // Lint, not a fn/method call
+ // Lint, idiomatic use is only in body of `Arm`
+ 3 if drop(println_and(&14)) == () => (), //~ WARN calls to `std::mem::drop`
+ // Lint, not a fn/method call
+ 4 => drop(&2), //~ WARN calls to `std::mem::drop`
_ => (),
}
}
diff --git a/tests/ui/lint/drop_ref.stderr b/tests/ui/lint/drop_ref.stderr
new file mode 100644
index 00000000000..04c988fe99d
--- /dev/null
+++ b/tests/ui/lint/drop_ref.stderr
@@ -0,0 +1,127 @@
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_ref.rs:8:5
+ |
+LL | drop(&SomeStruct);
+ | ^^^^^-----------^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+note: the lint level is defined here
+ --> $DIR/drop_ref.rs:3:9
+ |
+LL | #![warn(drop_ref)]
+ | ^^^^^^^^
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_ref.rs:11:5
+ |
+LL | drop(&owned1);
+ | ^^^^^-------^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_ref.rs:12:5
+ |
+LL | drop(&&owned1);
+ | ^^^^^--------^
+ | |
+ | argument has type `&&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_ref.rs:13:5
+ |
+LL | drop(&mut owned1);
+ | ^^^^^-----------^
+ | |
+ | argument has type `&mut SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_ref.rs:17:5
+ |
+LL | drop(reference1);
+ | ^^^^^----------^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_ref.rs:20:5
+ |
+LL | drop(reference2);
+ | ^^^^^----------^
+ | |
+ | argument has type `&mut SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_ref.rs:23:5
+ |
+LL | drop(reference3);
+ | ^^^^^----------^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_ref.rs:28:5
+ |
+LL | drop(&val);
+ | ^^^^^----^
+ | |
+ | argument has type `&T`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_ref.rs:36:5
+ |
+LL | std::mem::drop(&SomeStruct);
+ | ^^^^^^^^^^^^^^^-----------^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_ref.rs:91:13
+ |
+LL | drop(println_and(&13));
+ | ^^^^^----------------^
+ | |
+ | argument has type `&i32`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_ref.rs:94:14
+ |
+LL | 3 if drop(println_and(&14)) == () => (),
+ | ^^^^^----------------^
+ | |
+ | argument has type `&i32`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+ --> $DIR/drop_ref.rs:96:14
+ |
+LL | 4 => drop(&2),
+ | ^^^^^--^
+ | |
+ | argument has type `&i32`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: 12 warnings emitted
+
diff --git a/tests/ui/lint/forget_copy.rs b/tests/ui/lint/forget_copy.rs
new file mode 100644
index 00000000000..a6b17b76971
--- /dev/null
+++ b/tests/ui/lint/forget_copy.rs
@@ -0,0 +1,56 @@
+// check-pass
+
+#![warn(forget_copy)]
+
+use std::mem::forget;
+use std::vec::Vec;
+
+#[derive(Copy, Clone)]
+struct SomeStruct;
+
+struct AnotherStruct {
+ x: u8,
+ y: u8,
+ z: Vec<u8>,
+}
+
+impl Clone for AnotherStruct {
+ fn clone(&self) -> AnotherStruct {
+ AnotherStruct {
+ x: self.x,
+ y: self.y,
+ z: self.z.clone(),
+ }
+ }
+}
+
+fn main() {
+ let s1 = SomeStruct {};
+ let s2 = s1;
+ let s3 = &s1;
+ let mut s4 = s1;
+ let ref s5 = s1;
+
+ forget(s1); //~ WARN calls to `std::mem::forget`
+ forget(s2); //~ WARN calls to `std::mem::forget`
+ forget(s3); //~ WARN calls to `std::mem::forget`
+ forget(s4); //~ WARN calls to `std::mem::forget`
+ forget(s5); //~ WARN calls to `std::mem::forget`
+
+ let a1 = AnotherStruct {
+ x: 255,
+ y: 0,
+ z: vec![1, 2, 3],
+ };
+ let a2 = &a1;
+ let mut a3 = a1.clone();
+ let ref a4 = a1;
+ let a5 = a1.clone();
+
+ forget(a2); //~ WARN calls to `std::mem::forget`
+ let a3 = &a1;
+ forget(a3); //~ WARN calls to `std::mem::forget`
+ forget(a4); //~ WARN calls to `std::mem::forget`
+ let a5 = a1.clone();
+ forget(a5);
+}
diff --git a/tests/ui/lint/forget_copy.stderr b/tests/ui/lint/forget_copy.stderr
new file mode 100644
index 00000000000..37bc8a8854e
--- /dev/null
+++ b/tests/ui/lint/forget_copy.stderr
@@ -0,0 +1,88 @@
+warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing
+ --> $DIR/forget_copy.rs:34:5
+ |
+LL | forget(s1);
+ | ^^^^^^^--^
+ | |
+ | argument has type `SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+note: the lint level is defined here
+ --> $DIR/forget_copy.rs:3:9
+ |
+LL | #![warn(forget_copy)]
+ | ^^^^^^^^^^^
+
+warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing
+ --> $DIR/forget_copy.rs:35:5
+ |
+LL | forget(s2);
+ | ^^^^^^^--^
+ | |
+ | argument has type `SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_copy.rs:36:5
+ |
+LL | forget(s3);
+ | ^^^^^^^--^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+ = note: `#[warn(forget_ref)]` on by default
+
+warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing
+ --> $DIR/forget_copy.rs:37:5
+ |
+LL | forget(s4);
+ | ^^^^^^^--^
+ | |
+ | argument has type `SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_copy.rs:38:5
+ |
+LL | forget(s5);
+ | ^^^^^^^--^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_copy.rs:50:5
+ |
+LL | forget(a2);
+ | ^^^^^^^--^
+ | |
+ | argument has type `&AnotherStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_copy.rs:52:5
+ |
+LL | forget(a3);
+ | ^^^^^^^--^
+ | |
+ | argument has type `&AnotherStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_copy.rs:53:5
+ |
+LL | forget(a4);
+ | ^^^^^^^--^
+ | |
+ | argument has type `&AnotherStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: 8 warnings emitted
+
diff --git a/tests/ui/lint/forget_ref.rs b/tests/ui/lint/forget_ref.rs
new file mode 100644
index 00000000000..13f6d4be3d1
--- /dev/null
+++ b/tests/ui/lint/forget_ref.rs
@@ -0,0 +1,39 @@
+// check-pass
+
+#![warn(forget_ref)]
+
+use std::mem::forget;
+
+struct SomeStruct;
+
+fn main() {
+ forget(&SomeStruct); //~ WARN calls to `std::mem::forget`
+
+ let mut owned = SomeStruct;
+ forget(&owned); //~ WARN calls to `std::mem::forget`
+ forget(&&owned); //~ WARN calls to `std::mem::forget`
+ forget(&mut owned); //~ WARN calls to `std::mem::forget`
+ forget(owned);
+
+ let reference1 = &SomeStruct;
+ forget(&*reference1); //~ WARN calls to `std::mem::forget`
+
+ let reference2 = &mut SomeStruct;
+ forget(reference2); //~ WARN calls to `std::mem::forget`
+
+ let ref reference3 = SomeStruct;
+ forget(reference3); //~ WARN calls to `std::mem::forget`
+}
+
+#[allow(dead_code)]
+fn test_generic_fn_forget<T>(val: T) {
+ forget(&val); //~ WARN calls to `std::mem::forget`
+ forget(val);
+}
+
+#[allow(dead_code)]
+fn test_similarly_named_function() {
+ fn forget<T>(_val: T) {}
+ forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name
+ std::mem::forget(&SomeStruct); //~ WARN calls to `std::mem::forget`
+}
diff --git a/tests/ui/lint/forget_ref.stderr b/tests/ui/lint/forget_ref.stderr
new file mode 100644
index 00000000000..63fc7791980
--- /dev/null
+++ b/tests/ui/lint/forget_ref.stderr
@@ -0,0 +1,97 @@
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_ref.rs:10:5
+ |
+LL | forget(&SomeStruct);
+ | ^^^^^^^-----------^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+note: the lint level is defined here
+ --> $DIR/forget_ref.rs:3:9
+ |
+LL | #![warn(forget_ref)]
+ | ^^^^^^^^^^
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_ref.rs:13:5
+ |
+LL | forget(&owned);
+ | ^^^^^^^------^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_ref.rs:14:5
+ |
+LL | forget(&&owned);
+ | ^^^^^^^-------^
+ | |
+ | argument has type `&&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_ref.rs:15:5
+ |
+LL | forget(&mut owned);
+ | ^^^^^^^----------^
+ | |
+ | argument has type `&mut SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_ref.rs:19:5
+ |
+LL | forget(&*reference1);
+ | ^^^^^^^------------^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_ref.rs:22:5
+ |
+LL | forget(reference2);
+ | ^^^^^^^----------^
+ | |
+ | argument has type `&mut SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_ref.rs:25:5
+ |
+LL | forget(reference3);
+ | ^^^^^^^----------^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_ref.rs:30:5
+ |
+LL | forget(&val);
+ | ^^^^^^^----^
+ | |
+ | argument has type `&T`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+ --> $DIR/forget_ref.rs:38:5
+ |
+LL | std::mem::forget(&SomeStruct);
+ | ^^^^^^^^^^^^^^^^^-----------^
+ | |
+ | argument has type `&SomeStruct`
+ |
+ = note: use `let _ = ...` to ignore the expression or result
+
+warning: 9 warnings emitted
+
diff --git a/tests/ui/lint/issue-111359.rs b/tests/ui/lint/issue-111359.rs
new file mode 100644
index 00000000000..e390c3fc565
--- /dev/null
+++ b/tests/ui/lint/issue-111359.rs
@@ -0,0 +1,27 @@
+#[deny(missing_debug_implementations)]
+#[deny(missing_copy_implementations)]
+
+mod priv_mod {
+ use std::convert::TryFrom;
+
+ pub struct BarPub;
+ //~^ ERROR type does not implement `Debug`; consider adding `#[derive(Debug)]` or a manual implementation
+ //~| ERROR type could implement `Copy`; consider adding `impl Copy`
+ struct BarPriv;
+
+ impl<'a> TryFrom<BarPriv> for u8 {
+ type Error = ();
+ fn try_from(o: BarPriv) -> Result<Self, ()> {
+ unimplemented!()
+ }
+ }
+
+ impl<'a> TryFrom<BarPub> for u8 {
+ type Error = ();
+ fn try_from(o: BarPub) -> Result<Self, ()> {
+ unimplemented!()
+ }
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/issue-111359.stderr b/tests/ui/lint/issue-111359.stderr
new file mode 100644
index 00000000000..2296d8413d6
--- /dev/null
+++ b/tests/ui/lint/issue-111359.stderr
@@ -0,0 +1,26 @@
+error: type does not implement `Debug`; consider adding `#[derive(Debug)]` or a manual implementation
+ --> $DIR/issue-111359.rs:7:5
+ |
+LL | pub struct BarPub;
+ | ^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-111359.rs:1:8
+ |
+LL | #[deny(missing_debug_implementations)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: type could implement `Copy`; consider adding `impl Copy`
+ --> $DIR/issue-111359.rs:7:5
+ |
+LL | pub struct BarPub;
+ | ^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-111359.rs:2:8
+ |
+LL | #[deny(missing_copy_implementations)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/liveness/liveness-unused.rs b/tests/ui/liveness/liveness-unused.rs
index 9c7be15fcc8..8ef6ab1b6ff 100644
--- a/tests/ui/liveness/liveness-unused.rs
+++ b/tests/ui/liveness/liveness-unused.rs
@@ -1,7 +1,7 @@
#![warn(unused)]
#![deny(unused_variables)]
#![deny(unused_assignments)]
-#![allow(dead_code, non_camel_case_types, trivial_numeric_casts)]
+#![allow(dead_code, non_camel_case_types, trivial_numeric_casts, drop_copy)]
use std::ops::AddAssign;
diff --git a/tests/ui/macros/builtin-prelude-no-accidents.stderr b/tests/ui/macros/builtin-prelude-no-accidents.stderr
index 56af618d484..8cd9a63b808 100644
--- a/tests/ui/macros/builtin-prelude-no-accidents.stderr
+++ b/tests/ui/macros/builtin-prelude-no-accidents.stderr
@@ -4,18 +4,21 @@ error[E0433]: failed to resolve: use of undeclared crate or module `env`
LL | env::current_dir;
| ^^^ use of undeclared crate or module `env`
+error[E0433]: failed to resolve: use of undeclared crate or module `vec`
+ --> $DIR/builtin-prelude-no-accidents.rs:7:14
+ |
+LL | type B = vec::Vec<u8>;
+ | ^^^
+ | |
+ | use of undeclared crate or module `vec`
+ | help: a struct with a similar name exists (notice the capitalization): `Vec`
+
error[E0433]: failed to resolve: use of undeclared crate or module `panic`
--> $DIR/builtin-prelude-no-accidents.rs:6:14
|
LL | type A = panic::PanicInfo;
| ^^^^^ use of undeclared crate or module `panic`
-error[E0433]: failed to resolve: use of undeclared crate or module `vec`
- --> $DIR/builtin-prelude-no-accidents.rs:7:14
- |
-LL | type B = vec::Vec<u8>;
- | ^^^ use of undeclared crate or module `vec`
-
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0433`.
diff --git a/tests/ui/issues/issue-2804-2.rs b/tests/ui/macros/issue-2804-2.rs
index d02725505ac..d02725505ac 100644
--- a/tests/ui/issues/issue-2804-2.rs
+++ b/tests/ui/macros/issue-2804-2.rs
diff --git a/tests/ui/macros/panic-temporaries.rs b/tests/ui/macros/panic-temporaries.rs
new file mode 100644
index 00000000000..5b5b8b7c2d9
--- /dev/null
+++ b/tests/ui/macros/panic-temporaries.rs
@@ -0,0 +1,19 @@
+// check-pass
+// edition:2021
+
+#![allow(unreachable_code)]
+
+async fn f(_: u8) {}
+
+async fn g() {
+ // Todo returns `!`, so the await is never reached, and in particular the
+ // temporaries inside the formatting machinery are not still alive at the
+ // await point.
+ f(todo!("...")).await;
+}
+
+fn require_send(_: impl Send) {}
+
+fn main() {
+ require_send(g());
+}
diff --git a/tests/ui/macros/parse-complex-macro-invoc-op.rs b/tests/ui/macros/parse-complex-macro-invoc-op.rs
index 8fef9b0ed87..c50dfdf0116 100644
--- a/tests/ui/macros/parse-complex-macro-invoc-op.rs
+++ b/tests/ui/macros/parse-complex-macro-invoc-op.rs
@@ -4,6 +4,7 @@
#![allow(unused_assignments)]
#![allow(unused_variables)]
#![allow(stable_features)]
+#![allow(drop_copy)]
// Test parsing binary operators after macro invocations.
diff --git a/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout b/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout
index ad97f7a4a75..b69b5bc3b53 100644
--- a/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout
+++ b/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout
@@ -26,7 +26,7 @@ fn arbitrary_consuming_method_for_demonstration_purposes() {
{
::std::rt::panic_fmt(format_args!("Assertion failed: elem as usize\nWith captures:\n elem = {0:?}\n",
- __capture0))
+ __capture0));
}
}
};
@@ -42,7 +42,7 @@ fn addr_of() {
(&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
{
::std::rt::panic_fmt(format_args!("Assertion failed: &elem\nWith captures:\n elem = {0:?}\n",
- __capture0))
+ __capture0));
}
}
};
@@ -58,7 +58,7 @@ fn binary() {
(&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
{
::std::rt::panic_fmt(format_args!("Assertion failed: elem == 1\nWith captures:\n elem = {0:?}\n",
- __capture0))
+ __capture0));
}
}
};
@@ -71,7 +71,7 @@ fn binary() {
(&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
{
::std::rt::panic_fmt(format_args!("Assertion failed: elem >= 1\nWith captures:\n elem = {0:?}\n",
- __capture0))
+ __capture0));
}
}
};
@@ -84,7 +84,7 @@ fn binary() {
(&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
{
::std::rt::panic_fmt(format_args!("Assertion failed: elem > 0\nWith captures:\n elem = {0:?}\n",
- __capture0))
+ __capture0));
}
}
};
@@ -97,7 +97,7 @@ fn binary() {
(&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
{
::std::rt::panic_fmt(format_args!("Assertion failed: elem < 3\nWith captures:\n elem = {0:?}\n",
- __capture0))
+ __capture0));
}
}
};
@@ -110,7 +110,7 @@ fn binary() {
(&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
{
::std::rt::panic_fmt(format_args!("Assertion failed: elem <= 3\nWith captures:\n elem = {0:?}\n",
- __capture0))
+ __capture0));
}
}
};
@@ -123,7 +123,7 @@ fn binary() {
(&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
{
::std::rt::panic_fmt(format_args!("Assertion failed: elem != 3\nWith captures:\n elem = {0:?}\n",
- __capture0))
+ __capture0));
}
}
};
@@ -139,7 +139,7 @@ fn unary() {
(&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
{
::std::rt::panic_fmt(format_args!("Assertion failed: *elem\nWith captures:\n elem = {0:?}\n",
- __capture0))
+ __capture0));
}
}
};
diff --git a/tests/ui/methods/method-self-arg-1.stderr b/tests/ui/methods/method-self-arg-1.stderr
index 9241a8be58f..dcc21acc5c0 100644
--- a/tests/ui/methods/method-self-arg-1.stderr
+++ b/tests/ui/methods/method-self-arg-1.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
--> $DIR/method-self-arg-1.rs:11:14
|
LL | Foo::bar(x);
- | -------- ^
- | | |
- | | expected `&Foo`, found `Foo`
- | | help: consider borrowing here: `&x`
+ | -------- ^ expected `&Foo`, found `Foo`
+ | |
| arguments to this function are incorrect
|
note: method defined here
@@ -13,6 +11,10 @@ note: method defined here
|
LL | fn bar(&self) {}
| ^^^ -----
+help: consider borrowing here
+ |
+LL | Foo::bar(&x);
+ | +
error[E0308]: mismatched types
--> $DIR/method-self-arg-1.rs:13:14
diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr
index 2a36a352c73..6b9ac3c5852 100644
--- a/tests/ui/mismatched_types/cast-rfc0401.stderr
+++ b/tests/ui/mismatched_types/cast-rfc0401.stderr
@@ -220,11 +220,7 @@ LL | let _ = fat_v as *const dyn Foo;
| ^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
- = note: required for the cast from `[u8]` to the object type `dyn Foo`
-help: consider borrowing the value, since `&[u8]` can be coerced into `dyn Foo`
- |
-LL | let _ = &fat_v as *const dyn Foo;
- | +
+ = note: required for the cast from `*const [u8]` to `*const dyn Foo`
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/cast-rfc0401.rs:62:13
@@ -233,11 +229,7 @@ LL | let _ = a as *const dyn Foo;
| ^ 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 Foo`
-help: consider borrowing the value, since `&str` can be coerced into `dyn Foo`
- |
-LL | let _ = &a as *const dyn Foo;
- | +
+ = note: required for the cast from `*const str` to `*const dyn Foo`
error[E0606]: casting `&{float}` as `f32` is invalid
--> $DIR/cast-rfc0401.rs:71:30
diff --git a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
index 13942682d28..7be94ef4ad6 100644
--- a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
+++ b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
--> $DIR/dont-point-return-on-E0308.rs:11:11
|
LL | f(());
- | - ^^
- | | |
- | | expected `&()`, found `()`
- | | help: consider borrowing here: `&()`
+ | - ^^ expected `&()`, found `()`
+ | |
| arguments to this function are incorrect
|
note: function defined here
@@ -13,6 +11,10 @@ note: function defined here
|
LL | async fn f(_: &()) {}
| ^ ------
+help: consider borrowing here
+ |
+LL | f(&());
+ | +
error: aborting due to previous error
diff --git a/tests/ui/mut/mut-cross-borrowing.stderr b/tests/ui/mut/mut-cross-borrowing.stderr
index 8401827e51f..8a3076db9b2 100644
--- a/tests/ui/mut/mut-cross-borrowing.stderr
+++ b/tests/ui/mut/mut-cross-borrowing.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
--> $DIR/mut-cross-borrowing.rs:7:7
|
LL | f(x)
- | - ^
- | | |
- | | expected `&mut isize`, found `Box<{integer}>`
- | | help: consider mutably borrowing here: `&mut x`
+ | - ^ expected `&mut isize`, found `Box<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected mutable reference `&mut isize`
@@ -15,6 +13,10 @@ note: function defined here
|
LL | fn f(_: &mut isize) {}
| ^ -------------
+help: consider mutably borrowing here
+ |
+LL | f(&mut x)
+ | ++++
error: aborting due to previous error
diff --git a/tests/ui/never_type/fallback-closure-wrap.fallback.stderr b/tests/ui/never_type/fallback-closure-wrap.fallback.stderr
index a0f790dba15..5b6f0235123 100644
--- a/tests/ui/never_type/fallback-closure-wrap.fallback.stderr
+++ b/tests/ui/never_type/fallback-closure-wrap.fallback.stderr
@@ -10,7 +10,7 @@ LL | | }) as Box<dyn FnMut()>);
|
= note: expected unit type `()`
found type `!`
- = note: required for the cast from `[closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47]` to the object type `dyn FnMut()`
+ = note: required for the cast from `Box<[closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47]>` to `Box<dyn FnMut()>`
error: aborting due to previous error
diff --git a/tests/ui/never_type/never-assign-dead-code.rs b/tests/ui/never_type/never-assign-dead-code.rs
index 7bb7c87097c..e95a992d780 100644
--- a/tests/ui/never_type/never-assign-dead-code.rs
+++ b/tests/ui/never_type/never-assign-dead-code.rs
@@ -3,6 +3,7 @@
// check-pass
#![feature(never_type)]
+#![allow(drop_copy)]
#![warn(unused)]
fn main() {
diff --git a/tests/ui/never_type/never-assign-dead-code.stderr b/tests/ui/never_type/never-assign-dead-code.stderr
index 521b82023c9..5660bde5c27 100644
--- a/tests/ui/never_type/never-assign-dead-code.stderr
+++ b/tests/ui/never_type/never-assign-dead-code.stderr
@@ -1,5 +1,5 @@
warning: unreachable statement
- --> $DIR/never-assign-dead-code.rs:10:5
+ --> $DIR/never-assign-dead-code.rs:11:5
|
LL | let x: ! = panic!("aah");
| ------------- any code following this expression is unreachable
@@ -7,14 +7,14 @@ LL | drop(x);
| ^^^^^^^^ unreachable statement
|
note: the lint level is defined here
- --> $DIR/never-assign-dead-code.rs:6:9
+ --> $DIR/never-assign-dead-code.rs:7:9
|
LL | #![warn(unused)]
| ^^^^^^
= note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]`
warning: unreachable call
- --> $DIR/never-assign-dead-code.rs:10:5
+ --> $DIR/never-assign-dead-code.rs:11:5
|
LL | drop(x);
| ^^^^ - any code following this expression is unreachable
@@ -22,7 +22,7 @@ LL | drop(x);
| unreachable call
warning: unused variable: `x`
- --> $DIR/never-assign-dead-code.rs:9:9
+ --> $DIR/never-assign-dead-code.rs:10:9
|
LL | let x: ! = panic!("aah");
| ^ help: if this is intentional, prefix it with an underscore: `_x`
diff --git a/tests/ui/issues/issue-30438-a.rs b/tests/ui/nll/issue-30438-a.rs
index 0d4eb796ad9..0d4eb796ad9 100644
--- a/tests/ui/issues/issue-30438-a.rs
+++ b/tests/ui/nll/issue-30438-a.rs
diff --git a/tests/ui/issues/issue-30438-a.stderr b/tests/ui/nll/issue-30438-a.stderr
index 53845af82fb..53845af82fb 100644
--- a/tests/ui/issues/issue-30438-a.stderr
+++ b/tests/ui/nll/issue-30438-a.stderr
diff --git a/tests/ui/issues/issue-30438-b.rs b/tests/ui/nll/issue-30438-b.rs
index 79510cdb663..79510cdb663 100644
--- a/tests/ui/issues/issue-30438-b.rs
+++ b/tests/ui/nll/issue-30438-b.rs
diff --git a/tests/ui/issues/issue-30438-b.stderr b/tests/ui/nll/issue-30438-b.stderr
index fd6bd25b1da..fd6bd25b1da 100644
--- a/tests/ui/issues/issue-30438-b.stderr
+++ b/tests/ui/nll/issue-30438-b.stderr
diff --git a/tests/ui/issues/issue-30438-c.rs b/tests/ui/nll/issue-30438-c.rs
index 813c1d3e2cc..813c1d3e2cc 100644
--- a/tests/ui/issues/issue-30438-c.rs
+++ b/tests/ui/nll/issue-30438-c.rs
diff --git a/tests/ui/issues/issue-30438-c.stderr b/tests/ui/nll/issue-30438-c.stderr
index 7c001088097..7c001088097 100644
--- a/tests/ui/issues/issue-30438-c.stderr
+++ b/tests/ui/nll/issue-30438-c.stderr
diff --git a/tests/ui/nll/issue-47388.stderr b/tests/ui/nll/issue-47388.stderr
index c780451dfa9..09b9d638afb 100644
--- a/tests/ui/nll/issue-47388.stderr
+++ b/tests/ui/nll/issue-47388.stderr
@@ -7,7 +7,7 @@ LL | fancy_ref.num = 6;
help: consider changing this to be a mutable reference
|
LL | let fancy_ref = &mut (&mut fancy);
- | ~~~~~~~~~~~~~~~~~
+ | +++
error: aborting due to previous error
diff --git a/tests/ui/nll/issue-51244.stderr b/tests/ui/nll/issue-51244.stderr
index 03d8acc8188..8ccb5809e39 100644
--- a/tests/ui/nll/issue-51244.stderr
+++ b/tests/ui/nll/issue-51244.stderr
@@ -7,7 +7,7 @@ LL | *my_ref = 0;
help: consider changing this to be a mutable reference
|
LL | let ref mut my_ref @ _ = 0;
- | ~~~~~~~~~~~~~~
+ | +++
error: aborting due to previous error
diff --git a/tests/ui/issues/issue-54302-cases.rs b/tests/ui/nll/issue-54302-cases.rs
index faa116269ee..faa116269ee 100644
--- a/tests/ui/issues/issue-54302-cases.rs
+++ b/tests/ui/nll/issue-54302-cases.rs
diff --git a/tests/ui/issues/issue-54302-cases.stderr b/tests/ui/nll/issue-54302-cases.stderr
index 6e8b69c4bee..6e8b69c4bee 100644
--- a/tests/ui/issues/issue-54302-cases.stderr
+++ b/tests/ui/nll/issue-54302-cases.stderr
diff --git a/tests/ui/issues/issue-54302.rs b/tests/ui/nll/issue-54302.rs
index 1bfaebc3895..1bfaebc3895 100644
--- a/tests/ui/issues/issue-54302.rs
+++ b/tests/ui/nll/issue-54302.rs
diff --git a/tests/ui/issues/issue-54302.stderr b/tests/ui/nll/issue-54302.stderr
index 26c46571f9c..26c46571f9c 100644
--- a/tests/ui/issues/issue-54302.stderr
+++ b/tests/ui/nll/issue-54302.stderr
diff --git a/tests/ui/nll/issue-57989.stderr b/tests/ui/nll/issue-57989.stderr
index d5effd6f346..6062b31d688 100644
--- a/tests/ui/nll/issue-57989.stderr
+++ b/tests/ui/nll/issue-57989.stderr
@@ -7,7 +7,7 @@ LL | *x = 0;
help: consider changing this to be a mutable reference
|
LL | fn f(x: &mut i32) {
- | ~~~~~~~~
+ | +++
error[E0506]: cannot assign to `*x` because it is borrowed
--> $DIR/issue-57989.rs:5:5
diff --git a/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs b/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
index 7cc0acf45f2..73ceaeeb875 100644
--- a/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
+++ b/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
@@ -5,6 +5,8 @@
// check-pass
// compile-flags:-Zno-leak-check
+#![allow(drop_copy)]
+
fn make_it() -> for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 {
panic!()
}
diff --git a/tests/ui/nll/ty-outlives/projection-body.rs b/tests/ui/nll/ty-outlives/projection-body.rs
index b03a539ebdb..bff9058a507 100644
--- a/tests/ui/nll/ty-outlives/projection-body.rs
+++ b/tests/ui/nll/ty-outlives/projection-body.rs
@@ -3,6 +3,8 @@
//
// check-pass
+#![allow(drop_ref)]
+
trait MyTrait<'a> {
type Output;
}
diff --git a/tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs b/tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs
new file mode 100644
index 00000000000..318be2a6401
--- /dev/null
+++ b/tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs
@@ -0,0 +1,19 @@
+// run-pass
+// compile-flags: -C overflow_checks=true
+
+#![feature(cfg_overflow_checks)]
+
+fn main() {
+ assert!(cfg!(overflow_checks));
+ assert!(compiles_differently());
+}
+
+#[cfg(overflow_checks)]
+fn compiles_differently()->bool {
+ true
+}
+
+#[cfg(not(overflow_checks))]
+fn compiles_differently()->bool {
+ false
+}
diff --git a/tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs b/tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs
new file mode 100644
index 00000000000..0367d980a64
--- /dev/null
+++ b/tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs
@@ -0,0 +1,19 @@
+// run-pass
+// compile-flags: -C overflow_checks=false
+
+#![feature(cfg_overflow_checks)]
+
+fn main() {
+ assert!(!cfg!(overflow_checks));
+ assert!(!compiles_differently());
+}
+
+#[cfg(overflow_checks)]
+fn compiles_differently()->bool {
+ true
+}
+
+#[cfg(not(overflow_checks))]
+fn compiles_differently()->bool {
+ false
+}
diff --git a/tests/ui/object-safety/issue-19538.stderr b/tests/ui/object-safety/issue-19538.stderr
index 8420637b3de..183245b2322 100644
--- a/tests/ui/object-safety/issue-19538.stderr
+++ b/tests/ui/object-safety/issue-19538.stderr
@@ -29,8 +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 for `&mut Thing` to implement `CoerceUnsized<&mut dyn Bar>`
- = note: required by cast to type `&mut dyn Bar`
+ = note: required for the cast from `&mut Thing` to `&mut dyn Bar`
error: aborting due to 2 previous errors
diff --git a/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
index f44de07d5da..db3e0885a85 100644
--- a/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
+++ b/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
@@ -12,8 +12,7 @@ LL | trait Bar {
LL | const X: usize;
| ^ ...because it contains this associated `const`
= help: consider moving `X` to another trait
- = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
- = note: required by cast to type `&dyn Bar`
+ = note: required for the cast from `&T` to `&dyn Bar`
error: aborting due to previous error
diff --git a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
index 9a2d472d5e7..b200b64a1f0 100644
--- a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
+++ b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
@@ -12,8 +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 for `&T` to implement `CoerceUnsized<&dyn Bar>`
- = note: required by cast to type `&dyn Bar`
+ = note: required for the cast from `&T` to `&dyn Bar`
error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/object-safety-generics.rs:26:5
@@ -29,8 +28,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 for `&T` to implement `CoerceUnsized<&dyn Bar>`
- = note: required by cast to type `&dyn Bar`
+ = note: required for the cast from `&T` to `&dyn Bar`
error: aborting due to 2 previous errors
diff --git a/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
index 40a298bd1a7..414614d8d0b 100644
--- a/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
+++ b/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
@@ -12,8 +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 for `&T` to implement `CoerceUnsized<&dyn Bar>`
- = note: required by cast to type `&dyn Bar`
+ = note: required for the cast from `&T` to `&dyn Bar`
error[E0038]: the trait `Baz` cannot be made into an object
--> $DIR/object-safety-mentions-Self.rs:30:5
@@ -29,8 +28,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 for `&T` to implement `CoerceUnsized<&dyn Baz>`
- = note: required by cast to type `&dyn Baz`
+ = note: required for the cast from `&T` to `&dyn Baz`
error: aborting due to 2 previous errors
diff --git a/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
index da87b58c9e2..befcef952a8 100644
--- a/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
+++ b/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
@@ -11,8 +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 for `Box<Bar>` to implement `CoerceUnsized<Box<dyn Foo>>`
- = note: required by cast to type `Box<dyn Foo>`
+ = note: required for the cast from `Box<Bar>` to `Box<dyn Foo>`
help: consider turning `foo` into a method by giving it a `&self` argument
|
LL | fn foo(&self) {}
diff --git a/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
index 6c29c8d5f7c..90e5c59dd02 100644
--- a/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
+++ b/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
@@ -11,8 +11,7 @@ LL | trait Bar
| --- this trait cannot be made into an object...
LL | where Self : Sized
| ^^^^^ ...because it requires `Self: Sized`
- = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
- = note: required by cast to type `&dyn Bar`
+ = note: required for the cast from `&T` to `&dyn Bar`
error: aborting due to previous error
diff --git a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
index 70a44ed6101..a6c22b8747e 100644
--- a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
+++ b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
@@ -11,8 +11,7 @@ LL | trait Bar : Sized {
| --- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
- = note: required by cast to type `&dyn Bar`
+ = note: required for the cast from `&T` to `&dyn Bar`
error: aborting due to previous error
diff --git a/tests/ui/offset-of/offset-of-arg-count.rs b/tests/ui/offset-of/offset-of-arg-count.rs
index 163b07454ec..92a205f14d9 100644
--- a/tests/ui/offset-of/offset-of-arg-count.rs
+++ b/tests/ui/offset-of/offset-of-arg-count.rs
@@ -3,7 +3,20 @@
use std::mem::offset_of;
fn main() {
- offset_of!(NotEnoughArguments); //~ ERROR expected one of
- offset_of!(NotEnoughArgumentsWithAComma, ); //~ ERROR expected 2 arguments
- offset_of!(Container, field, too many arguments); //~ ERROR expected 2 arguments
+ offset_of!(NotEnoughArguments); //~ ERROR unexpected end of macro invocation
+ offset_of!(NotEnoughArgumentsWithAComma, ); //~ ERROR unexpected end of macro invocation
+ offset_of!(Container, field, too many arguments); //~ ERROR no rules expected the token `too`
+ offset_of!(S, f); // compiles fine
+ offset_of!(S, f,); // also compiles fine
+ offset_of!(S, f.); //~ ERROR unexpected end of macro invocation
+ offset_of!(S, f.,); //~ ERROR expected identifier
+ offset_of!(S, f..); //~ ERROR no rules expected the token
+ offset_of!(S, f..,); //~ ERROR no rules expected the token
+ offset_of!(Lt<'static>, bar); // issue #111657
+
+}
+
+struct S { f: u8, }
+struct Lt<'a> {
+ bar: &'a (),
}
diff --git a/tests/ui/offset-of/offset-of-arg-count.stderr b/tests/ui/offset-of/offset-of-arg-count.stderr
index ebecc982c51..4275a89545f 100644
--- a/tests/ui/offset-of/offset-of-arg-count.stderr
+++ b/tests/ui/offset-of/offset-of-arg-count.stderr
@@ -1,20 +1,59 @@
-error: expected one of `!`, `(`, `+`, `,`, `::`, or `<`, found `<eof>`
- --> $DIR/offset-of-arg-count.rs:6:16
+error: unexpected end of macro invocation
+ --> $DIR/offset-of-arg-count.rs:6:34
|
LL | offset_of!(NotEnoughArguments);
- | ^^^^^^^^^^^^^^^^^^ expected one of `!`, `(`, `+`, `,`, `::`, or `<`
+ | ^ missing tokens in macro arguments
+ |
+note: while trying to match `,`
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
-error: expected 2 arguments
- --> $DIR/offset-of-arg-count.rs:7:5
+error: unexpected end of macro invocation
+ --> $DIR/offset-of-arg-count.rs:7:45
|
LL | offset_of!(NotEnoughArgumentsWithAComma, );
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^ missing tokens in macro arguments
+ |
+note: while trying to match meta-variable `$fields:tt`
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
-error: expected 2 arguments
- --> $DIR/offset-of-arg-count.rs:8:5
+error: no rules expected the token `too`
+ --> $DIR/offset-of-arg-count.rs:8:34
|
LL | offset_of!(Container, field, too many arguments);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^ no rules expected this token in macro call
+ |
+ = note: while trying to match sequence end
+
+error: unexpected end of macro invocation
+ --> $DIR/offset-of-arg-count.rs:11:21
+ |
+LL | offset_of!(S, f.);
+ | ^ missing tokens in macro arguments
+ |
+note: while trying to match meta-variable `$fields:tt`
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+
+error: expected identifier, found `,`
+ --> $DIR/offset-of-arg-count.rs:12:21
+ |
+LL | offset_of!(S, f.,);
+ | ^ expected identifier
+
+error: no rules expected the token `..`
+ --> $DIR/offset-of-arg-count.rs:13:20
+ |
+LL | offset_of!(S, f..);
+ | ^^ no rules expected this token in macro call
+ |
+ = note: while trying to match sequence start
+
+error: no rules expected the token `..`
+ --> $DIR/offset-of-arg-count.rs:14:20
+ |
+LL | offset_of!(S, f..,);
+ | ^^ no rules expected this token in macro call
+ |
+ = note: while trying to match sequence start
-error: aborting due to 3 previous errors
+error: aborting due to 7 previous errors
diff --git a/tests/ui/offset-of/offset-of-builtin.rs b/tests/ui/offset-of/offset-of-builtin.rs
new file mode 100644
index 00000000000..1be9899887b
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-builtin.rs
@@ -0,0 +1,44 @@
+#![feature(builtin_syntax)]
+
+// For the exposed macro we already test these errors in the other files,
+// but this test helps to make sure the builtin construct also errors.
+// This has the same examples as offset-of-arg-count.rs
+
+fn main() {
+ builtin # offset_of(NotEnoughArguments); //~ ERROR expected one of
+}
+fn t1() {
+ // Already errored upon at the macro level. Yielding an error would require
+ // extra effort.
+ builtin # offset_of(NotEnoughArgumentsWithAComma, );
+}
+fn t2() {
+ builtin # offset_of(Container, field, too many arguments); //~ ERROR expected identifier, found
+ //~| ERROR found `,`
+ //~| ERROR found `many`
+ //~| ERROR found `arguments`
+}
+fn t3() {
+ builtin # offset_of(S, f); // compiles fine
+}
+fn t4() {
+ // Already errored upon at the macro level. Yielding an error would require
+ // extra effort.
+ builtin # offset_of(S, f);
+}
+fn t5() {
+ builtin # offset_of(S, f.); //~ ERROR expected identifier
+}
+fn t6() {
+ builtin # offset_of(S, f.,); //~ ERROR expected identifier
+}
+fn t7() {
+ builtin # offset_of(S, f..); //~ ERROR expected one of
+}
+fn t8() {
+ // Already errored upon at the macro level. Yielding an error would require
+ // extra effort.
+ builtin # offset_of(S, f..,);
+}
+
+struct S { f: u8, }
diff --git a/tests/ui/offset-of/offset-of-builtin.stderr b/tests/ui/offset-of/offset-of-builtin.stderr
new file mode 100644
index 00000000000..1a1f33cc613
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-builtin.stderr
@@ -0,0 +1,65 @@
+error: expected one of `!`, `(`, `+`, `,`, `::`, or `<`, found `)`
+ --> $DIR/offset-of-builtin.rs:8:43
+ |
+LL | builtin # offset_of(NotEnoughArguments);
+ | ^ expected one of `!`, `(`, `+`, `,`, `::`, or `<`
+
+error: expected identifier, found `,`
+ --> $DIR/offset-of-builtin.rs:16:41
+ |
+LL | builtin # offset_of(Container, field, too many arguments);
+ | ^
+ | |
+ | expected identifier
+ | help: remove this comma
+
+error: expected one of `)` or `.`, found `,`
+ --> $DIR/offset-of-builtin.rs:16:41
+ |
+LL | builtin # offset_of(Container, field, too many arguments);
+ | ^
+ | |
+ | expected one of `)` or `.`
+ | help: missing `.`
+
+error: expected one of `)` or `.`, found `many`
+ --> $DIR/offset-of-builtin.rs:16:47
+ |
+LL | builtin # offset_of(Container, field, too many arguments);
+ | -^^^^ expected one of `)` or `.`
+ | |
+ | help: missing `.`
+
+error: expected one of `)` or `.`, found `arguments`
+ --> $DIR/offset-of-builtin.rs:16:52
+ |
+LL | builtin # offset_of(Container, field, too many arguments);
+ | -^^^^^^^^^ expected one of `)` or `.`
+ | |
+ | help: missing `.`
+
+error: expected identifier, found `)`
+ --> $DIR/offset-of-builtin.rs:30:30
+ |
+LL | builtin # offset_of(S, f.);
+ | ^ expected identifier
+
+error: expected identifier, found `,`
+ --> $DIR/offset-of-builtin.rs:33:30
+ |
+LL | builtin # offset_of(S, f.,);
+ | ^ expected identifier
+
+error: expected one of `)` or `.`, found `..`
+ --> $DIR/offset-of-builtin.rs:36:29
+ |
+LL | builtin # offset_of(S, f..);
+ | ^^ expected one of `)` or `.`
+ |
+help: if you meant to bind the contents of the rest of the array pattern into `f`, use `@`
+ |
+LL | builtin # offset_of(S, f @ ..);
+ | +
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr
index 8e88015b07a..e6e0f499236 100644
--- a/tests/ui/offset-of/offset-of-dst-field.stderr
+++ b/tests/ui/offset-of/offset-of-dst-field.stderr
@@ -5,6 +5,7 @@ LL | offset_of!(Alpha, z);
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
+ = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
--> $DIR/offset-of-dst-field.rs:31:5
@@ -13,6 +14,7 @@ LL | offset_of!(Beta, z);
| ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn Trait + 'static)`
+ = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the size for values of type `Extern` cannot be known at compilation time
--> $DIR/offset-of-dst-field.rs:32:5
@@ -21,6 +23,7 @@ LL | offset_of!(Gamma, z);
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `Extern`
+ = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 3 previous errors
diff --git a/tests/ui/offset-of/offset-of-unstable.stderr b/tests/ui/offset-of/offset-of-unstable.stderr
index 25811a061d7..c39882519a5 100644
--- a/tests/ui/offset-of/offset-of-unstable.stderr
+++ b/tests/ui/offset-of/offset-of-unstable.stderr
@@ -33,6 +33,7 @@ LL | | );
| |_____^
|
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+ = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0658]: use of unstable library feature 'unstable_test_feature'
--> $DIR/offset-of-unstable.rs:18:5
@@ -41,6 +42,7 @@ LL | offset_of!(StableWithUnstableField, unstable);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+ = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0658]: use of unstable library feature 'unstable_test_feature'
--> $DIR/offset-of-unstable.rs:20:5
@@ -49,6 +51,7 @@ LL | offset_of!(StableWithUnstableFieldType, stable.unstable);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+ = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0658]: use of unstable library feature 'unstable_test_feature'
--> $DIR/offset-of-unstable.rs:21:5
@@ -61,6 +64,7 @@ LL | | );
| |_____^
|
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+ = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0658]: use of unstable library feature 'unstable_test_feature'
--> $DIR/offset-of-unstable.rs:26:5
@@ -73,6 +77,7 @@ LL | | );
| |_____^
|
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+ = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 8 previous errors
diff --git a/tests/ui/or-patterns/or-patterns-default-binding-modes.rs b/tests/ui/or-patterns/or-patterns-default-binding-modes.rs
index e56f9ffe23c..c138d99d303 100644
--- a/tests/ui/or-patterns/or-patterns-default-binding-modes.rs
+++ b/tests/ui/or-patterns/or-patterns-default-binding-modes.rs
@@ -3,6 +3,8 @@
// check-pass
#![allow(irrefutable_let_patterns)]
+#![allow(drop_copy)]
+#![allow(drop_ref)]
fn main() {
// A regression test for a mistake we made at one point:
diff --git a/tests/ui/parser/builtin-syntax.rs b/tests/ui/parser/builtin-syntax.rs
new file mode 100644
index 00000000000..897dab8ec50
--- /dev/null
+++ b/tests/ui/parser/builtin-syntax.rs
@@ -0,0 +1,9 @@
+#![feature(builtin_syntax)]
+
+fn main() {
+ builtin # foobar(); //~ ERROR unknown `builtin #` construct
+}
+
+fn not_identifier() {
+ builtin # {}(); //~ ERROR expected identifier after
+}
diff --git a/tests/ui/parser/builtin-syntax.stderr b/tests/ui/parser/builtin-syntax.stderr
new file mode 100644
index 00000000000..ee3764a6221
--- /dev/null
+++ b/tests/ui/parser/builtin-syntax.stderr
@@ -0,0 +1,14 @@
+error: unknown `builtin #` construct `foobar`
+ --> $DIR/builtin-syntax.rs:4:5
+ |
+LL | builtin # foobar();
+ | ^^^^^^^^^^^^^^^^
+
+error: expected identifier after `builtin #`
+ --> $DIR/builtin-syntax.rs:8:15
+ |
+LL | builtin # {}();
+ | ^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/parser/dyn-trait-compatibility.stderr b/tests/ui/parser/dyn-trait-compatibility.stderr
index 653be5b3b71..e34d855a9d4 100644
--- a/tests/ui/parser/dyn-trait-compatibility.stderr
+++ b/tests/ui/parser/dyn-trait-compatibility.stderr
@@ -1,9 +1,3 @@
-error[E0433]: failed to resolve: use of undeclared crate or module `dyn`
- --> $DIR/dyn-trait-compatibility.rs:3:11
- |
-LL | type A1 = dyn::dyn;
- | ^^^ use of undeclared crate or module `dyn`
-
error[E0412]: cannot find type `dyn` in this scope
--> $DIR/dyn-trait-compatibility.rs:1:11
|
@@ -46,6 +40,12 @@ error[E0412]: cannot find type `dyn` in this scope
LL | type A3 = dyn<<dyn as dyn>::dyn>;
| ^^^ not found in this scope
+error[E0433]: failed to resolve: use of undeclared crate or module `dyn`
+ --> $DIR/dyn-trait-compatibility.rs:3:11
+ |
+LL | type A1 = dyn::dyn;
+ | ^^^ use of undeclared crate or module `dyn`
+
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0405, E0412, E0433.
diff --git a/tests/ui/parser/impl-on-unsized-typo.rs b/tests/ui/parser/impl-on-unsized-typo.rs
new file mode 100644
index 00000000000..e09c0463045
--- /dev/null
+++ b/tests/ui/parser/impl-on-unsized-typo.rs
@@ -0,0 +1,6 @@
+trait Tr {}
+
+impl<T ?Sized> Tr for T {}
+//~^ ERROR expected one of `,`, `:`, `=`, or `>`, found `?`
+
+fn main() {}
diff --git a/tests/ui/parser/impl-on-unsized-typo.stderr b/tests/ui/parser/impl-on-unsized-typo.stderr
new file mode 100644
index 00000000000..23dcc1efd68
--- /dev/null
+++ b/tests/ui/parser/impl-on-unsized-typo.stderr
@@ -0,0 +1,8 @@
+error: expected one of `,`, `:`, `=`, or `>`, found `?`
+ --> $DIR/impl-on-unsized-typo.rs:3:8
+ |
+LL | impl<T ?Sized> Tr for T {}
+ | ^ expected one of `,`, `:`, `=`, or `>`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/parser/issues/issue-111416.rs b/tests/ui/parser/issues/issue-111416.rs
new file mode 100644
index 00000000000..cfd1b6b99ba
--- /dev/null
+++ b/tests/ui/parser/issues/issue-111416.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let my = monad_bind(mx, T: Try); //~ ERROR invalid `struct` delimiters or `fn` call arguments
+}
diff --git a/tests/ui/parser/issues/issue-111416.stderr b/tests/ui/parser/issues/issue-111416.stderr
new file mode 100644
index 00000000000..ddacf4d6dfc
--- /dev/null
+++ b/tests/ui/parser/issues/issue-111416.stderr
@@ -0,0 +1,18 @@
+error: invalid `struct` delimiters or `fn` call arguments
+ --> $DIR/issue-111416.rs:2:14
+ |
+LL | let my = monad_bind(mx, T: Try);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: if `monad_bind` is a struct, use braces as delimiters
+ |
+LL | let my = monad_bind { mx, T: Try };
+ | ~ ~
+help: if `monad_bind` is a function, use the arguments directly
+ |
+LL - let my = monad_bind(mx, T: Try);
+LL + let my = monad_bind(mx, Try);
+ |
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
index fbdefd9d36c..965204bf240 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
@@ -2,6 +2,9 @@
// Test `@` patterns combined with `box` patterns.
+#![allow(drop_ref)]
+#![allow(drop_copy)]
+
#![feature(box_patterns)]
#[derive(Copy, Clone)]
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs
index 0108861cfce..3eb5d2cbf54 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs
@@ -2,6 +2,8 @@
// Test `Copy` bindings in the rhs of `@` patterns.
+#![allow(drop_copy)]
+
#[derive(Copy, Clone)]
struct C;
diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs
index 5445696fdff..0550238549e 100644
--- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs
+++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs
@@ -1,5 +1,7 @@
// check-pass
+#![allow(drop_ref)]
+
fn main() {}
struct U;
diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
index c7c7c074f7c..a033cc0655e 100644
--- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
+++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
@@ -112,7 +112,7 @@ LL | *_x0 = U;
help: consider changing this to be a mutable reference
|
LL | let (ref mut _x0, _x1, ref _x2, ..) = tup;
- | ~~~~~~~~~~~
+ | +++
error[E0594]: cannot assign to `*_x2`, which is behind a `&` reference
--> $DIR/borrowck-move-ref-pattern.rs:27:5
@@ -123,7 +123,7 @@ LL | *_x2 = U;
help: consider changing this to be a mutable reference
|
LL | let (ref _x0, _x1, ref mut _x2, ..) = tup;
- | ~~~~~~~~~~~
+ | +++
error[E0382]: use of moved value: `tup.1`
--> $DIR/borrowck-move-ref-pattern.rs:28:10
diff --git a/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs b/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs
index 583f70f41aa..788975d960a 100644
--- a/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs
+++ b/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs
@@ -1,5 +1,7 @@
// check-pass
+#![allow(drop_ref)]
+
fn main() {
struct U;
fn accept_fn_once(_: impl FnOnce()) {}
diff --git a/tests/ui/pattern/pattern-error-continue.stderr b/tests/ui/pattern/pattern-error-continue.stderr
index e1349fb02ea..10fcccb0301 100644
--- a/tests/ui/pattern/pattern-error-continue.stderr
+++ b/tests/ui/pattern/pattern-error-continue.stderr
@@ -1,9 +1,3 @@
-error[E0433]: failed to resolve: use of undeclared type `E`
- --> $DIR/pattern-error-continue.rs:33:9
- |
-LL | E::V => {}
- | ^ use of undeclared type `E`
-
error[E0532]: expected tuple struct or tuple variant, found unit variant `A::D`
--> $DIR/pattern-error-continue.rs:18:9
|
@@ -56,6 +50,15 @@ note: function defined here
LL | fn f(_c: char) {}
| ^ --------
+error[E0433]: failed to resolve: use of undeclared type `E`
+ --> $DIR/pattern-error-continue.rs:33:9
+ |
+LL | E::V => {}
+ | ^
+ | |
+ | use of undeclared type `E`
+ | help: an enum with a similar name exists: `A`
+
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0023, E0308, E0433, E0532.
diff --git a/tests/ui/pattern/usefulness/consts-opaque.rs b/tests/ui/pattern/usefulness/consts-opaque.rs
index ca4fcd85bb6..c10c6205a08 100644
--- a/tests/ui/pattern/usefulness/consts-opaque.rs
+++ b/tests/ui/pattern/usefulness/consts-opaque.rs
@@ -20,11 +20,12 @@ const BAR: Bar = Bar;
#[derive(PartialEq)]
enum Baz {
Baz1,
- Baz2
+ Baz2,
}
impl Eq for Baz {}
const BAZ: Baz = Baz::Baz1;
+#[rustfmt::skip]
fn main() {
match FOO {
FOO => {}
@@ -124,8 +125,16 @@ fn main() {
match WRAPQUUX {
Wrap(_) => {}
- WRAPQUUX => {} // detected unreachable because we do inspect the `Wrap` layer
- //~^ ERROR unreachable pattern
+ WRAPQUUX => {}
+ }
+
+ match WRAPQUUX {
+ Wrap(_) => {}
+ }
+
+ match WRAPQUUX {
+ //~^ ERROR: non-exhaustive patterns: `Wrap(_)` not covered
+ WRAPQUUX => {}
}
#[derive(PartialEq, Eq)]
@@ -138,8 +147,7 @@ fn main() {
match WHOKNOWSQUUX {
WHOKNOWSQUUX => {}
WhoKnows::Yay(_) => {}
- WHOKNOWSQUUX => {} // detected unreachable because we do inspect the `WhoKnows` layer
- //~^ ERROR unreachable pattern
+ WHOKNOWSQUUX => {}
WhoKnows::Nope => {}
}
}
diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr
index 3f0b4a9f26a..e01b06ccc82 100644
--- a/tests/ui/pattern/usefulness/consts-opaque.stderr
+++ b/tests/ui/pattern/usefulness/consts-opaque.stderr
@@ -1,5 +1,5 @@
error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]`
- --> $DIR/consts-opaque.rs:30:9
+ --> $DIR/consts-opaque.rs:31:9
|
LL | FOO => {}
| ^^^
@@ -8,7 +8,7 @@ LL | FOO => {}
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]`
- --> $DIR/consts-opaque.rs:37:9
+ --> $DIR/consts-opaque.rs:38:9
|
LL | FOO_REF => {}
| ^^^^^^^
@@ -17,7 +17,7 @@ LL | FOO_REF => {}
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
warning: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]`
- --> $DIR/consts-opaque.rs:45:9
+ --> $DIR/consts-opaque.rs:46:9
|
LL | FOO_REF_REF => {}
| ^^^^^^^^^^^
@@ -29,7 +29,7 @@ LL | FOO_REF_REF => {}
= note: `#[warn(indirect_structural_match)]` on by default
error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
- --> $DIR/consts-opaque.rs:53:9
+ --> $DIR/consts-opaque.rs:54:9
|
LL | BAR => {} // should not be emitting unreachable warning
| ^^^
@@ -38,7 +38,7 @@ LL | BAR => {} // should not be emitting unreachable warning
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
- --> $DIR/consts-opaque.rs:61:9
+ --> $DIR/consts-opaque.rs:62:9
|
LL | BAR => {}
| ^^^
@@ -47,7 +47,7 @@ LL | BAR => {}
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
- --> $DIR/consts-opaque.rs:70:9
+ --> $DIR/consts-opaque.rs:71:9
|
LL | BAR => {}
| ^^^
@@ -56,7 +56,7 @@ LL | BAR => {}
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
- --> $DIR/consts-opaque.rs:72:9
+ --> $DIR/consts-opaque.rs:73:9
|
LL | BAR => {} // should not be emitting unreachable warning
| ^^^
@@ -65,7 +65,7 @@ LL | BAR => {} // should not be emitting unreachable warning
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
- --> $DIR/consts-opaque.rs:80:9
+ --> $DIR/consts-opaque.rs:81:9
|
LL | BAZ => {}
| ^^^
@@ -74,7 +74,7 @@ LL | BAZ => {}
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
- --> $DIR/consts-opaque.rs:90:9
+ --> $DIR/consts-opaque.rs:91:9
|
LL | BAZ => {}
| ^^^
@@ -83,7 +83,7 @@ LL | BAZ => {}
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
- --> $DIR/consts-opaque.rs:97:9
+ --> $DIR/consts-opaque.rs:98:9
|
LL | BAZ => {}
| ^^^
@@ -92,7 +92,7 @@ LL | BAZ => {}
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
error: unreachable pattern
- --> $DIR/consts-opaque.rs:32:9
+ --> $DIR/consts-opaque.rs:33:9
|
LL | FOO => {}
| --- matches any value
@@ -107,7 +107,7 @@ LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
- --> $DIR/consts-opaque.rs:39:9
+ --> $DIR/consts-opaque.rs:40:9
|
LL | FOO_REF => {}
| ------- matches any value
@@ -116,7 +116,7 @@ LL | Foo(_) => {} // should not be emitting unreachable warning
| ^^^^^^ unreachable pattern
error: unreachable pattern
- --> $DIR/consts-opaque.rs:53:9
+ --> $DIR/consts-opaque.rs:54:9
|
LL | Bar => {}
| --- matches any value
@@ -124,7 +124,7 @@ LL | BAR => {} // should not be emitting unreachable warning
| ^^^ unreachable pattern
error: unreachable pattern
- --> $DIR/consts-opaque.rs:56:9
+ --> $DIR/consts-opaque.rs:57:9
|
LL | Bar => {}
| --- matches any value
@@ -133,7 +133,7 @@ LL | _ => {}
| ^ unreachable pattern
error: unreachable pattern
- --> $DIR/consts-opaque.rs:63:9
+ --> $DIR/consts-opaque.rs:64:9
|
LL | BAR => {}
| --- matches any value
@@ -142,7 +142,7 @@ LL | Bar => {} // should not be emitting unreachable warning
| ^^^ unreachable pattern
error: unreachable pattern
- --> $DIR/consts-opaque.rs:65:9
+ --> $DIR/consts-opaque.rs:66:9
|
LL | BAR => {}
| --- matches any value
@@ -151,7 +151,7 @@ LL | _ => {}
| ^ unreachable pattern
error: unreachable pattern
- --> $DIR/consts-opaque.rs:72:9
+ --> $DIR/consts-opaque.rs:73:9
|
LL | BAR => {}
| --- matches any value
@@ -160,7 +160,7 @@ LL | BAR => {} // should not be emitting unreachable warning
| ^^^ unreachable pattern
error: unreachable pattern
- --> $DIR/consts-opaque.rs:75:9
+ --> $DIR/consts-opaque.rs:76:9
|
LL | BAR => {}
| --- matches any value
@@ -169,7 +169,7 @@ LL | _ => {} // should not be emitting unreachable warning
| ^ unreachable pattern
error: unreachable pattern
- --> $DIR/consts-opaque.rs:82:9
+ --> $DIR/consts-opaque.rs:83:9
|
LL | BAZ => {}
| --- matches any value
@@ -178,7 +178,7 @@ LL | Baz::Baz1 => {} // should not be emitting unreachable warning
| ^^^^^^^^^ unreachable pattern
error: unreachable pattern
- --> $DIR/consts-opaque.rs:84:9
+ --> $DIR/consts-opaque.rs:85:9
|
LL | BAZ => {}
| --- matches any value
@@ -187,7 +187,7 @@ LL | _ => {}
| ^ unreachable pattern
error: unreachable pattern
- --> $DIR/consts-opaque.rs:92:9
+ --> $DIR/consts-opaque.rs:93:9
|
LL | BAZ => {}
| --- matches any value
@@ -196,7 +196,7 @@ LL | _ => {}
| ^ unreachable pattern
error: unreachable pattern
- --> $DIR/consts-opaque.rs:99:9
+ --> $DIR/consts-opaque.rs:100:9
|
LL | BAZ => {}
| --- matches any value
@@ -205,7 +205,7 @@ LL | Baz::Baz2 => {} // should not be emitting unreachable warning
| ^^^^^^^^^ unreachable pattern
error: unreachable pattern
- --> $DIR/consts-opaque.rs:101:9
+ --> $DIR/consts-opaque.rs:102:9
|
LL | BAZ => {}
| --- matches any value
@@ -213,19 +213,24 @@ LL | BAZ => {}
LL | _ => {} // should not be emitting unreachable warning
| ^ unreachable pattern
-error: unreachable pattern
- --> $DIR/consts-opaque.rs:127:9
+error[E0004]: non-exhaustive patterns: `Wrap(_)` not covered
+ --> $DIR/consts-opaque.rs:135:11
|
-LL | Wrap(_) => {}
- | ------- matches any value
-LL | WRAPQUUX => {} // detected unreachable because we do inspect the `Wrap` layer
- | ^^^^^^^^ unreachable pattern
-
-error: unreachable pattern
- --> $DIR/consts-opaque.rs:141:9
+LL | match WRAPQUUX {
+ | ^^^^^^^^ pattern `Wrap(_)` not covered
+ |
+note: `Wrap<fn(usize, usize) -> usize>` defined here
+ --> $DIR/consts-opaque.rs:117:12
+ |
+LL | struct Wrap<T>(T);
+ | ^^^^
+ = note: the matched value is of type `Wrap<fn(usize, usize) -> usize>`
+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 ~ WRAPQUUX => {},
+LL + Wrap(_) => todo!()
|
-LL | WHOKNOWSQUUX => {} // detected unreachable because we do inspect the `WhoKnows` layer
- | ^^^^^^^^^^^^
-error: aborting due to 24 previous errors; 1 warning emitted
+error: aborting due to 23 previous errors; 1 warning emitted
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/print_type_sizes/async.rs b/tests/ui/print_type_sizes/async.rs
index 1598b069691..c73268dc46a 100644
--- a/tests/ui/print_type_sizes/async.rs
+++ b/tests/ui/print_type_sizes/async.rs
@@ -3,6 +3,8 @@
// build-pass
// ignore-pass
+#![allow(drop_copy)]
+
async fn wait() {}
pub async fn test(arg: [u8; 8192]) {
diff --git a/tests/ui/print_type_sizes/async.stdout b/tests/ui/print_type_sizes/async.stdout
index 1c6887412be..873def9031a 100644
--- a/tests/ui/print_type_sizes/async.stdout
+++ b/tests/ui/print_type_sizes/async.stdout
@@ -1,4 +1,4 @@
-print-type-size type: `[async fn body@$DIR/async.rs:8:36: 11:2]`: 16386 bytes, alignment: 1 bytes
+print-type-size type: `[async fn body@$DIR/async.rs:10:36: 13:2]`: 16386 bytes, alignment: 1 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 8192 bytes
print-type-size upvar `.arg`: 8192 bytes
@@ -16,14 +16,14 @@ print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment
print-type-size variant `MaybeUninit`: 8192 bytes
print-type-size field `.uninit`: 0 bytes
print-type-size field `.value`: 8192 bytes
-print-type-size type: `[async fn body@$DIR/async.rs:6:17: 6:19]`: 1 bytes, alignment: 1 bytes
+print-type-size type: `[async fn body@$DIR/async.rs:8:17: 8:19]`: 1 bytes, alignment: 1 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 0 bytes
print-type-size variant `Returned`: 0 bytes
print-type-size variant `Panicked`: 0 bytes
-print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/async.rs:6:17: 6:19]>`: 1 bytes, alignment: 1 bytes
+print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/async.rs:8:17: 8:19]>`: 1 bytes, alignment: 1 bytes
print-type-size field `.value`: 1 bytes
-print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/async.rs:6:17: 6:19]>`: 1 bytes, alignment: 1 bytes
+print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/async.rs:8:17: 8:19]>`: 1 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 1 bytes
print-type-size field `.uninit`: 0 bytes
print-type-size field `.value`: 1 bytes
diff --git a/tests/ui/print_type_sizes/generator_discr_placement.rs b/tests/ui/print_type_sizes/generator_discr_placement.rs
index 1a85fe95bb6..a77a03f0a8a 100644
--- a/tests/ui/print_type_sizes/generator_discr_placement.rs
+++ b/tests/ui/print_type_sizes/generator_discr_placement.rs
@@ -6,6 +6,7 @@
// Avoid emitting panic handlers, like the rest of these tests...
#![feature(generators)]
+#![allow(drop_copy)]
pub fn foo() {
let a = || {
diff --git a/tests/ui/print_type_sizes/generator_discr_placement.stdout b/tests/ui/print_type_sizes/generator_discr_placement.stdout
index f2a11c7a33b..fe0022cf5f4 100644
--- a/tests/ui/print_type_sizes/generator_discr_placement.stdout
+++ b/tests/ui/print_type_sizes/generator_discr_placement.stdout
@@ -1,4 +1,4 @@
-print-type-size type: `[generator@$DIR/generator_discr_placement.rs:11:13: 11:15]`: 8 bytes, alignment: 4 bytes
+print-type-size type: `[generator@$DIR/generator_discr_placement.rs:12:13: 12:15]`: 8 bytes, alignment: 4 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 0 bytes
print-type-size variant `Suspend0`: 7 bytes
diff --git a/tests/ui/range/issue-54505-no-literals.fixed b/tests/ui/range/issue-54505-no-literals.fixed
index 4d8f67182b9..71c36c741cc 100644
--- a/tests/ui/range/issue-54505-no-literals.fixed
+++ b/tests/ui/range/issue-54505-no-literals.fixed
@@ -16,60 +16,60 @@ fn main() {
take_range(&std::ops::Range { start: 0, end: 1 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &std::ops::Range { start: 0, end: 1 }
+ //~| SUGGESTION &
take_range(&::std::ops::Range { start: 0, end: 1 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 }
+ //~| SUGGESTION &
take_range(&std::ops::RangeFrom { start: 1 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &std::ops::RangeFrom { start: 1 }
+ //~| SUGGESTION &
take_range(&::std::ops::RangeFrom { start: 1 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &::std::ops::RangeFrom { start: 1 }
+ //~| SUGGESTION &
take_range(&std::ops::RangeFull {});
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &std::ops::RangeFull {}
+ //~| SUGGESTION &
take_range(&::std::ops::RangeFull {});
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &::std::ops::RangeFull {}
+ //~| SUGGESTION &
take_range(&std::ops::RangeInclusive::new(0, 1));
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1)
+ //~| SUGGESTION &
take_range(&::std::ops::RangeInclusive::new(0, 1));
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1)
+ //~| SUGGESTION &
take_range(&std::ops::RangeTo { end: 5 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &std::ops::RangeTo { end: 5 }
+ //~| SUGGESTION &
take_range(&::std::ops::RangeTo { end: 5 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &::std::ops::RangeTo { end: 5 }
+ //~| SUGGESTION &
take_range(&std::ops::RangeToInclusive { end: 5 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 }
+ //~| SUGGESTION &
take_range(&::std::ops::RangeToInclusive { end: 5 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 }
+ //~| SUGGESTION &
}
diff --git a/tests/ui/range/issue-54505-no-literals.rs b/tests/ui/range/issue-54505-no-literals.rs
index dc21dcbc2db..db125d1a22b 100644
--- a/tests/ui/range/issue-54505-no-literals.rs
+++ b/tests/ui/range/issue-54505-no-literals.rs
@@ -16,60 +16,60 @@ fn main() {
take_range(std::ops::Range { start: 0, end: 1 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &std::ops::Range { start: 0, end: 1 }
+ //~| SUGGESTION &
take_range(::std::ops::Range { start: 0, end: 1 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 }
+ //~| SUGGESTION &
take_range(std::ops::RangeFrom { start: 1 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &std::ops::RangeFrom { start: 1 }
+ //~| SUGGESTION &
take_range(::std::ops::RangeFrom { start: 1 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &::std::ops::RangeFrom { start: 1 }
+ //~| SUGGESTION &
take_range(std::ops::RangeFull {});
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &std::ops::RangeFull {}
+ //~| SUGGESTION &
take_range(::std::ops::RangeFull {});
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &::std::ops::RangeFull {}
+ //~| SUGGESTION &
take_range(std::ops::RangeInclusive::new(0, 1));
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1)
+ //~| SUGGESTION &
take_range(::std::ops::RangeInclusive::new(0, 1));
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1)
+ //~| SUGGESTION &
take_range(std::ops::RangeTo { end: 5 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &std::ops::RangeTo { end: 5 }
+ //~| SUGGESTION &
take_range(::std::ops::RangeTo { end: 5 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &::std::ops::RangeTo { end: 5 }
+ //~| SUGGESTION &
take_range(std::ops::RangeToInclusive { end: 5 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 }
+ //~| SUGGESTION &
take_range(::std::ops::RangeToInclusive { end: 5 });
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 }
+ //~| SUGGESTION &
}
diff --git a/tests/ui/range/issue-54505-no-literals.stderr b/tests/ui/range/issue-54505-no-literals.stderr
index d112983848d..5894bb6ba55 100644
--- a/tests/ui/range/issue-54505-no-literals.stderr
+++ b/tests/ui/range/issue-54505-no-literals.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
--> $DIR/issue-54505-no-literals.rs:16:16
|
LL | take_range(std::ops::Range { start: 0, end: 1 });
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&_`, found `Range<{integer}>`
- | | help: consider borrowing here: `&std::ops::Range { start: 0, end: 1 }`
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `Range<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -15,15 +13,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&std::ops::Range { start: 0, end: 1 });
+ | +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-literals.rs:21:16
|
LL | take_range(::std::ops::Range { start: 0, end: 1 });
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&_`, found `Range<{integer}>`
- | | help: consider borrowing here: `&::std::ops::Range { start: 0, end: 1 }`
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `Range<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -33,15 +33,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&::std::ops::Range { start: 0, end: 1 });
+ | +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-literals.rs:26:16
|
LL | take_range(std::ops::RangeFrom { start: 1 });
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&_`, found `RangeFrom<{integer}>`
- | | help: consider borrowing here: `&std::ops::RangeFrom { start: 1 }`
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFrom<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -51,15 +53,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&std::ops::RangeFrom { start: 1 });
+ | +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-literals.rs:31:16
|
LL | take_range(::std::ops::RangeFrom { start: 1 });
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&_`, found `RangeFrom<{integer}>`
- | | help: consider borrowing here: `&::std::ops::RangeFrom { start: 1 }`
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFrom<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -69,15 +73,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&::std::ops::RangeFrom { start: 1 });
+ | +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-literals.rs:36:16
|
LL | take_range(std::ops::RangeFull {});
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&_`, found `RangeFull`
- | | help: consider borrowing here: `&std::ops::RangeFull {}`
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFull`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -87,15 +93,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&std::ops::RangeFull {});
+ | +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-literals.rs:41:16
|
LL | take_range(::std::ops::RangeFull {});
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&_`, found `RangeFull`
- | | help: consider borrowing here: `&::std::ops::RangeFull {}`
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFull`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -105,15 +113,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&::std::ops::RangeFull {});
+ | +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-literals.rs:46:16
|
LL | take_range(std::ops::RangeInclusive::new(0, 1));
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&_`, found `RangeInclusive<{integer}>`
- | | help: consider borrowing here: `&std::ops::RangeInclusive::new(0, 1)`
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeInclusive<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -123,15 +133,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&std::ops::RangeInclusive::new(0, 1));
+ | +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-literals.rs:51:16
|
LL | take_range(::std::ops::RangeInclusive::new(0, 1));
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&_`, found `RangeInclusive<{integer}>`
- | | help: consider borrowing here: `&::std::ops::RangeInclusive::new(0, 1)`
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeInclusive<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -141,15 +153,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&::std::ops::RangeInclusive::new(0, 1));
+ | +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-literals.rs:56:16
|
LL | take_range(std::ops::RangeTo { end: 5 });
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&_`, found `RangeTo<{integer}>`
- | | help: consider borrowing here: `&std::ops::RangeTo { end: 5 }`
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeTo<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -159,15 +173,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&std::ops::RangeTo { end: 5 });
+ | +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-literals.rs:61:16
|
LL | take_range(::std::ops::RangeTo { end: 5 });
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&_`, found `RangeTo<{integer}>`
- | | help: consider borrowing here: `&::std::ops::RangeTo { end: 5 }`
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeTo<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -177,15 +193,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&::std::ops::RangeTo { end: 5 });
+ | +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-literals.rs:66:16
|
LL | take_range(std::ops::RangeToInclusive { end: 5 });
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&_`, found `RangeToInclusive<{integer}>`
- | | help: consider borrowing here: `&std::ops::RangeToInclusive { end: 5 }`
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeToInclusive<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -195,15 +213,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&std::ops::RangeToInclusive { end: 5 });
+ | +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-literals.rs:71:16
|
LL | take_range(::std::ops::RangeToInclusive { end: 5 });
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&_`, found `RangeToInclusive<{integer}>`
- | | help: consider borrowing here: `&::std::ops::RangeToInclusive { end: 5 }`
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeToInclusive<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -213,6 +233,10 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&::std::ops::RangeToInclusive { end: 5 });
+ | +
error: aborting due to 12 previous errors
diff --git a/tests/ui/range/issue-54505-no-std.rs b/tests/ui/range/issue-54505-no-std.rs
index 9f378b4836e..db455fada3b 100644
--- a/tests/ui/range/issue-54505-no-std.rs
+++ b/tests/ui/range/issue-54505-no-std.rs
@@ -29,30 +29,30 @@ fn main() {
take_range(0..1);
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(0..1)
+ //~| SUGGESTION &(
take_range(1..);
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(1..)
+ //~| SUGGESTION &(
take_range(..);
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(..)
+ //~| SUGGESTION &(
take_range(0..=1);
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(0..=1)
+ //~| SUGGESTION &(
take_range(..5);
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(..5)
+ //~| SUGGESTION &(
take_range(..=42);
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(..=42)
+ //~| SUGGESTION &(
}
diff --git a/tests/ui/range/issue-54505-no-std.stderr b/tests/ui/range/issue-54505-no-std.stderr
index a6a9f89da74..13563d1940c 100644
--- a/tests/ui/range/issue-54505-no-std.stderr
+++ b/tests/ui/range/issue-54505-no-std.stderr
@@ -14,10 +14,8 @@ error[E0308]: mismatched types
--> $DIR/issue-54505-no-std.rs:29:16
|
LL | take_range(0..1);
- | ---------- ^^^^
- | | |
- | | expected `&_`, found `Range<{integer}>`
- | | help: consider borrowing here: `&(0..1)`
+ | ---------- ^^^^ expected `&_`, found `Range<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -27,15 +25,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&(0..1));
+ | ++ +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-std.rs:34:16
|
LL | take_range(1..);
- | ---------- ^^^
- | | |
- | | expected `&_`, found `RangeFrom<{integer}>`
- | | help: consider borrowing here: `&(1..)`
+ | ---------- ^^^ expected `&_`, found `RangeFrom<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -45,15 +45,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&(1..));
+ | ++ +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-std.rs:39:16
|
LL | take_range(..);
- | ---------- ^^
- | | |
- | | expected `&_`, found `RangeFull`
- | | help: consider borrowing here: `&(..)`
+ | ---------- ^^ expected `&_`, found `RangeFull`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -63,15 +65,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&(..));
+ | ++ +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-std.rs:44:16
|
LL | take_range(0..=1);
- | ---------- ^^^^^
- | | |
- | | expected `&_`, found `RangeInclusive<{integer}>`
- | | help: consider borrowing here: `&(0..=1)`
+ | ---------- ^^^^^ expected `&_`, found `RangeInclusive<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -81,15 +85,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&(0..=1));
+ | ++ +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-std.rs:49:16
|
LL | take_range(..5);
- | ---------- ^^^
- | | |
- | | expected `&_`, found `RangeTo<{integer}>`
- | | help: consider borrowing here: `&(..5)`
+ | ---------- ^^^ expected `&_`, found `RangeTo<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -99,15 +105,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&(..5));
+ | ++ +
error[E0308]: mismatched types
--> $DIR/issue-54505-no-std.rs:54:16
|
LL | take_range(..=42);
- | ---------- ^^^^^
- | | |
- | | expected `&_`, found `RangeToInclusive<{integer}>`
- | | help: consider borrowing here: `&(..=42)`
+ | ---------- ^^^^^ expected `&_`, found `RangeToInclusive<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -117,6 +125,10 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&(..=42));
+ | ++ +
error: aborting due to 8 previous errors
diff --git a/tests/ui/range/issue-54505.fixed b/tests/ui/range/issue-54505.fixed
index f8298c0b5ce..9d113ba1d35 100644
--- a/tests/ui/range/issue-54505.fixed
+++ b/tests/ui/range/issue-54505.fixed
@@ -14,30 +14,30 @@ fn main() {
take_range(&(0..1));
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(0..1)
+ //~| SUGGESTION &(
take_range(&(1..));
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(1..)
+ //~| SUGGESTION &(
take_range(&(..));
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(..)
+ //~| SUGGESTION &(
take_range(&(0..=1));
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(0..=1)
+ //~| SUGGESTION &(
take_range(&(..5));
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(..5)
+ //~| SUGGESTION &(
take_range(&(..=42));
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(..=42)
+ //~| SUGGESTION &(
}
diff --git a/tests/ui/range/issue-54505.rs b/tests/ui/range/issue-54505.rs
index 03673252dd3..c9929988fe5 100644
--- a/tests/ui/range/issue-54505.rs
+++ b/tests/ui/range/issue-54505.rs
@@ -14,30 +14,30 @@ fn main() {
take_range(0..1);
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(0..1)
+ //~| SUGGESTION &(
take_range(1..);
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(1..)
+ //~| SUGGESTION &(
take_range(..);
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(..)
+ //~| SUGGESTION &(
take_range(0..=1);
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(0..=1)
+ //~| SUGGESTION &(
take_range(..5);
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(..5)
+ //~| SUGGESTION &(
take_range(..=42);
//~^ ERROR mismatched types [E0308]
//~| HELP consider borrowing here
- //~| SUGGESTION &(..=42)
+ //~| SUGGESTION &(
}
diff --git a/tests/ui/range/issue-54505.stderr b/tests/ui/range/issue-54505.stderr
index eda047b507a..0e959fc05e2 100644
--- a/tests/ui/range/issue-54505.stderr
+++ b/tests/ui/range/issue-54505.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
--> $DIR/issue-54505.rs:14:16
|
LL | take_range(0..1);
- | ---------- ^^^^
- | | |
- | | expected `&_`, found `Range<{integer}>`
- | | help: consider borrowing here: `&(0..1)`
+ | ---------- ^^^^ expected `&_`, found `Range<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -15,15 +13,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&(0..1));
+ | ++ +
error[E0308]: mismatched types
--> $DIR/issue-54505.rs:19:16
|
LL | take_range(1..);
- | ---------- ^^^
- | | |
- | | expected `&_`, found `RangeFrom<{integer}>`
- | | help: consider borrowing here: `&(1..)`
+ | ---------- ^^^ expected `&_`, found `RangeFrom<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -33,15 +33,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&(1..));
+ | ++ +
error[E0308]: mismatched types
--> $DIR/issue-54505.rs:24:16
|
LL | take_range(..);
- | ---------- ^^
- | | |
- | | expected `&_`, found `RangeFull`
- | | help: consider borrowing here: `&(..)`
+ | ---------- ^^ expected `&_`, found `RangeFull`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -51,15 +53,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&(..));
+ | ++ +
error[E0308]: mismatched types
--> $DIR/issue-54505.rs:29:16
|
LL | take_range(0..=1);
- | ---------- ^^^^^
- | | |
- | | expected `&_`, found `RangeInclusive<{integer}>`
- | | help: consider borrowing here: `&(0..=1)`
+ | ---------- ^^^^^ expected `&_`, found `RangeInclusive<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -69,15 +73,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&(0..=1));
+ | ++ +
error[E0308]: mismatched types
--> $DIR/issue-54505.rs:34:16
|
LL | take_range(..5);
- | ---------- ^^^
- | | |
- | | expected `&_`, found `RangeTo<{integer}>`
- | | help: consider borrowing here: `&(..5)`
+ | ---------- ^^^ expected `&_`, found `RangeTo<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -87,15 +93,17 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&(..5));
+ | ++ +
error[E0308]: mismatched types
--> $DIR/issue-54505.rs:39:16
|
LL | take_range(..=42);
- | ---------- ^^^^^
- | | |
- | | expected `&_`, found `RangeToInclusive<{integer}>`
- | | help: consider borrowing here: `&(..=42)`
+ | ---------- ^^^^^ expected `&_`, found `RangeToInclusive<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -105,6 +113,10 @@ note: function defined here
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+ |
+LL | take_range(&(..=42));
+ | ++ +
error: aborting due to 6 previous errors
diff --git a/tests/ui/range/issue-73553-misinterp-range-literal.stderr b/tests/ui/range/issue-73553-misinterp-range-literal.stderr
index 77595b3678e..52efa241d0b 100644
--- a/tests/ui/range/issue-73553-misinterp-range-literal.stderr
+++ b/tests/ui/range/issue-73553-misinterp-range-literal.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
--> $DIR/issue-73553-misinterp-range-literal.rs:12:10
|
LL | demo(tell(1)..tell(10));
- | ---- ^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&Range<usize>`, found `Range<usize>`
- | | help: consider borrowing here: `&(tell(1)..tell(10))`
+ | ---- ^^^^^^^^^^^^^^^^^ expected `&Range<usize>`, found `Range<usize>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&std::ops::Range<usize>`
@@ -15,15 +13,17 @@ note: function defined here
|
LL | fn demo(r: &Range) {
| ^^^^ ---------
+help: consider borrowing here
+ |
+LL | demo(&(tell(1)..tell(10)));
+ | ++ +
error[E0308]: mismatched types
--> $DIR/issue-73553-misinterp-range-literal.rs:14:10
|
LL | demo(1..10);
- | ---- ^^^^^
- | | |
- | | expected `&Range<usize>`, found `Range<{integer}>`
- | | help: consider borrowing here: `&(1..10)`
+ | ---- ^^^^^ expected `&Range<usize>`, found `Range<{integer}>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&std::ops::Range<usize>`
@@ -33,6 +33,10 @@ note: function defined here
|
LL | fn demo(r: &Range) {
| ^^^^ ---------
+help: consider borrowing here
+ |
+LL | demo(&(1..10));
+ | ++ +
error: aborting due to 2 previous errors
diff --git a/tests/ui/reachable/auxiliary/foreign-priv-aux.rs b/tests/ui/reachable/auxiliary/foreign-priv-aux.rs
new file mode 100644
index 00000000000..10dc0861461
--- /dev/null
+++ b/tests/ui/reachable/auxiliary/foreign-priv-aux.rs
@@ -0,0 +1,21 @@
+trait PrivTrait {
+ fn priv_fn(&self);
+}
+
+pub struct ImplPrivTrait;
+
+impl PrivTrait for ImplPrivTrait {
+ fn priv_fn(&self) {}
+}
+
+pub struct Wrapper<T>(T);
+
+pub trait PubTrait {
+ fn pub_fn(&self);
+}
+
+impl<T: PrivTrait> PubTrait for Wrapper<T> {
+ fn pub_fn(&self) {
+ self.0.priv_fn()
+ }
+}
diff --git a/tests/ui/reachable/foreign-priv.rs b/tests/ui/reachable/foreign-priv.rs
new file mode 100644
index 00000000000..bf336b6be7a
--- /dev/null
+++ b/tests/ui/reachable/foreign-priv.rs
@@ -0,0 +1,12 @@
+// aux-build:foreign-priv-aux.rs
+// build-pass
+
+#![crate_type = "lib"]
+
+extern crate foreign_priv_aux;
+
+use foreign_priv_aux::{ImplPrivTrait, PubTrait, Wrapper};
+
+pub fn foo(x: Wrapper<ImplPrivTrait>) {
+ x.pub_fn();
+}
diff --git a/tests/ui/issues/issue-948.rs b/tests/ui/reachable/issue-948.rs
index b9bbeb3951e..b9bbeb3951e 100644
--- a/tests/ui/issues/issue-948.rs
+++ b/tests/ui/reachable/issue-948.rs
diff --git a/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs b/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs
index a65c17e0efc..5ae5ebb450e 100644
--- a/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs
+++ b/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs
@@ -55,11 +55,11 @@ where
}
pub fn x<T: Copy>(a: Array<T>) {
- // drop just avoids a must_use warning
- drop((0..1).filter(|_| true));
+ // _ just avoids a must_use warning
+ let _ = (0..1).filter(|_| true);
let y = a.index_axis();
a.axis_iter().for_each(|_| {
- drop(y);
+ let _ = y;
});
}
diff --git a/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs b/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs
index d463f311c34..af2bb09805a 100644
--- a/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs
+++ b/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs
@@ -3,6 +3,8 @@
// check-pass
+#![allow(drop_copy)]
+
use std::marker::PhantomData;
fn apply<T, F: FnOnce(T)>(_: T, _: F) {}
diff --git a/tests/ui/resolve/explicit-self-lowercase-param.rs b/tests/ui/resolve/explicit-self-lowercase-param.rs
new file mode 100644
index 00000000000..7171bd8a42d
--- /dev/null
+++ b/tests/ui/resolve/explicit-self-lowercase-param.rs
@@ -0,0 +1,8 @@
+struct Foo;
+
+impl Foo {
+ fn do_nothing(self: Box<self>) {} //~ ERROR attempt to use a non-constant value in a constant
+ //~^ HELP try using `Self`
+}
+
+fn main() {}
diff --git a/tests/ui/resolve/explicit-self-lowercase-param.stderr b/tests/ui/resolve/explicit-self-lowercase-param.stderr
new file mode 100644
index 00000000000..cd64dbb3854
--- /dev/null
+++ b/tests/ui/resolve/explicit-self-lowercase-param.stderr
@@ -0,0 +1,8 @@
+error: attempt to use a non-constant value in a constant
+ --> $DIR/explicit-self-lowercase-param.rs:4:29
+ |
+LL | fn do_nothing(self: Box<self>) {}
+ | ^^^^ help: try using `Self`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/resolve/issue-109250.rs b/tests/ui/resolve/issue-109250.rs
new file mode 100644
index 00000000000..68e33f693ce
--- /dev/null
+++ b/tests/ui/resolve/issue-109250.rs
@@ -0,0 +1,3 @@
+fn main() { //~ HELP consider importing
+ HashMap::new; //~ ERROR failed to resolve: use of undeclared type `HashMap`
+}
diff --git a/tests/ui/resolve/issue-109250.stderr b/tests/ui/resolve/issue-109250.stderr
new file mode 100644
index 00000000000..d5b8c08ced7
--- /dev/null
+++ b/tests/ui/resolve/issue-109250.stderr
@@ -0,0 +1,14 @@
+error[E0433]: failed to resolve: use of undeclared type `HashMap`
+ --> $DIR/issue-109250.rs:2:5
+ |
+LL | HashMap::new;
+ | ^^^^^^^ use of undeclared type `HashMap`
+ |
+help: consider importing this struct
+ |
+LL + use std::collections::HashMap;
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/tests/ui/resolve/issue-111312.rs b/tests/ui/resolve/issue-111312.rs
new file mode 100644
index 00000000000..acea37b358b
--- /dev/null
+++ b/tests/ui/resolve/issue-111312.rs
@@ -0,0 +1,11 @@
+// edition: 2021
+
+trait Has {
+ fn has() {}
+}
+
+trait HasNot {}
+
+fn main() {
+ HasNot::has(); //~ ERROR
+}
diff --git a/tests/ui/resolve/issue-111312.stderr b/tests/ui/resolve/issue-111312.stderr
new file mode 100644
index 00000000000..4c864029c98
--- /dev/null
+++ b/tests/ui/resolve/issue-111312.stderr
@@ -0,0 +1,15 @@
+error[E0599]: no function or associated item named `has` found for trait `HasNot`
+ --> $DIR/issue-111312.rs:10:13
+ |
+LL | HasNot::has();
+ | ^^^ function or associated item not found in `HasNot`
+ |
+note: `Has` defines an item `has`
+ --> $DIR/issue-111312.rs:3:1
+ |
+LL | trait Has {
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/issues/issue-3099-a.rs b/tests/ui/resolve/issue-3099-a.rs
index 9c3d8cf5a55..9c3d8cf5a55 100644
--- a/tests/ui/issues/issue-3099-a.rs
+++ b/tests/ui/resolve/issue-3099-a.rs
diff --git a/tests/ui/issues/issue-3099-a.stderr b/tests/ui/resolve/issue-3099-a.stderr
index e3733cebba5..e3733cebba5 100644
--- a/tests/ui/issues/issue-3099-a.stderr
+++ b/tests/ui/resolve/issue-3099-a.stderr
diff --git a/tests/ui/issues/issue-3099-b.rs b/tests/ui/resolve/issue-3099-b.rs
index 71952c3b060..71952c3b060 100644
--- a/tests/ui/issues/issue-3099-b.rs
+++ b/tests/ui/resolve/issue-3099-b.rs
diff --git a/tests/ui/issues/issue-3099-b.stderr b/tests/ui/resolve/issue-3099-b.stderr
index c0cfefeb940..c0cfefeb940 100644
--- a/tests/ui/issues/issue-3099-b.stderr
+++ b/tests/ui/resolve/issue-3099-b.stderr
diff --git a/tests/ui/resolve/issue-50599.rs b/tests/ui/resolve/issue-50599.rs
index 72238a59198..00588735b9a 100644
--- a/tests/ui/resolve/issue-50599.rs
+++ b/tests/ui/resolve/issue-50599.rs
@@ -2,5 +2,4 @@ fn main() {
const N: u32 = 1_000;
const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value
let mut digits = [0u32; M];
- //~^ constant
}
diff --git a/tests/ui/resolve/issue-50599.stderr b/tests/ui/resolve/issue-50599.stderr
index d7419b64fac..d58b6ca5b5c 100644
--- a/tests/ui/resolve/issue-50599.stderr
+++ b/tests/ui/resolve/issue-50599.stderr
@@ -16,12 +16,6 @@ LL - const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize;
LL + const M: usize = (f64::from(N) * LOG10_2) as usize;
|
-note: erroneous constant used
- --> $DIR/issue-50599.rs:4:29
- |
-LL | let mut digits = [0u32; M];
- | ^
-
error: aborting due to previous error
For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/resolve/resolve-variant-assoc-item.stderr b/tests/ui/resolve/resolve-variant-assoc-item.stderr
index 4be1019968b..ed157197d17 100644
--- a/tests/ui/resolve/resolve-variant-assoc-item.stderr
+++ b/tests/ui/resolve/resolve-variant-assoc-item.stderr
@@ -3,12 +3,26 @@ error[E0433]: failed to resolve: `V` is a variant, not a module
|
LL | E::V::associated_item;
| ^ `V` is a variant, not a module
+ |
+help: there is an enum variant `E::V`; try using the variant's enum
+ |
+LL | E;
+ | ~
error[E0433]: failed to resolve: `V` is a variant, not a module
--> $DIR/resolve-variant-assoc-item.rs:6:5
|
LL | V::associated_item;
| ^ `V` is a variant, not a module
+ |
+help: there is an enum variant `E::V`; try using the variant's enum
+ |
+LL | E;
+ | ~
+help: an enum with a similar name exists
+ |
+LL | E::associated_item;
+ | ~
error: aborting due to 2 previous errors
diff --git a/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs b/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
index be775b37f7b..8f45b989f13 100644
--- a/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
+++ b/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
@@ -3,6 +3,8 @@
// check-pass
+#![allow(drop_ref)]
+
// aux-build:monovariants.rs
extern crate monovariants;
diff --git a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
index 04d924a9aed..4c1562790d5 100644
--- a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
+++ b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
@@ -4,6 +4,8 @@
// Tests ensuring that `dbg!(expr)` has the expected run-time behavior.
// as well as some compile time properties we expect.
+#![allow(drop_copy)]
+
#[derive(Copy, Clone, Debug)]
struct Unit;
diff --git a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
index 49d72158e92..a20a6062c13 100644
--- a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
+++ b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
@@ -1,28 +1,28 @@
-[$DIR/dbg-macro-expected-behavior.rs:20] Unit = Unit
-[$DIR/dbg-macro-expected-behavior.rs:21] a = Unit
-[$DIR/dbg-macro-expected-behavior.rs:27] Point { x: 42, y: 24 } = Point {
+[$DIR/dbg-macro-expected-behavior.rs:22] Unit = Unit
+[$DIR/dbg-macro-expected-behavior.rs:23] a = Unit
+[$DIR/dbg-macro-expected-behavior.rs:29] Point { x: 42, y: 24 } = Point {
x: 42,
y: 24,
}
-[$DIR/dbg-macro-expected-behavior.rs:28] b = Point {
+[$DIR/dbg-macro-expected-behavior.rs:30] b = Point {
x: 42,
y: 24,
}
-[$DIR/dbg-macro-expected-behavior.rs:36]
-[$DIR/dbg-macro-expected-behavior.rs:40] &a = NoCopy(
+[$DIR/dbg-macro-expected-behavior.rs:38]
+[$DIR/dbg-macro-expected-behavior.rs:42] &a = NoCopy(
1337,
)
-[$DIR/dbg-macro-expected-behavior.rs:40] dbg!(& a) = NoCopy(
+[$DIR/dbg-macro-expected-behavior.rs:42] dbg!(& a) = NoCopy(
1337,
)
-[$DIR/dbg-macro-expected-behavior.rs:45] f(&42) = 42
+[$DIR/dbg-macro-expected-behavior.rs:47] f(&42) = 42
before
-[$DIR/dbg-macro-expected-behavior.rs:50] { foo += 1; eprintln!("before"); 7331 } = 7331
-[$DIR/dbg-macro-expected-behavior.rs:58] ("Yeah",) = (
+[$DIR/dbg-macro-expected-behavior.rs:52] { foo += 1; eprintln!("before"); 7331 } = 7331
+[$DIR/dbg-macro-expected-behavior.rs:60] ("Yeah",) = (
"Yeah",
)
-[$DIR/dbg-macro-expected-behavior.rs:61] 1 = 1
-[$DIR/dbg-macro-expected-behavior.rs:61] 2 = 2
-[$DIR/dbg-macro-expected-behavior.rs:65] 1u8 = 1
-[$DIR/dbg-macro-expected-behavior.rs:65] 2u32 = 2
-[$DIR/dbg-macro-expected-behavior.rs:65] "Yeah" = "Yeah"
+[$DIR/dbg-macro-expected-behavior.rs:63] 1 = 1
+[$DIR/dbg-macro-expected-behavior.rs:63] 2 = 2
+[$DIR/dbg-macro-expected-behavior.rs:67] 1u8 = 1
+[$DIR/dbg-macro-expected-behavior.rs:67] 2u32 = 2
+[$DIR/dbg-macro-expected-behavior.rs:67] "Yeah" = "Yeah"
diff --git a/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs b/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
index 3ac90992486..f31123f16f1 100644
--- a/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
+++ b/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
@@ -12,7 +12,9 @@ trait Specialize {}
trait Foo {}
#[const_trait]
-trait Bar {}
+trait Bar {
+ fn bar();
+}
// bgr360: I was only able to exercise the code path that raises the
// "missing ~const qualifier" error by making this base impl non-const, even
@@ -21,26 +23,36 @@ trait Bar {}
impl<T> Bar for T
where
T: ~const Foo,
-{}
+{
+ default fn bar() {}
+}
impl<T> Bar for T
where
T: Foo, //~ ERROR missing `~const` qualifier
T: Specialize,
-{}
+{
+ fn bar() {}
+}
#[const_trait]
-trait Baz {}
+trait Baz {
+ fn baz();
+}
impl<T> const Baz for T
where
T: ~const Foo,
-{}
+{
+ default fn baz() {}
+}
impl<T> const Baz for T //~ ERROR conflicting implementations of trait `Baz`
where
T: Foo,
T: Specialize,
-{}
+{
+ fn baz() {}
+}
fn main() {}
diff --git a/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
index 4aea1979421..057cf4aea8a 100644
--- a/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
+++ b/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
@@ -1,11 +1,11 @@
error: missing `~const` qualifier for specialization
- --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:8
+ --> $DIR/const-default-bound-non-const-specialized-bound.rs:32:8
|
LL | T: Foo,
| ^^^
error[E0119]: conflicting implementations of trait `Baz`
- --> $DIR/const-default-bound-non-const-specialized-bound.rs:40:1
+ --> $DIR/const-default-bound-non-const-specialized-bound.rs:50:1
|
LL | impl<T> const Baz for T
| ----------------------- first implementation here
diff --git a/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs b/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
index 9c2c2cf1610..92d8be6bb16 100644
--- a/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
+++ b/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
@@ -11,27 +11,39 @@
trait Specialize {}
#[const_trait]
-trait Foo {}
+trait Foo {
+ fn foo();
+}
-impl<T> const Foo for T {}
+impl<T> const Foo for T {
+ default fn foo() {}
+}
impl<T> const Foo for T
where
T: ~const Specialize,
-{}
+{
+ fn foo() {}
+}
#[const_trait]
-trait Bar {}
+trait Bar {
+ fn bar() {}
+}
impl<T> const Bar for T
where
T: ~const Foo,
-{}
+{
+ default fn bar() {}
+}
impl<T> const Bar for T
where
T: ~const Foo,
T: ~const Specialize,
-{}
+{
+ fn bar() {}
+}
fn main() {}
diff --git a/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
index 1e6b1c6513b..51bfaf73b57 100644
--- a/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
+++ b/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
@@ -15,31 +15,43 @@ trait Specialize {}
trait Foo {}
#[const_trait]
-trait Bar {}
+trait Bar {
+ fn bar();
+}
impl<T> Bar for T
where
T: Foo,
-{}
+{
+ default fn bar() {}
+}
impl<T> const Bar for T
where
T: ~const Foo,
T: Specialize,
-{}
+{
+ fn bar() {}
+}
#[const_trait]
-trait Baz {}
+trait Baz {
+ fn baz();
+}
impl<T> const Baz for T
where
T: Foo,
-{}
+{
+ default fn baz() {}
+}
impl<T> const Baz for T
where
T: ~const Foo,
T: Specialize,
-{}
+{
+ fn baz() {}
+}
fn main() {}
diff --git a/tests/ui/rust-2018/remove-extern-crate.fixed b/tests/ui/rust-2018/remove-extern-crate.fixed
index 15e0ccc5256..4ed4d610025 100644
--- a/tests/ui/rust-2018/remove-extern-crate.fixed
+++ b/tests/ui/rust-2018/remove-extern-crate.fixed
@@ -5,6 +5,7 @@
// compile-flags:--extern remove_extern_crate
#![warn(rust_2018_idioms)]
+#![allow(drop_copy)]
//~ WARNING unused extern crate
// Shouldn't suggest changing to `use`, as `another_name`
diff --git a/tests/ui/rust-2018/remove-extern-crate.rs b/tests/ui/rust-2018/remove-extern-crate.rs
index aec0bc7c374..5dafdb2b7b7 100644
--- a/tests/ui/rust-2018/remove-extern-crate.rs
+++ b/tests/ui/rust-2018/remove-extern-crate.rs
@@ -5,6 +5,7 @@
// compile-flags:--extern remove_extern_crate
#![warn(rust_2018_idioms)]
+#![allow(drop_copy)]
extern crate core; //~ WARNING unused extern crate
// Shouldn't suggest changing to `use`, as `another_name`
diff --git a/tests/ui/rust-2018/remove-extern-crate.stderr b/tests/ui/rust-2018/remove-extern-crate.stderr
index d07358e471b..f752cac8ed6 100644
--- a/tests/ui/rust-2018/remove-extern-crate.stderr
+++ b/tests/ui/rust-2018/remove-extern-crate.stderr
@@ -1,5 +1,5 @@
warning: unused extern crate
- --> $DIR/remove-extern-crate.rs:9:1
+ --> $DIR/remove-extern-crate.rs:10:1
|
LL | extern crate core;
| ^^^^^^^^^^^^^^^^^^ help: remove it
@@ -12,7 +12,7 @@ LL | #![warn(rust_2018_idioms)]
= note: `#[warn(unused_extern_crates)]` implied by `#[warn(rust_2018_idioms)]`
warning: `extern crate` is not idiomatic in the new edition
- --> $DIR/remove-extern-crate.rs:33:5
+ --> $DIR/remove-extern-crate.rs:34:5
|
LL | extern crate core;
| ^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL | use core;
| ~~~
warning: `extern crate` is not idiomatic in the new edition
- --> $DIR/remove-extern-crate.rs:43:5
+ --> $DIR/remove-extern-crate.rs:44:5
|
LL | pub extern crate core;
| ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
index 0ec0d4be5f2..13591f5b635 100644
--- a/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
+++ b/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
@@ -31,8 +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 for `Rc<usize>` to implement `CoerceUnsized<Rc<dyn Foo>>`
- = note: required by cast to type `Rc<dyn Foo>`
+ = note: required for the cast from `Rc<usize>` to `Rc<dyn Foo>`
error: aborting due to 2 previous errors
diff --git a/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
index b494b448e2e..593f705353a 100644
--- a/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
+++ b/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
@@ -14,8 +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 for `Rc<usize>` to implement `CoerceUnsized<Rc<dyn Foo>>`
- = note: required by cast to type `Rc<dyn Foo>`
+ = note: required for the cast from `Rc<usize>` to `Rc<dyn Foo>`
error: aborting due to previous error
diff --git a/tests/ui/self/self-ctor-inner-const.rs b/tests/ui/self/self-ctor-inner-const.rs
deleted file mode 100644
index b015397a5bc..00000000000
--- a/tests/ui/self/self-ctor-inner-const.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Verify that we ban usage of `Self` as constructor from inner items.
-
-struct S0<T>(T);
-
-impl<T> S0<T> {
- fn foo() {
- const C: S0<u8> = Self(0);
- //~^ ERROR can't use generic parameters from outer function
- fn bar() -> Self {
- //~^ ERROR can't use generic parameters from outer function
- Self(0)
- //~^ ERROR can't use generic parameters from outer function
- }
- }
-}
-
-fn main() {}
diff --git a/tests/ui/self/self-ctor-inner-const.stderr b/tests/ui/self/self-ctor-inner-const.stderr
deleted file mode 100644
index 7287c64c659..00000000000
--- a/tests/ui/self/self-ctor-inner-const.stderr
+++ /dev/null
@@ -1,33 +0,0 @@
-error[E0401]: can't use generic parameters from outer function
- --> $DIR/self-ctor-inner-const.rs:7:27
- |
-LL | const C: S0<u8> = Self(0);
- | ^^^^
- | |
- | use of generic parameter from outer function
- | can't use `Self` here
-
-error[E0401]: can't use generic parameters from outer function
- --> $DIR/self-ctor-inner-const.rs:9:21
- |
-LL | impl<T> S0<T> {
- | ---- `Self` type implicitly declared here, by this `impl`
-...
-LL | fn bar() -> Self {
- | ^^^^
- | |
- | use of generic parameter from outer function
- | use a type here instead
-
-error[E0401]: can't use generic parameters from outer function
- --> $DIR/self-ctor-inner-const.rs:11:13
- |
-LL | Self(0)
- | ^^^^
- | |
- | use of generic parameter from outer function
- | can't use `Self` here
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0401`.
diff --git a/tests/ui/self/self-ctor-nongeneric.rs b/tests/ui/self/self-ctor-nongeneric.rs
new file mode 100644
index 00000000000..0ae7f8da4b4
--- /dev/null
+++ b/tests/ui/self/self-ctor-nongeneric.rs
@@ -0,0 +1,15 @@
+// `Self` as a constructor is currently allowed when the outer item is not generic.
+// check-pass
+
+struct S0(usize);
+
+impl S0 {
+ fn foo() {
+ const C: S0 = Self(0);
+ fn bar() -> S0 {
+ Self(0)
+ }
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr b/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
index 570328fc211..80c5f9da40c 100644
--- a/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
+++ b/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
@@ -18,7 +18,7 @@ LL | &mut x.y
help: consider changing this to be a mutable reference
|
LL | fn deref_extend_mut_field1(x: &mut Own<Point>) -> &mut isize {
- | ~~~~~~~~~~~~~~~
+ | +++
error[E0499]: cannot borrow `*x` as mutable more than once at a time
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:78:19
@@ -50,7 +50,7 @@ LL | x.y = 3;
help: consider changing this to be a mutable reference
|
LL | fn assign_field2<'a>(x: &'a mut Own<Point>) {
- | ~~~~~~~~~~~~~~~~~~
+ | +++
error[E0499]: cannot borrow `*x` as mutable more than once at a time
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:101:5
@@ -82,7 +82,7 @@ LL | x.y_mut()
help: consider changing this to be a mutable reference
|
LL | fn deref_extend_mut_method1(x: &mut Own<Point>) -> &mut isize {
- | ~~~~~~~~~~~~~~~
+ | +++
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:129:6
@@ -104,7 +104,7 @@ LL | *x.y_mut() = 3;
help: consider changing this to be a mutable reference
|
LL | fn assign_method2<'a>(x: &'a mut Own<Point>) {
- | ~~~~~~~~~~~~~~~~~~
+ | +++
error: aborting due to 10 previous errors
diff --git a/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr b/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
index 3fed7b3f4dc..dbd52dc2d38 100644
--- a/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
+++ b/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
@@ -18,7 +18,7 @@ LL | &mut **x
help: consider changing this to be a mutable reference
|
LL | fn deref_extend_mut1<'a>(x: &'a mut Own<isize>) -> &'a mut isize {
- | ~~~~~~~~~~~~~~~~~~
+ | +++
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-borrow-overloaded-deref-mut.rs:49:6
@@ -40,7 +40,7 @@ LL | **x = 3;
help: consider changing this to be a mutable reference
|
LL | fn assign2<'a>(x: &'a mut Own<isize>) {
- | ~~~~~~~~~~~~~~~~~~
+ | +++
error: aborting due to 4 previous errors
diff --git a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr
index 9711dad8078..99c8fa1f932 100644
--- a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr
+++ b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr
@@ -19,7 +19,7 @@ LL | (*f)();
help: consider changing this to be a mutable reference
|
LL | fn test2<F>(f: &mut F) where F: FnMut() {
- | ~~~~~~
+ | +++
error[E0596]: cannot borrow `f.f` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:34:5
@@ -29,8 +29,8 @@ LL | f.f.call_mut(())
|
help: consider changing this to be a mutable reference
|
-LL | fn test4(f: &mut Test<'_>) {
- | ~~~~~~~~~~~~~
+LL | fn test4(f: &mut Test) {
+ | +++
error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13
diff --git a/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr b/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr
index 2a842f5a2a9..328197ae9f4 100644
--- a/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr
+++ b/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr
@@ -7,7 +7,7 @@ LL | x.h();
help: consider changing this to be a mutable reference
|
LL | fn b(x: &mut Foo) {
- | ~~~~~~~~
+ | +++
error: aborting due to previous error
diff --git a/tests/ui/span/borrowck-fn-in-const-b.stderr b/tests/ui/span/borrowck-fn-in-const-b.stderr
index 1df19deb12f..17fdcc622f7 100644
--- a/tests/ui/span/borrowck-fn-in-const-b.stderr
+++ b/tests/ui/span/borrowck-fn-in-const-b.stderr
@@ -7,7 +7,7 @@ LL | x.push(format!("this is broken"));
help: consider changing this to be a mutable reference
|
LL | fn broken(x: &mut Vec<String>) {
- | ~~~~~~~~~~~~~~~~
+ | +++
error: aborting due to previous error
diff --git a/tests/ui/span/borrowck-object-mutability.stderr b/tests/ui/span/borrowck-object-mutability.stderr
index b6517e0b309..805a8034c18 100644
--- a/tests/ui/span/borrowck-object-mutability.stderr
+++ b/tests/ui/span/borrowck-object-mutability.stderr
@@ -7,7 +7,7 @@ LL | x.borrowed_mut();
help: consider changing this to be a mutable reference
|
LL | fn borrowed_receiver(x: &mut dyn Foo) {
- | ~~~~~~~~~~~~
+ | +++
error[E0596]: cannot borrow `*x` as mutable, as `x` is not declared as mutable
--> $DIR/borrowck-object-mutability.rs:18:5
diff --git a/tests/ui/span/coerce-suggestions.stderr b/tests/ui/span/coerce-suggestions.stderr
index bb30f000ea7..ff840b781f0 100644
--- a/tests/ui/span/coerce-suggestions.stderr
+++ b/tests/ui/span/coerce-suggestions.stderr
@@ -10,11 +10,14 @@ error[E0308]: mismatched types
--> $DIR/coerce-suggestions.rs:9:19
|
LL | let x: &str = String::new();
- | ---- ^^^^^^^^^^^^^
- | | |
- | | expected `&str`, found `String`
- | | help: consider borrowing here: `&String::new()`
+ | ---- ^^^^^^^^^^^^^ expected `&str`, found `String`
+ | |
| expected due to this
+ |
+help: consider borrowing here
+ |
+LL | let x: &str = &String::new();
+ | +
error[E0308]: mismatched types
--> $DIR/coerce-suggestions.rs:12:10
diff --git a/tests/ui/span/issue-39018.stderr b/tests/ui/span/issue-39018.stderr
index bae93639271..c8c4a513988 100644
--- a/tests/ui/span/issue-39018.stderr
+++ b/tests/ui/span/issue-39018.stderr
@@ -78,10 +78,12 @@ error[E0308]: mismatched types
--> $DIR/issue-39018.rs:29:17
|
LL | let _ = a + b;
- | ^
- | |
- | expected `&str`, found `String`
- | help: consider borrowing here: `&b`
+ | ^ expected `&str`, found `String`
+ |
+help: consider borrowing here
+ |
+LL | let _ = a + &b;
+ | +
error[E0369]: cannot add `String` to `&String`
--> $DIR/issue-39018.rs:30:15
diff --git a/tests/ui/span/mut-arg-hint.stderr b/tests/ui/span/mut-arg-hint.stderr
index 96ce4d5bc6c..06011eac674 100644
--- a/tests/ui/span/mut-arg-hint.stderr
+++ b/tests/ui/span/mut-arg-hint.stderr
@@ -7,7 +7,7 @@ LL | a.push_str("bar");
help: consider changing this to be a mutable reference
|
LL | fn foo(mut a: &mut String) {
- | ~~~~~~~~~~~
+ | +++
error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
--> $DIR/mut-arg-hint.rs:8:5
@@ -18,7 +18,7 @@ LL | a.push_str("foo");
help: consider changing this to be a mutable reference
|
LL | pub fn foo<'a>(mut a: &'a mut String) {
- | ~~~~~~~~~~~~~~
+ | +++
error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
--> $DIR/mut-arg-hint.rs:15:9
@@ -29,7 +29,7 @@ LL | a.push_str("foo");
help: consider changing this to be a mutable reference
|
LL | pub fn foo(mut a: &mut String) {
- | ~~~~~~~~~~~
+ | +++
error: aborting due to 3 previous errors
diff --git a/tests/ui/specialization/min_specialization/specialize-associated-type.rs b/tests/ui/specialization/min_specialization/specialize-associated-type.rs
new file mode 100644
index 00000000000..c4960b0c28e
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize-associated-type.rs
@@ -0,0 +1,37 @@
+// Another regression test for #109815.
+
+// check-pass
+
+#![feature(min_specialization)]
+#![feature(rustc_attrs)]
+
+#[rustc_specialization_trait]
+trait X {}
+trait Z {
+ type Assoc: X;
+}
+struct A<T>(T);
+
+impl X for () {}
+
+impl<T: X> Z for A<T> {
+ type Assoc = ();
+}
+
+trait MyFrom<T> {
+ fn from(other: T) -> Self;
+}
+
+impl<T> MyFrom<()> for T {
+ default fn from(other: ()) -> T {
+ panic!();
+ }
+}
+
+impl<T: X> MyFrom<<A<T> as Z>::Assoc> for T {
+ fn from(other: ()) -> T {
+ panic!();
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/min_specialization/specialize_nothing.rs b/tests/ui/specialization/min_specialization/specialize_nothing.rs
new file mode 100644
index 00000000000..ef92254d465
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize_nothing.rs
@@ -0,0 +1,14 @@
+#![feature(min_specialization)]
+
+trait Special {
+ fn be_special();
+}
+
+impl<T> Special for T {
+ fn be_special() {}
+}
+
+impl Special for usize {}
+//~^ ERROR specialization impl does not specialize any associated items
+
+fn main() {}
diff --git a/tests/ui/specialization/min_specialization/specialize_nothing.stderr b/tests/ui/specialization/min_specialization/specialize_nothing.stderr
new file mode 100644
index 00000000000..65f73781cae
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize_nothing.stderr
@@ -0,0 +1,14 @@
+error: specialization impl does not specialize any associated items
+ --> $DIR/specialize_nothing.rs:11:1
+ |
+LL | impl Special for usize {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: impl is a specialization of this impl
+ --> $DIR/specialize_nothing.rs:7:1
+ |
+LL | impl<T> Special for T {
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/specialization/min_specialization/specialize_on_type_error.rs b/tests/ui/specialization/min_specialization/specialize_on_type_error.rs
new file mode 100644
index 00000000000..24e92a0abc3
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize_on_type_error.rs
@@ -0,0 +1,33 @@
+// A regression test for #109815.
+
+#![feature(min_specialization)]
+#![feature(rustc_attrs)]
+
+#[rustc_specialization_trait]
+trait X {}
+trait Y: X {}
+trait Z {
+ type Assoc: Y;
+}
+struct A<T>(T);
+
+impl<T: X> Z for A<T> {}
+//~^ ERROR not all trait items implemented
+
+trait MyFrom<T> {
+ fn from(other: T) -> Self;
+}
+
+impl<T> MyFrom<T> for T {
+ default fn from(other: T) -> T {
+ other
+ }
+}
+
+impl<T: X> MyFrom<<A<T> as Z>::Assoc> for T {
+ fn from(other: <A<T> as Z>::Assoc) -> T {
+ other
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/min_specialization/specialize_on_type_error.stderr b/tests/ui/specialization/min_specialization/specialize_on_type_error.stderr
new file mode 100644
index 00000000000..cc12302bd8c
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize_on_type_error.stderr
@@ -0,0 +1,12 @@
+error[E0046]: not all trait items implemented, missing: `Assoc`
+ --> $DIR/specialize_on_type_error.rs:14:1
+ |
+LL | type Assoc: Y;
+ | ------------- `Assoc` from trait
+...
+LL | impl<T: X> Z for A<T> {}
+ | ^^^^^^^^^^^^^^^^^^^^^ missing `Assoc` in implementation
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.rs b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.rs
new file mode 100644
index 00000000000..d90b81f717a
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.rs
@@ -0,0 +1,50 @@
+// Regression test for #79457.
+
+#![feature(min_specialization)]
+
+use std::any::Any;
+
+pub trait Tr {
+ fn method(self) -> Box<dyn Any + 'static>;
+ fn other(self);
+}
+
+impl<T: Any + 'static> Tr for T {
+ default fn method(self) -> Box<dyn Any + 'static> {
+ Box::new(self)
+ }
+
+ default fn other(self) {}
+}
+
+impl<'a> Tr for &'a i32 {
+ //~^ ERROR does not fulfill the required lifetime
+ fn other(self) {}
+}
+
+fn promote_to_static<'a>(i: &'a i32) -> &'static i32 {
+ *i.method().downcast().unwrap()
+}
+
+struct Wrapper<'a>(&'a i32);
+
+impl<'a> Tr for Wrapper<'a> {
+ //~^ ERROR does not fulfill the required lifetime
+ fn other(self) {}
+}
+
+fn promote_to_static_2<'a>(w: Wrapper<'a>) -> Wrapper<'static> {
+ *w.method().downcast().unwrap()
+}
+
+fn main() {
+ let i = Box::new(100_i32);
+ let static_i: &'static i32 = promote_to_static(&*i);
+ drop(i);
+ println!("{}", *static_i);
+
+ let j = Box::new(200_i32);
+ let static_w: Wrapper<'static> = promote_to_static_2(Wrapper(&*j));
+ drop(j);
+ println!("{}", *static_w.0);
+}
diff --git a/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr
new file mode 100644
index 00000000000..2af75876d5b
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr
@@ -0,0 +1,27 @@
+error[E0477]: the type `&'a i32` does not fulfill the required lifetime
+ --> $DIR/specialize_with_generalize_lifetimes.rs:20:1
+ |
+LL | impl<'a> Tr for &'a i32 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: type must satisfy the static lifetime as required by this binding
+ --> $DIR/specialize_with_generalize_lifetimes.rs:12:15
+ |
+LL | impl<T: Any + 'static> Tr for T {
+ | ^^^^^^^
+
+error[E0477]: the type `Wrapper<'a>` does not fulfill the required lifetime
+ --> $DIR/specialize_with_generalize_lifetimes.rs:31:1
+ |
+LL | impl<'a> Tr for Wrapper<'a> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: type must satisfy the static lifetime as required by this binding
+ --> $DIR/specialize_with_generalize_lifetimes.rs:12:15
+ |
+LL | impl<T: Any + 'static> Tr for T {
+ | ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0477`.
diff --git a/tests/ui/statics/issue-91050-1.rs b/tests/ui/statics/issue-91050-1.rs
index 403a41462ef..f59bcf0b803 100644
--- a/tests/ui/statics/issue-91050-1.rs
+++ b/tests/ui/statics/issue-91050-1.rs
@@ -12,6 +12,8 @@
//
// In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!"
+#![allow(drop_copy)]
+
pub mod before {
#[no_mangle]
pub static GLOBAL1: [u8; 1] = [1];
diff --git a/tests/ui/str/str-array-assignment.stderr b/tests/ui/str/str-array-assignment.stderr
index c23400a1d14..515cb9e12f8 100644
--- a/tests/ui/str/str-array-assignment.stderr
+++ b/tests/ui/str/str-array-assignment.stderr
@@ -10,10 +10,12 @@ error[E0308]: mismatched types
--> $DIR/str-array-assignment.rs:5:27
|
LL | let u: &str = if true { s[..2] } else { s };
- | ^^^^^^
- | |
- | expected `&str`, found `str`
- | help: consider borrowing here: `&s[..2]`
+ | ^^^^^^ expected `&str`, found `str`
+ |
+help: consider borrowing here
+ |
+LL | let u: &str = if true { &s[..2] } else { s };
+ | +
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/str-array-assignment.rs:7:7
@@ -33,11 +35,14 @@ error[E0308]: mismatched types
--> $DIR/str-array-assignment.rs:9:17
|
LL | let w: &str = s[..2];
- | ---- ^^^^^^
- | | |
- | | expected `&str`, found `str`
- | | help: consider borrowing here: `&s[..2]`
+ | ---- ^^^^^^ expected `&str`, found `str`
+ | |
| expected due to this
+ |
+help: consider borrowing here
+ |
+LL | let w: &str = &s[..2];
+ | +
error: aborting due to 4 previous errors
diff --git a/tests/ui/structs-enums/issue-103869.fixed b/tests/ui/structs-enums/issue-103869.fixed
new file mode 100644
index 00000000000..49fe32c7109
--- /dev/null
+++ b/tests/ui/structs-enums/issue-103869.fixed
@@ -0,0 +1,13 @@
+// run-rustfix
+
+struct VecOrMap {
+ //~^ HELP: perhaps you meant to use `struct` here
+ vec: Vec<usize>,
+ //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `:`
+ //~| HELP: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
+}
+
+fn main() {
+ let o = VecOrMap { vec: vec![1, 2, 3] };
+ println!("{:?}", o.vec);
+}
diff --git a/tests/ui/parser/issue-103869.rs b/tests/ui/structs-enums/issue-103869.rs
index 9213437458a..729079e0501 100644
--- a/tests/ui/parser/issue-103869.rs
+++ b/tests/ui/structs-enums/issue-103869.rs
@@ -1,8 +1,13 @@
-enum VecOrMap{
+// run-rustfix
+
+enum VecOrMap {
+ //~^ HELP: perhaps you meant to use `struct` here
vec: Vec<usize>,
//~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `:`
//~| HELP: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
- map: HashMap<String,usize>
}
-fn main() {}
+fn main() {
+ let o = VecOrMap { vec: vec![1, 2, 3] };
+ println!("{:?}", o.vec);
+}
diff --git a/tests/ui/parser/issue-103869.stderr b/tests/ui/structs-enums/issue-103869.stderr
index 9eb20e2005a..4665ebf89a3 100644
--- a/tests/ui/parser/issue-103869.stderr
+++ b/tests/ui/structs-enums/issue-103869.stderr
@@ -1,12 +1,17 @@
error: expected one of `(`, `,`, `=`, `{`, or `}`, found `:`
- --> $DIR/issue-103869.rs:2:8
+ --> $DIR/issue-103869.rs:5:8
|
-LL | enum VecOrMap{
+LL | enum VecOrMap {
| -------- while parsing this enum
+LL |
LL | vec: Vec<usize>,
| ^ expected one of `(`, `,`, `=`, `{`, or `}`
|
= help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
+help: perhaps you meant to use `struct` here
+ |
+LL | struct VecOrMap {
+ | ~~~~~~
error: aborting due to previous error
diff --git a/tests/ui/suggestions/as-ref.stderr b/tests/ui/suggestions/as-ref.stderr
index 0ee343ebf9f..2147d2d92e3 100644
--- a/tests/ui/suggestions/as-ref.stderr
+++ b/tests/ui/suggestions/as-ref.stderr
@@ -2,61 +2,73 @@ error[E0308]: mismatched types
--> $DIR/as-ref.rs:7:29
|
LL | opt.map(|arg| takes_ref(arg));
- | --- --------- ^^^ expected `&Foo`, found `Foo`
- | | |
- | | arguments to this function are incorrect
- | help: consider using `as_ref` instead: `as_ref().map`
+ | --------- ^^^ expected `&Foo`, found `Foo`
+ | |
+ | arguments to this function are incorrect
|
note: function defined here
--> $DIR/as-ref.rs:3:4
|
LL | fn takes_ref(_: &Foo) {}
| ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+ |
+LL | opt.as_ref().map(|arg| takes_ref(arg));
+ | +++++++++
error[E0308]: mismatched types
--> $DIR/as-ref.rs:8:39
|
LL | opt.and_then(|arg| Some(takes_ref(arg)));
- | -------- --------- ^^^ expected `&Foo`, found `Foo`
- | | |
- | | arguments to this function are incorrect
- | help: consider using `as_ref` instead: `as_ref().and_then`
+ | --------- ^^^ expected `&Foo`, found `Foo`
+ | |
+ | arguments to this function are incorrect
|
note: function defined here
--> $DIR/as-ref.rs:3:4
|
LL | fn takes_ref(_: &Foo) {}
| ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+ |
+LL | opt.as_ref().and_then(|arg| Some(takes_ref(arg)));
+ | +++++++++
error[E0308]: mismatched types
--> $DIR/as-ref.rs:10:29
|
LL | opt.map(|arg| takes_ref(arg));
- | --- --------- ^^^ expected `&Foo`, found `Foo`
- | | |
- | | arguments to this function are incorrect
- | help: consider using `as_ref` instead: `as_ref().map`
+ | --------- ^^^ expected `&Foo`, found `Foo`
+ | |
+ | arguments to this function are incorrect
|
note: function defined here
--> $DIR/as-ref.rs:3:4
|
LL | fn takes_ref(_: &Foo) {}
| ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+ |
+LL | opt.as_ref().map(|arg| takes_ref(arg));
+ | +++++++++
error[E0308]: mismatched types
--> $DIR/as-ref.rs:11:37
|
LL | opt.and_then(|arg| Ok(takes_ref(arg)));
- | -------- --------- ^^^ expected `&Foo`, found `Foo`
- | | |
- | | arguments to this function are incorrect
- | help: consider using `as_ref` instead: `as_ref().and_then`
+ | --------- ^^^ expected `&Foo`, found `Foo`
+ | |
+ | arguments to this function are incorrect
|
note: function defined here
--> $DIR/as-ref.rs:3:4
|
LL | fn takes_ref(_: &Foo) {}
| ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+ |
+LL | opt.as_ref().and_then(|arg| Ok(takes_ref(arg)));
+ | +++++++++
error[E0308]: mismatched types
--> $DIR/as-ref.rs:13:29
@@ -101,61 +113,73 @@ error[E0308]: mismatched types
--> $DIR/as-ref.rs:22:42
|
LL | multiple_ref_opt.map(|arg| takes_ref(arg));
- | --- --------- ^^^ expected `&Foo`, found `Foo`
- | | |
- | | arguments to this function are incorrect
- | help: consider using `as_ref` instead: `as_ref().map`
+ | --------- ^^^ expected `&Foo`, found `Foo`
+ | |
+ | arguments to this function are incorrect
|
note: function defined here
--> $DIR/as-ref.rs:3:4
|
LL | fn takes_ref(_: &Foo) {}
| ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+ |
+LL | multiple_ref_opt.as_ref().map(|arg| takes_ref(arg));
+ | +++++++++
error[E0308]: mismatched types
--> $DIR/as-ref.rs:23:52
|
LL | multiple_ref_opt.and_then(|arg| Some(takes_ref(arg)));
- | -------- --------- ^^^ expected `&Foo`, found `Foo`
- | | |
- | | arguments to this function are incorrect
- | help: consider using `as_ref` instead: `as_ref().and_then`
+ | --------- ^^^ expected `&Foo`, found `Foo`
+ | |
+ | arguments to this function are incorrect
|
note: function defined here
--> $DIR/as-ref.rs:3:4
|
LL | fn takes_ref(_: &Foo) {}
| ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+ |
+LL | multiple_ref_opt.as_ref().and_then(|arg| Some(takes_ref(arg)));
+ | +++++++++
error[E0308]: mismatched types
--> $DIR/as-ref.rs:25:45
|
LL | multiple_ref_result.map(|arg| takes_ref(arg));
- | --- --------- ^^^ expected `&Foo`, found `Foo`
- | | |
- | | arguments to this function are incorrect
- | help: consider using `as_ref` instead: `as_ref().map`
+ | --------- ^^^ expected `&Foo`, found `Foo`
+ | |
+ | arguments to this function are incorrect
|
note: function defined here
--> $DIR/as-ref.rs:3:4
|
LL | fn takes_ref(_: &Foo) {}
| ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+ |
+LL | multiple_ref_result.as_ref().map(|arg| takes_ref(arg));
+ | +++++++++
error[E0308]: mismatched types
--> $DIR/as-ref.rs:26:53
|
LL | multiple_ref_result.and_then(|arg| Ok(takes_ref(arg)));
- | -------- --------- ^^^ expected `&Foo`, found `Foo`
- | | |
- | | arguments to this function are incorrect
- | help: consider using `as_ref` instead: `as_ref().and_then`
+ | --------- ^^^ expected `&Foo`, found `Foo`
+ | |
+ | arguments to this function are incorrect
|
note: function defined here
--> $DIR/as-ref.rs:3:4
|
LL | fn takes_ref(_: &Foo) {}
| ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+ |
+LL | multiple_ref_result.as_ref().and_then(|arg| Ok(takes_ref(arg)));
+ | +++++++++
error: aborting due to 11 previous errors
diff --git a/tests/ui/suggestions/derive-macro-missing-bounds.stderr b/tests/ui/suggestions/derive-macro-missing-bounds.stderr
index c3f305c1770..bffcb1af487 100644
--- a/tests/ui/suggestions/derive-macro-missing-bounds.stderr
+++ b/tests/ui/suggestions/derive-macro-missing-bounds.stderr
@@ -36,7 +36,7 @@ LL | impl<T: Debug + Trait> Debug for Inner<T> {
| unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= 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: required for the cast from `&&c::Inner<T>` to `&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`
|
@@ -58,7 +58,7 @@ LL | impl<T> Debug for Inner<T> where T: Debug, T: Trait {
| ^^^^^ ^^^^^^^^ ----- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= 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: required for the cast from `&&d::Inner<T>` to `&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`
|
@@ -80,7 +80,7 @@ LL | impl<T> Debug for Inner<T> where T: Debug + Trait {
| ^^^^^ ^^^^^^^^ ----- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= 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: required for the cast from `&&e::Inner<T>` to `&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`
|
@@ -102,7 +102,7 @@ LL | impl<T: Debug> Debug for Inner<T> where T: Trait {
| ^^^^^ ^^^^^^^^ ----- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= 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: required for the cast from `&&f::Inner<T>` to `&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/tests/ui/suggestions/issue-68049-2.stderr b/tests/ui/suggestions/issue-68049-2.stderr
index de35aa5b186..6f3c78443f8 100644
--- a/tests/ui/suggestions/issue-68049-2.stderr
+++ b/tests/ui/suggestions/issue-68049-2.stderr
@@ -4,10 +4,10 @@ error[E0594]: cannot assign to `*input`, which is behind a `&` reference
LL | *input = self.0;
| ^^^^^^^^^^^^^^^ `input` is a `&` reference, so the data it refers to cannot be written
|
-help: consider changing that to be a mutable reference
+help: consider changing this to be a mutable reference
|
-LL | fn example(&self, input: &mut i32); // should suggest here
- | ~~~~~~~~
+LL | fn example(&self, input: &mut i32) { // should not suggest here
+ | +++
error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
--> $DIR/issue-68049-2.rs:17:5
@@ -15,7 +15,7 @@ error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
LL | self.0 += *input;
| ^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
|
-help: consider changing that to be a mutable reference
+help: consider changing this to be a mutable reference
|
LL | fn example(&mut self, input: &i32); // should suggest here
| ~~~~~~~~~
diff --git a/tests/ui/suggestions/issue-99597.rs b/tests/ui/suggestions/issue-99597.rs
new file mode 100644
index 00000000000..8ba9e1fdd62
--- /dev/null
+++ b/tests/ui/suggestions/issue-99597.rs
@@ -0,0 +1,15 @@
+#![allow(dead_code)]
+
+trait T1 { }
+
+trait T2 {
+ fn test(&self) { }
+}
+
+fn go(s: &impl T1) {
+ //~^ SUGGESTION (
+ s.test();
+ //~^ ERROR no method named `test`
+}
+
+fn main() { }
diff --git a/tests/ui/suggestions/issue-99597.stderr b/tests/ui/suggestions/issue-99597.stderr
new file mode 100644
index 00000000000..bdf2a07c143
--- /dev/null
+++ b/tests/ui/suggestions/issue-99597.stderr
@@ -0,0 +1,15 @@
+error[E0599]: no method named `test` found for reference `&impl T1` in the current scope
+ --> $DIR/issue-99597.rs:11:7
+ |
+LL | s.test();
+ | ^^^^ method not found in `&impl T1`
+ |
+ = help: items from traits can only be used if the type parameter is bounded by the trait
+help: the following trait defines an item `test`, perhaps you need to restrict type parameter `impl T1` with it:
+ |
+LL | fn go(s: &(impl T1 + T2)) {
+ | + +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/suggestions/suggest-borrow-to-dyn-object.rs b/tests/ui/suggestions/suggest-borrow-to-dyn-object.rs
deleted file mode 100644
index 120fc538307..00000000000
--- a/tests/ui/suggestions/suggest-borrow-to-dyn-object.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-use std::ffi::{OsStr, OsString};
-use std::path::Path;
-
-fn check(p: &dyn AsRef<Path>) {
- let m = std::fs::metadata(&p);
- println!("{:?}", &m);
-}
-
-fn main() {
- let s: OsString = ".".into();
- let s: &OsStr = &s;
- check(s);
- //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
- //~| HELP within `OsStr`, the trait `Sized` is not implemented for `[u8]`
- //~| HELP consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>`
-}
diff --git a/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr b/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr
deleted file mode 100644
index 365c1016eb3..00000000000
--- a/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
- --> $DIR/suggest-borrow-to-dyn-object.rs:12:11
- |
-LL | check(s);
- | ^ 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`
- --> $SRC_DIR/std/src/ffi/os_str.rs:LL:COL
- = note: required for the cast from `OsStr` to the object type `dyn AsRef<Path>`
-help: consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>`
- |
-LL | check(&s);
- | +
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/suggestions/suggest-ref-macro.rs b/tests/ui/suggestions/suggest-ref-macro.rs
index 6f780f32a14..730f5fa1b5e 100644
--- a/tests/ui/suggestions/suggest-ref-macro.rs
+++ b/tests/ui/suggestions/suggest-ref-macro.rs
@@ -14,7 +14,7 @@ macro_rules! bla {
() => {
x(123);
//~^ ERROR mismatched types
- //~| SUGGESTION &mut 123
+ //~| SUGGESTION &mut
};
($v:expr) => {
x($v)
@@ -25,5 +25,5 @@ fn main() {
bla!();
bla!(456);
//~^ ERROR mismatched types
- //~| SUGGESTION &mut 456
+ //~| SUGGESTION &mut
}
diff --git a/tests/ui/suggestions/suggest-ref-macro.stderr b/tests/ui/suggestions/suggest-ref-macro.stderr
index 17de49fbd84..08bc9e86a50 100644
--- a/tests/ui/suggestions/suggest-ref-macro.stderr
+++ b/tests/ui/suggestions/suggest-ref-macro.stderr
@@ -18,10 +18,8 @@ error[E0308]: mismatched types
--> $DIR/suggest-ref-macro.rs:15:11
|
LL | x(123);
- | - ^^^
- | | |
- | | expected `&mut i32`, found integer
- | | help: consider mutably borrowing here: `&mut 123`
+ | - ^^^ expected `&mut i32`, found integer
+ | |
| arguments to this function are incorrect
...
LL | bla!();
@@ -33,6 +31,10 @@ note: function defined here
LL | fn x(_: &mut i32) {}
| ^ -----------
= note: this error originates in the macro `bla` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider mutably borrowing here
+ |
+LL | x(&mut 123);
+ | ++++
error[E0308]: mismatched types
--> $DIR/suggest-ref-macro.rs:26:10
@@ -41,16 +43,17 @@ LL | x($v)
| - arguments to this function are incorrect
...
LL | bla!(456);
- | ^^^
- | |
- | expected `&mut i32`, found integer
- | help: consider mutably borrowing here: `&mut 456`
+ | ^^^ expected `&mut i32`, found integer
|
note: function defined here
--> $DIR/suggest-ref-macro.rs:11:4
|
LL | fn x(_: &mut i32) {}
| ^ -----------
+help: consider mutably borrowing here
+ |
+LL | bla!(&mut 456);
+ | ++++
error: aborting due to 3 previous errors
diff --git a/tests/ui/suggestions/suggest-ref-mut.rs b/tests/ui/suggestions/suggest-ref-mut.rs
index d04113ffccc..b40439b8e37 100644
--- a/tests/ui/suggestions/suggest-ref-mut.rs
+++ b/tests/ui/suggestions/suggest-ref-mut.rs
@@ -12,12 +12,10 @@ impl X {
fn main() {
let ref foo = 16;
//~^ HELP
- //~| SUGGESTION ref mut foo
*foo = 32;
//~^ ERROR
if let Some(ref bar) = Some(16) {
//~^ HELP
- //~| SUGGESTION ref mut bar
*bar = 32;
//~^ ERROR
}
@@ -25,6 +23,5 @@ fn main() {
ref quo => { *quo = 32; },
//~^ ERROR
//~| HELP
- //~| SUGGESTION ref mut quo
}
}
diff --git a/tests/ui/suggestions/suggest-ref-mut.stderr b/tests/ui/suggestions/suggest-ref-mut.stderr
index 7973759bf5e..cc00022ab8e 100644
--- a/tests/ui/suggestions/suggest-ref-mut.stderr
+++ b/tests/ui/suggestions/suggest-ref-mut.stderr
@@ -10,7 +10,7 @@ LL | fn zap(&mut self) {
| ~~~~~~~~~
error[E0594]: cannot assign to `*foo`, which is behind a `&` reference
- --> $DIR/suggest-ref-mut.rs:16:5
+ --> $DIR/suggest-ref-mut.rs:15:5
|
LL | *foo = 32;
| ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
@@ -18,10 +18,10 @@ LL | *foo = 32;
help: consider changing this to be a mutable reference
|
LL | let ref mut foo = 16;
- | ~~~~~~~~~~~
+ | +++
error[E0594]: cannot assign to `*bar`, which is behind a `&` reference
- --> $DIR/suggest-ref-mut.rs:21:9
+ --> $DIR/suggest-ref-mut.rs:19:9
|
LL | *bar = 32;
| ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written
@@ -29,10 +29,10 @@ LL | *bar = 32;
help: consider changing this to be a mutable reference
|
LL | if let Some(ref mut bar) = Some(16) {
- | ~~~~~~~~~~~
+ | +++
error[E0594]: cannot assign to `*quo`, which is behind a `&` reference
- --> $DIR/suggest-ref-mut.rs:25:22
+ --> $DIR/suggest-ref-mut.rs:23:22
|
LL | ref quo => { *quo = 32; },
| ^^^^^^^^^ `quo` is a `&` reference, so the data it refers to cannot be written
@@ -40,7 +40,7 @@ LL | ref quo => { *quo = 32; },
help: consider changing this to be a mutable reference
|
LL | ref mut quo => { *quo = 32; },
- | ~~~~~~~~~~~
+ | +++
error: aborting due to 4 previous errors
diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.fixed b/tests/ui/suggestions/type-ascription-instead-of-let.fixed
new file mode 100644
index 00000000000..e3d03b6f22a
--- /dev/null
+++ b/tests/ui/suggestions/type-ascription-instead-of-let.fixed
@@ -0,0 +1,11 @@
+// run-rustfix
+
+fn fun(x: i32) -> i32 { x }
+
+fn main() {
+ let _closure_annotated = |value: i32| -> i32 {
+ let temp: i32 = fun(5i32);
+ //~^ ERROR expected identifier, found `:`
+ temp + value + 1
+ };
+}
diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.rs b/tests/ui/suggestions/type-ascription-instead-of-let.rs
index 5ad60243298..6e1c86f9671 100644
--- a/tests/ui/suggestions/type-ascription-instead-of-let.rs
+++ b/tests/ui/suggestions/type-ascription-instead-of-let.rs
@@ -1,7 +1,9 @@
+// run-rustfix
+
fn fun(x: i32) -> i32 { x }
fn main() {
- let closure_annotated = |value: i32| -> i32 {
+ let _closure_annotated = |value: i32| -> i32 {
temp: i32 = fun(5i32);
//~^ ERROR expected identifier, found `:`
temp + value + 1
diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.stderr b/tests/ui/suggestions/type-ascription-instead-of-let.stderr
index fb697b0ccfd..065b1f4d353 100644
--- a/tests/ui/suggestions/type-ascription-instead-of-let.stderr
+++ b/tests/ui/suggestions/type-ascription-instead-of-let.stderr
@@ -1,8 +1,13 @@
error: expected identifier, found `:`
- --> $DIR/type-ascription-instead-of-let.rs:5:13
+ --> $DIR/type-ascription-instead-of-let.rs:7:13
|
LL | temp: i32 = fun(5i32);
| ^ expected identifier
+ |
+help: you might have meant to introduce a new binding
+ |
+LL | let temp: i32 = fun(5i32);
+ | +++
error: aborting due to previous error
diff --git a/tests/ui/issues/issue-12997-1.rs b/tests/ui/test-attrs/issue-12997-1.rs
index 9f808dac362..9f808dac362 100644
--- a/tests/ui/issues/issue-12997-1.rs
+++ b/tests/ui/test-attrs/issue-12997-1.rs
diff --git a/tests/ui/issues/issue-12997-1.stderr b/tests/ui/test-attrs/issue-12997-1.stderr
index 00c605174fb..00c605174fb 100644
--- a/tests/ui/issues/issue-12997-1.stderr
+++ b/tests/ui/test-attrs/issue-12997-1.stderr
diff --git a/tests/ui/issues/issue-12997-2.rs b/tests/ui/test-attrs/issue-12997-2.rs
index 9df965315ab..9df965315ab 100644
--- a/tests/ui/issues/issue-12997-2.rs
+++ b/tests/ui/test-attrs/issue-12997-2.rs
diff --git a/tests/ui/issues/issue-12997-2.stderr b/tests/ui/test-attrs/issue-12997-2.stderr
index 2a3d0e3457b..2a3d0e3457b 100644
--- a/tests/ui/issues/issue-12997-2.stderr
+++ b/tests/ui/test-attrs/issue-12997-2.stderr
diff --git a/tests/ui/issues/issue-34932.rs b/tests/ui/test-attrs/issue-34932.rs
index ab568fd01ef..ab568fd01ef 100644
--- a/tests/ui/issues/issue-34932.rs
+++ b/tests/ui/test-attrs/issue-34932.rs
diff --git a/tests/ui/track-diagnostics/track6.rs b/tests/ui/track-diagnostics/track6.rs
index 307e3101849..fc6f5f23d92 100644
--- a/tests/ui/track-diagnostics/track6.rs
+++ b/tests/ui/track-diagnostics/track6.rs
@@ -1,6 +1,9 @@
// compile-flags: -Z track-diagnostics
// error-pattern: created at
+// Normalize the emitted location so this doesn't need
+// updating everytime someone adds or removes a line.
+// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC"
pub trait Foo {
diff --git a/tests/ui/track-diagnostics/track6.stderr b/tests/ui/track-diagnostics/track6.stderr
index 1c7537633ff..89438aea9ad 100644
--- a/tests/ui/track-diagnostics/track6.stderr
+++ b/tests/ui/track-diagnostics/track6.stderr
@@ -1,9 +1,9 @@
error[E0658]: specialization is unstable
- --> $DIR/track6.rs:11:5
+ --> $DIR/track6.rs:LL:CC
|
LL | default fn bar() {}
| ^^^^^^^^^^^^^^^^^^^
--Ztrack-diagnostics: created at $COMPILER_DIR/rustc_session/src/parse.rs:93:5
+-Ztrack-diagnostics: created at $COMPILER_DIR/rustc_session/src/parse.rs:LL:CC
|
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
= help: add `#![feature(specialization)]` to the crate attributes to enable
diff --git a/tests/ui/traits/coercion-generic-bad.stderr b/tests/ui/traits/coercion-generic-bad.stderr
index 93d6770eb47..e7e8a796796 100644
--- a/tests/ui/traits/coercion-generic-bad.stderr
+++ b/tests/ui/traits/coercion-generic-bad.stderr
@@ -5,7 +5,7 @@ LL | let s: Box<dyn Trait<isize>> = Box::new(Struct { person: "Fred" });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<isize>` is not implemented for `Struct`
|
= help: the trait `Trait<&'static str>` is implemented for `Struct`
- = note: required for the cast from `Struct` to the object type `dyn Trait<isize>`
+ = note: required for the cast from `Box<Struct>` to `Box<dyn Trait<isize>>`
error: aborting due to previous error
diff --git a/tests/ui/traits/copy-guessing.rs b/tests/ui/traits/copy-guessing.rs
index f031dd9ca48..558303c2e40 100644
--- a/tests/ui/traits/copy-guessing.rs
+++ b/tests/ui/traits/copy-guessing.rs
@@ -1,5 +1,8 @@
// run-pass
+
#![allow(dead_code)]
+#![allow(drop_copy)]
+
// "guessing" in trait selection can affect `copy_or_move`. Check that this
// is correctly handled. I am not sure what is the "correct" behaviour,
// but we should at least not ICE.
diff --git a/tests/ui/traits/impl-evaluation-order.rs b/tests/ui/traits/impl-evaluation-order.rs
index 57809d89aa6..256ce992eef 100644
--- a/tests/ui/traits/impl-evaluation-order.rs
+++ b/tests/ui/traits/impl-evaluation-order.rs
@@ -6,6 +6,8 @@
// check-pass
+#![allow(drop_copy)]
+
trait A {
type B;
}
diff --git a/tests/ui/traits/issue-106072.rs b/tests/ui/traits/issue-106072.rs
index 7064a39d21e..b174669545a 100644
--- a/tests/ui/traits/issue-106072.rs
+++ b/tests/ui/traits/issue-106072.rs
@@ -1,5 +1,4 @@
#[derive(Clone)] //~ trait objects must include the `dyn` keyword
- //~| trait objects must include the `dyn` keyword
struct Foo;
trait Foo {} //~ the name `Foo` is defined multiple times
fn main() {}
diff --git a/tests/ui/traits/issue-106072.stderr b/tests/ui/traits/issue-106072.stderr
index f9b7b814663..1037603ceb7 100644
--- a/tests/ui/traits/issue-106072.stderr
+++ b/tests/ui/traits/issue-106072.stderr
@@ -1,5 +1,5 @@
error[E0428]: the name `Foo` is defined multiple times
- --> $DIR/issue-106072.rs:4:1
+ --> $DIR/issue-106072.rs:3:1
|
LL | struct Foo;
| ----------- previous definition of the type `Foo` here
@@ -16,15 +16,7 @@ LL | #[derive(Clone)]
|
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
-error[E0782]: trait objects must include the `dyn` keyword
- --> $DIR/issue-106072.rs:1:10
- |
-LL | #[derive(Clone)]
- | ^^^^^
- |
- = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
Some errors have detailed explanations: E0428, E0782.
For more information about an error, try `rustc --explain E0428`.
diff --git a/tests/ui/traits/issue-20692.stderr b/tests/ui/traits/issue-20692.stderr
index 2028994cdaa..30e3c9da1a0 100644
--- a/tests/ui/traits/issue-20692.stderr
+++ b/tests/ui/traits/issue-20692.stderr
@@ -27,8 +27,7 @@ LL | trait Array: Sized + Copy {}
| | |
| | ...because it requires `Self: Sized`
| this trait cannot be made into an object...
- = note: required for `&T` to implement `CoerceUnsized<&dyn Array>`
- = note: required by cast to type `&dyn Array`
+ = note: required for the cast from `&T` to `&dyn Array`
error: aborting due to 2 previous errors
diff --git a/tests/ui/traits/issue-38604.stderr b/tests/ui/traits/issue-38604.stderr
index 50d6fb05465..d5327602430 100644
--- a/tests/ui/traits/issue-38604.stderr
+++ b/tests/ui/traits/issue-38604.stderr
@@ -25,8 +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 for `Box<()>` to implement `CoerceUnsized<Box<dyn Foo>>`
- = note: required by cast to type `Box<dyn Foo>`
+ = note: required for the cast from `Box<()>` to `Box<dyn Foo>`
error: aborting due to 2 previous errors
diff --git a/tests/ui/traits/issue-7013.stderr b/tests/ui/traits/issue-7013.stderr
index 9ac5c4725ab..1c0e8bcf185 100644
--- a/tests/ui/traits/issue-7013.stderr
+++ b/tests/ui/traits/issue-7013.stderr
@@ -12,7 +12,7 @@ note: required because it appears within the type `B`
|
LL | struct B {
| ^
- = note: required for the cast from `B` to the object type `dyn Foo + Send`
+ = note: required for the cast from `Box<B>` to `Box<dyn Foo + Send>`
error: aborting due to previous error
diff --git a/tests/ui/traits/map-types.stderr b/tests/ui/traits/map-types.stderr
index f685c50b07d..4315056f206 100644
--- a/tests/ui/traits/map-types.stderr
+++ b/tests/ui/traits/map-types.stderr
@@ -5,7 +5,7 @@ LL | let y: Box<dyn Map<usize, isize>> = Box::new(x);
| ^^^^^^^^^^^ the trait `Map<usize, isize>` is not implemented for `Box<dyn Map<isize, isize>>`
|
= help: the trait `Map<K, V>` is implemented for `HashMap<K, V>`
- = note: required for the cast from `Box<dyn Map<isize, isize>>` to the object type `dyn Map<usize, isize>`
+ = note: required for the cast from `Box<Box<dyn Map<isize, isize>>>` to `Box<dyn Map<usize, isize>>`
error: aborting due to previous error
diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.rs b/tests/ui/traits/new-solver/alias-bound-unsound.rs
new file mode 100644
index 00000000000..00294c708f1
--- /dev/null
+++ b/tests/ui/traits/new-solver/alias-bound-unsound.rs
@@ -0,0 +1,27 @@
+// compile-flags: -Ztrait-solver=next
+
+// Makes sure that alias bounds are not unsound!
+
+#![feature(trivial_bounds)]
+
+trait Foo {
+ type Item: Copy
+ where
+ <Self as Foo>::Item: Copy;
+
+ fn copy_me(x: &Self::Item) -> Self::Item {
+ *x
+ }
+}
+
+impl Foo for () {
+ type Item = String where String: Copy;
+}
+
+fn main() {
+ let x = String::from("hello, world");
+ drop(<() as Foo>::copy_me(&x));
+ //~^ ERROR `<() as Foo>::Item: Copy` is not satisfied
+ //~| ERROR `<() as Foo>::Item` is not well-formed
+ println!("{x}");
+}
diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.stderr b/tests/ui/traits/new-solver/alias-bound-unsound.stderr
new file mode 100644
index 00000000000..9a43d2a6639
--- /dev/null
+++ b/tests/ui/traits/new-solver/alias-bound-unsound.stderr
@@ -0,0 +1,24 @@
+error[E0277]: the trait bound `<() as Foo>::Item: Copy` is not satisfied
+ --> $DIR/alias-bound-unsound.rs:23:10
+ |
+LL | drop(<() as Foo>::copy_me(&x));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `<() as Foo>::Item`
+ |
+note: required by a bound in `Foo::Item`
+ --> $DIR/alias-bound-unsound.rs:10:30
+ |
+LL | type Item: Copy
+ | ---- required by a bound in this associated type
+LL | where
+LL | <Self as Foo>::Item: Copy;
+ | ^^^^ required by this bound in `Foo::Item`
+
+error: the type `<() as Foo>::Item` is not well-formed
+ --> $DIR/alias-bound-unsound.rs:23:10
+ |
+LL | drop(<() as Foo>::copy_me(&x));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
index 6a926534e07..4aefdd6bb07 100644
--- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
+++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
@@ -1,5 +1,5 @@
error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely
- --> $DIR/auto-with-drop_tracking_mir.rs:24:13
+ --> $DIR/auto-with-drop_tracking_mir.rs:25:13
|
LL | is_send(foo());
| ------- ^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely
@@ -8,7 +8,7 @@ LL | is_send(foo());
|
= help: the trait `Send` is not implemented for `impl Future<Output = ()>`
note: required by a bound in `is_send`
- --> $DIR/auto-with-drop_tracking_mir.rs:23:24
+ --> $DIR/auto-with-drop_tracking_mir.rs:24:24
|
LL | fn is_send(_: impl Send) {}
| ^^^^ required by this bound in `is_send`
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
index a5db7c4636b..f115e143318 100644
--- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
+++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
@@ -14,6 +14,7 @@ async fn foo() {
#[cfg(fail)]
let x = &NotSync;
bar().await;
+ #[allow(drop_ref)]
drop(x);
}
diff --git a/tests/ui/traits/new-solver/nested-alias-bound.rs b/tests/ui/traits/new-solver/nested-alias-bound.rs
new file mode 100644
index 00000000000..c365902dbe5
--- /dev/null
+++ b/tests/ui/traits/new-solver/nested-alias-bound.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+trait A {
+ type A: B;
+}
+
+trait B {
+ type B: C;
+}
+
+trait C {}
+
+fn needs_c<T: C>() {}
+
+fn test<T: A>() {
+ needs_c::<<T::A as B>::B>();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/temporary-ambiguity.rs b/tests/ui/traits/new-solver/temporary-ambiguity.rs
index 18ee0545700..c6c11a1a1de 100644
--- a/tests/ui/traits/new-solver/temporary-ambiguity.rs
+++ b/tests/ui/traits/new-solver/temporary-ambiguity.rs
@@ -18,5 +18,5 @@ fn main() {
let w = Wrapper(x);
needs_foo(w);
x = 1;
- drop(x);
+ let _ = x;
}
diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr b/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr
index 47fa29b6648..d56519223f4 100644
--- a/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr
+++ b/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr
@@ -20,8 +20,7 @@ LL | trait Foo: for<T> Bar<T> {}
| --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables
| |
| this trait cannot be made into an object...
- = note: required for `&()` to implement `CoerceUnsized<&dyn Foo>`
- = note: required by cast to type `&dyn Foo`
+ = note: required for the cast from `&()` to `&dyn Foo`
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/supertrait-object-safety.rs:19:12
diff --git a/tests/ui/traits/non_lifetime_binders/universe-error1.rs b/tests/ui/traits/non_lifetime_binders/universe-error1.rs
new file mode 100644
index 00000000000..eadee6b711e
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/universe-error1.rs
@@ -0,0 +1,18 @@
+#![feature(non_lifetime_binders)]
+//~^ WARN the feature `non_lifetime_binders` is incomplete
+
+trait Other<U: ?Sized> {}
+
+impl<U: ?Sized> Other<U> for U {}
+
+#[rustfmt::skip]
+fn foo<U: ?Sized>()
+where
+ for<T> T: Other<U> {}
+
+fn bar() {
+ foo::<_>();
+ //~^ ERROR the trait bound `T: Other<_>` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/traits/non_lifetime_binders/universe-error1.stderr b/tests/ui/traits/non_lifetime_binders/universe-error1.stderr
new file mode 100644
index 00000000000..bfcad72e352
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/universe-error1.stderr
@@ -0,0 +1,27 @@
+warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/universe-error1.rs:1:12
+ |
+LL | #![feature(non_lifetime_binders)]
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the trait bound `T: Other<_>` is not satisfied
+ --> $DIR/universe-error1.rs:14:11
+ |
+LL | foo::<_>();
+ | ^ the trait `Other<_>` is not implemented for `T`
+ |
+note: required by a bound in `foo`
+ --> $DIR/universe-error1.rs:11:15
+ |
+LL | fn foo<U: ?Sized>()
+ | --- required by a bound in this function
+LL | where
+LL | for<T> T: Other<U> {}
+ | ^^^^^^^^ required by this bound in `foo`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/object/safety.stderr b/tests/ui/traits/object/safety.stderr
index dc18adeafc7..a51b6975938 100644
--- a/tests/ui/traits/object/safety.stderr
+++ b/tests/ui/traits/object/safety.stderr
@@ -11,8 +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 for `&St` to implement `CoerceUnsized<&dyn Tr>`
- = note: required by cast to type `&dyn Tr`
+ = note: required for the cast from `&St` to `&dyn Tr`
help: consider turning `foo` into a method by giving it a `&self` argument
|
LL | fn foo(&self);
diff --git a/tests/ui/traits/test-2.stderr b/tests/ui/traits/test-2.stderr
index 6c0e8b8af4b..74a0fc42708 100644
--- a/tests/ui/traits/test-2.stderr
+++ b/tests/ui/traits/test-2.stderr
@@ -76,8 +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 for `Box<{integer}>` to implement `CoerceUnsized<Box<dyn bar>>`
- = note: required by cast to type `Box<dyn bar>`
+ = note: required for the cast from `Box<{integer}>` to `Box<dyn bar>`
error: aborting due to 5 previous errors
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr
index fe269d8e99b..82b4e9bd72a 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr
@@ -15,7 +15,7 @@ error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied
LL | let _ = x as &dyn Bar<_>; // Ambiguous
| ^ the trait `Bar<_>` is not implemented for `&dyn Foo`
|
- = note: required for the cast from `&dyn Foo` to the object type `dyn Bar<_>`
+ = note: required for the cast from `&&dyn Foo` to `&dyn Bar<_>`
error: aborting due to 2 previous errors
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr
index ef007d5cb90..856303ef4dd 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr
@@ -15,7 +15,7 @@ error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
LL | let _ = x as &dyn Bar<u32>; // Error
| ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>`
|
- = note: required for the cast from `&dyn Foo<i32>` to the object type `dyn Bar<u32>`
+ = note: required for the cast from `&&dyn Foo<i32>` to `&dyn Bar<u32>`
error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>`
--> $DIR/type-checking-test-2.rs:25:13
@@ -34,7 +34,7 @@ error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
LL | let a = x as &dyn Bar<_>; // Ambiguous
| ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>`
|
- = note: required for the cast from `&dyn Foo<u32>` to the object type `dyn Bar<_>`
+ = note: required for the cast from `&&dyn Foo<u32>` to `&dyn Bar<_>`
error: aborting due to 4 previous errors
diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr
index 39b60c31197..c054ddb893d 100644
--- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr
+++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr
@@ -7,7 +7,7 @@ LL | *t
help: consider changing this to be a mutable reference
|
LL | fn reborrow_mut<'a>(t: &'a mut &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
- | ~~~~~~~~~~~~~~~~~~~
+ | +++
error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference
--> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:10:6
@@ -18,7 +18,7 @@ LL | {*t}
help: consider changing this to be a mutable reference
|
LL | fn copy_reborrow_mut<'a>(t: &'a mut &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
- | ~~~~~~~~~~~~~~~~~~~
+ | +++
error: aborting due to 2 previous errors
diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
index 3416503b851..6ed7667115a 100644
--- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
+++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
@@ -1,6 +1,8 @@
// check-pass
// Check tautalogically false `Copy` bounds
+
#![feature(trivial_bounds)]
+#![allow(drop_ref, drop_copy)]
fn copy_string(t: String) -> String where String: Copy { //~ WARNING trivial_bounds
is_copy(&t);
diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr
index 1e26623899b..deeb352a2a8 100644
--- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr
+++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr
@@ -1,5 +1,5 @@
warning: trait bound String: Copy does not depend on any type or lifetime parameters
- --> $DIR/trivial-bounds-inconsistent-copy.rs:5:51
+ --> $DIR/trivial-bounds-inconsistent-copy.rs:7:51
|
LL | fn copy_string(t: String) -> String where String: Copy {
| ^^^^
@@ -7,19 +7,19 @@ LL | fn copy_string(t: String) -> String where String: Copy {
= note: `#[warn(trivial_bounds)]` on by default
warning: trait bound String: Copy does not depend on any type or lifetime parameters
- --> $DIR/trivial-bounds-inconsistent-copy.rs:12:56
+ --> $DIR/trivial-bounds-inconsistent-copy.rs:14:56
|
LL | fn copy_out_string(t: &String) -> String where String: Copy {
| ^^^^
warning: trait bound String: Copy does not depend on any type or lifetime parameters
- --> $DIR/trivial-bounds-inconsistent-copy.rs:16:55
+ --> $DIR/trivial-bounds-inconsistent-copy.rs:18:55
|
LL | fn copy_string_with_param<T>(x: String) where String: Copy {
| ^^^^
warning: trait bound for<'b> &'b mut i32: Copy does not depend on any type or lifetime parameters
- --> $DIR/trivial-bounds-inconsistent-copy.rs:22:76
+ --> $DIR/trivial-bounds-inconsistent-copy.rs:24:76
|
LL | fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy {
| ^^^^
diff --git a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs
index 551815d021a..58eaa9c2c42 100644
--- a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs
+++ b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs
@@ -5,15 +5,16 @@
trait Trait {
type Opaque1;
type Opaque2;
- fn constrain(self);
+ fn constrain(self) -> (Self::Opaque1, Self::Opaque2);
}
impl<'a> Trait for &'a () {
type Opaque1 = impl Sized;
type Opaque2 = impl Sized + 'a;
- fn constrain(self) {
- let _: Self::Opaque1 = ();
- let _: Self::Opaque2 = self;
+ fn constrain(self) -> (Self::Opaque1, Self::Opaque2) {
+ let a: Self::Opaque1 = ();
+ let b: Self::Opaque2 = self;
+ (a, b)
}
}
diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs
new file mode 100644
index 00000000000..93c52126d69
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs
@@ -0,0 +1,16 @@
+#![feature(impl_trait_in_assoc_type)]
+
+trait Foo {
+ type Foo;
+ fn bar();
+}
+
+impl Foo for () {
+ type Foo = impl std::fmt::Debug;
+ fn bar() {
+ let x: Self::Foo = ();
+ //~^ ERROR: mismatched types
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr
new file mode 100644
index 00000000000..2beed73cb85
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr
@@ -0,0 +1,22 @@
+error[E0308]: mismatched types
+ --> $DIR/invalid_impl_trait_in_assoc_ty.rs:11:28
+ |
+LL | type Foo = impl std::fmt::Debug;
+ | -------------------- the expected opaque type
+LL | fn bar() {
+LL | let x: Self::Foo = ();
+ | --------- ^^ expected opaque type, found `()`
+ | |
+ | expected due to this
+ |
+ = note: expected opaque type `<() as Foo>::Foo`
+ found unit type `()`
+note: this item must have the opaque type in its signature in order to be able to register hidden types
+ --> $DIR/invalid_impl_trait_in_assoc_ty.rs:10:5
+ |
+LL | fn bar() {
+ | ^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type-alias-impl-trait/issue-98604.stderr b/tests/ui/type-alias-impl-trait/issue-98604.stderr
index fa16d321890..af758d8099f 100644
--- a/tests/ui/type-alias-impl-trait/issue-98604.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-98604.stderr
@@ -4,7 +4,7 @@ error[E0271]: expected `test` to be a fn item that returns `Pin<Box<dyn Future<O
LL | Box::new(test) as AsyncFnPtr;
| ^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found future
|
- = note: required for the cast from `fn() -> impl Future<Output = ()> {test}` to the object type `dyn Fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>>`
+ = note: required for the cast from `Box<fn() -> impl Future<Output = ()> {test}>` to `Box<(dyn Fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> + 'static)>`
error: aborting due to previous error
diff --git a/tests/ui/type-alias-impl-trait/issue-98608.stderr b/tests/ui/type-alias-impl-trait/issue-98608.stderr
index 506d40cb776..9b651008371 100644
--- a/tests/ui/type-alias-impl-trait/issue-98608.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-98608.stderr
@@ -9,7 +9,7 @@ LL | let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi);
|
= note: expected struct `Box<u8>`
found opaque type `impl Sized`
- = note: required for the cast from `fn() -> impl Sized {hi}` to the object type `dyn Fn() -> Box<u8>`
+ = note: required for the cast from `Box<fn() -> impl Sized {hi}>` to `Box<dyn Fn() -> Box<u8>>`
error: aborting due to previous error
diff --git a/tests/ui/type-alias-impl-trait/wf-in-associated-type.fail.stderr b/tests/ui/type-alias-impl-trait/wf-in-associated-type.fail.stderr
new file mode 100644
index 00000000000..9e96323ab54
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/wf-in-associated-type.fail.stderr
@@ -0,0 +1,25 @@
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/wf-in-associated-type.rs:36:23
+ |
+LL | type Opaque = impl Sized + 'a;
+ | ^^^^^^^^^^^^^^^ ...so that the type `&'a T` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | impl<'a, T: 'a> Trait<'a, T> for () {
+ | ++++
+
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/wf-in-associated-type.rs:36:23
+ |
+LL | type Opaque = impl Sized + 'a;
+ | ^^^^^^^^^^^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | impl<'a, T: 'a> Trait<'a, T> for () {
+ | ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0309`.
diff --git a/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs b/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs
new file mode 100644
index 00000000000..31fbef9f78f
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs
@@ -0,0 +1,45 @@
+// WF check for impl Trait in associated type position.
+//
+// revisions: pass fail
+// [pass] check-pass
+// [fail] check-fail
+
+#![feature(impl_trait_in_assoc_type)]
+
+// The hidden type here (`&'a T`) requires proving `T: 'a`.
+// We know it holds because of implied bounds from the impl header.
+#[cfg(pass)]
+mod pass {
+ trait Trait<Req> {
+ type Opaque1;
+ fn constrain_opaque1(req: Req) -> Self::Opaque1;
+ }
+
+ impl<'a, T> Trait<&'a T> for () {
+ type Opaque1 = impl IntoIterator<Item = impl Sized + 'a>;
+ fn constrain_opaque1(req: &'a T) -> Self::Opaque1 {
+ [req]
+ }
+ }
+}
+
+// The hidden type here (`&'a T`) requires proving `T: 'a`,
+// but that is not known to hold in the impl.
+#[cfg(fail)]
+mod fail {
+ trait Trait<'a, T> {
+ type Opaque;
+ fn constrain_opaque(req: &'a T) -> Self::Opaque;
+ }
+
+ impl<'a, T> Trait<'a, T> for () {
+ type Opaque = impl Sized + 'a;
+ //[fail]~^ ERROR the parameter type `T` may not live long enough
+ //[fail]~| ERROR the parameter type `T` may not live long enough
+ fn constrain_opaque(req: &'a T) -> Self::Opaque {
+ req
+ }
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr b/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr
new file mode 100644
index 00000000000..753a46e882e
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr
@@ -0,0 +1,19 @@
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/wf-nested.rs:55:27
+ |
+LL | type InnerOpaque<T> = impl Sized;
+ | ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+ |
+note: ...that is required by this bound
+ --> $DIR/wf-nested.rs:12:20
+ |
+LL | struct IsStatic<T: 'static>(T);
+ | ^^^^^^^
+help: consider adding an explicit lifetime bound...
+ |
+LL | type InnerOpaque<T: 'static> = impl Sized;
+ | +++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr b/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr
new file mode 100644
index 00000000000..9ab6685a7f7
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr
@@ -0,0 +1,14 @@
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/wf-nested.rs:46:17
+ |
+LL | let _ = outer.get();
+ | ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn test<T: 'static>() {
+ | +++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/tests/ui/type-alias-impl-trait/wf-nested.rs b/tests/ui/type-alias-impl-trait/wf-nested.rs
new file mode 100644
index 00000000000..de388329489
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/wf-nested.rs
@@ -0,0 +1,60 @@
+// Well-formedness of nested opaque types, i.e. `impl Sized` in
+// `type Outer = impl Trait<Assoc = impl Sized>`.
+// See the comments below.
+//
+// revisions: pass pass_sound fail
+// [pass] check-pass
+// [pass_sound] check-fail
+// [fail] check-fail
+
+#![feature(type_alias_impl_trait)]
+
+struct IsStatic<T: 'static>(T);
+
+trait Trait<In> {
+ type Out;
+
+ fn get(&self) -> Result<Self::Out, ()> {
+ Err(())
+ }
+}
+
+impl<T> Trait<&'static T> for () {
+ type Out = IsStatic<T>;
+}
+
+// The hidden type for `impl Sized` is `IsStatic<T>`, which requires `T: 'static`.
+// We know it is well-formed because it can *only* be referenced as a projection:
+// <OuterOpaque<T> as Trait<&'static T>>::Out`.
+// So any instantiation of the type already requires proving `T: 'static`.
+#[cfg(pass)]
+mod pass {
+ use super::*;
+ type OuterOpaque<T> = impl Trait<&'static T, Out = impl Sized>;
+ fn define<T>() -> OuterOpaque<T> {}
+}
+
+// Test the soundness of `pass` - We should require `T: 'static` at the use site.
+#[cfg(pass_sound)]
+mod pass_sound {
+ use super::*;
+ type OuterOpaque<T> = impl Trait<&'static T, Out = impl Sized>;
+ fn define<T>() -> OuterOpaque<T> {}
+
+ fn test<T>() {
+ let outer = define::<T>();
+ let _ = outer.get(); //[pass_sound]~ ERROR `T` may not live long enough
+ }
+}
+
+// Similar to `pass` but here `impl Sized` can be referenced directly as
+// InnerOpaque<T>, so we require an explicit bound `T: 'static`.
+#[cfg(fail)]
+mod fail {
+ use super::*;
+ type InnerOpaque<T> = impl Sized; //[fail]~ ERROR `T` may not live long enough
+ type OuterOpaque<T> = impl Trait<&'static T, Out = InnerOpaque<T>>;
+ fn define<T>() -> OuterOpaque<T> {}
+}
+
+fn main() {}
diff --git a/tests/ui/type/issue-58355.stderr b/tests/ui/type/issue-58355.stderr
index 6f89a7b0049..67078bcfe89 100644
--- a/tests/ui/type/issue-58355.stderr
+++ b/tests/ui/type/issue-58355.stderr
@@ -6,7 +6,7 @@ LL | x = Some(Box::new(callback));
|
= help: within `fn() -> dyn ToString`, the trait `Sized` is not implemented for `dyn ToString`
= note: required because it appears within the type `fn() -> dyn ToString`
- = note: required for the cast from `fn() -> dyn ToString` to the object type `dyn Fn() -> (dyn ToString + 'static)`
+ = note: required for the cast from `Box<fn() -> dyn ToString>` to `Box<dyn Fn() -> (dyn ToString + 'static)>`
error: aborting due to previous error
diff --git a/tests/ui/type/missing-let-in-binding-2.fixed b/tests/ui/type/missing-let-in-binding-2.fixed
new file mode 100644
index 00000000000..d64013c8c83
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-2.fixed
@@ -0,0 +1,5 @@
+// run-rustfix
+
+fn main() {
+ let _v: Vec<i32> = vec![1, 2, 3]; //~ ERROR expected identifier, found `:`
+}
diff --git a/tests/ui/type/missing-let-in-binding-2.rs b/tests/ui/type/missing-let-in-binding-2.rs
new file mode 100644
index 00000000000..f95f7bef215
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-2.rs
@@ -0,0 +1,5 @@
+// run-rustfix
+
+fn main() {
+ _v: Vec<i32> = vec![1, 2, 3]; //~ ERROR expected identifier, found `:`
+}
diff --git a/tests/ui/type/missing-let-in-binding-2.stderr b/tests/ui/type/missing-let-in-binding-2.stderr
new file mode 100644
index 00000000000..2e10125943e
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-2.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found `:`
+ --> $DIR/missing-let-in-binding-2.rs:4:7
+ |
+LL | _v: Vec<i32> = vec![1, 2, 3];
+ | ^ expected identifier
+ |
+help: you might have meant to introduce a new binding
+ |
+LL | let _v: Vec<i32> = vec![1, 2, 3];
+ | +++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type/missing-let-in-binding-3.rs b/tests/ui/type/missing-let-in-binding-3.rs
new file mode 100644
index 00000000000..d56b1393336
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-3.rs
@@ -0,0 +1,5 @@
+struct A {
+ : :u8, //~ ERROR expected identifier, found `:`
+}
+
+fn main() {}
diff --git a/tests/ui/type/missing-let-in-binding-3.stderr b/tests/ui/type/missing-let-in-binding-3.stderr
new file mode 100644
index 00000000000..ca828ce37eb
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-3.stderr
@@ -0,0 +1,10 @@
+error: expected identifier, found `:`
+ --> $DIR/missing-let-in-binding-3.rs:2:5
+ |
+LL | struct A {
+ | - while parsing this struct
+LL | : :u8,
+ | ^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type/missing-let-in-binding-4.rs b/tests/ui/type/missing-let-in-binding-4.rs
new file mode 100644
index 00000000000..879a6fedcd6
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-4.rs
@@ -0,0 +1,5 @@
+struct A {
+ : u8 =, //~ ERROR expected identifier, found `:`
+}
+
+fn main() {}
diff --git a/tests/ui/type/missing-let-in-binding-4.stderr b/tests/ui/type/missing-let-in-binding-4.stderr
new file mode 100644
index 00000000000..e6f173a6658
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-4.stderr
@@ -0,0 +1,10 @@
+error: expected identifier, found `:`
+ --> $DIR/missing-let-in-binding-4.rs:2:5
+ |
+LL | struct A {
+ | - while parsing this struct
+LL | : u8 =,
+ | ^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type/type-dependent-def-issue-49241.rs b/tests/ui/type/type-dependent-def-issue-49241.rs
index caf5bade5c7..4b6bc6124db 100644
--- a/tests/ui/type/type-dependent-def-issue-49241.rs
+++ b/tests/ui/type/type-dependent-def-issue-49241.rs
@@ -2,5 +2,4 @@ fn main() {
let v = vec![0];
const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant
let s: [u32; l] = v.into_iter().collect();
- //~^ constant
}
diff --git a/tests/ui/type/type-dependent-def-issue-49241.stderr b/tests/ui/type/type-dependent-def-issue-49241.stderr
index af16a6e8f84..64c7687f7a8 100644
--- a/tests/ui/type/type-dependent-def-issue-49241.stderr
+++ b/tests/ui/type/type-dependent-def-issue-49241.stderr
@@ -6,12 +6,6 @@ LL | const l: usize = v.count();
| |
| help: consider using `let` instead of `const`: `let l`
-note: erroneous constant used
- --> $DIR/type-dependent-def-issue-49241.rs:4:18
- |
-LL | let s: [u32; l] = v.into_iter().collect();
- | ^
-
error: aborting due to previous error
For more information about this error, try `rustc --explain E0435`.
diff --git a/tests/ui/type/type-mismatch.stderr b/tests/ui/type/type-mismatch.stderr
index 67a1f893050..ce6f29d354f 100644
--- a/tests/ui/type/type-mismatch.stderr
+++ b/tests/ui/type/type-mismatch.stderr
@@ -378,10 +378,8 @@ error[E0308]: mismatched types
--> $DIR/type-mismatch.rs:47:23
|
LL | want::<&Foo<foo>>(f);
- | ----------------- ^
- | | |
- | | expected `&Foo<foo>`, found `Foo<foo>`
- | | help: consider borrowing here: `&f`
+ | ----------------- ^ expected `&Foo<foo>`, found `Foo<foo>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&Foo<foo>`
@@ -391,6 +389,10 @@ note: function defined here
|
LL | fn want<T>(t: T) {}
| ^^^^ ----
+help: consider borrowing here
+ |
+LL | want::<&Foo<foo>>(&f);
+ | +
error[E0308]: mismatched types
--> $DIR/type-mismatch.rs:48:26
@@ -556,10 +558,8 @@ error[E0308]: mismatched types
--> $DIR/type-mismatch.rs:61:26
|
LL | want::<&Foo<foo, B>>(f);
- | -------------------- ^
- | | |
- | | expected `&Foo<foo, B>`, found `Foo<foo, B>`
- | | help: consider borrowing here: `&f`
+ | -------------------- ^ expected `&Foo<foo, B>`, found `Foo<foo, B>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&Foo<foo, B>`
@@ -569,6 +569,10 @@ note: function defined here
|
LL | fn want<T>(t: T) {}
| ^^^^ ----
+help: consider borrowing here
+ |
+LL | want::<&Foo<foo, B>>(&f);
+ | +
error[E0308]: mismatched types
--> $DIR/type-mismatch.rs:65:19
diff --git a/tests/ui/type/type-path-err-node-types.stderr b/tests/ui/type/type-path-err-node-types.stderr
index 1aed1dbe4ba..8b12aa1a393 100644
--- a/tests/ui/type/type-path-err-node-types.stderr
+++ b/tests/ui/type/type-path-err-node-types.stderr
@@ -1,9 +1,3 @@
-error[E0433]: failed to resolve: use of undeclared type `NonExistent`
- --> $DIR/type-path-err-node-types.rs:15:5
- |
-LL | NonExistent::Assoc::<u8>;
- | ^^^^^^^^^^^ use of undeclared type `NonExistent`
-
error[E0412]: cannot find type `Nonexistent` in this scope
--> $DIR/type-path-err-node-types.rs:7:12
|
@@ -22,6 +16,12 @@ error[E0425]: cannot find value `nonexistent` in this scope
LL | nonexistent.nonexistent::<u8>();
| ^^^^^^^^^^^ not found in this scope
+error[E0433]: failed to resolve: use of undeclared type `NonExistent`
+ --> $DIR/type-path-err-node-types.rs:15:5
+ |
+LL | NonExistent::Assoc::<u8>;
+ | ^^^^^^^^^^^ use of undeclared type `NonExistent`
+
error[E0282]: type annotations needed
--> $DIR/type-path-err-node-types.rs:23:14
|
diff --git a/tests/ui/typeck/bad-index-due-to-nested.stderr b/tests/ui/typeck/bad-index-due-to-nested.stderr
index cdb23372c4b..f9cdb280e27 100644
--- a/tests/ui/typeck/bad-index-due-to-nested.stderr
+++ b/tests/ui/typeck/bad-index-due-to-nested.stderr
@@ -42,13 +42,14 @@ error[E0308]: mismatched types
LL | fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V {
| - this type parameter
LL | map[k]
- | ^
- | |
- | expected `&K`, found type parameter `K`
- | help: consider borrowing here: `&k`
+ | ^ expected `&K`, found type parameter `K`
|
= note: expected reference `&K`
found type parameter `K`
+help: consider borrowing here
+ |
+LL | map[&k]
+ | +
error[E0308]: mismatched types
--> $DIR/bad-index-due-to-nested.rs:20:5
@@ -56,13 +57,14 @@ error[E0308]: mismatched types
LL | fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V {
| - this type parameter ----- expected `&'a V` because of return type
LL | map[k]
- | ^^^^^^
- | |
- | expected `&V`, found type parameter `V`
- | help: consider borrowing here: `&map[k]`
+ | ^^^^^^ expected `&V`, found type parameter `V`
|
= note: expected reference `&'a V`
found type parameter `V`
+help: consider borrowing here
+ |
+LL | &map[k]
+ | +
error: aborting due to 4 previous errors
diff --git a/tests/ui/typeck/bad-type-in-vec-contains.stderr b/tests/ui/typeck/bad-type-in-vec-contains.stderr
index 72533ab1fa3..b9b3a5fe5ec 100644
--- a/tests/ui/typeck/bad-type-in-vec-contains.stderr
+++ b/tests/ui/typeck/bad-type-in-vec-contains.stderr
@@ -2,16 +2,18 @@ error[E0308]: mismatched types
--> $DIR/bad-type-in-vec-contains.rs:5:21
|
LL | primes.contains(3);
- | -------- ^
- | | |
- | | expected `&_`, found integer
- | | help: consider borrowing here: `&3`
+ | -------- ^ expected `&_`, found integer
+ | |
| arguments to this method are incorrect
|
= note: expected reference `&_`
found type `{integer}`
note: method defined here
--> $SRC_DIR/core/src/slice/mod.rs:LL:COL
+help: consider borrowing here
+ |
+LL | primes.contains(&3);
+ | +
error: aborting due to previous error
diff --git a/tests/ui/typeck/issue-13853.stderr b/tests/ui/typeck/issue-13853.stderr
index 11d34f5b93b..8ecb8b68016 100644
--- a/tests/ui/typeck/issue-13853.stderr
+++ b/tests/ui/typeck/issue-13853.stderr
@@ -20,10 +20,8 @@ error[E0308]: mismatched types
--> $DIR/issue-13853.rs:37:13
|
LL | iterate(graph);
- | ------- ^^^^^
- | | |
- | | expected `&_`, found `Vec<Stuff>`
- | | help: consider borrowing here: `&graph`
+ | ------- ^^^^^ expected `&_`, found `Vec<Stuff>`
+ | |
| arguments to this function are incorrect
|
= note: expected reference `&_`
@@ -33,6 +31,10 @@ note: function defined here
|
LL | fn iterate<N: Node, G: Graph<N>>(graph: &G) {
| ^^^^^^^ ---------
+help: consider borrowing here
+ |
+LL | iterate(&graph);
+ | +
error: aborting due to 3 previous errors
diff --git a/tests/ui/unsized-locals/align.rs b/tests/ui/unsized-locals/align.rs
new file mode 100644
index 00000000000..01be8f3bb9c
--- /dev/null
+++ b/tests/ui/unsized-locals/align.rs
@@ -0,0 +1,30 @@
+// Test that unsized locals uphold alignment requirements.
+// Regression test for #71416.
+// run-pass
+#![feature(unsized_locals)]
+#![allow(incomplete_features)]
+use std::any::Any;
+
+#[repr(align(256))]
+#[allow(dead_code)]
+struct A {
+ v: u8
+}
+
+impl A {
+ fn f(&self) -> *const A {
+ assert_eq!(self as *const A as usize % 256, 0);
+ self
+ }
+}
+
+fn mk() -> Box<dyn Any> {
+ Box::new(A { v: 4 })
+}
+
+fn main() {
+ let x = *mk();
+ let dwncst = x.downcast_ref::<A>().unwrap();
+ let addr = dwncst.f();
+ assert_eq!(addr as usize % 256, 0);
+}
diff --git a/tests/ui/unsized-locals/suggest-borrow.stderr b/tests/ui/unsized-locals/suggest-borrow.stderr
index d456c16de0d..8741b35cdcf 100644
--- a/tests/ui/unsized-locals/suggest-borrow.stderr
+++ b/tests/ui/unsized-locals/suggest-borrow.stderr
@@ -16,11 +16,14 @@ error[E0308]: mismatched types
--> $DIR/suggest-borrow.rs:3:20
|
LL | let x: &[u8] = vec!(1, 2, 3)[..];
- | ----- ^^^^^^^^^^^^^^^^^
- | | |
- | | expected `&[u8]`, found `[{integer}]`
- | | help: consider borrowing here: `&vec!(1, 2, 3)[..]`
+ | ----- ^^^^^^^^^^^^^^^^^ expected `&[u8]`, found `[{integer}]`
+ | |
| expected due to this
+ |
+help: consider borrowing here
+ |
+LL | let x: &[u8] = &vec!(1, 2, 3)[..];
+ | +
error[E0308]: mismatched types
--> $DIR/suggest-borrow.rs:4:19
diff --git a/tests/ui/unsized/unsized-fn-param.stderr b/tests/ui/unsized/unsized-fn-param.stderr
index b4772605432..0de3dbbb557 100644
--- a/tests/ui/unsized/unsized-fn-param.stderr
+++ b/tests/ui/unsized/unsized-fn-param.stderr
@@ -5,8 +5,8 @@ LL | foo11("bar", &"baz");
| ^^^^^ 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>`
-help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<Path>`
+ = note: required for the cast from `&'static str` to `&dyn AsRef<Path>`
+help: consider borrowing the value, since `&&'static str` can be coerced into `&dyn AsRef<Path>`
|
LL | foo11(&"bar", &"baz");
| +
@@ -18,8 +18,8 @@ LL | foo12(&"bar", "baz");
| ^^^^^ 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>`
-help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<Path>`
+ = note: required for the cast from `&'static str` to `&dyn AsRef<Path>`
+help: consider borrowing the value, since `&&'static str` can be coerced into `&dyn AsRef<Path>`
|
LL | foo12(&"bar", &"baz");
| +
@@ -31,8 +31,8 @@ LL | foo21("bar", &"baz");
| ^^^^^ 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>`
-help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<str>`
+ = note: required for the cast from `&'static str` to `&dyn AsRef<str>`
+help: consider borrowing the value, since `&&'static str` can be coerced into `&dyn AsRef<str>`
|
LL | foo21(&"bar", &"baz");
| +
@@ -44,8 +44,8 @@ LL | foo22(&"bar", "baz");
| ^^^^^ 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>`
-help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<str>`
+ = note: required for the cast from `&'static str` to `&dyn AsRef<str>`
+help: consider borrowing the value, since `&&'static str` can be coerced into `&dyn AsRef<str>`
|
LL | foo22(&"bar", &"baz");
| +
diff --git a/tests/ui/weird-exprs.rs b/tests/ui/weird-exprs.rs
index d65703ef5ca..c4fa850a4f9 100644
--- a/tests/ui/weird-exprs.rs
+++ b/tests/ui/weird-exprs.rs
@@ -5,13 +5,16 @@
#![allow(non_camel_case_types)]
#![allow(dead_code)]
+#![allow(redundant_semicolons)]
#![allow(unreachable_code)]
#![allow(unused_braces, unused_must_use, unused_parens)]
#![allow(uncommon_codepoints, confusable_idents)]
+#![allow(unused_imports)]
#![allow(unreachable_patterns)]
#![recursion_limit = "256"]
+extern crate core;
use std::cell::Cell;
use std::mem::swap;
@@ -204,6 +207,30 @@ fn closure_matching() {
assert!(matches!(x(..), |_| Some(4)));
}
+fn semisemisemisemisemi() {
+ ;;;;;;; ;;;;;;; ;;; ;;; ;;
+ ;; ;; ;;;; ;;;; ;;
+ ;;;;;;; ;;;;; ;; ;;;; ;; ;;
+ ;; ;; ;; ;; ;; ;;
+ ;;;;;;; ;;;;;;; ;; ;; ;;
+}
+
+fn useful_syntax() {
+ use {{std::{{collections::{{HashMap}}}}}};
+ use ::{{{{core}, {std}}}};
+ use {{::{{core as core2}}}};
+}
+
+fn infcx() {
+ pub mod cx {
+ pub mod cx {
+ pub use super::cx;
+ pub struct Cx;
+ }
+ }
+ let _cx: cx::cx::Cx = cx::cx::cx::cx::cx::Cx;
+}
+
pub fn main() {
strange();
funny();
@@ -227,4 +254,7 @@ pub fn main() {
function();
bathroom_stall();
closure_matching();
+ semisemisemisemisemi();
+ useful_syntax();
+ infcx();
}
diff --git a/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
index 6cf4f33f947..40a25c7df6b 100644
--- a/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
+++ b/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
@@ -11,8 +11,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required for `Box<S>` to implement `CoerceUnsized<Box<dyn Trait>>`
- = note: required by cast to type `Box<dyn Trait>`
+ = note: required for the cast from `Box<S>` to `Box<dyn Trait>`
error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15
@@ -27,8 +26,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required for `Box<S>` to implement `CoerceUnsized<Box<dyn Trait>>`
- = note: required by cast to type `Box<(dyn Trait + 'static)>`
+ = note: required for the cast from `Box<S>` to `Box<(dyn Trait + 'static)>`
error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5
@@ -43,8 +41,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required for `Box<S>` to implement `CoerceUnsized<Box<dyn Trait>>`
- = note: required by cast to type `Box<dyn Trait>`
+ = note: required for the cast from `Box<S>` to `Box<dyn Trait>`
error: aborting due to 3 previous errors
diff --git a/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr b/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr
index c9bd4549aaf..e2c71df2feb 100644
--- a/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr
+++ b/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr
@@ -11,8 +11,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>`
- = note: required by cast to type `&dyn Trait`
+ = note: required for the cast from `&S` to `&dyn Trait`
error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/wf-convert-unsafe-trait-obj.rs:17:17
@@ -27,8 +26,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>`
- = note: required by cast to type `&dyn Trait`
+ = note: required for the cast from `&S` to `&dyn Trait`
error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/wf-convert-unsafe-trait-obj.rs:15:5
@@ -43,8 +41,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>`
- = note: required by cast to type `&dyn Trait`
+ = note: required for the cast from `&S` to `&dyn Trait`
error: aborting due to 3 previous errors
diff --git a/tests/ui/wf/wf-unsafe-trait-obj-match.stderr b/tests/ui/wf/wf-unsafe-trait-obj-match.stderr
index d2b41630976..66504e44060 100644
--- a/tests/ui/wf/wf-unsafe-trait-obj-match.stderr
+++ b/tests/ui/wf/wf-unsafe-trait-obj-match.stderr
@@ -25,8 +25,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>`
- = note: required by cast to type `&dyn Trait`
+ = note: required for the cast from `&S` to `&dyn Trait`
error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/wf-unsafe-trait-obj-match.rs:25:25
@@ -45,8 +44,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required for `&R` to implement `CoerceUnsized<&dyn Trait>`
- = note: required by cast to type `&dyn Trait`
+ = note: required for the cast from `&R` to `&dyn Trait`
error: aborting due to 3 previous errors
diff --git a/triagebot.toml b/triagebot.toml
index 54c8b2060c5..a5152434d89 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -512,6 +512,7 @@ compiler-team = [
]
compiler-team-contributors = [
"@compiler-errors",
+ "@eholk",
"@jackh726",
"@TaKO8Ki",
"@WaffleLapkin",
@@ -532,6 +533,7 @@ bootstrap = [
"@Mark-Simulacrum",
"@albertlarsan68",
"@ozkanonur",
+ "@clubby789",
]
infra-ci = [
"@Mark-Simulacrum",