summaryrefslogtreecommitdiffstats
path: root/src/test/mir-opt
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/mir-opt
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/mir-opt')
-rw-r--r--src/test/mir-opt/76803_regression.encode.SimplifyBranchSame.diff29
-rw-r--r--src/test/mir-opt/76803_regression.rs19
-rw-r--r--src/test/mir-opt/README.md39
-rw-r--r--src/test/mir-opt/address-of.rs47
-rw-r--r--src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir308
-rw-r--r--src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir47
-rw-r--r--src/test/mir-opt/array-index-is-temporary.rs17
-rw-r--r--src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir64
-rw-r--r--src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir64
-rw-r--r--src/test/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir24
-rw-r--r--src/test/mir-opt/asm_unwind_panic_abort.rs16
-rw-r--r--src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir84
-rw-r--r--src/test/mir-opt/basic_assignment.rs24
-rw-r--r--src/test/mir-opt/bool_compare.opt1.InstCombine.diff35
-rw-r--r--src/test/mir-opt/bool_compare.opt2.InstCombine.diff35
-rw-r--r--src/test/mir-opt/bool_compare.opt3.InstCombine.diff35
-rw-r--r--src/test/mir-opt/bool_compare.opt4.InstCombine.diff35
-rw-r--r--src/test/mir-opt/bool_compare.rs26
-rw-r--r--src/test/mir-opt/box_expr.main.ElaborateDrops.before.mir80
-rw-r--r--src/test/mir-opt/box_expr.rs21
-rw-r--r--src/test/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir31
-rw-r--r--src/test/mir-opt/byte_slice.rs7
-rw-r--r--src/test/mir-opt/combine_array_len.norm2.InstCombine.32bit.diff77
-rw-r--r--src/test/mir-opt/combine_array_len.norm2.InstCombine.64bit.diff77
-rw-r--r--src/test/mir-opt/combine_array_len.rs12
-rw-r--r--src/test/mir-opt/combine_clone_of_primitives.rs20
-rw-r--r--src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff85
-rw-r--r--src/test/mir-opt/const-promotion-extern-static.rs18
-rw-r--r--src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir62
-rw-r--r--src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir66
-rw-r--r--src/test/mir-opt/const_allocation.rs9
-rw-r--r--src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir61
-rw-r--r--src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir64
-rw-r--r--src/test/mir-opt/const_allocation2.rs11
-rw-r--r--src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir55
-rw-r--r--src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir56
-rw-r--r--src/test/mir-opt/const_allocation3.rs29
-rw-r--r--src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff115
-rw-r--r--src/test/mir-opt/const_debuginfo.rs24
-rw-r--r--src/test/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff52
-rw-r--r--src/test/mir-opt/const_goto.rs16
-rw-r--r--src/test/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff51
-rw-r--r--src/test/mir-opt/const_goto_const_eval_fail.rs16
-rw-r--r--src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff103
-rw-r--r--src/test/mir-opt/const_goto_storage.rs19
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir23
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff54
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir17
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir21
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff54
-rw-r--r--src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff32
-rw-r--r--src/test/mir-opt/const_prop/aggregate.rs6
-rw-r--r--src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff38
-rw-r--r--src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff38
-rw-r--r--src/test/mir-opt/const_prop/array_index.rs6
-rw-r--r--src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff54
-rw-r--r--src/test/mir-opt/const_prop/bad_op_div_by_zero.rs6
-rw-r--r--src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff54
-rw-r--r--src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs6
-rw-r--r--src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff56
-rw-r--r--src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff56
-rw-r--r--src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs9
-rw-r--r--src/test/mir-opt/const_prop/boolean_identities.rs10
-rw-r--r--src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff33
-rw-r--r--src/test/mir-opt/const_prop/boxes.main.ConstProp.diff67
-rw-r--r--src/test/mir-opt/const_prop/boxes.rs13
-rw-r--r--src/test/mir-opt/const_prop/cast.main.ConstProp.diff28
-rw-r--r--src/test/mir-opt/const_prop/cast.rs7
-rw-r--r--src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff28
-rw-r--r--src/test/mir-opt/const_prop/checked_add.rs6
-rw-r--r--src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff44
-rw-r--r--src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs9
-rw-r--r--src/test/mir-opt/const_prop/control-flow-simplification.rs20
-rw-r--r--src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff34
-rw-r--r--src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir9
-rw-r--r--src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff52
-rw-r--r--src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff52
-rw-r--r--src/test/mir-opt/const_prop/discriminant.rs12
-rw-r--r--src/test/mir-opt/const_prop/indirect.main.ConstProp.diff33
-rw-r--r--src/test/mir-opt/const_prop/indirect.rs6
-rw-r--r--src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff77
-rw-r--r--src/test/mir-opt/const_prop/invalid_constant.rs42
-rw-r--r--src/test/mir-opt/const_prop/issue-66971.rs17
-rw-r--r--src/test/mir-opt/const_prop/issue-67019.rs12
-rw-r--r--src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff33
-rw-r--r--src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff34
-rw-r--r--src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff37
-rw-r--r--src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff37
-rw-r--r--src/test/mir-opt/const_prop/large_array_index.rs7
-rw-r--r--src/test/mir-opt/const_prop/mult_by_zero.rs10
-rw-r--r--src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff18
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff28
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable.rs8
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff30
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate.rs8
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff36
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs9
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff35
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs14
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff48
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_no_prop.rs12
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff53
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs15
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff68
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff68
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir27
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir27
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.rs15
-rw-r--r--src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff48
-rw-r--r--src/test/mir-opt/const_prop/read_immutable_static.rs8
-rw-r--r--src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff27
-rw-r--r--src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff30
-rw-r--r--src/test/mir-opt/const_prop/ref_deref.rs6
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff26
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff30
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project.rs6
-rw-r--r--src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff29
-rw-r--r--src/test/mir-opt/const_prop/reify_fn_ptr.rs5
-rw-r--r--src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff43
-rw-r--r--src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff43
-rw-r--r--src/test/mir-opt/const_prop/repeat.rs7
-rw-r--r--src/test/mir-opt/const_prop/return_place.add.ConstProp.diff21
-rw-r--r--src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir10
-rw-r--r--src/test/mir-opt/const_prop/return_place.rs11
-rw-r--r--src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff35
-rw-r--r--src/test/mir-opt/const_prop/scalar_literal_propagation.rs8
-rw-r--r--src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff53
-rw-r--r--src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff53
-rw-r--r--src/test/mir-opt/const_prop/slice_len.rs6
-rw-r--r--src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff34
-rw-r--r--src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff34
-rw-r--r--src/test/mir-opt/const_prop/switch_int.rs11
-rw-r--r--src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff36
-rw-r--r--src/test/mir-opt/const_prop/tuple_literal_propagation.rs9
-rw-r--r--src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff42
-rw-r--r--src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff36
-rw-r--r--src/test/mir-opt/const_prop_miscompile.rs22
-rw-r--r--src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot6
-rw-r--r--src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot13
-rw-r--r--src/test/mir-opt/coverage_graphviz.rs20
-rw-r--r--src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff75
-rw-r--r--src/test/mir-opt/dead-store-elimination/cycle.rs22
-rw-r--r--src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff35
-rw-r--r--src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff14
-rw-r--r--src/test/mir-opt/dead-store-elimination/provenance_soundness.rs18
-rw-r--r--src/test/mir-opt/deaggregator_test.bar.Deaggregator.diff21
-rw-r--r--src/test/mir-opt/deaggregator_test.rs15
-rw-r--r--src/test/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff20
-rw-r--r--src/test/mir-opt/deaggregator_test_enum.rs17
-rw-r--r--src/test/mir-opt/deaggregator_test_enum_2.rs20
-rw-r--r--src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff45
-rw-r--r--src/test/mir-opt/deaggregator_test_multiple.rs16
-rw-r--r--src/test/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff35
-rw-r--r--src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff107
-rw-r--r--src/test/mir-opt/deduplicate_blocks.rs13
-rw-r--r--src/test/mir-opt/derefer_complex_case.main.Derefer.diff107
-rw-r--r--src/test/mir-opt/derefer_complex_case.rs6
-rw-r--r--src/test/mir-opt/derefer_inline_test.main.Derefer.diff61
-rw-r--r--src/test/mir-opt/derefer_inline_test.rs11
-rw-r--r--src/test/mir-opt/derefer_terminator_test.main.Derefer.diff99
-rw-r--r--src/test/mir-opt/derefer_terminator_test.rs16
-rw-r--r--src/test/mir-opt/derefer_test.main.Derefer.diff54
-rw-r--r--src/test/mir-opt/derefer_test.rs7
-rw-r--r--src/test/mir-opt/derefer_test_multiple.main.Derefer.diff92
-rw-r--r--src/test/mir-opt/derefer_test_multiple.rs9
-rw-r--r--src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff65
-rw-r--r--src/test/mir-opt/dest-prop/branch.rs21
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff26
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff28
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff18
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff28
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.rs39
-rw-r--r--src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff53
-rw-r--r--src/test/mir-opt/dest-prop/cycle.rs15
-rw-r--r--src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff39
-rw-r--r--src/test/mir-opt/dest-prop/simple.rs14
-rw-r--r--src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff41
-rw-r--r--src/test/mir-opt/dest-prop/union.rs16
-rw-r--r--src/test/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff78
-rw-r--r--src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff92
-rw-r--r--src/test/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff78
-rw-r--r--src/test/mir-opt/early_otherwise_branch.rs32
-rw-r--r--src/test/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff100
-rw-r--r--src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs13
-rw-r--r--src/test/mir-opt/early_otherwise_branch_68867.rs32
-rw-r--r--src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff344
-rw-r--r--src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff253
-rw-r--r--src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff95
-rw-r--r--src/test/mir-opt/early_otherwise_branch_noopt.rs18
-rw-r--r--src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff47
-rw-r--r--src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff40
-rw-r--r--src/test/mir-opt/early_otherwise_branch_soundness.rs32
-rw-r--r--src/test/mir-opt/enum_cast.bar.mir_map.0.mir13
-rw-r--r--src/test/mir-opt/enum_cast.boo.mir_map.0.mir13
-rw-r--r--src/test/mir-opt/enum_cast.droppy.mir_map.0.mir54
-rw-r--r--src/test/mir-opt/enum_cast.foo.mir_map.0.mir13
-rw-r--r--src/test/mir-opt/enum_cast.rs50
-rw-r--r--src/test/mir-opt/equal_true.opt.InstCombine.diff35
-rw-r--r--src/test/mir-opt/equal_true.rs9
-rw-r--r--src/test/mir-opt/exponential-or.rs11
-rw-r--r--src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir83
-rw-r--r--src/test/mir-opt/fn-ptr-shim.rs15
-rw-r--r--src/test/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir13
-rw-r--r--src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff146
-rw-r--r--src/test/mir-opt/funky_arms.rs56
-rw-r--r--src/test/mir-opt/generator-drop-cleanup.rs14
-rw-r--r--src/test/mir-opt/generator-storage-dead-unwind.rs29
-rw-r--r--src/test/mir-opt/generator-tiny.rs26
-rw-r--r--src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir84
-rw-r--r--src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir114
-rw-r--r--src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir84
-rw-r--r--src/test/mir-opt/graphviz.main.mir_map.0.dot7
-rw-r--r--src/test/mir-opt/graphviz.rs5
-rw-r--r--src/test/mir-opt/if-condition-int.rs65
-rw-r--r--src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff30
-rw-r--r--src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff34
-rw-r--r--src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff58
-rw-r--r--src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff39
-rw-r--r--src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff39
-rw-r--r--src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff65
-rw-r--r--src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff39
-rw-r--r--src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff39
-rw-r--r--src/test/mir-opt/inline/caller-with-trivial-bound.rs26
-rw-r--r--src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff33
-rw-r--r--src/test/mir-opt/inline/cycle.f.Inline.diff43
-rw-r--r--src/test/mir-opt/inline/cycle.g.Inline.diff57
-rw-r--r--src/test/mir-opt/inline/cycle.main.Inline.diff74
-rw-r--r--src/test/mir-opt/inline/cycle.rs18
-rw-r--r--src/test/mir-opt/inline/dyn-trait.rs35
-rw-r--r--src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff62
-rw-r--r--src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff23
-rw-r--r--src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff37
-rw-r--r--src/test/mir-opt/inline/inline-any-operand.rs18
-rw-r--r--src/test/mir-opt/inline/inline-async.rs18
-rw-r--r--src/test/mir-opt/inline/inline-closure-borrows-arg.rs17
-rw-r--r--src/test/mir-opt/inline/inline-closure-captures.rs13
-rw-r--r--src/test/mir-opt/inline/inline-closure.rs13
-rw-r--r--src/test/mir-opt/inline/inline-compatibility.rs55
-rw-r--r--src/test/mir-opt/inline/inline-cycle-generic.rs40
-rw-r--r--src/test/mir-opt/inline/inline-cycle.rs60
-rw-r--r--src/test/mir-opt/inline/inline-diverging.rs40
-rw-r--r--src/test/mir-opt/inline/inline-generator.rs16
-rw-r--r--src/test/mir-opt/inline/inline-instruction-set.rs54
-rw-r--r--src/test/mir-opt/inline/inline-into-box-place.rs9
-rw-r--r--src/test/mir-opt/inline/inline-options.rs19
-rw-r--r--src/test/mir-opt/inline/inline-retag.rs18
-rw-r--r--src/test/mir-opt/inline/inline-shims.rs13
-rw-r--r--src/test/mir-opt/inline/inline-specialization.rs15
-rw-r--r--src/test/mir-opt/inline/inline-trait-method.rs22
-rw-r--r--src/test/mir-opt/inline/inline-trait-method_2.rs27
-rw-r--r--src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir44
-rw-r--r--src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir49
-rw-r--r--src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir56
-rw-r--r--src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir69
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff24
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff24
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff25
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff22
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff22
-rw-r--r--src/test/mir-opt/inline/inline_cycle.one.Inline.diff30
-rw-r--r--src/test/mir-opt/inline/inline_cycle.two.Inline.diff55
-rw-r--r--src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff32
-rw-r--r--src/test/mir-opt/inline/inline_diverging.f.Inline.diff24
-rw-r--r--src/test/mir-opt/inline/inline_diverging.g.Inline.diff49
-rw-r--r--src/test/mir-opt/inline/inline_diverging.h.Inline.diff56
-rw-r--r--src/test/mir-opt/inline/inline_generator.main.Inline.diff156
-rw-r--r--src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff44
-rw-r--r--src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff46
-rw-r--r--src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff86
-rw-r--r--src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff86
-rw-r--r--src/test/mir-opt/inline/inline_options.main.Inline.after.mir55
-rw-r--r--src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir72
-rw-r--r--src/test/mir-opt/inline/inline_shims.clone.Inline.diff26
-rw-r--r--src/test/mir-opt/inline/inline_shims.drop.Inline.diff56
-rw-r--r--src/test/mir-opt/inline/inline_specialization.main.Inline.diff28
-rw-r--r--src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir21
-rw-r--r--src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir32
-rw-r--r--src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs27
-rw-r--r--src/test/mir-opt/inline/issue-76997-inline-scopes-parenting.rs7
-rw-r--r--src/test/mir-opt/inline/issue-78442.rs20
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir30
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir42
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir22
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir30
-rw-r--r--src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir42
-rw-r--r--src/test/mir-opt/inline/issue_78442.bar.Inline.diff68
-rw-r--r--src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff57
-rw-r--r--src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff13
-rw-r--r--src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff51
-rw-r--r--src/test/mir-opt/instrument_coverage.rs36
-rw-r--r--src/test/mir-opt/issue-38669.rs12
-rw-r--r--src/test/mir-opt/issue-41110.rs30
-rw-r--r--src/test/mir-opt/issue-41697.rs40
-rw-r--r--src/test/mir-opt/issue-41888.rs24
-rw-r--r--src/test/mir-opt/issue-49232.rs15
-rw-r--r--src/test/mir-opt/issue-62289.rs14
-rw-r--r--src/test/mir-opt/issue-72181-1.rs21
-rw-r--r--src/test/mir-opt/issue-72181.rs28
-rw-r--r--src/test/mir-opt/issue-73223.rs13
-rw-r--r--src/test/mir-opt/issue-78192.rs11
-rw-r--r--src/test/mir-opt/issue-99325.rs12
-rw-r--r--src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir52
-rw-r--r--src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir70
-rw-r--r--src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir101
-rw-r--r--src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir20
-rw-r--r--src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir20
-rw-r--r--src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir152
-rw-r--r--src/test/mir-opt/issue_49232.main.mir_map.0.mir82
-rw-r--r--src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir122
-rw-r--r--src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir17
-rw-r--r--src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir17
-rw-r--r--src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir27
-rw-r--r--src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir27
-rw-r--r--src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir62
-rw-r--r--src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir62
-rw-r--r--src/test/mir-opt/issue_72181_1.f.mir_map.0.mir29
-rw-r--r--src/test/mir-opt/issue_72181_1.main.mir_map.0.mir57
-rw-r--r--src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff117
-rw-r--r--src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff117
-rw-r--r--src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff157
-rw-r--r--src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff157
-rw-r--r--src/test/mir-opt/issue_76432.rs16
-rw-r--r--src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff115
-rw-r--r--src/test/mir-opt/issue_78192.f.InstCombine.diff29
-rw-r--r--src/test/mir-opt/issue_99325.main.mir_map.0.mir295
-rw-r--r--src/test/mir-opt/issues/issue-59352.rs19
-rw-r--r--src/test/mir-opt/issues/issue-75439.rs18
-rw-r--r--src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir109
-rw-r--r--src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff89
-rw-r--r--src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir52
-rw-r--r--src/test/mir-opt/loop_test.rs17
-rw-r--r--src/test/mir-opt/lower_array_len.array_bound.InstCombine.diff66
-rw-r--r--src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff68
-rw-r--r--src/test/mir-opt/lower_array_len.array_bound.SimplifyLocals.diff70
-rw-r--r--src/test/mir-opt/lower_array_len.array_bound_mut.InstCombine.diff79
-rw-r--r--src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff81
-rw-r--r--src/test/mir-opt/lower_array_len.array_bound_mut.SimplifyLocals.diff93
-rw-r--r--src/test/mir-opt/lower_array_len.array_len.InstCombine.diff27
-rw-r--r--src/test/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff30
-rw-r--r--src/test/mir-opt/lower_array_len.array_len.SimplifyLocals.diff22
-rw-r--r--src/test/mir-opt/lower_array_len.array_len_by_value.InstCombine.diff26
-rw-r--r--src/test/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff30
-rw-r--r--src/test/mir-opt/lower_array_len.array_len_by_value.SimplifyLocals.diff22
-rw-r--r--src/test/mir-opt/lower_array_len.rs47
-rw-r--r--src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff20
-rw-r--r--src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff115
-rw-r--r--src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir32
-rw-r--r--src/test/mir-opt/lower_intrinsics.f_unit.PreCodegen.before.mir30
-rw-r--r--src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff29
-rw-r--r--src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff31
-rw-r--r--src/test/mir-opt/lower_intrinsics.rs78
-rw-r--r--src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff20
-rw-r--r--src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff22
-rw-r--r--src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff83
-rw-r--r--src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff63
-rw-r--r--src/test/mir-opt/lower_slice_len.rs14
-rw-r--r--src/test/mir-opt/match-arm-scopes.rs35
-rw-r--r--src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff272
-rw-r--r--src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir113
-rw-r--r--src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir108
-rw-r--r--src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir153
-rw-r--r--src/test/mir-opt/match_false_edges.rs39
-rw-r--r--src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir106
-rw-r--r--src/test/mir-opt/match_test.rs18
-rw-r--r--src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff88
-rw-r--r--src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff88
-rw-r--r--src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff30
-rw-r--r--src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff30
-rw-r--r--src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.32bit.mir10
-rw-r--r--src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.64bit.mir10
-rw-r--r--src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff42
-rw-r--r--src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff42
-rw-r--r--src/test/mir-opt/matches_reduce_branches.rs59
-rw-r--r--src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff28
-rw-r--r--src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff28
-rw-r--r--src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff28
-rw-r--r--src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff28
-rw-r--r--src/test/mir-opt/matches_u8.rs32
-rw-r--r--src/test/mir-opt/multiple_return_terminators.rs14
-rw-r--r--src/test/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff12
-rw-r--r--src/test/mir-opt/nll/named-lifetimes-basic.rs15
-rw-r--r--src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir48
-rw-r--r--src/test/mir-opt/nll/region-subtyping-basic.rs25
-rw-r--r--src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir112
-rw-r--r--src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir112
-rw-r--r--src/test/mir-opt/no-drop-for-inactive-variant.rs16
-rw-r--r--src/test/mir-opt/no-spurious-drop-after-call.rs10
-rw-r--r--src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir49
-rw-r--r--src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir49
-rw-r--r--src/test/mir-opt/not_equal_false.opt.InstCombine.diff35
-rw-r--r--src/test/mir-opt/not_equal_false.rs9
-rw-r--r--src/test/mir-opt/nrvo-simple.rs12
-rw-r--r--src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff43
-rw-r--r--src/test/mir-opt/packed-struct-drop-aligned.rs17
-rw-r--r--src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir55
-rw-r--r--src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir55
-rw-r--r--src/test/mir-opt/receiver-ptr-mutability.rs20
-rw-r--r--src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir96
-rw-r--r--src/test/mir-opt/remove-never-const.rs22
-rw-r--r--src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff76
-rw-r--r--src/test/mir-opt/remove_fake_borrows.rs15
-rw-r--r--src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir11
-rw-r--r--src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff100
-rw-r--r--src/test/mir-opt/remove_storage_markers.rs11
-rw-r--r--src/test/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff31
-rw-r--r--src/test/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff31
-rw-r--r--src/test/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff27
-rw-r--r--src/test/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff27
-rw-r--r--src/test/mir-opt/remove_unneeded_drops.rs29
-rw-r--r--src/test/mir-opt/remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir15
-rw-r--r--src/test/mir-opt/remove_zsts_dont_touch_unions.rs19
-rw-r--r--src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir198
-rw-r--r--src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir20
-rw-r--r--src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir22
-rw-r--r--src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir210
-rw-r--r--src/test/mir-opt/retag.rs65
-rw-r--r--src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir20
-rw-r--r--src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir15
-rw-r--r--src/test/mir-opt/return_an_array.rs8
-rw-r--r--src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff72
-rw-r--r--src/test/mir-opt/separate_const_switch.identity.ConstProp.diff145
-rw-r--r--src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir127
-rw-r--r--src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff155
-rw-r--r--src/test/mir-opt/separate_const_switch.rs35
-rw-r--r--src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff95
-rw-r--r--src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir69
-rw-r--r--src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff102
-rw-r--r--src/test/mir-opt/simple-match.rs12
-rw-r--r--src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir29
-rw-r--r--src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir29
-rw-r--r--src/test/mir-opt/simplify-arm-identity.rs23
-rw-r--r--src/test/mir-opt/simplify-arm.rs47
-rw-r--r--src/test/mir-opt/simplify-locals-fixedpoint.rs15
-rw-r--r--src/test/mir-opt/simplify-locals-removes-unused-consts.rs17
-rw-r--r--src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs15
-rw-r--r--src/test/mir-opt/simplify-locals.rs81
-rw-r--r--src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff46
-rw-r--r--src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff46
-rw-r--r--src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff58
-rw-r--r--src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff58
-rw-r--r--src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff89
-rw-r--r--src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff89
-rw-r--r--src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.32bit.diff61
-rw-r--r--src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.64bit.diff61
-rw-r--r--src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff52
-rw-r--r--src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff71
-rw-r--r--src/test/mir-opt/simplify_cfg.rs18
-rw-r--r--src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff40
-rw-r--r--src/test/mir-opt/simplify_if.rs9
-rw-r--r--src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff33
-rw-r--r--src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff19
-rw-r--r--src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff29
-rw-r--r--src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff21
-rw-r--r--src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff31
-rw-r--r--src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff22
-rw-r--r--src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff22
-rw-r--r--src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff26
-rw-r--r--src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff22
-rw-r--r--src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff62
-rw-r--r--src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff71
-rw-r--r--src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff39
-rw-r--r--src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff39
-rw-r--r--src/test/mir-opt/simplify_match.main.ConstProp.diff40
-rw-r--r--src/test/mir-opt/simplify_match.rs10
-rw-r--r--src/test/mir-opt/simplify_try.rs30
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff102
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff81
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir79
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir54
-rw-r--r--src/test/mir-opt/simplify_try_if_let.rs43
-rw-r--r--src/test/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff104
-rw-r--r--src/test/mir-opt/slice-drop-shim.rs7
-rw-r--r--src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir101
-rw-r--r--src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir101
-rw-r--r--src/test/mir-opt/spanview-block.rs5
-rw-r--r--src/test/mir-opt/spanview-statement.rs5
-rw-r--r--src/test/mir-opt/spanview-terminator.rs5
-rw-r--r--src/test/mir-opt/spanview_block.main.mir_map.0.html66
-rw-r--r--src/test/mir-opt/spanview_statement.main.mir_map.0.html66
-rw-r--r--src/test/mir-opt/spanview_terminator.main.mir_map.0.html65
-rw-r--r--src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir203
-rw-r--r--src/test/mir-opt/storage_live_dead_in_statics.rs33
-rw-r--r--src/test/mir-opt/storage_ranges.main.nll.0.mir64
-rw-r--r--src/test/mir-opt/storage_ranges.rs9
-rw-r--r--src/test/mir-opt/tls-access.rs14
-rw-r--r--src/test/mir-opt/tls_access.main.PreCodegen.after.mir28
-rw-r--r--src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir111
-rw-r--r--src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir111
-rw-r--r--src/test/mir-opt/uniform_array_move_out.rs18
-rw-r--r--src/test/mir-opt/uninhabited-enum.rs19
-rw-r--r--src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir18
-rw-r--r--src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir18
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir63
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff93
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching.rs30
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir96
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff138
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching2.rs34
-rw-r--r--src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff38
-rw-r--r--src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff34
-rw-r--r--src/test/mir-opt/uninhabited_fallthrough_elimination.rs32
-rw-r--r--src/test/mir-opt/unreachable.main.UnreachablePropagation.diff69
-rw-r--r--src/test/mir-opt/unreachable.rs20
-rw-r--r--src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff74
-rw-r--r--src/test/mir-opt/unreachable_diverging.rs20
-rw-r--r--src/test/mir-opt/unusual-item-types.rs29
-rw-r--r--src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir10
-rw-r--r--src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir10
-rw-r--r--src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir12
-rw-r--r--src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir12
-rw-r--r--src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir39
-rw-r--r--src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir39
-rw-r--r--src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir10
-rw-r--r--src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir10
-rw-r--r--src/test/mir-opt/while-storage.rs19
-rw-r--r--src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff55
-rw-r--r--src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff55
-rw-r--r--src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir17
-rw-r--r--src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir17
-rw-r--r--src/test/mir-opt/while_let_loops.rs15
-rw-r--r--src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir64
521 files changed, 23025 insertions, 0 deletions
diff --git a/src/test/mir-opt/76803_regression.encode.SimplifyBranchSame.diff b/src/test/mir-opt/76803_regression.encode.SimplifyBranchSame.diff
new file mode 100644
index 000000000..57e298625
--- /dev/null
+++ b/src/test/mir-opt/76803_regression.encode.SimplifyBranchSame.diff
@@ -0,0 +1,29 @@
+- // MIR for `encode` before SimplifyBranchSame
++ // MIR for `encode` after SimplifyBranchSame
+
+ fn encode(_1: Type) -> Type {
+ debug v => _1; // in scope 0 at $DIR/76803_regression.rs:+0:15: +0:16
+ let mut _0: Type; // return place in scope 0 at $DIR/76803_regression.rs:+0:27: +0:31
+ let mut _2: isize; // in scope 0 at $DIR/76803_regression.rs:+2:9: +2:16
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/76803_regression.rs:+1:11: +1:12
+ switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/76803_regression.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = move _1; // scope 0 at $DIR/76803_regression.rs:+3:14: +3:15
+ goto -> bb3; // scope 0 at $DIR/76803_regression.rs:+3:14: +3:15
+ }
+
+ bb2: {
+ Deinit(_0); // scope 0 at $DIR/76803_regression.rs:+2:20: +2:27
+ discriminant(_0) = 1; // scope 0 at $DIR/76803_regression.rs:+2:20: +2:27
+ goto -> bb3; // scope 0 at $DIR/76803_regression.rs:+2:20: +2:27
+ }
+
+ bb3: {
+ return; // scope 0 at $DIR/76803_regression.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/76803_regression.rs b/src/test/mir-opt/76803_regression.rs
new file mode 100644
index 000000000..05dc3c978
--- /dev/null
+++ b/src/test/mir-opt/76803_regression.rs
@@ -0,0 +1,19 @@
+// compile-flags: -Z mir-opt-level=1
+// EMIT_MIR 76803_regression.encode.SimplifyBranchSame.diff
+
+#[derive(Debug, Eq, PartialEq)]
+pub enum Type {
+ A,
+ B,
+}
+
+pub fn encode(v: Type) -> Type {
+ match v {
+ Type::A => Type::B,
+ _ => v,
+ }
+}
+
+fn main() {
+ assert_eq!(Type::B, encode(Type::A));
+}
diff --git a/src/test/mir-opt/README.md b/src/test/mir-opt/README.md
new file mode 100644
index 000000000..a0550466c
--- /dev/null
+++ b/src/test/mir-opt/README.md
@@ -0,0 +1,39 @@
+This folder contains tests for MIR optimizations.
+
+The `mir-opt` test format emits MIR to extra files that you can automatically update by specifying
+`--bless` on the command line (just like `ui` tests updating `.stderr` files).
+
+# `--bless`able test format
+
+By default 32 bit and 64 bit targets use the same dump files, which can be problematic in the
+presence of pointers in constants or other bit width dependent things. In that case you can add
+
+```
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+```
+
+to your test, causing separate files to be generated for 32bit and 64bit systems.
+
+## Emit a diff of the mir for a specific optimization
+
+This is what you want most often when you want to see how an optimization changes the MIR.
+
+```
+// EMIT_MIR $file_name_of_some_mir_dump.diff
+```
+
+## Emit mir after a specific optimization
+
+Use this if you are just interested in the final state after an optimization.
+
+```
+// EMIT_MIR $file_name_of_some_mir_dump.after.mir
+```
+
+## Emit mir before a specific optimization
+
+This exists mainly for completeness and is rarely useful.
+
+```
+// EMIT_MIR $file_name_of_some_mir_dump.before.mir
+```
diff --git a/src/test/mir-opt/address-of.rs b/src/test/mir-opt/address-of.rs
new file mode 100644
index 000000000..c4bea5613
--- /dev/null
+++ b/src/test/mir-opt/address-of.rs
@@ -0,0 +1,47 @@
+// EMIT_MIR address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
+
+fn address_of_reborrow() {
+ let y = &[0; 10];
+ let mut z = &mut [0; 10];
+
+ y as *const _;
+ y as *const [i32; 10];
+ y as *const dyn Send;
+ y as *const [i32];
+ y as *const i32; // This is a cast, not a coercion
+
+ let p: *const _ = y;
+ let p: *const [i32; 10] = y;
+ let p: *const dyn Send = y;
+ let p: *const [i32] = y;
+
+ z as *const _;
+ z as *const [i32; 10];
+ z as *const dyn Send;
+ z as *const [i32];
+
+ let p: *const _ = z;
+ let p: *const [i32; 10] = z;
+ let p: *const dyn Send = z;
+ let p: *const [i32] = z;
+
+ z as *mut _;
+ z as *mut [i32; 10];
+ z as *mut dyn Send;
+ z as *mut [i32];
+
+ let p: *mut _ = z;
+ let p: *mut [i32; 10] = z;
+ let p: *mut dyn Send = z;
+ let p: *mut [i32] = z;
+}
+
+// The normal borrows here should be preserved
+// EMIT_MIR address_of.borrow_and_cast.SimplifyCfg-initial.after.mir
+fn borrow_and_cast(mut x: i32) {
+ let p = &x as *const i32;
+ let q = &mut x as *const i32;
+ let r = &mut x as *mut i32;
+}
+
+fn main() {}
diff --git a/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
new file mode 100644
index 000000000..d41a66871
--- /dev/null
+++ b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
@@ -0,0 +1,308 @@
+// MIR for `address_of_reborrow` after SimplifyCfg-initial
+
+| User Type Annotations
+| 0: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:7:5: 7:18, inferred_ty: *const [i32; 10]
+| 1: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:9:5: 9:25, inferred_ty: *const dyn std::marker::Send
+| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:13:12: 13:20, inferred_ty: *const [i32; 10]
+| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:13:12: 13:20, inferred_ty: *const [i32; 10]
+| 4: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:14:12: 14:28, inferred_ty: *const [i32; 10]
+| 5: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:14:12: 14:28, inferred_ty: *const [i32; 10]
+| 6: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send
+| 7: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send
+| 8: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:16:12: 16:24, inferred_ty: *const [i32]
+| 9: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:16:12: 16:24, inferred_ty: *const [i32]
+| 10: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:18:5: 18:18, inferred_ty: *const [i32; 10]
+| 11: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:20:5: 20:25, inferred_ty: *const dyn std::marker::Send
+| 12: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:23:12: 23:20, inferred_ty: *const [i32; 10]
+| 13: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:23:12: 23:20, inferred_ty: *const [i32; 10]
+| 14: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:24:12: 24:28, inferred_ty: *const [i32; 10]
+| 15: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:24:12: 24:28, inferred_ty: *const [i32; 10]
+| 16: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send
+| 17: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send
+| 18: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:26:12: 26:24, inferred_ty: *const [i32]
+| 19: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:26:12: 26:24, inferred_ty: *const [i32]
+| 20: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:28:5: 28:16, inferred_ty: *mut [i32; 10]
+| 21: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:30:5: 30:23, inferred_ty: *mut dyn std::marker::Send
+| 22: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10]
+| 23: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10]
+| 24: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address-of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10]
+| 25: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address-of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10]
+| 26: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send
+| 27: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send
+| 28: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address-of.rs:36:12: 36:22, inferred_ty: *mut [i32]
+| 29: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address-of.rs:36:12: 36:22, inferred_ty: *mut [i32]
+|
+fn address_of_reborrow() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/address-of.rs:+0:26: +0:26
+ let _1: &[i32; 10]; // in scope 0 at $DIR/address-of.rs:+1:9: +1:10
+ let _2: [i32; 10]; // in scope 0 at $DIR/address-of.rs:+1:14: +1:21
+ let mut _4: [i32; 10]; // in scope 0 at $DIR/address-of.rs:+2:22: +2:29
+ let _5: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+4:5: +4:18
+ let mut _6: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+4:5: +4:18
+ let _7: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+5:5: +5:26
+ let _8: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+6:5: +6:25
+ let mut _9: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+6:5: +6:25
+ let mut _10: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+6:5: +6:6
+ let _11: *const [i32]; // in scope 0 at $DIR/address-of.rs:+7:5: +7:22
+ let mut _12: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+7:5: +7:6
+ let _13: *const i32; // in scope 0 at $DIR/address-of.rs:+8:5: +8:20
+ let mut _14: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+8:5: +8:6
+ let mut _18: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+12:30: +12:31
+ let mut _20: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+13:27: +13:28
+ let _21: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+15:5: +15:18
+ let mut _22: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+15:5: +15:18
+ let _23: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+16:5: +16:26
+ let _24: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+17:5: +17:25
+ let mut _25: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+17:5: +17:25
+ let mut _26: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+17:5: +17:6
+ let _27: *const [i32]; // in scope 0 at $DIR/address-of.rs:+18:5: +18:22
+ let mut _28: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+18:5: +18:6
+ let mut _32: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+22:30: +22:31
+ let mut _34: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+23:27: +23:28
+ let _35: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+25:5: +25:16
+ let mut _36: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+25:5: +25:16
+ let _37: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+26:5: +26:24
+ let _38: *mut dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+27:5: +27:23
+ let mut _39: *mut dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+27:5: +27:23
+ let mut _40: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+27:5: +27:6
+ let _41: *mut [i32]; // in scope 0 at $DIR/address-of.rs:+28:5: +28:20
+ let mut _42: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+28:5: +28:6
+ let mut _46: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+32:28: +32:29
+ let mut _48: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+33:25: +33:26
+ scope 1 {
+ debug y => _1; // in scope 1 at $DIR/address-of.rs:+1:9: +1:10
+ let mut _3: &mut [i32; 10]; // in scope 1 at $DIR/address-of.rs:+2:9: +2:14
+ scope 2 {
+ debug z => _3; // in scope 2 at $DIR/address-of.rs:+2:9: +2:14
+ let _15: *const [i32; 10] as UserTypeProjection { base: UserType(2), projs: [] }; // in scope 2 at $DIR/address-of.rs:+10:9: +10:10
+ scope 3 {
+ debug p => _15; // in scope 3 at $DIR/address-of.rs:+10:9: +10:10
+ let _16: *const [i32; 10] as UserTypeProjection { base: UserType(4), projs: [] }; // in scope 3 at $DIR/address-of.rs:+11:9: +11:10
+ scope 4 {
+ debug p => _16; // in scope 4 at $DIR/address-of.rs:+11:9: +11:10
+ let _17: *const dyn std::marker::Send as UserTypeProjection { base: UserType(6), projs: [] }; // in scope 4 at $DIR/address-of.rs:+12:9: +12:10
+ scope 5 {
+ debug p => _17; // in scope 5 at $DIR/address-of.rs:+12:9: +12:10
+ let _19: *const [i32] as UserTypeProjection { base: UserType(8), projs: [] }; // in scope 5 at $DIR/address-of.rs:+13:9: +13:10
+ scope 6 {
+ debug p => _19; // in scope 6 at $DIR/address-of.rs:+13:9: +13:10
+ let _29: *const [i32; 10] as UserTypeProjection { base: UserType(12), projs: [] }; // in scope 6 at $DIR/address-of.rs:+20:9: +20:10
+ scope 7 {
+ debug p => _29; // in scope 7 at $DIR/address-of.rs:+20:9: +20:10
+ let _30: *const [i32; 10] as UserTypeProjection { base: UserType(14), projs: [] }; // in scope 7 at $DIR/address-of.rs:+21:9: +21:10
+ scope 8 {
+ debug p => _30; // in scope 8 at $DIR/address-of.rs:+21:9: +21:10
+ let _31: *const dyn std::marker::Send as UserTypeProjection { base: UserType(16), projs: [] }; // in scope 8 at $DIR/address-of.rs:+22:9: +22:10
+ scope 9 {
+ debug p => _31; // in scope 9 at $DIR/address-of.rs:+22:9: +22:10
+ let _33: *const [i32] as UserTypeProjection { base: UserType(18), projs: [] }; // in scope 9 at $DIR/address-of.rs:+23:9: +23:10
+ scope 10 {
+ debug p => _33; // in scope 10 at $DIR/address-of.rs:+23:9: +23:10
+ let _43: *mut [i32; 10] as UserTypeProjection { base: UserType(22), projs: [] }; // in scope 10 at $DIR/address-of.rs:+30:9: +30:10
+ scope 11 {
+ debug p => _43; // in scope 11 at $DIR/address-of.rs:+30:9: +30:10
+ let _44: *mut [i32; 10] as UserTypeProjection { base: UserType(24), projs: [] }; // in scope 11 at $DIR/address-of.rs:+31:9: +31:10
+ scope 12 {
+ debug p => _44; // in scope 12 at $DIR/address-of.rs:+31:9: +31:10
+ let _45: *mut dyn std::marker::Send as UserTypeProjection { base: UserType(26), projs: [] }; // in scope 12 at $DIR/address-of.rs:+32:9: +32:10
+ scope 13 {
+ debug p => _45; // in scope 13 at $DIR/address-of.rs:+32:9: +32:10
+ let _47: *mut [i32] as UserTypeProjection { base: UserType(28), projs: [] }; // in scope 13 at $DIR/address-of.rs:+33:9: +33:10
+ scope 14 {
+ debug p => _47; // in scope 14 at $DIR/address-of.rs:+33:9: +33:10
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/address-of.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/address-of.rs:+1:14: +1:21
+ _2 = [const 0_i32; 10]; // scope 0 at $DIR/address-of.rs:+1:14: +1:21
+ _1 = &_2; // scope 0 at $DIR/address-of.rs:+1:13: +1:21
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/address-of.rs:+1:9: +1:10
+ StorageLive(_3); // scope 1 at $DIR/address-of.rs:+2:9: +2:14
+ StorageLive(_4); // scope 1 at $DIR/address-of.rs:+2:22: +2:29
+ _4 = [const 0_i32; 10]; // scope 1 at $DIR/address-of.rs:+2:22: +2:29
+ _3 = &mut _4; // scope 1 at $DIR/address-of.rs:+2:17: +2:29
+ FakeRead(ForLet(None), _3); // scope 1 at $DIR/address-of.rs:+2:9: +2:14
+ StorageLive(_5); // scope 2 at $DIR/address-of.rs:+4:5: +4:18
+ StorageLive(_6); // scope 2 at $DIR/address-of.rs:+4:5: +4:18
+ _6 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+4:5: +4:6
+ AscribeUserType(_6, o, UserTypeProjection { base: UserType(0), projs: [] }); // scope 2 at $DIR/address-of.rs:+4:5: +4:18
+ _5 = _6; // scope 2 at $DIR/address-of.rs:+4:5: +4:18
+ StorageDead(_6); // scope 2 at $DIR/address-of.rs:+4:18: +4:19
+ StorageDead(_5); // scope 2 at $DIR/address-of.rs:+4:18: +4:19
+ StorageLive(_7); // scope 2 at $DIR/address-of.rs:+5:5: +5:26
+ _7 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+5:5: +5:6
+ StorageDead(_7); // scope 2 at $DIR/address-of.rs:+5:26: +5:27
+ StorageLive(_8); // scope 2 at $DIR/address-of.rs:+6:5: +6:25
+ StorageLive(_9); // scope 2 at $DIR/address-of.rs:+6:5: +6:25
+ StorageLive(_10); // scope 2 at $DIR/address-of.rs:+6:5: +6:6
+ _10 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+6:5: +6:6
+ _9 = move _10 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 2 at $DIR/address-of.rs:+6:5: +6:6
+ StorageDead(_10); // scope 2 at $DIR/address-of.rs:+6:5: +6:6
+ AscribeUserType(_9, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/address-of.rs:+6:5: +6:25
+ _8 = _9; // scope 2 at $DIR/address-of.rs:+6:5: +6:25
+ StorageDead(_9); // scope 2 at $DIR/address-of.rs:+6:25: +6:26
+ StorageDead(_8); // scope 2 at $DIR/address-of.rs:+6:25: +6:26
+ StorageLive(_11); // scope 2 at $DIR/address-of.rs:+7:5: +7:22
+ StorageLive(_12); // scope 2 at $DIR/address-of.rs:+7:5: +7:6
+ _12 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+7:5: +7:6
+ _11 = move _12 as *const [i32] (Pointer(Unsize)); // scope 2 at $DIR/address-of.rs:+7:5: +7:6
+ StorageDead(_12); // scope 2 at $DIR/address-of.rs:+7:5: +7:6
+ StorageDead(_11); // scope 2 at $DIR/address-of.rs:+7:22: +7:23
+ StorageLive(_13); // scope 2 at $DIR/address-of.rs:+8:5: +8:20
+ StorageLive(_14); // scope 2 at $DIR/address-of.rs:+8:5: +8:6
+ _14 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+8:5: +8:6
+ _13 = move _14 as *const i32 (Pointer(ArrayToPointer)); // scope 2 at $DIR/address-of.rs:+8:5: +8:20
+ StorageDead(_14); // scope 2 at $DIR/address-of.rs:+8:19: +8:20
+ StorageDead(_13); // scope 2 at $DIR/address-of.rs:+8:20: +8:21
+ StorageLive(_15); // scope 2 at $DIR/address-of.rs:+10:9: +10:10
+ _15 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+10:23: +10:24
+ FakeRead(ForLet(None), _15); // scope 2 at $DIR/address-of.rs:+10:9: +10:10
+ AscribeUserType(_15, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 2 at $DIR/address-of.rs:+10:12: +10:20
+ StorageLive(_16); // scope 3 at $DIR/address-of.rs:+11:9: +11:10
+ _16 = &raw const (*_1); // scope 3 at $DIR/address-of.rs:+11:31: +11:32
+ FakeRead(ForLet(None), _16); // scope 3 at $DIR/address-of.rs:+11:9: +11:10
+ AscribeUserType(_16, o, UserTypeProjection { base: UserType(5), projs: [] }); // scope 3 at $DIR/address-of.rs:+11:12: +11:28
+ StorageLive(_17); // scope 4 at $DIR/address-of.rs:+12:9: +12:10
+ StorageLive(_18); // scope 4 at $DIR/address-of.rs:+12:30: +12:31
+ _18 = &raw const (*_1); // scope 4 at $DIR/address-of.rs:+12:30: +12:31
+ _17 = move _18 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 4 at $DIR/address-of.rs:+12:30: +12:31
+ StorageDead(_18); // scope 4 at $DIR/address-of.rs:+12:30: +12:31
+ FakeRead(ForLet(None), _17); // scope 4 at $DIR/address-of.rs:+12:9: +12:10
+ AscribeUserType(_17, o, UserTypeProjection { base: UserType(7), projs: [] }); // scope 4 at $DIR/address-of.rs:+12:12: +12:27
+ StorageLive(_19); // scope 5 at $DIR/address-of.rs:+13:9: +13:10
+ StorageLive(_20); // scope 5 at $DIR/address-of.rs:+13:27: +13:28
+ _20 = &raw const (*_1); // scope 5 at $DIR/address-of.rs:+13:27: +13:28
+ _19 = move _20 as *const [i32] (Pointer(Unsize)); // scope 5 at $DIR/address-of.rs:+13:27: +13:28
+ StorageDead(_20); // scope 5 at $DIR/address-of.rs:+13:27: +13:28
+ FakeRead(ForLet(None), _19); // scope 5 at $DIR/address-of.rs:+13:9: +13:10
+ AscribeUserType(_19, o, UserTypeProjection { base: UserType(9), projs: [] }); // scope 5 at $DIR/address-of.rs:+13:12: +13:24
+ StorageLive(_21); // scope 6 at $DIR/address-of.rs:+15:5: +15:18
+ StorageLive(_22); // scope 6 at $DIR/address-of.rs:+15:5: +15:18
+ _22 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+15:5: +15:6
+ AscribeUserType(_22, o, UserTypeProjection { base: UserType(10), projs: [] }); // scope 6 at $DIR/address-of.rs:+15:5: +15:18
+ _21 = _22; // scope 6 at $DIR/address-of.rs:+15:5: +15:18
+ StorageDead(_22); // scope 6 at $DIR/address-of.rs:+15:18: +15:19
+ StorageDead(_21); // scope 6 at $DIR/address-of.rs:+15:18: +15:19
+ StorageLive(_23); // scope 6 at $DIR/address-of.rs:+16:5: +16:26
+ _23 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+16:5: +16:6
+ StorageDead(_23); // scope 6 at $DIR/address-of.rs:+16:26: +16:27
+ StorageLive(_24); // scope 6 at $DIR/address-of.rs:+17:5: +17:25
+ StorageLive(_25); // scope 6 at $DIR/address-of.rs:+17:5: +17:25
+ StorageLive(_26); // scope 6 at $DIR/address-of.rs:+17:5: +17:6
+ _26 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+17:5: +17:6
+ _25 = move _26 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 6 at $DIR/address-of.rs:+17:5: +17:6
+ StorageDead(_26); // scope 6 at $DIR/address-of.rs:+17:5: +17:6
+ AscribeUserType(_25, o, UserTypeProjection { base: UserType(11), projs: [] }); // scope 6 at $DIR/address-of.rs:+17:5: +17:25
+ _24 = _25; // scope 6 at $DIR/address-of.rs:+17:5: +17:25
+ StorageDead(_25); // scope 6 at $DIR/address-of.rs:+17:25: +17:26
+ StorageDead(_24); // scope 6 at $DIR/address-of.rs:+17:25: +17:26
+ StorageLive(_27); // scope 6 at $DIR/address-of.rs:+18:5: +18:22
+ StorageLive(_28); // scope 6 at $DIR/address-of.rs:+18:5: +18:6
+ _28 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+18:5: +18:6
+ _27 = move _28 as *const [i32] (Pointer(Unsize)); // scope 6 at $DIR/address-of.rs:+18:5: +18:6
+ StorageDead(_28); // scope 6 at $DIR/address-of.rs:+18:5: +18:6
+ StorageDead(_27); // scope 6 at $DIR/address-of.rs:+18:22: +18:23
+ StorageLive(_29); // scope 6 at $DIR/address-of.rs:+20:9: +20:10
+ _29 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+20:23: +20:24
+ FakeRead(ForLet(None), _29); // scope 6 at $DIR/address-of.rs:+20:9: +20:10
+ AscribeUserType(_29, o, UserTypeProjection { base: UserType(13), projs: [] }); // scope 6 at $DIR/address-of.rs:+20:12: +20:20
+ StorageLive(_30); // scope 7 at $DIR/address-of.rs:+21:9: +21:10
+ _30 = &raw const (*_3); // scope 7 at $DIR/address-of.rs:+21:31: +21:32
+ FakeRead(ForLet(None), _30); // scope 7 at $DIR/address-of.rs:+21:9: +21:10
+ AscribeUserType(_30, o, UserTypeProjection { base: UserType(15), projs: [] }); // scope 7 at $DIR/address-of.rs:+21:12: +21:28
+ StorageLive(_31); // scope 8 at $DIR/address-of.rs:+22:9: +22:10
+ StorageLive(_32); // scope 8 at $DIR/address-of.rs:+22:30: +22:31
+ _32 = &raw const (*_3); // scope 8 at $DIR/address-of.rs:+22:30: +22:31
+ _31 = move _32 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 8 at $DIR/address-of.rs:+22:30: +22:31
+ StorageDead(_32); // scope 8 at $DIR/address-of.rs:+22:30: +22:31
+ FakeRead(ForLet(None), _31); // scope 8 at $DIR/address-of.rs:+22:9: +22:10
+ AscribeUserType(_31, o, UserTypeProjection { base: UserType(17), projs: [] }); // scope 8 at $DIR/address-of.rs:+22:12: +22:27
+ StorageLive(_33); // scope 9 at $DIR/address-of.rs:+23:9: +23:10
+ StorageLive(_34); // scope 9 at $DIR/address-of.rs:+23:27: +23:28
+ _34 = &raw const (*_3); // scope 9 at $DIR/address-of.rs:+23:27: +23:28
+ _33 = move _34 as *const [i32] (Pointer(Unsize)); // scope 9 at $DIR/address-of.rs:+23:27: +23:28
+ StorageDead(_34); // scope 9 at $DIR/address-of.rs:+23:27: +23:28
+ FakeRead(ForLet(None), _33); // scope 9 at $DIR/address-of.rs:+23:9: +23:10
+ AscribeUserType(_33, o, UserTypeProjection { base: UserType(19), projs: [] }); // scope 9 at $DIR/address-of.rs:+23:12: +23:24
+ StorageLive(_35); // scope 10 at $DIR/address-of.rs:+25:5: +25:16
+ StorageLive(_36); // scope 10 at $DIR/address-of.rs:+25:5: +25:16
+ _36 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+25:5: +25:6
+ AscribeUserType(_36, o, UserTypeProjection { base: UserType(20), projs: [] }); // scope 10 at $DIR/address-of.rs:+25:5: +25:16
+ _35 = _36; // scope 10 at $DIR/address-of.rs:+25:5: +25:16
+ StorageDead(_36); // scope 10 at $DIR/address-of.rs:+25:16: +25:17
+ StorageDead(_35); // scope 10 at $DIR/address-of.rs:+25:16: +25:17
+ StorageLive(_37); // scope 10 at $DIR/address-of.rs:+26:5: +26:24
+ _37 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+26:5: +26:6
+ StorageDead(_37); // scope 10 at $DIR/address-of.rs:+26:24: +26:25
+ StorageLive(_38); // scope 10 at $DIR/address-of.rs:+27:5: +27:23
+ StorageLive(_39); // scope 10 at $DIR/address-of.rs:+27:5: +27:23
+ StorageLive(_40); // scope 10 at $DIR/address-of.rs:+27:5: +27:6
+ _40 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+27:5: +27:6
+ _39 = move _40 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 10 at $DIR/address-of.rs:+27:5: +27:6
+ StorageDead(_40); // scope 10 at $DIR/address-of.rs:+27:5: +27:6
+ AscribeUserType(_39, o, UserTypeProjection { base: UserType(21), projs: [] }); // scope 10 at $DIR/address-of.rs:+27:5: +27:23
+ _38 = _39; // scope 10 at $DIR/address-of.rs:+27:5: +27:23
+ StorageDead(_39); // scope 10 at $DIR/address-of.rs:+27:23: +27:24
+ StorageDead(_38); // scope 10 at $DIR/address-of.rs:+27:23: +27:24
+ StorageLive(_41); // scope 10 at $DIR/address-of.rs:+28:5: +28:20
+ StorageLive(_42); // scope 10 at $DIR/address-of.rs:+28:5: +28:6
+ _42 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+28:5: +28:6
+ _41 = move _42 as *mut [i32] (Pointer(Unsize)); // scope 10 at $DIR/address-of.rs:+28:5: +28:6
+ StorageDead(_42); // scope 10 at $DIR/address-of.rs:+28:5: +28:6
+ StorageDead(_41); // scope 10 at $DIR/address-of.rs:+28:20: +28:21
+ StorageLive(_43); // scope 10 at $DIR/address-of.rs:+30:9: +30:10
+ _43 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+30:21: +30:22
+ FakeRead(ForLet(None), _43); // scope 10 at $DIR/address-of.rs:+30:9: +30:10
+ AscribeUserType(_43, o, UserTypeProjection { base: UserType(23), projs: [] }); // scope 10 at $DIR/address-of.rs:+30:12: +30:18
+ StorageLive(_44); // scope 11 at $DIR/address-of.rs:+31:9: +31:10
+ _44 = &raw mut (*_3); // scope 11 at $DIR/address-of.rs:+31:29: +31:30
+ FakeRead(ForLet(None), _44); // scope 11 at $DIR/address-of.rs:+31:9: +31:10
+ AscribeUserType(_44, o, UserTypeProjection { base: UserType(25), projs: [] }); // scope 11 at $DIR/address-of.rs:+31:12: +31:26
+ StorageLive(_45); // scope 12 at $DIR/address-of.rs:+32:9: +32:10
+ StorageLive(_46); // scope 12 at $DIR/address-of.rs:+32:28: +32:29
+ _46 = &raw mut (*_3); // scope 12 at $DIR/address-of.rs:+32:28: +32:29
+ _45 = move _46 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 12 at $DIR/address-of.rs:+32:28: +32:29
+ StorageDead(_46); // scope 12 at $DIR/address-of.rs:+32:28: +32:29
+ FakeRead(ForLet(None), _45); // scope 12 at $DIR/address-of.rs:+32:9: +32:10
+ AscribeUserType(_45, o, UserTypeProjection { base: UserType(27), projs: [] }); // scope 12 at $DIR/address-of.rs:+32:12: +32:25
+ StorageLive(_47); // scope 13 at $DIR/address-of.rs:+33:9: +33:10
+ StorageLive(_48); // scope 13 at $DIR/address-of.rs:+33:25: +33:26
+ _48 = &raw mut (*_3); // scope 13 at $DIR/address-of.rs:+33:25: +33:26
+ _47 = move _48 as *mut [i32] (Pointer(Unsize)); // scope 13 at $DIR/address-of.rs:+33:25: +33:26
+ StorageDead(_48); // scope 13 at $DIR/address-of.rs:+33:25: +33:26
+ FakeRead(ForLet(None), _47); // scope 13 at $DIR/address-of.rs:+33:9: +33:10
+ AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] }); // scope 13 at $DIR/address-of.rs:+33:12: +33:22
+ _0 = const (); // scope 0 at $DIR/address-of.rs:+0:26: +34:2
+ StorageDead(_47); // scope 13 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_45); // scope 12 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_44); // scope 11 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_43); // scope 10 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_33); // scope 9 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_31); // scope 8 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_30); // scope 7 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_29); // scope 6 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_19); // scope 5 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_17); // scope 4 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_16); // scope 3 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_15); // scope 2 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_4); // scope 1 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_3); // scope 1 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_2); // scope 0 at $DIR/address-of.rs:+34:1: +34:2
+ StorageDead(_1); // scope 0 at $DIR/address-of.rs:+34:1: +34:2
+ return; // scope 0 at $DIR/address-of.rs:+34:2: +34:2
+ }
+}
diff --git a/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir
new file mode 100644
index 000000000..060077b8a
--- /dev/null
+++ b/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir
@@ -0,0 +1,47 @@
+// MIR for `borrow_and_cast` after SimplifyCfg-initial
+
+fn borrow_and_cast(_1: i32) -> () {
+ debug x => _1; // in scope 0 at $DIR/address-of.rs:+0:20: +0:25
+ let mut _0: (); // return place in scope 0 at $DIR/address-of.rs:+0:32: +0:32
+ let _2: *const i32; // in scope 0 at $DIR/address-of.rs:+1:9: +1:10
+ let _3: &i32; // in scope 0 at $DIR/address-of.rs:+1:13: +1:15
+ let _5: &mut i32; // in scope 0 at $DIR/address-of.rs:+2:13: +2:19
+ let mut _7: &mut i32; // in scope 0 at $DIR/address-of.rs:+3:13: +3:19
+ scope 1 {
+ debug p => _2; // in scope 1 at $DIR/address-of.rs:+1:9: +1:10
+ let _4: *const i32; // in scope 1 at $DIR/address-of.rs:+2:9: +2:10
+ scope 2 {
+ debug q => _4; // in scope 2 at $DIR/address-of.rs:+2:9: +2:10
+ let _6: *mut i32; // in scope 2 at $DIR/address-of.rs:+3:9: +3:10
+ scope 3 {
+ debug r => _6; // in scope 3 at $DIR/address-of.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/address-of.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/address-of.rs:+1:13: +1:15
+ _3 = &_1; // scope 0 at $DIR/address-of.rs:+1:13: +1:15
+ _2 = &raw const (*_3); // scope 0 at $DIR/address-of.rs:+1:13: +1:15
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/address-of.rs:+1:9: +1:10
+ StorageDead(_3); // scope 0 at $DIR/address-of.rs:+1:29: +1:30
+ StorageLive(_4); // scope 1 at $DIR/address-of.rs:+2:9: +2:10
+ StorageLive(_5); // scope 1 at $DIR/address-of.rs:+2:13: +2:19
+ _5 = &mut _1; // scope 1 at $DIR/address-of.rs:+2:13: +2:19
+ _4 = &raw const (*_5); // scope 1 at $DIR/address-of.rs:+2:13: +2:19
+ FakeRead(ForLet(None), _4); // scope 1 at $DIR/address-of.rs:+2:9: +2:10
+ StorageDead(_5); // scope 1 at $DIR/address-of.rs:+2:33: +2:34
+ StorageLive(_6); // scope 2 at $DIR/address-of.rs:+3:9: +3:10
+ StorageLive(_7); // scope 2 at $DIR/address-of.rs:+3:13: +3:19
+ _7 = &mut _1; // scope 2 at $DIR/address-of.rs:+3:13: +3:19
+ _6 = &raw mut (*_7); // scope 2 at $DIR/address-of.rs:+3:13: +3:19
+ FakeRead(ForLet(None), _6); // scope 2 at $DIR/address-of.rs:+3:9: +3:10
+ StorageDead(_7); // scope 2 at $DIR/address-of.rs:+3:31: +3:32
+ _0 = const (); // scope 0 at $DIR/address-of.rs:+0:32: +4:2
+ StorageDead(_6); // scope 2 at $DIR/address-of.rs:+4:1: +4:2
+ StorageDead(_4); // scope 1 at $DIR/address-of.rs:+4:1: +4:2
+ StorageDead(_2); // scope 0 at $DIR/address-of.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/address-of.rs:+4:2: +4:2
+ }
+}
diff --git a/src/test/mir-opt/array-index-is-temporary.rs b/src/test/mir-opt/array-index-is-temporary.rs
new file mode 100644
index 000000000..0e4c486e4
--- /dev/null
+++ b/src/test/mir-opt/array-index-is-temporary.rs
@@ -0,0 +1,17 @@
+// Retagging (from Stacked Borrows) relies on the array index being a fresh
+// temporary, so that side-effects cannot change it.
+// Test that this is indeed the case.
+
+unsafe fn foo(z: *mut usize) -> u32 {
+ *z = 2;
+ 99
+}
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
+fn main() {
+ let mut x = [42, 43, 44];
+ let mut y = 1;
+ let z: *mut usize = &mut y;
+ x[y] = unsafe { foo(z) };
+}
diff --git a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir
new file mode 100644
index 000000000..27f883ed3
--- /dev/null
+++ b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir
@@ -0,0 +1,64 @@
+// MIR for `main` after SimplifyCfg-elaborate-drops
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +0:11
+ let mut _1: [u32; 3]; // in scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
+ let mut _4: &mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
+ let mut _5: u32; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:12: +4:29
+ let mut _6: *mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
+ let _7: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
+ let mut _8: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
+ let mut _9: bool; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
+ let mut _2: usize; // in scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
+ let _3: *mut usize; // in scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _3; // in scope 3 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
+ scope 4 {
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
+ _1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array-index-is-temporary.rs:+1:17: +1:29
+ StorageLive(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
+ _2 = const 1_usize; // scope 1 at $DIR/array-index-is-temporary.rs:+2:17: +2:18
+ StorageLive(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
+ StorageLive(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
+ _4 = &mut _2; // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
+ _3 = &raw mut (*_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
+ StorageDead(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:31: +3:32
+ StorageLive(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:12: +4:29
+ StorageLive(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
+ _6 = _3; // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
+ _5 = foo(move _6) -> bb1; // scope 4 at $DIR/array-index-is-temporary.rs:+4:21: +4:27
+ // mir::Constant
+ // + span: $DIR/array-index-is-temporary.rs:16:21: 16:24
+ // + literal: Const { ty: unsafe fn(*mut usize) -> u32 {foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:26: +4:27
+ StorageLive(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
+ _7 = _2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
+ _8 = Len(_1); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
+ _9 = Lt(_7, _8); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
+ }
+
+ bb2: {
+ _1[_7] = move _5; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:29
+ StorageDead(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:28: +4:29
+ StorageDead(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:29: +4:30
+ _0 = const (); // scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +5:2
+ StorageDead(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
+ StorageDead(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/array-index-is-temporary.rs:+5:2: +5:2
+ }
+}
diff --git a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir
new file mode 100644
index 000000000..27f883ed3
--- /dev/null
+++ b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir
@@ -0,0 +1,64 @@
+// MIR for `main` after SimplifyCfg-elaborate-drops
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +0:11
+ let mut _1: [u32; 3]; // in scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
+ let mut _4: &mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
+ let mut _5: u32; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:12: +4:29
+ let mut _6: *mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
+ let _7: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
+ let mut _8: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
+ let mut _9: bool; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
+ let mut _2: usize; // in scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
+ let _3: *mut usize; // in scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _3; // in scope 3 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
+ scope 4 {
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
+ _1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array-index-is-temporary.rs:+1:17: +1:29
+ StorageLive(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
+ _2 = const 1_usize; // scope 1 at $DIR/array-index-is-temporary.rs:+2:17: +2:18
+ StorageLive(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
+ StorageLive(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
+ _4 = &mut _2; // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
+ _3 = &raw mut (*_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
+ StorageDead(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:31: +3:32
+ StorageLive(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:12: +4:29
+ StorageLive(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
+ _6 = _3; // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
+ _5 = foo(move _6) -> bb1; // scope 4 at $DIR/array-index-is-temporary.rs:+4:21: +4:27
+ // mir::Constant
+ // + span: $DIR/array-index-is-temporary.rs:16:21: 16:24
+ // + literal: Const { ty: unsafe fn(*mut usize) -> u32 {foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:26: +4:27
+ StorageLive(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
+ _7 = _2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
+ _8 = Len(_1); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
+ _9 = Lt(_7, _8); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
+ }
+
+ bb2: {
+ _1[_7] = move _5; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:29
+ StorageDead(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:28: +4:29
+ StorageDead(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:29: +4:30
+ _0 = const (); // scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +5:2
+ StorageDead(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
+ StorageDead(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/array-index-is-temporary.rs:+5:2: +5:2
+ }
+}
diff --git a/src/test/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir b/src/test/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
new file mode 100644
index 000000000..2487ef5c2
--- /dev/null
+++ b/src/test/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
@@ -0,0 +1,24 @@
+// MIR for `main` after AbortUnwindingCalls
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/asm_unwind_panic_abort.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/asm_unwind_panic_abort.rs:+2:9: +2:49
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 1 at $DIR/asm_unwind_panic_abort.rs:+2:9: +2:49
+ _1 = const (); // scope 1 at $DIR/asm_unwind_panic_abort.rs:+2:9: +2:49
+ asm!("", options(MAY_UNWIND)) -> [return: bb1, unwind: bb2]; // scope 1 at $DIR/asm_unwind_panic_abort.rs:+2:9: +2:49
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 1 at $DIR/asm_unwind_panic_abort.rs:+2:48: +2:49
+ _0 = const (); // scope 1 at $DIR/asm_unwind_panic_abort.rs:+1:5: +3:6
+ return; // scope 0 at $DIR/asm_unwind_panic_abort.rs:+4:2: +4:2
+ }
+
+ bb2 (cleanup): {
+ abort; // scope 0 at $DIR/asm_unwind_panic_abort.rs:+0:1: +4:2
+ }
+}
diff --git a/src/test/mir-opt/asm_unwind_panic_abort.rs b/src/test/mir-opt/asm_unwind_panic_abort.rs
new file mode 100644
index 000000000..8201d5434
--- /dev/null
+++ b/src/test/mir-opt/asm_unwind_panic_abort.rs
@@ -0,0 +1,16 @@
+//! Tests that unwinding from an asm block is caught and forced to abort
+//! when `-C panic=abort`.
+
+// min-llvm-version: 13.0.0
+// only-x86_64
+// compile-flags: -C panic=abort
+// no-prefer-dynamic
+
+#![feature(asm_unwind)]
+
+// EMIT_MIR asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
+fn main() {
+ unsafe {
+ std::arch::asm!("", options(may_unwind));
+ }
+}
diff --git a/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir
new file mode 100644
index 000000000..1f099cd5e
--- /dev/null
+++ b/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir
@@ -0,0 +1,84 @@
+// MIR for `main` after SimplifyCfg-initial
+
+| User Type Annotations
+| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<std::boxed::Box<u32>>) }, span: $DIR/basic_assignment.rs:18:17: 18:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
+| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<std::boxed::Box<u32>>) }, span: $DIR/basic_assignment.rs:18:17: 18:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
+|
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/basic_assignment.rs:+0:11: +0:11
+ let _1: bool; // in scope 0 at $DIR/basic_assignment.rs:+1:9: +1:17
+ let mut _3: bool; // in scope 0 at $DIR/basic_assignment.rs:+6:16: +6:24
+ let mut _6: std::option::Option<std::boxed::Box<u32>>; // in scope 0 at $DIR/basic_assignment.rs:+13:14: +13:20
+ scope 1 {
+ debug nodrop_x => _1; // in scope 1 at $DIR/basic_assignment.rs:+1:9: +1:17
+ let _2: bool; // in scope 1 at $DIR/basic_assignment.rs:+2:9: +2:17
+ scope 2 {
+ debug nodrop_y => _2; // in scope 2 at $DIR/basic_assignment.rs:+2:9: +2:17
+ let _4: std::option::Option<std::boxed::Box<u32>> as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 2 at $DIR/basic_assignment.rs:+8:9: +8:15
+ scope 3 {
+ debug drop_x => _4; // in scope 3 at $DIR/basic_assignment.rs:+8:9: +8:15
+ let _5: std::option::Option<std::boxed::Box<u32>>; // in scope 3 at $DIR/basic_assignment.rs:+9:9: +9:15
+ scope 4 {
+ debug drop_y => _5; // in scope 4 at $DIR/basic_assignment.rs:+9:9: +9:15
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/basic_assignment.rs:+1:9: +1:17
+ _1 = const false; // scope 0 at $DIR/basic_assignment.rs:+1:20: +1:25
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/basic_assignment.rs:+1:9: +1:17
+ StorageLive(_2); // scope 1 at $DIR/basic_assignment.rs:+2:9: +2:17
+ StorageLive(_3); // scope 2 at $DIR/basic_assignment.rs:+6:16: +6:24
+ _3 = _1; // scope 2 at $DIR/basic_assignment.rs:+6:16: +6:24
+ _2 = move _3; // scope 2 at $DIR/basic_assignment.rs:+6:5: +6:24
+ StorageDead(_3); // scope 2 at $DIR/basic_assignment.rs:+6:23: +6:24
+ StorageLive(_4); // scope 2 at $DIR/basic_assignment.rs:+8:9: +8:15
+ _4 = Option::<Box<u32>>::None; // scope 2 at $DIR/basic_assignment.rs:+8:36: +8:40
+ FakeRead(ForLet(None), _4); // scope 2 at $DIR/basic_assignment.rs:+8:9: +8:15
+ AscribeUserType(_4, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/basic_assignment.rs:+8:17: +8:33
+ StorageLive(_5); // scope 3 at $DIR/basic_assignment.rs:+9:9: +9:15
+ StorageLive(_6); // scope 4 at $DIR/basic_assignment.rs:+13:14: +13:20
+ _6 = move _4; // scope 4 at $DIR/basic_assignment.rs:+13:14: +13:20
+ replace(_5 <- move _6) -> [return: bb1, unwind: bb5]; // scope 4 at $DIR/basic_assignment.rs:+13:5: +13:11
+ }
+
+ bb1: {
+ drop(_6) -> [return: bb2, unwind: bb6]; // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20
+ }
+
+ bb2: {
+ StorageDead(_6); // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20
+ _0 = const (); // scope 0 at $DIR/basic_assignment.rs:+0:11: +14:2
+ drop(_5) -> [return: bb3, unwind: bb7]; // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2
+ }
+
+ bb3: {
+ StorageDead(_5); // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2
+ drop(_4) -> [return: bb4, unwind: bb8]; // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2
+ }
+
+ bb4: {
+ StorageDead(_4); // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2
+ StorageDead(_2); // scope 1 at $DIR/basic_assignment.rs:+14:1: +14:2
+ StorageDead(_1); // scope 0 at $DIR/basic_assignment.rs:+14:1: +14:2
+ return; // scope 0 at $DIR/basic_assignment.rs:+14:2: +14:2
+ }
+
+ bb5 (cleanup): {
+ drop(_6) -> bb6; // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20
+ }
+
+ bb6 (cleanup): {
+ drop(_5) -> bb7; // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2
+ }
+
+ bb7 (cleanup): {
+ drop(_4) -> bb8; // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2
+ }
+
+ bb8 (cleanup): {
+ resume; // scope 0 at $DIR/basic_assignment.rs:+0:1: +14:2
+ }
+}
diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs
new file mode 100644
index 000000000..ac350271e
--- /dev/null
+++ b/src/test/mir-opt/basic_assignment.rs
@@ -0,0 +1,24 @@
+// this tests move up progration, which is not yet implemented
+
+// EMIT_MIR basic_assignment.main.SimplifyCfg-initial.after.mir
+
+// Check codegen for assignments (`a = b`) where the left-hand-side is
+// not yet initialized. Assignments tend to be absent in simple code,
+// so subtle breakage in them can leave a quite hard-to-find trail of
+// destruction.
+
+fn main() {
+ let nodrop_x = false;
+ let nodrop_y;
+
+ // Since boolean does not require drop, this can be a simple
+ // assignment:
+ nodrop_y = nodrop_x;
+
+ let drop_x: Option<Box<u32>> = None;
+ let drop_y;
+
+ // Since the type of `drop_y` has drop, we generate a `replace`
+ // terminator:
+ drop_y = drop_x;
+}
diff --git a/src/test/mir-opt/bool_compare.opt1.InstCombine.diff b/src/test/mir-opt/bool_compare.opt1.InstCombine.diff
new file mode 100644
index 000000000..9c5a9fa9a
--- /dev/null
+++ b/src/test/mir-opt/bool_compare.opt1.InstCombine.diff
@@ -0,0 +1,35 @@
+- // MIR for `opt1` before InstCombine
++ // MIR for `opt1` after InstCombine
+
+ fn opt1(_1: bool) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/bool_compare.rs:+0:9: +0:10
+ let mut _0: u32; // return place in scope 0 at $DIR/bool_compare.rs:+0:21: +0:24
+ let mut _2: bool; // in scope 0 at $DIR/bool_compare.rs:+1:8: +1:17
+ let mut _3: bool; // in scope 0 at $DIR/bool_compare.rs:+1:8: +1:9
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17
+ StorageLive(_3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:9
+- _2 = Ne(move _3, const true); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17
++ _2 = Not(move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17
+ StorageDead(_3); // scope 0 at $DIR/bool_compare.rs:+1:16: +1:17
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17
+ }
+
+ bb1: {
+ _0 = const 0_u32; // scope 0 at $DIR/bool_compare.rs:+1:20: +1:21
+ goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:34
+ }
+
+ bb2: {
+ _0 = const 1_u32; // scope 0 at $DIR/bool_compare.rs:+1:31: +1:32
+ goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:34
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/bool_compare.rs:+1:33: +1:34
+ return; // scope 0 at $DIR/bool_compare.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/bool_compare.opt2.InstCombine.diff b/src/test/mir-opt/bool_compare.opt2.InstCombine.diff
new file mode 100644
index 000000000..58c52c4b7
--- /dev/null
+++ b/src/test/mir-opt/bool_compare.opt2.InstCombine.diff
@@ -0,0 +1,35 @@
+- // MIR for `opt2` before InstCombine
++ // MIR for `opt2` after InstCombine
+
+ fn opt2(_1: bool) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/bool_compare.rs:+0:9: +0:10
+ let mut _0: u32; // return place in scope 0 at $DIR/bool_compare.rs:+0:21: +0:24
+ let mut _2: bool; // in scope 0 at $DIR/bool_compare.rs:+1:8: +1:17
+ let mut _3: bool; // in scope 0 at $DIR/bool_compare.rs:+1:16: +1:17
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17
+ StorageLive(_3); // scope 0 at $DIR/bool_compare.rs:+1:16: +1:17
+ _3 = _1; // scope 0 at $DIR/bool_compare.rs:+1:16: +1:17
+- _2 = Ne(const true, move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17
++ _2 = Not(move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17
+ StorageDead(_3); // scope 0 at $DIR/bool_compare.rs:+1:16: +1:17
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17
+ }
+
+ bb1: {
+ _0 = const 0_u32; // scope 0 at $DIR/bool_compare.rs:+1:20: +1:21
+ goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:34
+ }
+
+ bb2: {
+ _0 = const 1_u32; // scope 0 at $DIR/bool_compare.rs:+1:31: +1:32
+ goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:34
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/bool_compare.rs:+1:33: +1:34
+ return; // scope 0 at $DIR/bool_compare.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/bool_compare.opt3.InstCombine.diff b/src/test/mir-opt/bool_compare.opt3.InstCombine.diff
new file mode 100644
index 000000000..676428c95
--- /dev/null
+++ b/src/test/mir-opt/bool_compare.opt3.InstCombine.diff
@@ -0,0 +1,35 @@
+- // MIR for `opt3` before InstCombine
++ // MIR for `opt3` after InstCombine
+
+ fn opt3(_1: bool) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/bool_compare.rs:+0:9: +0:10
+ let mut _0: u32; // return place in scope 0 at $DIR/bool_compare.rs:+0:21: +0:24
+ let mut _2: bool; // in scope 0 at $DIR/bool_compare.rs:+1:8: +1:18
+ let mut _3: bool; // in scope 0 at $DIR/bool_compare.rs:+1:8: +1:9
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18
+ StorageLive(_3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:9
+- _2 = Eq(move _3, const false); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18
++ _2 = Not(move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18
+ StorageDead(_3); // scope 0 at $DIR/bool_compare.rs:+1:17: +1:18
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18
+ }
+
+ bb1: {
+ _0 = const 0_u32; // scope 0 at $DIR/bool_compare.rs:+1:21: +1:22
+ goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:35
+ }
+
+ bb2: {
+ _0 = const 1_u32; // scope 0 at $DIR/bool_compare.rs:+1:32: +1:33
+ goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:35
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/bool_compare.rs:+1:34: +1:35
+ return; // scope 0 at $DIR/bool_compare.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/bool_compare.opt4.InstCombine.diff b/src/test/mir-opt/bool_compare.opt4.InstCombine.diff
new file mode 100644
index 000000000..addfcd769
--- /dev/null
+++ b/src/test/mir-opt/bool_compare.opt4.InstCombine.diff
@@ -0,0 +1,35 @@
+- // MIR for `opt4` before InstCombine
++ // MIR for `opt4` after InstCombine
+
+ fn opt4(_1: bool) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/bool_compare.rs:+0:9: +0:10
+ let mut _0: u32; // return place in scope 0 at $DIR/bool_compare.rs:+0:21: +0:24
+ let mut _2: bool; // in scope 0 at $DIR/bool_compare.rs:+1:8: +1:18
+ let mut _3: bool; // in scope 0 at $DIR/bool_compare.rs:+1:17: +1:18
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18
+ StorageLive(_3); // scope 0 at $DIR/bool_compare.rs:+1:17: +1:18
+ _3 = _1; // scope 0 at $DIR/bool_compare.rs:+1:17: +1:18
+- _2 = Eq(const false, move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18
++ _2 = Not(move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18
+ StorageDead(_3); // scope 0 at $DIR/bool_compare.rs:+1:17: +1:18
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18
+ }
+
+ bb1: {
+ _0 = const 0_u32; // scope 0 at $DIR/bool_compare.rs:+1:21: +1:22
+ goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:35
+ }
+
+ bb2: {
+ _0 = const 1_u32; // scope 0 at $DIR/bool_compare.rs:+1:32: +1:33
+ goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:35
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/bool_compare.rs:+1:34: +1:35
+ return; // scope 0 at $DIR/bool_compare.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/bool_compare.rs b/src/test/mir-opt/bool_compare.rs
new file mode 100644
index 000000000..3ff046325
--- /dev/null
+++ b/src/test/mir-opt/bool_compare.rs
@@ -0,0 +1,26 @@
+// EMIT_MIR bool_compare.opt1.InstCombine.diff
+fn opt1(x: bool) -> u32 {
+ if x != true { 0 } else { 1 }
+}
+
+// EMIT_MIR bool_compare.opt2.InstCombine.diff
+fn opt2(x: bool) -> u32 {
+ if true != x { 0 } else { 1 }
+}
+
+// EMIT_MIR bool_compare.opt3.InstCombine.diff
+fn opt3(x: bool) -> u32 {
+ if x == false { 0 } else { 1 }
+}
+
+// EMIT_MIR bool_compare.opt4.InstCombine.diff
+fn opt4(x: bool) -> u32 {
+ if false == x { 0 } else { 1 }
+}
+
+fn main() {
+ opt1(false);
+ opt2(false);
+ opt3(false);
+ opt4(false);
+}
diff --git a/src/test/mir-opt/box_expr.main.ElaborateDrops.before.mir b/src/test/mir-opt/box_expr.main.ElaborateDrops.before.mir
new file mode 100644
index 000000000..49133138d
--- /dev/null
+++ b/src/test/mir-opt/box_expr.main.ElaborateDrops.before.mir
@@ -0,0 +1,80 @@
+// MIR for `main` before ElaborateDrops
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/box_expr.rs:+0:11: +0:11
+ let _1: std::boxed::Box<S>; // in scope 0 at $DIR/box_expr.rs:+1:9: +1:10
+ let mut _2: usize; // in scope 0 at $DIR/box_expr.rs:+1:13: +1:25
+ let mut _3: usize; // in scope 0 at $DIR/box_expr.rs:+1:13: +1:25
+ let mut _4: *mut u8; // in scope 0 at $DIR/box_expr.rs:+1:13: +1:25
+ let mut _5: std::boxed::Box<S>; // in scope 0 at $DIR/box_expr.rs:+1:13: +1:25
+ let _6: (); // in scope 0 at $DIR/box_expr.rs:+2:5: +2:12
+ let mut _7: std::boxed::Box<S>; // in scope 0 at $DIR/box_expr.rs:+2:10: +2:11
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/box_expr.rs:+1:9: +1:10
+ }
+ scope 2 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/box_expr.rs:+1:9: +1:10
+ _2 = SizeOf(S); // scope 2 at $DIR/box_expr.rs:+1:13: +1:25
+ _3 = AlignOf(S); // scope 2 at $DIR/box_expr.rs:+1:13: +1:25
+ _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/box_expr.rs:+1:13: +1:25
+ // mir::Constant
+ // + span: $DIR/box_expr.rs:7:13: 7:25
+ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 0 at $DIR/box_expr.rs:+1:13: +1:25
+ _5 = ShallowInitBox(move _4, S); // scope 0 at $DIR/box_expr.rs:+1:13: +1:25
+ (*_5) = S::new() -> [return: bb2, unwind: bb8]; // scope 0 at $DIR/box_expr.rs:+1:17: +1:25
+ // mir::Constant
+ // + span: $DIR/box_expr.rs:7:17: 7:23
+ // + literal: Const { ty: fn() -> S {S::new}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ _1 = move _5; // scope 0 at $DIR/box_expr.rs:+1:13: +1:25
+ drop(_5) -> bb3; // scope 0 at $DIR/box_expr.rs:+1:24: +1:25
+ }
+
+ bb3: {
+ StorageDead(_5); // scope 0 at $DIR/box_expr.rs:+1:24: +1:25
+ StorageLive(_6); // scope 1 at $DIR/box_expr.rs:+2:5: +2:12
+ StorageLive(_7); // scope 1 at $DIR/box_expr.rs:+2:10: +2:11
+ _7 = move _1; // scope 1 at $DIR/box_expr.rs:+2:10: +2:11
+ _6 = std::mem::drop::<Box<S>>(move _7) -> [return: bb4, unwind: bb6]; // scope 1 at $DIR/box_expr.rs:+2:5: +2:12
+ // mir::Constant
+ // + span: $DIR/box_expr.rs:8:5: 8:9
+ // + literal: Const { ty: fn(Box<S>) {std::mem::drop::<Box<S>>}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ StorageDead(_7); // scope 1 at $DIR/box_expr.rs:+2:11: +2:12
+ StorageDead(_6); // scope 1 at $DIR/box_expr.rs:+2:12: +2:13
+ _0 = const (); // scope 0 at $DIR/box_expr.rs:+0:11: +3:2
+ drop(_1) -> bb5; // scope 0 at $DIR/box_expr.rs:+3:1: +3:2
+ }
+
+ bb5: {
+ StorageDead(_1); // scope 0 at $DIR/box_expr.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/box_expr.rs:+3:2: +3:2
+ }
+
+ bb6 (cleanup): {
+ drop(_7) -> bb7; // scope 1 at $DIR/box_expr.rs:+2:11: +2:12
+ }
+
+ bb7 (cleanup): {
+ drop(_1) -> bb9; // scope 0 at $DIR/box_expr.rs:+3:1: +3:2
+ }
+
+ bb8 (cleanup): {
+ drop(_5) -> bb9; // scope 0 at $DIR/box_expr.rs:+1:24: +1:25
+ }
+
+ bb9 (cleanup): {
+ resume; // scope 0 at $DIR/box_expr.rs:+0:1: +3:2
+ }
+}
diff --git a/src/test/mir-opt/box_expr.rs b/src/test/mir-opt/box_expr.rs
new file mode 100644
index 000000000..a214504f6
--- /dev/null
+++ b/src/test/mir-opt/box_expr.rs
@@ -0,0 +1,21 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+
+#![feature(box_syntax)]
+
+// EMIT_MIR box_expr.main.ElaborateDrops.before.mir
+fn main() {
+ let x = box S::new();
+ drop(x);
+}
+
+struct S;
+
+impl S {
+ fn new() -> Self { S }
+}
+
+impl Drop for S {
+ fn drop(&mut self) {
+ println!("splat!");
+ }
+}
diff --git a/src/test/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..73f5655a1
--- /dev/null
+++ b/src/test/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,31 @@
+// MIR for `main` after SimplifyCfg-elaborate-drops
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/byte_slice.rs:+0:11: +0:11
+ let _1: &[u8; 3]; // in scope 0 at $DIR/byte_slice.rs:+1:9: +1:10
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/byte_slice.rs:+1:9: +1:10
+ let _2: [u8; 2]; // in scope 1 at $DIR/byte_slice.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/byte_slice.rs:+2:9: +2:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/byte_slice.rs:+1:9: +1:10
+ _1 = const b"foo"; // scope 0 at $DIR/byte_slice.rs:+1:13: +1:19
+ // mir::Constant
+ // + span: $DIR/byte_slice.rs:5:13: 5:19
+ // + literal: Const { ty: &[u8; 3], val: Value(Scalar(alloc1)) }
+ StorageLive(_2); // scope 1 at $DIR/byte_slice.rs:+2:9: +2:10
+ _2 = [const 5_u8, const 120_u8]; // scope 1 at $DIR/byte_slice.rs:+2:13: +2:24
+ _0 = const (); // scope 0 at $DIR/byte_slice.rs:+0:11: +3:2
+ StorageDead(_2); // scope 1 at $DIR/byte_slice.rs:+3:1: +3:2
+ StorageDead(_1); // scope 0 at $DIR/byte_slice.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/byte_slice.rs:+3:2: +3:2
+ }
+}
+
+alloc1 (size: 3, align: 1) {
+ 66 6f 6f │ foo
+}
diff --git a/src/test/mir-opt/byte_slice.rs b/src/test/mir-opt/byte_slice.rs
new file mode 100644
index 000000000..48e9c48c1
--- /dev/null
+++ b/src/test/mir-opt/byte_slice.rs
@@ -0,0 +1,7 @@
+// compile-flags: -Z mir-opt-level=0
+
+// EMIT_MIR byte_slice.main.SimplifyCfg-elaborate-drops.after.mir
+fn main() {
+ let x = b"foo";
+ let y = [5u8, b'x'];
+}
diff --git a/src/test/mir-opt/combine_array_len.norm2.InstCombine.32bit.diff b/src/test/mir-opt/combine_array_len.norm2.InstCombine.32bit.diff
new file mode 100644
index 000000000..c73150f94
--- /dev/null
+++ b/src/test/mir-opt/combine_array_len.norm2.InstCombine.32bit.diff
@@ -0,0 +1,77 @@
+- // MIR for `norm2` before InstCombine
++ // MIR for `norm2` after InstCombine
+
+ fn norm2(_1: [f32; 2]) -> f32 {
+ debug x => _1; // in scope 0 at $DIR/combine_array_len.rs:+0:10: +0:11
+ let mut _0: f32; // return place in scope 0 at $DIR/combine_array_len.rs:+0:26: +0:29
+ let _2: f32; // in scope 0 at $DIR/combine_array_len.rs:+1:9: +1:10
+ let _3: usize; // in scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16
+ let mut _4: usize; // in scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
+ let mut _5: bool; // in scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
+ let _7: usize; // in scope 0 at $DIR/combine_array_len.rs:+2:15: +2:16
+ let mut _8: usize; // in scope 0 at $DIR/combine_array_len.rs:+2:13: +2:17
+ let mut _9: bool; // in scope 0 at $DIR/combine_array_len.rs:+2:13: +2:17
+ let mut _10: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:5: +3:8
+ let mut _11: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:5: +3:6
+ let mut _12: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:7: +3:8
+ let mut _13: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:11: +3:14
+ let mut _14: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:11: +3:12
+ let mut _15: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:13: +3:14
+ scope 1 {
+ debug a => _2; // in scope 1 at $DIR/combine_array_len.rs:+1:9: +1:10
+ let _6: f32; // in scope 1 at $DIR/combine_array_len.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _6; // in scope 2 at $DIR/combine_array_len.rs:+2:9: +2:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/combine_array_len.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16
+ _3 = const 0_usize; // scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16
+- _4 = Len(_1); // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
++ _4 = const 2_usize; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
+ _5 = Lt(_3, _4); // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
+ }
+
+ bb1: {
+ _2 = _1[_3]; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
+ StorageDead(_3); // scope 0 at $DIR/combine_array_len.rs:+1:17: +1:18
+ StorageLive(_6); // scope 1 at $DIR/combine_array_len.rs:+2:9: +2:10
+ StorageLive(_7); // scope 1 at $DIR/combine_array_len.rs:+2:15: +2:16
+ _7 = const 1_usize; // scope 1 at $DIR/combine_array_len.rs:+2:15: +2:16
+- _8 = Len(_1); // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
++ _8 = const 2_usize; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
+ _9 = Lt(_7, _8); // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
+ }
+
+ bb2: {
+ _6 = _1[_7]; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
+ StorageDead(_7); // scope 1 at $DIR/combine_array_len.rs:+2:17: +2:18
+ StorageLive(_10); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:8
+ StorageLive(_11); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:6
+ _11 = _2; // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:6
+ StorageLive(_12); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8
+ _12 = _2; // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8
+ _10 = Mul(move _11, move _12); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:8
+ StorageDead(_12); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8
+ StorageDead(_11); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8
+ StorageLive(_13); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:14
+ StorageLive(_14); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:12
+ _14 = _6; // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:12
+ StorageLive(_15); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
+ _15 = _6; // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
+ _13 = Mul(move _14, move _15); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:14
+ StorageDead(_15); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
+ StorageDead(_14); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
+ _0 = Add(move _10, move _13); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:14
+ StorageDead(_13); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
+ StorageDead(_10); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
+ StorageDead(_6); // scope 1 at $DIR/combine_array_len.rs:+4:1: +4:2
+ StorageDead(_2); // scope 0 at $DIR/combine_array_len.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/combine_array_len.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/combine_array_len.norm2.InstCombine.64bit.diff b/src/test/mir-opt/combine_array_len.norm2.InstCombine.64bit.diff
new file mode 100644
index 000000000..c73150f94
--- /dev/null
+++ b/src/test/mir-opt/combine_array_len.norm2.InstCombine.64bit.diff
@@ -0,0 +1,77 @@
+- // MIR for `norm2` before InstCombine
++ // MIR for `norm2` after InstCombine
+
+ fn norm2(_1: [f32; 2]) -> f32 {
+ debug x => _1; // in scope 0 at $DIR/combine_array_len.rs:+0:10: +0:11
+ let mut _0: f32; // return place in scope 0 at $DIR/combine_array_len.rs:+0:26: +0:29
+ let _2: f32; // in scope 0 at $DIR/combine_array_len.rs:+1:9: +1:10
+ let _3: usize; // in scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16
+ let mut _4: usize; // in scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
+ let mut _5: bool; // in scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
+ let _7: usize; // in scope 0 at $DIR/combine_array_len.rs:+2:15: +2:16
+ let mut _8: usize; // in scope 0 at $DIR/combine_array_len.rs:+2:13: +2:17
+ let mut _9: bool; // in scope 0 at $DIR/combine_array_len.rs:+2:13: +2:17
+ let mut _10: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:5: +3:8
+ let mut _11: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:5: +3:6
+ let mut _12: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:7: +3:8
+ let mut _13: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:11: +3:14
+ let mut _14: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:11: +3:12
+ let mut _15: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:13: +3:14
+ scope 1 {
+ debug a => _2; // in scope 1 at $DIR/combine_array_len.rs:+1:9: +1:10
+ let _6: f32; // in scope 1 at $DIR/combine_array_len.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _6; // in scope 2 at $DIR/combine_array_len.rs:+2:9: +2:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/combine_array_len.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16
+ _3 = const 0_usize; // scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16
+- _4 = Len(_1); // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
++ _4 = const 2_usize; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
+ _5 = Lt(_3, _4); // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
+ }
+
+ bb1: {
+ _2 = _1[_3]; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
+ StorageDead(_3); // scope 0 at $DIR/combine_array_len.rs:+1:17: +1:18
+ StorageLive(_6); // scope 1 at $DIR/combine_array_len.rs:+2:9: +2:10
+ StorageLive(_7); // scope 1 at $DIR/combine_array_len.rs:+2:15: +2:16
+ _7 = const 1_usize; // scope 1 at $DIR/combine_array_len.rs:+2:15: +2:16
+- _8 = Len(_1); // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
++ _8 = const 2_usize; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
+ _9 = Lt(_7, _8); // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
+ }
+
+ bb2: {
+ _6 = _1[_7]; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
+ StorageDead(_7); // scope 1 at $DIR/combine_array_len.rs:+2:17: +2:18
+ StorageLive(_10); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:8
+ StorageLive(_11); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:6
+ _11 = _2; // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:6
+ StorageLive(_12); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8
+ _12 = _2; // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8
+ _10 = Mul(move _11, move _12); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:8
+ StorageDead(_12); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8
+ StorageDead(_11); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8
+ StorageLive(_13); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:14
+ StorageLive(_14); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:12
+ _14 = _6; // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:12
+ StorageLive(_15); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
+ _15 = _6; // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
+ _13 = Mul(move _14, move _15); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:14
+ StorageDead(_15); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
+ StorageDead(_14); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
+ _0 = Add(move _10, move _13); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:14
+ StorageDead(_13); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
+ StorageDead(_10); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
+ StorageDead(_6); // scope 1 at $DIR/combine_array_len.rs:+4:1: +4:2
+ StorageDead(_2); // scope 0 at $DIR/combine_array_len.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/combine_array_len.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/combine_array_len.rs b/src/test/mir-opt/combine_array_len.rs
new file mode 100644
index 000000000..93490c14f
--- /dev/null
+++ b/src/test/mir-opt/combine_array_len.rs
@@ -0,0 +1,12 @@
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR combine_array_len.norm2.InstCombine.diff
+
+fn norm2(x: [f32; 2]) -> f32 {
+ let a = x[0];
+ let b = x[1];
+ a*a + b*b
+}
+
+fn main() {
+ assert_eq!(norm2([3.0, 4.0]), 5.0*5.0);
+}
diff --git a/src/test/mir-opt/combine_clone_of_primitives.rs b/src/test/mir-opt/combine_clone_of_primitives.rs
new file mode 100644
index 000000000..7cc50a86e
--- /dev/null
+++ b/src/test/mir-opt/combine_clone_of_primitives.rs
@@ -0,0 +1,20 @@
+// unit-test: InstCombine
+// ignore-wasm32 compiled with panic=abort by default
+
+// EMIT_MIR combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff
+
+#[derive(Clone)]
+struct MyThing<T> {
+ v: T,
+ i: u64,
+ a: [f32; 3],
+}
+
+fn main() {
+ let x = MyThing::<i16> { v: 2, i: 3, a: [0.0; 3] };
+ let y = x.clone();
+
+ assert_eq!(y.v, 2);
+ assert_eq!(y.i, 3);
+ assert_eq!(y.a, [0.0; 3]);
+}
diff --git a/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff b/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff
new file mode 100644
index 000000000..833d620cc
--- /dev/null
+++ b/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff
@@ -0,0 +1,85 @@
+- // MIR for `<impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone` before InstCombine
++ // MIR for `<impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone` after InstCombine
+
+ fn <impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone(_1: &MyThing<T>) -> MyThing<T> {
+ debug self => _1; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
+ let mut _0: MyThing<T>; // return place in scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
+ let mut _2: T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
+ let mut _3: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
+ let _4: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
+ let mut _5: u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
+ let mut _6: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
+ let _7: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
+ let mut _8: [f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
+ let mut _9: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
+ let _10: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
+ StorageLive(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
+ StorageLive(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
+ _4 = &((*_1).0: T); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
+- _3 = &(*_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
++ _3 = _4; // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
+ _2 = <T as Clone>::clone(move _3) -> bb1; // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
+ // mir::Constant
+ // + span: $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ // + literal: Const { ty: for<'r> fn(&'r T) -> T {<T as Clone>::clone}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:8: +2:9
+ StorageLive(_5); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
+ StorageLive(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
+ StorageLive(_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
+ _7 = &((*_1).1: u64); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
+- _6 = &(*_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
+- _5 = <u64 as Clone>::clone(move _6) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
+- // mir::Constant
+- // + span: $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+- // + literal: Const { ty: for<'r> fn(&'r u64) -> u64 {<u64 as Clone>::clone}, val: Value(<ZST>) }
++ _6 = _7; // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
++ _5 = (*_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
++ goto -> bb2; // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
+ }
+
+ bb2: {
+ StorageDead(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:10: +3:11
+ StorageLive(_8); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
+ StorageLive(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
+ StorageLive(_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
+ _10 = &((*_1).2: [f32; 3]); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
+- _9 = &(*_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
+- _8 = <[f32; 3] as Clone>::clone(move _9) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
+- // mir::Constant
+- // + span: $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+- // + literal: Const { ty: for<'r> fn(&'r [f32; 3]) -> [f32; 3] {<[f32; 3] as Clone>::clone}, val: Value(<ZST>) }
++ _9 = _10; // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
++ _8 = (*_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
++ goto -> bb3; // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
+ }
+
+ bb3: {
+ StorageDead(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:15: +4:16
+ Deinit(_0); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
+ (_0.0: T) = move _2; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
+ (_0.1: u64) = move _5; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
+ (_0.2: [f32; 3]) = move _8; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
+ StorageDead(_8); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15
+ StorageDead(_5); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15
+ StorageDead(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15
+ StorageDead(_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15
+ StorageDead(_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15
+ StorageDead(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15
+ return; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:15: +0:15
+ }
+
+ bb4 (cleanup): {
+ drop(_2) -> bb5; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15
+ }
+
+ bb5 (cleanup): {
+ resume; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
+ }
+ }
+
diff --git a/src/test/mir-opt/const-promotion-extern-static.rs b/src/test/mir-opt/const-promotion-extern-static.rs
new file mode 100644
index 000000000..a0d4e9b2c
--- /dev/null
+++ b/src/test/mir-opt/const-promotion-extern-static.rs
@@ -0,0 +1,18 @@
+// ignore-endian-big
+extern "C" {
+ static X: i32;
+}
+static Y: i32 = 42;
+
+// EMIT_MIR const_promotion_extern_static.BAR.PromoteTemps.diff
+// EMIT_MIR const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir
+static mut BAR: *const &i32 = [&Y].as_ptr();
+
+// EMIT_MIR const_promotion_extern_static.FOO.PromoteTemps.diff
+// EMIT_MIR const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir
+static mut FOO: *const &i32 = [unsafe { &X }].as_ptr();
+
+// EMIT_MIR const_promotion_extern_static.BOP.mir_map.0.mir
+static BOP: &i32 = &13;
+
+fn main() {}
diff --git a/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir
new file mode 100644
index 000000000..da5a64cac
--- /dev/null
+++ b/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir
@@ -0,0 +1,62 @@
+// MIR for `main` after ConstProp
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/const_allocation.rs:+0:11: +0:11
+ let _1: &[(std::option::Option<i32>, &[&str])]; // in scope 0 at $DIR/const_allocation.rs:+1:5: +1:8
+ let mut _2: &&[(std::option::Option<i32>, &[&str])]; // in scope 0 at $DIR/const_allocation.rs:+1:5: +1:8
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8
+ StorageLive(_2); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8
+ _2 = const {alloc1: &&[(Option<i32>, &[&str])]}; // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8
+ // mir::Constant
+ // + span: $DIR/const_allocation.rs:8:5: 8:8
+ // + literal: Const { ty: &&[(Option<i32>, &[&str])], val: Value(Scalar(alloc1)) }
+ _1 = (*_2); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8
+ StorageDead(_2); // scope 0 at $DIR/const_allocation.rs:+1:8: +1:9
+ StorageDead(_1); // scope 0 at $DIR/const_allocation.rs:+1:8: +1:9
+ nop; // scope 0 at $DIR/const_allocation.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/const_allocation.rs:+2:2: +2:2
+ }
+}
+
+alloc1 (static: FOO, size: 8, align: 4) {
+ ╾─alloc18─╼ 03 00 00 00 │ ╾──╼....
+}
+
+alloc18 (size: 48, align: 4) {
+ 0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc5──╼ 00 00 00 00 │ ....░░░░╾──╼....
+ 0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc9──╼ 02 00 00 00 │ ....░░░░╾──╼....
+ 0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc14─╼ 03 00 00 00 │ ....*...╾──╼....
+}
+
+alloc5 (size: 0, align: 4) {}
+
+alloc9 (size: 16, align: 4) {
+ ╾─alloc8──╼ 03 00 00 00 ╾─alloc10─╼ 03 00 00 00 │ ╾──╼....╾──╼....
+}
+
+alloc8 (size: 3, align: 1) {
+ 66 6f 6f │ foo
+}
+
+alloc10 (size: 3, align: 1) {
+ 62 61 72 │ bar
+}
+
+alloc14 (size: 24, align: 4) {
+ 0x00 │ ╾─alloc13─╼ 03 00 00 00 ╾─alloc15─╼ 03 00 00 00 │ ╾──╼....╾──╼....
+ 0x10 │ ╾─alloc16─╼ 04 00 00 00 │ ╾──╼....
+}
+
+alloc13 (size: 3, align: 1) {
+ 6d 65 68 │ meh
+}
+
+alloc15 (size: 3, align: 1) {
+ 6d 6f 70 │ mop
+}
+
+alloc16 (size: 4, align: 1) {
+ 6d c3 b6 70 │ m..p
+}
diff --git a/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir
new file mode 100644
index 000000000..febd99068
--- /dev/null
+++ b/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir
@@ -0,0 +1,66 @@
+// MIR for `main` after ConstProp
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/const_allocation.rs:+0:11: +0:11
+ let _1: &[(std::option::Option<i32>, &[&str])]; // in scope 0 at $DIR/const_allocation.rs:+1:5: +1:8
+ let mut _2: &&[(std::option::Option<i32>, &[&str])]; // in scope 0 at $DIR/const_allocation.rs:+1:5: +1:8
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8
+ StorageLive(_2); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8
+ _2 = const {alloc1: &&[(Option<i32>, &[&str])]}; // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8
+ // mir::Constant
+ // + span: $DIR/const_allocation.rs:8:5: 8:8
+ // + literal: Const { ty: &&[(Option<i32>, &[&str])], val: Value(Scalar(alloc1)) }
+ _1 = (*_2); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8
+ StorageDead(_2); // scope 0 at $DIR/const_allocation.rs:+1:8: +1:9
+ StorageDead(_1); // scope 0 at $DIR/const_allocation.rs:+1:8: +1:9
+ nop; // scope 0 at $DIR/const_allocation.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/const_allocation.rs:+2:2: +2:2
+ }
+}
+
+alloc1 (static: FOO, size: 16, align: 8) {
+ ╾───────alloc18───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........
+}
+
+alloc18 (size: 72, align: 8) {
+ 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc5────────╼ │ ....░░░░╾──────╼
+ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░
+ 0x20 │ ╾───────alloc9────────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........
+ 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc14───────╼ │ ....*...╾──────╼
+ 0x40 │ 03 00 00 00 00 00 00 00 │ ........
+}
+
+alloc5 (size: 0, align: 8) {}
+
+alloc9 (size: 32, align: 8) {
+ 0x00 │ ╾───────alloc8────────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........
+ 0x10 │ ╾───────alloc10───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........
+}
+
+alloc8 (size: 3, align: 1) {
+ 66 6f 6f │ foo
+}
+
+alloc10 (size: 3, align: 1) {
+ 62 61 72 │ bar
+}
+
+alloc14 (size: 48, align: 8) {
+ 0x00 │ ╾───────alloc13───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........
+ 0x10 │ ╾───────alloc15───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........
+ 0x20 │ ╾───────alloc16───────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........
+}
+
+alloc13 (size: 3, align: 1) {
+ 6d 65 68 │ meh
+}
+
+alloc15 (size: 3, align: 1) {
+ 6d 6f 70 │ mop
+}
+
+alloc16 (size: 4, align: 1) {
+ 6d c3 b6 70 │ m..p
+}
diff --git a/src/test/mir-opt/const_allocation.rs b/src/test/mir-opt/const_allocation.rs
new file mode 100644
index 000000000..b0fcb86fc
--- /dev/null
+++ b/src/test/mir-opt/const_allocation.rs
@@ -0,0 +1,9 @@
+// ignore-endian-big
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+static FOO: &[(Option<i32>, &[&str])] =
+ &[(None, &[]), (None, &["foo", "bar"]), (Some(42), &["meh", "mop", "möp"])];
+
+// EMIT_MIR const_allocation.main.ConstProp.after.mir
+fn main() {
+ FOO;
+}
diff --git a/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir
new file mode 100644
index 000000000..389641f20
--- /dev/null
+++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir
@@ -0,0 +1,61 @@
+// MIR for `main` after ConstProp
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/const_allocation2.rs:+0:11: +0:11
+ let _1: &[(std::option::Option<i32>, &[&u8])]; // in scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8
+ let mut _2: &&[(std::option::Option<i32>, &[&u8])]; // in scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8
+ StorageLive(_2); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8
+ _2 = const {alloc1: &&[(Option<i32>, &[&u8])]}; // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8
+ // mir::Constant
+ // + span: $DIR/const_allocation2.rs:5:5: 5:8
+ // + literal: Const { ty: &&[(Option<i32>, &[&u8])], val: Value(Scalar(alloc1)) }
+ _1 = (*_2); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8
+ StorageDead(_2); // scope 0 at $DIR/const_allocation2.rs:+1:8: +1:9
+ StorageDead(_1); // scope 0 at $DIR/const_allocation2.rs:+1:8: +1:9
+ nop; // scope 0 at $DIR/const_allocation2.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/const_allocation2.rs:+2:2: +2:2
+ }
+}
+
+alloc1 (static: FOO, size: 8, align: 4) {
+ ╾─alloc22─╼ 03 00 00 00 │ ╾──╼....
+}
+
+alloc22 (size: 48, align: 4) {
+ 0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc9──╼ 00 00 00 00 │ ....░░░░╾──╼....
+ 0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc14─╼ 02 00 00 00 │ ....░░░░╾──╼....
+ 0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc20─╼ 03 00 00 00 │ ....*...╾──╼....
+}
+
+alloc9 (size: 0, align: 4) {}
+
+alloc14 (size: 8, align: 4) {
+ ╾─alloc12─╼ ╾─alloc13─╼ │ ╾──╼╾──╼
+}
+
+alloc12 (size: 1, align: 1) {
+ 05 │ .
+}
+
+alloc13 (size: 1, align: 1) {
+ 06 │ .
+}
+
+alloc20 (size: 12, align: 4) {
+ ╾─a17+0x3─╼ ╾─alloc18─╼ ╾─a19+0x2─╼ │ ╾──╼╾──╼╾──╼
+}
+
+alloc17 (size: 4, align: 1) {
+ 2a 45 15 6f │ *E.o
+}
+
+alloc18 (size: 1, align: 1) {
+ 2a │ *
+}
+
+alloc19 (size: 4, align: 1) {
+ 2a 45 15 6f │ *E.o
+}
diff --git a/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir
new file mode 100644
index 000000000..ce3848e92
--- /dev/null
+++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir
@@ -0,0 +1,64 @@
+// MIR for `main` after ConstProp
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/const_allocation2.rs:+0:11: +0:11
+ let _1: &[(std::option::Option<i32>, &[&u8])]; // in scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8
+ let mut _2: &&[(std::option::Option<i32>, &[&u8])]; // in scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8
+ StorageLive(_2); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8
+ _2 = const {alloc1: &&[(Option<i32>, &[&u8])]}; // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8
+ // mir::Constant
+ // + span: $DIR/const_allocation2.rs:5:5: 5:8
+ // + literal: Const { ty: &&[(Option<i32>, &[&u8])], val: Value(Scalar(alloc1)) }
+ _1 = (*_2); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8
+ StorageDead(_2); // scope 0 at $DIR/const_allocation2.rs:+1:8: +1:9
+ StorageDead(_1); // scope 0 at $DIR/const_allocation2.rs:+1:8: +1:9
+ nop; // scope 0 at $DIR/const_allocation2.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/const_allocation2.rs:+2:2: +2:2
+ }
+}
+
+alloc1 (static: FOO, size: 16, align: 8) {
+ ╾───────alloc22───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........
+}
+
+alloc22 (size: 72, align: 8) {
+ 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc9────────╼ │ ....░░░░╾──────╼
+ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░
+ 0x20 │ ╾───────alloc14───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........
+ 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc20───────╼ │ ....*...╾──────╼
+ 0x40 │ 03 00 00 00 00 00 00 00 │ ........
+}
+
+alloc9 (size: 0, align: 8) {}
+
+alloc14 (size: 16, align: 8) {
+ ╾───────alloc12───────╼ ╾───────alloc13───────╼ │ ╾──────╼╾──────╼
+}
+
+alloc12 (size: 1, align: 1) {
+ 05 │ .
+}
+
+alloc13 (size: 1, align: 1) {
+ 06 │ .
+}
+
+alloc20 (size: 24, align: 8) {
+ 0x00 │ ╾─────alloc17+0x3─────╼ ╾───────alloc18───────╼ │ ╾──────╼╾──────╼
+ 0x10 │ ╾─────alloc19+0x2─────╼ │ ╾──────╼
+}
+
+alloc17 (size: 4, align: 1) {
+ 2a 45 15 6f │ *E.o
+}
+
+alloc18 (size: 1, align: 1) {
+ 2a │ *
+}
+
+alloc19 (size: 4, align: 1) {
+ 2a 45 15 6f │ *E.o
+}
diff --git a/src/test/mir-opt/const_allocation2.rs b/src/test/mir-opt/const_allocation2.rs
new file mode 100644
index 000000000..30afedffb
--- /dev/null
+++ b/src/test/mir-opt/const_allocation2.rs
@@ -0,0 +1,11 @@
+// ignore-endian-big
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR const_allocation2.main.ConstProp.after.mir
+fn main() {
+ FOO;
+}
+
+const BAR: [u8; 4] = [42, 69, 21, 111];
+
+static FOO: &[(Option<i32>, &[&u8])] =
+ &[(None, &[]), (None, &[&5, &6]), (Some(42), &[&BAR[3], &42, &BAR[2]])];
diff --git a/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir
new file mode 100644
index 000000000..b72519159
--- /dev/null
+++ b/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir
@@ -0,0 +1,55 @@
+// MIR for `main` after ConstProp
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/const_allocation3.rs:+0:11: +0:11
+ let _1: &Packed; // in scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8
+ let mut _2: &&Packed; // in scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8
+ StorageLive(_2); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8
+ _2 = const {alloc1: &&Packed}; // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8
+ // mir::Constant
+ // + span: $DIR/const_allocation3.rs:5:5: 5:8
+ // + literal: Const { ty: &&Packed, val: Value(Scalar(alloc1)) }
+ _1 = (*_2); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8
+ StorageDead(_2); // scope 0 at $DIR/const_allocation3.rs:+1:8: +1:9
+ StorageDead(_1); // scope 0 at $DIR/const_allocation3.rs:+1:8: +1:9
+ nop; // scope 0 at $DIR/const_allocation3.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/const_allocation3.rs:+2:2: +2:2
+ }
+}
+
+alloc1 (static: FOO, size: 4, align: 4) {
+ ╾─alloc11─╼ │ ╾──╼
+}
+
+alloc11 (size: 168, align: 1) {
+ 0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................
+ 0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾─alloc6──╼ │ ............╾──╼
+ 0x20 │ 01 ef cd ab 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x80 │ 00 00 00 00 00 00 00 00 00 00 ╾─alloc8──╼ 00 00 │ ..........╾──╼..
+ 0x90 │ ╾─a9+0x63─╼ 00 00 00 00 00 00 00 00 00 00 00 00 │ ╾──╼............
+ 0xa0 │ 00 00 00 00 00 00 00 00 │ ........
+}
+
+alloc6 (size: 4, align: 4) {
+ 2a 00 00 00 │ *...
+}
+
+alloc8 (fn: main)
+
+alloc9 (size: 100, align: 1) {
+ 0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x60 │ 00 00 00 00 │ ....
+}
diff --git a/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir
new file mode 100644
index 000000000..6bd047c7d
--- /dev/null
+++ b/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir
@@ -0,0 +1,56 @@
+// MIR for `main` after ConstProp
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/const_allocation3.rs:+0:11: +0:11
+ let _1: &Packed; // in scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8
+ let mut _2: &&Packed; // in scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8
+ StorageLive(_2); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8
+ _2 = const {alloc1: &&Packed}; // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8
+ // mir::Constant
+ // + span: $DIR/const_allocation3.rs:5:5: 5:8
+ // + literal: Const { ty: &&Packed, val: Value(Scalar(alloc1)) }
+ _1 = (*_2); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8
+ StorageDead(_2); // scope 0 at $DIR/const_allocation3.rs:+1:8: +1:9
+ StorageDead(_1); // scope 0 at $DIR/const_allocation3.rs:+1:8: +1:9
+ nop; // scope 0 at $DIR/const_allocation3.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/const_allocation3.rs:+2:2: +2:2
+ }
+}
+
+alloc1 (static: FOO, size: 8, align: 8) {
+ ╾───────alloc11───────╼ │ ╾──────╼
+}
+
+alloc11 (size: 180, align: 1) {
+ 0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................
+ 0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾──alloc6── │ ............╾───
+ 0x20 │ ──────────╼ 01 ef cd ab 00 00 00 00 00 00 00 00 │ ───╼............
+ 0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x80 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ╾──── │ ..............╾─
+ 0x90 │ ─────alloc8─────╼ 00 00 ╾─────alloc9+0x63─────╼ │ ─────╼..╾──────╼
+ 0xa0 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0xb0 │ 00 00 00 00 │ ....
+}
+
+alloc6 (size: 4, align: 4) {
+ 2a 00 00 00 │ *...
+}
+
+alloc8 (fn: main)
+
+alloc9 (size: 100, align: 1) {
+ 0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ 0x60 │ 00 00 00 00 │ ....
+}
diff --git a/src/test/mir-opt/const_allocation3.rs b/src/test/mir-opt/const_allocation3.rs
new file mode 100644
index 000000000..ddeb32ab9
--- /dev/null
+++ b/src/test/mir-opt/const_allocation3.rs
@@ -0,0 +1,29 @@
+// ignore-endian-big
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR const_allocation3.main.ConstProp.after.mir
+fn main() {
+ FOO;
+}
+
+#[repr(packed)]
+struct Packed {
+ a: [u8; 28],
+ b: &'static i32,
+ c: u32,
+ d: [u8; 102],
+ e: fn(),
+ f: u16,
+ g: &'static u8,
+ h: [u8; 20],
+}
+
+static FOO: &Packed = &Packed {
+ a: [0xAB; 28],
+ b: &42,
+ c: 0xABCD_EF01,
+ d: [0; 102],
+ e: main,
+ f: 0,
+ g: &[0; 100][99],
+ h: [0; 20],
+};
diff --git a/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
new file mode 100644
index 000000000..a092f3752
--- /dev/null
+++ b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
@@ -0,0 +1,115 @@
+- // MIR for `main` before ConstDebugInfo
++ // MIR for `main` after ConstDebugInfo
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/const_debuginfo.rs:+0:11: +0:11
+ let _1: u8; // in scope 0 at $DIR/const_debuginfo.rs:+1:9: +1:10
+ let mut _5: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:15: +4:20
+ let mut _6: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:15: +4:16
+ let mut _7: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:19: +4:20
+ let mut _8: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:23: +4:24
+ let mut _14: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16
+ let mut _15: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:19: +13:22
+ scope 1 {
+- debug x => _1; // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10
++ debug x => const 1_u8; // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10
+ let _2: u8; // in scope 1 at $DIR/const_debuginfo.rs:+2:9: +2:10
+ scope 2 {
+- debug y => _2; // in scope 2 at $DIR/const_debuginfo.rs:+2:9: +2:10
++ debug y => const 2_u8; // in scope 2 at $DIR/const_debuginfo.rs:+2:9: +2:10
+ let _3: u8; // in scope 2 at $DIR/const_debuginfo.rs:+3:9: +3:10
+ scope 3 {
+- debug z => _3; // in scope 3 at $DIR/const_debuginfo.rs:+3:9: +3:10
++ debug z => const 3_u8; // in scope 3 at $DIR/const_debuginfo.rs:+3:9: +3:10
+ let _4: u8; // in scope 3 at $DIR/const_debuginfo.rs:+4:9: +4:12
+ scope 4 {
+- debug sum => _4; // in scope 4 at $DIR/const_debuginfo.rs:+4:9: +4:12
++ debug sum => const 6_u8; // in scope 4 at $DIR/const_debuginfo.rs:+4:9: +4:12
+ let _9: &str; // in scope 4 at $DIR/const_debuginfo.rs:+6:9: +6:10
+ scope 5 {
+- debug s => _9; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10
++ debug s => const "hello, world!"; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10
+ let _10: (bool, bool, u32); // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ scope 6 {
+ debug f => _10; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ let _11: std::option::Option<u16>; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10
+ scope 7 {
+ debug o => _11; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10
+ let _12: Point; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ scope 8 {
+ debug p => _12; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ let _13: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10
+ scope 9 {
+- debug a => _13; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10
++ debug a => const 64_u32; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_debuginfo.rs:+1:9: +1:10
+ _1 = const 1_u8; // scope 0 at $DIR/const_debuginfo.rs:+1:13: +1:16
+ StorageLive(_2); // scope 1 at $DIR/const_debuginfo.rs:+2:9: +2:10
+ _2 = const 2_u8; // scope 1 at $DIR/const_debuginfo.rs:+2:13: +2:16
+ StorageLive(_3); // scope 2 at $DIR/const_debuginfo.rs:+3:9: +3:10
+ _3 = const 3_u8; // scope 2 at $DIR/const_debuginfo.rs:+3:13: +3:16
+ StorageLive(_4); // scope 3 at $DIR/const_debuginfo.rs:+4:9: +4:12
+ StorageLive(_5); // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:20
+ StorageLive(_6); // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:16
+ _6 = const 1_u8; // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:16
+ StorageLive(_7); // scope 3 at $DIR/const_debuginfo.rs:+4:19: +4:20
+ _7 = const 2_u8; // scope 3 at $DIR/const_debuginfo.rs:+4:19: +4:20
+ _5 = const 3_u8; // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:20
+ StorageDead(_7); // scope 3 at $DIR/const_debuginfo.rs:+4:19: +4:20
+ StorageDead(_6); // scope 3 at $DIR/const_debuginfo.rs:+4:19: +4:20
+ StorageLive(_8); // scope 3 at $DIR/const_debuginfo.rs:+4:23: +4:24
+ _8 = const 3_u8; // scope 3 at $DIR/const_debuginfo.rs:+4:23: +4:24
+ _4 = const 6_u8; // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:24
+ StorageDead(_8); // scope 3 at $DIR/const_debuginfo.rs:+4:23: +4:24
+ StorageDead(_5); // scope 3 at $DIR/const_debuginfo.rs:+4:23: +4:24
+ StorageLive(_9); // scope 4 at $DIR/const_debuginfo.rs:+6:9: +6:10
+ _9 = const "hello, world!"; // scope 4 at $DIR/const_debuginfo.rs:+6:13: +6:28
+ // mir::Constant
+ // + span: $DIR/const_debuginfo.rs:14:13: 14:28
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ StorageLive(_10); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ Deinit(_10); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ (_10.0: bool) = const true; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ (_10.1: bool) = const false; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ (_10.2: u32) = const 123_u32; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ StorageLive(_11); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10
+ Deinit(_11); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
+ ((_11 as Some).0: u16) = const 99_u16; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
+ discriminant(_11) = 1; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
+ StorageLive(_12); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ Deinit(_12); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+ (_12.0: u32) = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+ (_12.1: u32) = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+ StorageLive(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10
+ StorageLive(_14); // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16
+ _14 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16
+ StorageLive(_15); // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22
+ _15 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22
+ _13 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22
+ StorageDead(_15); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22
+ StorageDead(_14); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22
+ nop; // scope 0 at $DIR/const_debuginfo.rs:+0:11: +14:2
+ StorageDead(_13); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_12); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_11); // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_10); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_9); // scope 4 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_4); // scope 3 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_3); // scope 2 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_2); // scope 1 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_1); // scope 0 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ return; // scope 0 at $DIR/const_debuginfo.rs:+14:2: +14:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_debuginfo.rs b/src/test/mir-opt/const_debuginfo.rs
new file mode 100644
index 000000000..a188da385
--- /dev/null
+++ b/src/test/mir-opt/const_debuginfo.rs
@@ -0,0 +1,24 @@
+// compile-flags: -C overflow-checks=no -Zunsound-mir-opts
+
+struct Point {
+ x: u32,
+ y: u32,
+}
+
+fn main() {
+ let x = 1u8;
+ let y = 2u8;
+ let z = 3u8;
+ let sum = x + y + z;
+
+ let s = "hello, world!";
+
+ let f = (true, false, 123u32);
+
+ let o = Some(99u16);
+
+ let p = Point { x: 32, y: 32 };
+ let a = p.x + p.y;
+}
+
+// EMIT_MIR const_debuginfo.main.ConstDebugInfo.diff
diff --git a/src/test/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff b/src/test/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff
new file mode 100644
index 000000000..fade2d0bc
--- /dev/null
+++ b/src/test/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff
@@ -0,0 +1,52 @@
+- // MIR for `issue_77355_opt` before ConstGoto
++ // MIR for `issue_77355_opt` after ConstGoto
+
+ fn issue_77355_opt(_1: Foo) -> u64 {
+ debug num => _1; // in scope 0 at $DIR/const_goto.rs:+0:20: +0:23
+ let mut _0: u64; // return place in scope 0 at $DIR/const_goto.rs:+0:33: +0:36
+- let mut _2: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- let mut _3: isize; // in scope 0 at $DIR/const_goto.rs:+1:22: +1:28
++ let mut _2: isize; // in scope 0 at $DIR/const_goto.rs:+1:22: +1:28
+
+ bb0: {
+- StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- _3 = discriminant(_1); // scope 0 at $DIR/const_goto.rs:+1:17: +1:20
+- switchInt(move _3) -> [1_isize: bb2, 2_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ _2 = discriminant(_1); // scope 0 at $DIR/const_goto.rs:+1:17: +1:20
++ switchInt(move _2) -> [1_isize: bb2, 2_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb1: {
+- _2 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ _0 = const 42_u64; // scope 0 at $DIR/const_goto.rs:+1:53: +1:55
++ goto -> bb3; // scope 0 at $DIR/const_goto.rs:+1:5: +1:57
+ }
+
+ bb2: {
+- _2 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb3: {
+- switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb4: {
+ _0 = const 23_u64; // scope 0 at $DIR/const_goto.rs:+1:41: +1:43
+- goto -> bb6; // scope 0 at $DIR/const_goto.rs:+1:5: +1:57
++ goto -> bb3; // scope 0 at $DIR/const_goto.rs:+1:5: +1:57
+ }
+
+- bb5: {
+- _0 = const 42_u64; // scope 0 at $DIR/const_goto.rs:+1:53: +1:55
+- goto -> bb6; // scope 0 at $DIR/const_goto.rs:+1:5: +1:57
+- }
+-
+- bb6: {
+- StorageDead(_2); // scope 0 at $DIR/const_goto.rs:+1:56: +1:57
++ bb3: {
+ return; // scope 0 at $DIR/const_goto.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_goto.rs b/src/test/mir-opt/const_goto.rs
new file mode 100644
index 000000000..939902e70
--- /dev/null
+++ b/src/test/mir-opt/const_goto.rs
@@ -0,0 +1,16 @@
+pub enum Foo {
+ A,
+ B,
+ C,
+ D,
+ E,
+ F,
+}
+
+// EMIT_MIR const_goto.issue_77355_opt.ConstGoto.diff
+fn issue_77355_opt(num: Foo) -> u64 {
+ if matches!(num, Foo::B | Foo::C) { 23 } else { 42 }
+}
+fn main() {
+ issue_77355_opt(Foo::A);
+}
diff --git a/src/test/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff b/src/test/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff
new file mode 100644
index 000000000..623297aeb
--- /dev/null
+++ b/src/test/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff
@@ -0,0 +1,51 @@
+- // MIR for `f` before ConstGoto
++ // MIR for `f` after ConstGoto
+
+ fn f() -> u64 {
+ let mut _0: u64; // return place in scope 0 at $DIR/const_goto_const_eval_fail.rs:+0:44: +0:47
+ let mut _1: bool; // in scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:11: +6:6
+ let mut _2: i32; // in scope 0 at $DIR/const_goto_const_eval_fail.rs:+2:15: +2:16
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:11: +6:6
+ StorageLive(_2); // scope 0 at $DIR/const_goto_const_eval_fail.rs:+2:15: +2:16
+ _2 = const A; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+2:15: +2:16
+ switchInt(_2) -> [1_i32: bb2, 2_i32: bb2, 3_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+2:9: +2:16
+ }
+
+ bb1: {
+ _1 = const true; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+4:18: +4:22
+ goto -> bb3; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+4:18: +4:22
+ }
+
+ bb2: {
+ _1 = const B; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+3:26: +3:27
+- goto -> bb3; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+3:26: +3:27
++ switchInt(_1) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:5: +6:6
+ }
+
+ bb3: {
+- switchInt(_1) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:5: +6:6
+- }
+-
+- bb4: {
+ _0 = const 2_u64; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+8:17: +8:18
+- goto -> bb6; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+8:17: +8:18
++ goto -> bb5; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+8:17: +8:18
+ }
+
+- bb5: {
++ bb4: {
+ _0 = const 1_u64; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+7:18: +7:19
+- goto -> bb6; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+7:18: +7:19
++ goto -> bb5; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+7:18: +7:19
+ }
+
+- bb6: {
++ bb5: {
+ StorageDead(_2); // scope 0 at $DIR/const_goto_const_eval_fail.rs:+10:1: +10:2
+ StorageDead(_1); // scope 0 at $DIR/const_goto_const_eval_fail.rs:+10:1: +10:2
+ return; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+10:2: +10:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_goto_const_eval_fail.rs b/src/test/mir-opt/const_goto_const_eval_fail.rs
new file mode 100644
index 000000000..3b85fe6ab
--- /dev/null
+++ b/src/test/mir-opt/const_goto_const_eval_fail.rs
@@ -0,0 +1,16 @@
+#![feature(min_const_generics)]
+#![crate_type = "lib"]
+
+// If const eval fails, then don't crash
+// EMIT_MIR const_goto_const_eval_fail.f.ConstGoto.diff
+pub fn f<const A: i32, const B: bool>() -> u64 {
+ match {
+ match A {
+ 1 | 2 | 3 => B,
+ _ => true,
+ }
+ } {
+ false => 1,
+ true => 2,
+ }
+}
diff --git a/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff b/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff
new file mode 100644
index 000000000..2b09ef786
--- /dev/null
+++ b/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff
@@ -0,0 +1,103 @@
+- // MIR for `match_nested_if` before ConstGoto
++ // MIR for `match_nested_if` after ConstGoto
+
+ fn match_nested_if() -> bool {
+ let mut _0: bool; // return place in scope 0 at $DIR/const_goto_storage.rs:+0:25: +0:29
+ let _1: bool; // in scope 0 at $DIR/const_goto_storage.rs:+1:9: +1:12
+- let mut _2: (); // in scope 0 at $DIR/const_goto_storage.rs:+1:21: +1:23
+- let mut _3: bool; // in scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10
+- let mut _4: bool; // in scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76
+- let mut _5: bool; // in scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52
+- let mut _6: bool; // in scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28
++ let mut _2: bool; // in scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28
+ scope 1 {
+ debug val => _1; // in scope 1 at $DIR/const_goto_storage.rs:+1:9: +1:12
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_goto_storage.rs:+1:9: +1:12
+- StorageLive(_2); // scope 0 at $DIR/const_goto_storage.rs:+1:21: +1:23
+- nop; // scope 0 at $DIR/const_goto_storage.rs:+1:21: +1:23
+- StorageLive(_3); // scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10
+- StorageLive(_4); // scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76
+- StorageLive(_5); // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52
+- StorageLive(_6); // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28
+- _6 = const true; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28
+- switchInt(move _6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28
++ StorageLive(_2); // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28
++ _2 = const true; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28
++ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28
+ }
+
+ bb1: {
+- _5 = const true; // scope 0 at $DIR/const_goto_storage.rs:+2:31: +2:35
+- goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52
+- }
+-
+- bb2: {
+- _5 = const false; // scope 0 at $DIR/const_goto_storage.rs:+2:45: +2:50
+- goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52
+- }
+-
+- bb3: {
+- StorageDead(_6); // scope 0 at $DIR/const_goto_storage.rs:+2:51: +2:52
+- switchInt(move _5) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52
+- }
+-
+- bb4: {
+- _4 = const true; // scope 0 at $DIR/const_goto_storage.rs:+2:55: +2:59
+- goto -> bb6; // scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76
+- }
+-
+- bb5: {
+- _4 = const false; // scope 0 at $DIR/const_goto_storage.rs:+2:69: +2:74
+- goto -> bb6; // scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76
+- }
+-
+- bb6: {
+- StorageDead(_5); // scope 0 at $DIR/const_goto_storage.rs:+2:75: +2:76
+- switchInt(move _4) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76
+- }
+-
+- bb7: {
+- _3 = const true; // scope 0 at $DIR/const_goto_storage.rs:+3:13: +3:17
+- goto -> bb9; // scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10
+- }
+-
+- bb8: {
+- _3 = const false; // scope 0 at $DIR/const_goto_storage.rs:+5:13: +5:18
+- goto -> bb9; // scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10
+- }
+-
+- bb9: {
+- switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10
+- }
+-
+- bb10: {
+- StorageDead(_4); // scope 0 at $DIR/const_goto_storage.rs:+6:9: +6:10
+- StorageDead(_3); // scope 0 at $DIR/const_goto_storage.rs:+6:9: +6:10
++ StorageDead(_2); // scope 0 at $DIR/const_goto_storage.rs:+2:51: +2:52
+ _1 = const true; // scope 0 at $DIR/const_goto_storage.rs:+8:17: +8:21
+- goto -> bb12; // scope 0 at $DIR/const_goto_storage.rs:+8:17: +8:21
++ goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:+8:17: +8:21
+ }
+
+- bb11: {
+- StorageDead(_4); // scope 0 at $DIR/const_goto_storage.rs:+6:9: +6:10
+- StorageDead(_3); // scope 0 at $DIR/const_goto_storage.rs:+6:9: +6:10
++ bb2: {
++ StorageDead(_2); // scope 0 at $DIR/const_goto_storage.rs:+2:51: +2:52
+ _1 = const false; // scope 0 at $DIR/const_goto_storage.rs:+10:14: +10:19
+- goto -> bb12; // scope 0 at $DIR/const_goto_storage.rs:+10:14: +10:19
++ goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:+10:14: +10:19
+ }
+
+- bb12: {
+- StorageDead(_2); // scope 0 at $DIR/const_goto_storage.rs:+11:6: +11:7
++ bb3: {
+ _0 = _1; // scope 1 at $DIR/const_goto_storage.rs:+12:5: +12:8
+ StorageDead(_1); // scope 0 at $DIR/const_goto_storage.rs:+13:1: +13:2
+ return; // scope 0 at $DIR/const_goto_storage.rs:+13:2: +13:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_goto_storage.rs b/src/test/mir-opt/const_goto_storage.rs
new file mode 100644
index 000000000..4ef68e7e1
--- /dev/null
+++ b/src/test/mir-opt/const_goto_storage.rs
@@ -0,0 +1,19 @@
+// EMIT_MIR const_goto_storage.match_nested_if.ConstGoto.diff
+fn match_nested_if() -> bool {
+ let val = match () {
+ () if if if if true { true } else { false } { true } else { false } {
+ true
+ } else {
+ false
+ } =>
+ {
+ true
+ }
+ _ => false,
+ };
+ val
+}
+
+fn main() {
+ let _ = match_nested_if();
+}
diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..7650769de
--- /dev/null
+++ b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,23 @@
+// MIR for `BAR::promoted[0]` after SimplifyCfg-elaborate-drops
+
+promoted[0] in BAR: &[&i32; 1] = {
+ let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+ let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35
+ let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
+ let mut _3: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
+
+ bb0: {
+ _3 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
+ // mir::Constant
+ // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
+ // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
+ _2 = &(*_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
+ _1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35
+ _0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+ return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+ }
+}
+
+alloc1 (static: Y, size: 4, align: 4) {
+ 2a 00 00 00 │ *...
+}
diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
new file mode 100644
index 000000000..f58ba56b9
--- /dev/null
+++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
@@ -0,0 +1,54 @@
+- // MIR for `BAR` before PromoteTemps
++ // MIR for `BAR` after PromoteTemps
+
+ static mut BAR: *const &i32 = {
+ let mut _0: *const &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:17: +0:28
+ let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+ let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+ let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35
+ let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
+ let _5: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
++ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+ StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+- StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35
+- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
+- StorageLive(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
+- _5 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
++ _6 = const BAR::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+ // mir::Constant
+- // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
+- // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
+- _4 = &(*_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
+- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35
+- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
++ // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:44
++ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(BAR, [], Some(promoted[0])) }
++ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+ _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+- StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:34: +0:35
+ StorageDead(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:34: +0:35
+ _0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+ // mir::Constant
+ // + span: $DIR/const-promotion-extern-static.rs:9:36: 9:42
+ // + literal: Const { ty: for<'r> fn(&'r [&i32]) -> *const &i32 {core::slice::<impl [&i32]>::as_ptr}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+- StorageDead(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44
+- StorageDead(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44
+ StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44
+ return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:28
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:28
+ }
+- }
+-
+- alloc1 (static: Y, size: 4, align: 4) {
+- 2a 00 00 00 │ *...
+ }
+
diff --git a/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir b/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir
new file mode 100644
index 000000000..deb467977
--- /dev/null
+++ b/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir
@@ -0,0 +1,17 @@
+// MIR for `BOP` 0 mir_map
+
+static BOP: &i32 = {
+ let mut _0: &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:13: +0:17
+ let _1: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23
+ let _2: i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:21: +0:23
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23
+ StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:21: +0:23
+ _2 = const 13_i32; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:21: +0:23
+ _1 = &_2; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23
+ _0 = &(*_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23
+ StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:22: +0:23
+ return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:17
+ }
+}
diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..71827eab1
--- /dev/null
+++ b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,21 @@
+// MIR for `FOO::promoted[0]` after SimplifyCfg-elaborate-drops
+
+promoted[0] in FOO: &[&i32; 1] = {
+ let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46
+ let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45
+ let mut _3: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
+
+ bb0: {
+ _3 = const {alloc3: *const i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
+ // mir::Constant
+ // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
+ // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) }
+ _2 = &(*_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:41: +0:43
+ _1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46
+ _0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ }
+}
+
+alloc3 (extern static: X)
diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
new file mode 100644
index 000000000..5300f555f
--- /dev/null
+++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
@@ -0,0 +1,54 @@
+- // MIR for `FOO` before PromoteTemps
++ // MIR for `FOO` after PromoteTemps
+
+ static mut FOO: *const &i32 = {
+ let mut _0: *const &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:17: +0:28
+ let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46
+ let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45
+ let _5: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
++ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+- StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46
+- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45
+- StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
+- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
++ _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ // mir::Constant
+- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
+- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) }
+- _4 = &(*_5); // scope 1 at $DIR/const-promotion-extern-static.rs:+0:41: +0:43
+- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46
+- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
++ // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:55
++ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(FOO, [], Some(promoted[0])) }
++ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+- StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:45: +0:46
+ StorageDead(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:45: +0:46
+ _0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ // mir::Constant
+ // + span: $DIR/const-promotion-extern-static.rs:13:47: 13:53
+ // + literal: Const { ty: for<'r> fn(&'r [&i32]) -> *const &i32 {core::slice::<impl [&i32]>::as_ptr}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+- StorageDead(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55
+- StorageDead(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55
+ StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55
+ return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:28
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:28
+ }
+ }
+-
+- alloc3 (extern static: X)
+
diff --git a/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff b/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff
new file mode 100644
index 000000000..836443bf4
--- /dev/null
+++ b/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff
@@ -0,0 +1,32 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/aggregate.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/aggregate.rs:+1:9: +1:10
+ let mut _2: i32; // in scope 0 at $DIR/aggregate.rs:+1:13: +1:24
+ let mut _3: (i32, i32, i32); // in scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/aggregate.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/aggregate.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/aggregate.rs:+1:13: +1:24
+ StorageLive(_3); // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ Deinit(_3); // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ (_3.0: i32) = const 0_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ (_3.1: i32) = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ (_3.2: i32) = const 2_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+- _2 = (_3.1: i32); // scope 0 at $DIR/aggregate.rs:+1:13: +1:24
+- _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/aggregate.rs:+1:13: +1:28
++ _2 = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:24
++ _1 = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:28
+ StorageDead(_2); // scope 0 at $DIR/aggregate.rs:+1:27: +1:28
+ StorageDead(_3); // scope 0 at $DIR/aggregate.rs:+1:28: +1:29
+ nop; // scope 0 at $DIR/aggregate.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/aggregate.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/aggregate.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/aggregate.rs b/src/test/mir-opt/const_prop/aggregate.rs
new file mode 100644
index 000000000..7a3b26a73
--- /dev/null
+++ b/src/test/mir-opt/const_prop/aggregate.rs
@@ -0,0 +1,6 @@
+// compile-flags: -O
+
+// EMIT_MIR aggregate.main.ConstProp.diff
+fn main() {
+ let x = (0, 1, 2).1 + 0;
+}
diff --git a/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..bb9abdd10
--- /dev/null
+++ b/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff
@@ -0,0 +1,38 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/array_index.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/array_index.rs:+1:9: +1:10
+ let mut _2: [u32; 4]; // in scope 0 at $DIR/array_index.rs:+1:18: +1:30
+ let _3: usize; // in scope 0 at $DIR/array_index.rs:+1:31: +1:32
+ let mut _4: usize; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ let mut _5: bool; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/array_index.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/array_index.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:30
+ _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // scope 0 at $DIR/array_index.rs:+1:18: +1:30
+ StorageLive(_3); // scope 0 at $DIR/array_index.rs:+1:31: +1:32
+ _3 = const 2_usize; // scope 0 at $DIR/array_index.rs:+1:31: +1:32
+ _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _5 = const true; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ }
+
+ bb1: {
+- _1 = _2[_3]; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _1 = const 2_u32; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ StorageDead(_3); // scope 0 at $DIR/array_index.rs:+1:33: +1:34
+ StorageDead(_2); // scope 0 at $DIR/array_index.rs:+1:33: +1:34
+ nop; // scope 0 at $DIR/array_index.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/array_index.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/array_index.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..bb9abdd10
--- /dev/null
+++ b/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff
@@ -0,0 +1,38 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/array_index.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/array_index.rs:+1:9: +1:10
+ let mut _2: [u32; 4]; // in scope 0 at $DIR/array_index.rs:+1:18: +1:30
+ let _3: usize; // in scope 0 at $DIR/array_index.rs:+1:31: +1:32
+ let mut _4: usize; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ let mut _5: bool; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/array_index.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/array_index.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:30
+ _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // scope 0 at $DIR/array_index.rs:+1:18: +1:30
+ StorageLive(_3); // scope 0 at $DIR/array_index.rs:+1:31: +1:32
+ _3 = const 2_usize; // scope 0 at $DIR/array_index.rs:+1:31: +1:32
+ _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _5 = const true; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ }
+
+ bb1: {
+- _1 = _2[_3]; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _1 = const 2_u32; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ StorageDead(_3); // scope 0 at $DIR/array_index.rs:+1:33: +1:34
+ StorageDead(_2); // scope 0 at $DIR/array_index.rs:+1:33: +1:34
+ nop; // scope 0 at $DIR/array_index.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/array_index.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/array_index.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/array_index.rs b/src/test/mir-opt/const_prop/array_index.rs
new file mode 100644
index 000000000..2c5254b5d
--- /dev/null
+++ b/src/test/mir-opt/const_prop/array_index.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
+// EMIT_MIR array_index.main.ConstProp.diff
+fn main() {
+ let x: u32 = [0, 1, 2, 3][2];
+}
diff --git a/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff
new file mode 100644
index 000000000..45134a3fd
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff
@@ -0,0 +1,54 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/bad_op_div_by_zero.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+1:9: +1:10
+ let mut _3: i32; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
+ let mut _4: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ let mut _5: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ let mut _6: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ let mut _7: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ scope 1 {
+ debug y => _1; // in scope 1 at $DIR/bad_op_div_by_zero.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/bad_op_div_by_zero.rs:+2:9: +2:11
+ scope 2 {
+ debug _z => _2; // in scope 2 at $DIR/bad_op_div_by_zero.rs:+2:9: +2:11
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/bad_op_div_by_zero.rs:+1:9: +1:10
+ _1 = const 0_i32; // scope 0 at $DIR/bad_op_div_by_zero.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:9: +2:11
+ StorageLive(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
+- _3 = _1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
+- _4 = Eq(_3, const 0_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+- assert(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ _3 = const 0_i32; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
++ _4 = const true; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ assert(!const true, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ }
+
+ bb1: {
+- _5 = Eq(_3, const -1_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+- _6 = Eq(const 1_i32, const i32::MIN); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+- _7 = BitAnd(move _5, move _6); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+- assert(!move _7, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> bb2; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ _5 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ _6 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ _7 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, const 0_i32) -> bb2; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ }
+
+ bb2: {
+- _2 = Div(const 1_i32, move _3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ _2 = Div(const 1_i32, const 0_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ StorageDead(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
+ nop; // scope 0 at $DIR/bad_op_div_by_zero.rs:+0:11: +3:2
+ StorageDead(_2); // scope 1 at $DIR/bad_op_div_by_zero.rs:+3:1: +3:2
+ StorageDead(_1); // scope 0 at $DIR/bad_op_div_by_zero.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/bad_op_div_by_zero.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs b/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs
new file mode 100644
index 000000000..6f39209b9
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR bad_op_div_by_zero.main.ConstProp.diff
+#[allow(unconditional_panic)]
+fn main() {
+ let y = 0;
+ let _z = 1 / y;
+}
diff --git a/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff
new file mode 100644
index 000000000..221513042
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff
@@ -0,0 +1,54 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/bad_op_mod_by_zero.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10
+ let mut _3: i32; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
+ let mut _4: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ let mut _5: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ let mut _6: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ let mut _7: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ scope 1 {
+ debug y => _1; // in scope 1 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11
+ scope 2 {
+ debug _z => _2; // in scope 2 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10
+ _1 = const 0_i32; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11
+ StorageLive(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
+- _3 = _1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
+- _4 = Eq(_3, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+- assert(!move _4, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ _3 = const 0_i32; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
++ _4 = const true; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ assert(!const true, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ }
+
+ bb1: {
+- _5 = Eq(_3, const -1_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+- _6 = Eq(const 1_i32, const i32::MIN); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+- _7 = BitAnd(move _5, move _6); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+- assert(!move _7, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ _5 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ _6 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ _7 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, const 0_i32) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ }
+
+ bb2: {
+- _2 = Rem(const 1_i32, move _3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ _2 = Rem(const 1_i32, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ StorageDead(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
+ nop; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+0:11: +3:2
+ StorageDead(_2); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2
+ StorageDead(_1); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs
new file mode 100644
index 000000000..cc16a4a5a
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR bad_op_mod_by_zero.main.ConstProp.diff
+#[allow(unconditional_panic)]
+fn main() {
+ let y = 0;
+ let _z = 1 % y;
+}
diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..553488838
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
@@ -0,0 +1,56 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+0:11: +0:11
+ let _1: *const [i32]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
+ let mut _2: *const [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ let _3: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ let _4: [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:26: +1:35
+ let _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ let mut _7: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ let mut _8: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ let mut _9: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
+ scope 2 {
+ let _5: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ scope 3 {
+ debug _b => _5; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ // mir::Constant
+ // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
+ // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
+ _3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ StorageDead(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35
+ StorageDead(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36
+ StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ _7 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ _8 = Lt(const 3_usize, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ }
+
+ bb1: {
+ _5 = (*_1)[_6]; // 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
+ nop; // 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
+ StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..553488838
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
@@ -0,0 +1,56 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+0:11: +0:11
+ let _1: *const [i32]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
+ let mut _2: *const [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ let _3: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ let _4: [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:26: +1:35
+ let _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ let mut _7: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ let mut _8: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ let mut _9: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
+ scope 2 {
+ let _5: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ scope 3 {
+ debug _b => _5; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ // mir::Constant
+ // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
+ // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
+ _3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ StorageDead(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35
+ StorageDead(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36
+ StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ _7 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ _8 = Lt(const 3_usize, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ }
+
+ bb1: {
+ _5 = (*_1)[_6]; // 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
+ nop; // 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
+ StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs
new file mode 100644
index 000000000..cf22b06d5
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs
@@ -0,0 +1,9 @@
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR bad_op_unsafe_oob_for_slices.main.ConstProp.diff
+#[allow(unconditional_panic)]
+fn main() {
+ let a: *const [_] = &[1, 2, 3];
+ unsafe {
+ let _b = (*a)[3];
+ }
+}
diff --git a/src/test/mir-opt/const_prop/boolean_identities.rs b/src/test/mir-opt/const_prop/boolean_identities.rs
new file mode 100644
index 000000000..57164e3e7
--- /dev/null
+++ b/src/test/mir-opt/const_prop/boolean_identities.rs
@@ -0,0 +1,10 @@
+// compile-flags: -O -Zmir-opt-level=4
+
+// EMIT_MIR boolean_identities.test.ConstProp.diff
+pub fn test(x: bool, y: bool) -> bool {
+ (y | true) & (x & false)
+}
+
+fn main() {
+ test(true, false);
+}
diff --git a/src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff b/src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff
new file mode 100644
index 000000000..0de800917
--- /dev/null
+++ b/src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff
@@ -0,0 +1,33 @@
+- // MIR for `test` before ConstProp
++ // MIR for `test` after ConstProp
+
+ fn test(_1: bool, _2: bool) -> bool {
+ debug x => _1; // in scope 0 at $DIR/boolean_identities.rs:+0:13: +0:14
+ debug y => _2; // in scope 0 at $DIR/boolean_identities.rs:+0:22: +0:23
+ let mut _0: bool; // return place in scope 0 at $DIR/boolean_identities.rs:+0:34: +0:38
+ let mut _3: bool; // in scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15
+ let mut _4: bool; // in scope 0 at $DIR/boolean_identities.rs:+1:6: +1:7
+ let mut _5: bool; // in scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
+ let mut _6: bool; // in scope 0 at $DIR/boolean_identities.rs:+1:19: +1:20
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15
+ StorageLive(_4); // scope 0 at $DIR/boolean_identities.rs:+1:6: +1:7
+ _4 = _2; // scope 0 at $DIR/boolean_identities.rs:+1:6: +1:7
+- _3 = BitOr(move _4, const true); // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15
++ _3 = const true; // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15
+ StorageDead(_4); // scope 0 at $DIR/boolean_identities.rs:+1:14: +1:15
+ StorageLive(_5); // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
+ StorageLive(_6); // scope 0 at $DIR/boolean_identities.rs:+1:19: +1:20
+ _6 = _1; // scope 0 at $DIR/boolean_identities.rs:+1:19: +1:20
+- _5 = BitAnd(move _6, const false); // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
++ _5 = const false; // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
+ StorageDead(_6); // scope 0 at $DIR/boolean_identities.rs:+1:28: +1:29
+- _0 = BitAnd(move _3, move _5); // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:29
++ _0 = const false; // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:29
+ StorageDead(_5); // scope 0 at $DIR/boolean_identities.rs:+1:28: +1:29
+ StorageDead(_3); // scope 0 at $DIR/boolean_identities.rs:+1:28: +1:29
+ return; // scope 0 at $DIR/boolean_identities.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff
new file mode 100644
index 000000000..f2d4bee1b
--- /dev/null
+++ b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff
@@ -0,0 +1,67 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/boxes.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/boxes.rs:+1:9: +1:10
+ let mut _2: i32; // in scope 0 at $DIR/boxes.rs:+1:13: +1:22
+ let mut _3: std::boxed::Box<i32>; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _4: usize; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _5: usize; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _6: *mut u8; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _7: std::boxed::Box<i32>; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _8: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _9: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _10: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _11: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/boxes.rs:+1:9: +1:10
+ }
+ scope 2 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/boxes.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/boxes.rs:+1:13: +1:22
+ StorageLive(_3); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
+- _4 = SizeOf(i32); // scope 2 at $DIR/boxes.rs:+1:14: +1:22
+- _5 = AlignOf(i32); // scope 2 at $DIR/boxes.rs:+1:14: +1:22
+- _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> bb1; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
++ _4 = const 4_usize; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
++ _5 = const 4_usize; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
++ _6 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> bb1; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
+ // mir::Constant
+ // + span: $DIR/boxes.rs:12:14: 12:22
+ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_7); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ _7 = ShallowInitBox(move _6, i32); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ StorageLive(_8); // scope 0 at $DIR/boxes.rs:+1:19: +1:21
+ _8 = (((_7.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:19: +1:21
+ (*_8) = const 42_i32; // scope 0 at $DIR/boxes.rs:+1:19: +1:21
+ StorageDead(_8); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ _3 = move _7; // scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ StorageDead(_7); // scope 0 at $DIR/boxes.rs:+1:21: +1:22
+ StorageLive(_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:22
+ _9 = (((_3.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:13: +1:22
+ _2 = (*_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:22
+ StorageDead(_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:26
+ _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/boxes.rs:+1:13: +1:26
+ StorageDead(_2); // scope 0 at $DIR/boxes.rs:+1:25: +1:26
+ drop(_3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/boxes.rs:+1:26: +1:27
+ }
+
+ bb2: {
+ StorageDead(_3); // scope 0 at $DIR/boxes.rs:+1:26: +1:27
+ nop; // scope 0 at $DIR/boxes.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/boxes.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/boxes.rs:+2:2: +2:2
+ }
+
+ bb3 (cleanup): {
+ resume; // scope 0 at $DIR/boxes.rs:+0:1: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/boxes.rs b/src/test/mir-opt/const_prop/boxes.rs
new file mode 100644
index 000000000..fea666a44
--- /dev/null
+++ b/src/test/mir-opt/const_prop/boxes.rs
@@ -0,0 +1,13 @@
+// compile-flags: -O
+// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32
+// ignore-wasm64
+
+#![feature(box_syntax)]
+
+// Note: this test verifies that we, in fact, do not const prop `box`
+
+// EMIT_MIR boxes.main.ConstProp.diff
+fn main() {
+ let x = *(box 42) + 0;
+}
diff --git a/src/test/mir-opt/const_prop/cast.main.ConstProp.diff b/src/test/mir-opt/const_prop/cast.main.ConstProp.diff
new file mode 100644
index 000000000..5698a612f
--- /dev/null
+++ b/src/test/mir-opt/const_prop/cast.main.ConstProp.diff
@@ -0,0 +1,28 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/cast.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/cast.rs:+1:9: +1:10
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/cast.rs:+1:9: +1:10
+ let _2: u8; // in scope 1 at $DIR/cast.rs:+3:9: +3:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/cast.rs:+3:9: +3:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/cast.rs:+1:9: +1:10
+- _1 = const 42_u8 as u32 (Misc); // scope 0 at $DIR/cast.rs:+1:13: +1:24
++ _1 = const 42_u32; // scope 0 at $DIR/cast.rs:+1:13: +1:24
+ StorageLive(_2); // scope 1 at $DIR/cast.rs:+3:9: +3:10
+- _2 = const 42_u32 as u8 (Misc); // scope 1 at $DIR/cast.rs:+3:13: +3:24
++ _2 = const 42_u8; // scope 1 at $DIR/cast.rs:+3:13: +3:24
+ nop; // scope 0 at $DIR/cast.rs:+0:11: +4:2
+ StorageDead(_2); // scope 1 at $DIR/cast.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/cast.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/cast.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/cast.rs b/src/test/mir-opt/const_prop/cast.rs
new file mode 100644
index 000000000..680cab007
--- /dev/null
+++ b/src/test/mir-opt/const_prop/cast.rs
@@ -0,0 +1,7 @@
+// EMIT_MIR cast.main.ConstProp.diff
+
+fn main() {
+ let x = 42u8 as u32;
+
+ let y = 42u32 as u8;
+}
diff --git a/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff
new file mode 100644
index 000000000..5e33d0542
--- /dev/null
+++ b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff
@@ -0,0 +1,28 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/checked_add.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/checked_add.rs:+1:9: +1:10
+ let mut _2: (u32, bool); // in scope 0 at $DIR/checked_add.rs:+1:18: +1:23
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/checked_add.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/checked_add.rs:+1:9: +1:10
+- _2 = CheckedAdd(const 1_u32, const 1_u32); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
+- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
++ _2 = const (2_u32, false); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
+ }
+
+ bb1: {
+- _1 = move (_2.0: u32); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
++ _1 = const 2_u32; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
+ nop; // scope 0 at $DIR/checked_add.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/checked_add.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/checked_add.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/checked_add.rs b/src/test/mir-opt/const_prop/checked_add.rs
new file mode 100644
index 000000000..08d59b6fb
--- /dev/null
+++ b/src/test/mir-opt/const_prop/checked_add.rs
@@ -0,0 +1,6 @@
+// compile-flags: -C overflow-checks=on
+
+// EMIT_MIR checked_add.main.ConstProp.diff
+fn main() {
+ let x: u32 = 1 + 1;
+}
diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
new file mode 100644
index 000000000..c21b24591
--- /dev/null
+++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
@@ -0,0 +1,44 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/const_prop_fails_gracefully.rs:+0:11: +0:11
+ let _1: usize; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10
+ let mut _2: *const i32; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:30
+ let _3: &i32; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
+ let _4: (); // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12
+ let mut _5: usize; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10
+ StorageLive(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:30
+ StorageLive(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
+ _3 = const FOO; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
+ // mir::Constant
+ // + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
+ // + literal: Const { ty: &i32, val: Unevaluated(FOO, [], None) }
+ _2 = &raw const (*_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
+ _1 = move _2 as usize (PointerExposeAddress); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:39
+ StorageDead(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:38: +2:39
+ StorageDead(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:39: +2:40
+ StorageLive(_4); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12
+ StorageLive(_5); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11
+ _5 = _1; // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11
+ _4 = read(move _5) -> bb1; // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12
+ // mir::Constant
+ // + span: $DIR/const_prop_fails_gracefully.rs:8:5: 8:9
+ // + literal: Const { ty: fn(usize) {read}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_5); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:11: +3:12
+ StorageDead(_4); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:12: +3:13
+ nop; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+0:11: +4:2
+ StorageDead(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs
new file mode 100644
index 000000000..8bd68527f
--- /dev/null
+++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs
@@ -0,0 +1,9 @@
+#[inline(never)]
+fn read(_: usize) { }
+
+// EMIT_MIR const_prop_fails_gracefully.main.ConstProp.diff
+fn main() {
+ const FOO: &i32 = &1;
+ let x = FOO as *const i32 as usize;
+ read(x);
+}
diff --git a/src/test/mir-opt/const_prop/control-flow-simplification.rs b/src/test/mir-opt/const_prop/control-flow-simplification.rs
new file mode 100644
index 000000000..aa4ce19f6
--- /dev/null
+++ b/src/test/mir-opt/const_prop/control-flow-simplification.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Zmir-opt-level=1
+
+trait NeedsDrop:Sized{
+ const NEEDS:bool=std::mem::needs_drop::<Self>();
+}
+
+impl<This> NeedsDrop for This{}
+
+// EMIT_MIR control_flow_simplification.hello.ConstProp.diff
+// EMIT_MIR control_flow_simplification.hello.PreCodegen.before.mir
+fn hello<T>(){
+ if <bool>::NEEDS {
+ panic!()
+ }
+}
+
+pub fn main() {
+ hello::<()>();
+ hello::<Vec<()>>();
+}
diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff
new file mode 100644
index 000000000..5f4df0d88
--- /dev/null
+++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff
@@ -0,0 +1,34 @@
+- // MIR for `hello` before ConstProp
++ // MIR for `hello` after ConstProp
+
+ fn hello() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:+0:14: +0:14
+ let mut _1: bool; // in scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
+ let mut _2: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
+- _1 = const <bool as NeedsDrop>::NEEDS; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
+- switchInt(move _1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
++ _1 = const false; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
++ switchInt(const false) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
+ }
+
+ bb1: {
+ StorageLive(_2); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+ _2 = begin_panic::<&str>(const "explicit panic"); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
+ // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ }
+
+ bb2: {
+ nop; // scope 0 at $DIR/control-flow-simplification.rs:+3:6: +3:6
+ StorageDead(_1); // scope 0 at $DIR/control-flow-simplification.rs:+3:5: +3:6
+ return; // scope 0 at $DIR/control-flow-simplification.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir b/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir
new file mode 100644
index 000000000..70f979775
--- /dev/null
+++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir
@@ -0,0 +1,9 @@
+// MIR for `hello` before PreCodegen
+
+fn hello() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:+0:14: +0:14
+
+ bb0: {
+ return; // scope 0 at $DIR/control-flow-simplification.rs:+4:2: +4:2
+ }
+}
diff --git a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..5b4ecaa80
--- /dev/null
+++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff
@@ -0,0 +1,52 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/discriminant.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/discriminant.rs:+1:9: +1:10
+ let mut _2: i32; // in scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ let mut _3: std::option::Option<bool>; // in scope 0 at $DIR/discriminant.rs:+1:34: +1:44
+ let mut _4: isize; // in scope 0 at $DIR/discriminant.rs:+1:21: +1:31
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/discriminant.rs:+1:9: +1:10
+ }
+ scope 2 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/discriminant.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ StorageLive(_3); // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+ Deinit(_3); // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+ ((_3 as Some).0: bool) = const true; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+ discriminant(_3) = 1; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+- _4 = discriminant(_3); // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
++ _4 = const 1_isize; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
++ switchInt(const 1_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+ }
+
+ bb1: {
+ switchInt(((_3 as Some).0: bool)) -> [false: bb3, otherwise: bb2]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+ }
+
+ bb2: {
+ _2 = const 42_i32; // scope 2 at $DIR/discriminant.rs:+1:47: +1:49
+ goto -> bb4; // scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ }
+
+ bb3: {
+ _2 = const 10_i32; // scope 0 at $DIR/discriminant.rs:+1:59: +1:61
+ goto -> bb4; // scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ }
+
+ bb4: {
+ _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/discriminant.rs:+1:13: +1:68
+ StorageDead(_2); // scope 0 at $DIR/discriminant.rs:+1:67: +1:68
+ StorageDead(_3); // scope 0 at $DIR/discriminant.rs:+1:68: +1:69
+ nop; // scope 0 at $DIR/discriminant.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/discriminant.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/discriminant.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..5b4ecaa80
--- /dev/null
+++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff
@@ -0,0 +1,52 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/discriminant.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/discriminant.rs:+1:9: +1:10
+ let mut _2: i32; // in scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ let mut _3: std::option::Option<bool>; // in scope 0 at $DIR/discriminant.rs:+1:34: +1:44
+ let mut _4: isize; // in scope 0 at $DIR/discriminant.rs:+1:21: +1:31
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/discriminant.rs:+1:9: +1:10
+ }
+ scope 2 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/discriminant.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ StorageLive(_3); // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+ Deinit(_3); // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+ ((_3 as Some).0: bool) = const true; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+ discriminant(_3) = 1; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+- _4 = discriminant(_3); // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
++ _4 = const 1_isize; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
++ switchInt(const 1_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+ }
+
+ bb1: {
+ switchInt(((_3 as Some).0: bool)) -> [false: bb3, otherwise: bb2]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+ }
+
+ bb2: {
+ _2 = const 42_i32; // scope 2 at $DIR/discriminant.rs:+1:47: +1:49
+ goto -> bb4; // scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ }
+
+ bb3: {
+ _2 = const 10_i32; // scope 0 at $DIR/discriminant.rs:+1:59: +1:61
+ goto -> bb4; // scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ }
+
+ bb4: {
+ _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/discriminant.rs:+1:13: +1:68
+ StorageDead(_2); // scope 0 at $DIR/discriminant.rs:+1:67: +1:68
+ StorageDead(_3); // scope 0 at $DIR/discriminant.rs:+1:68: +1:69
+ nop; // scope 0 at $DIR/discriminant.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/discriminant.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/discriminant.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/discriminant.rs b/src/test/mir-opt/const_prop/discriminant.rs
new file mode 100644
index 000000000..67538b3c7
--- /dev/null
+++ b/src/test/mir-opt/const_prop/discriminant.rs
@@ -0,0 +1,12 @@
+// compile-flags: -O
+
+// FIXME(wesleywiser): Ideally, we could const-prop away all of this and just be left with
+// `let x = 42` but that doesn't work because const-prop doesn't support `Operand::Indirect`
+// and `InterpCx::eval_place()` always forces an allocation which creates the `Indirect`.
+// Fixing either of those will allow us to const-prop this away.
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR discriminant.main.ConstProp.diff
+fn main() {
+ let x = (if let Some(true) = Some(true) { 42 } else { 10 }) + 0;
+}
diff --git a/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff
new file mode 100644
index 000000000..2e1e32545
--- /dev/null
+++ b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff
@@ -0,0 +1,33 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/indirect.rs:+0:11: +0:11
+ let _1: u8; // in scope 0 at $DIR/indirect.rs:+1:9: +1:10
+ let mut _2: u8; // in scope 0 at $DIR/indirect.rs:+1:13: +1:25
+ let mut _3: (u8, bool); // in scope 0 at $DIR/indirect.rs:+1:13: +1:29
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/indirect.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/indirect.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/indirect.rs:+1:13: +1:25
+- _2 = const 2_u32 as u8 (Misc); // scope 0 at $DIR/indirect.rs:+1:13: +1:25
+- _3 = CheckedAdd(_2, const 1_u8); // scope 0 at $DIR/indirect.rs:+1:13: +1:29
+- assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
++ _2 = const 2_u8; // scope 0 at $DIR/indirect.rs:+1:13: +1:25
++ _3 = const (3_u8, false); // scope 0 at $DIR/indirect.rs:+1:13: +1:29
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u8, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
+ }
+
+ bb1: {
+- _1 = move (_3.0: u8); // scope 0 at $DIR/indirect.rs:+1:13: +1:29
++ _1 = const 3_u8; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
+ StorageDead(_2); // scope 0 at $DIR/indirect.rs:+1:28: +1:29
+ nop; // scope 0 at $DIR/indirect.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/indirect.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/indirect.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/indirect.rs b/src/test/mir-opt/const_prop/indirect.rs
new file mode 100644
index 000000000..37217ca81
--- /dev/null
+++ b/src/test/mir-opt/const_prop/indirect.rs
@@ -0,0 +1,6 @@
+// compile-flags: -C overflow-checks=on
+
+// EMIT_MIR indirect.main.ConstProp.diff
+fn main() {
+ let x = (2u32 as u8) + 1;
+}
diff --git a/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff
new file mode 100644
index 000000000..67a4dc3c0
--- /dev/null
+++ b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff
@@ -0,0 +1,77 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/invalid_constant.rs:+0:11: +0:11
+ let _1: char; // in scope 0 at $DIR/invalid_constant.rs:+6:9: +6:22
+ let mut _2: main::InvalidChar; // in scope 0 at $DIR/invalid_constant.rs:+6:34: +6:63
+ let mut _4: E; // in scope 0 at $DIR/invalid_constant.rs:+13:25: +13:59
+ let mut _5: main::InvalidTag; // in scope 0 at $DIR/invalid_constant.rs:+13:34: +13:55
+ let mut _7: Empty; // in scope 0 at $DIR/invalid_constant.rs:+20:35: +20:73
+ let mut _8: main::NoVariants; // in scope 0 at $DIR/invalid_constant.rs:+20:44: +20:65
+ scope 1 {
+ debug _invalid_char => _1; // in scope 1 at $DIR/invalid_constant.rs:+6:9: +6:22
+ let _3: [E; 1]; // in scope 1 at $DIR/invalid_constant.rs:+13:9: +13:21
+ scope 3 {
+ debug _invalid_tag => _3; // in scope 3 at $DIR/invalid_constant.rs:+13:9: +13:21
+ let _6: [Empty; 1]; // in scope 3 at $DIR/invalid_constant.rs:+20:9: +20:31
+ scope 5 {
+ debug _enum_without_variants => _6; // in scope 5 at $DIR/invalid_constant.rs:+20:9: +20:31
+ let _9: main::Str<"���">; // in scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22
+ scope 7 {
+ debug _non_utf8_str => _9; // in scope 7 at $DIR/invalid_constant.rs:+24:9: +24:22
+ }
+ }
+ scope 6 {
+ }
+ }
+ scope 4 {
+ }
+ }
+ scope 2 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/invalid_constant.rs:+6:9: +6:22
+ StorageLive(_2); // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:63
+ Deinit(_2); // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:63
+ (_2.0: u32) = const 1114113_u32; // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:63
+- _1 = (_2.1: char); // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:67
++ _1 = const {transmute(0x00110001): char}; // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:67
+ StorageDead(_2); // scope 0 at $DIR/invalid_constant.rs:+6:69: +6:70
+ StorageLive(_3); // scope 1 at $DIR/invalid_constant.rs:+13:9: +13:21
+ StorageLive(_4); // scope 1 at $DIR/invalid_constant.rs:+13:25: +13:59
+ StorageLive(_5); // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:55
+ Deinit(_5); // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:55
+ (_5.0: u32) = const 4_u32; // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:55
+- _4 = (_5.1: E); // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:57
+- _3 = [move _4]; // scope 1 at $DIR/invalid_constant.rs:+13:24: +13:60
++ _4 = const Scalar(0x00000004): E; // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:57
++ // mir::Constant
++ // + span: $DIR/invalid_constant.rs:28:34: 28:57
++ // + literal: Const { ty: E, val: Value(Scalar(0x00000004)) }
++ _3 = [const Scalar(0x00000004): E]; // scope 1 at $DIR/invalid_constant.rs:+13:24: +13:60
++ // mir::Constant
++ // + span: $DIR/invalid_constant.rs:28:24: 28:60
++ // + literal: Const { ty: E, val: Value(Scalar(0x00000004)) }
+ StorageDead(_4); // scope 1 at $DIR/invalid_constant.rs:+13:59: +13:60
+ StorageDead(_5); // scope 1 at $DIR/invalid_constant.rs:+13:60: +13:61
+ StorageLive(_6); // scope 3 at $DIR/invalid_constant.rs:+20:9: +20:31
+ StorageLive(_7); // scope 3 at $DIR/invalid_constant.rs:+20:35: +20:73
+ StorageLive(_8); // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65
+ Deinit(_8); // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65
+ (_8.0: u32) = const 0_u32; // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65
+ nop; // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:71
+ nop; // scope 3 at $DIR/invalid_constant.rs:+20:34: +20:74
+ StorageDead(_7); // scope 3 at $DIR/invalid_constant.rs:+20:73: +20:74
+ StorageDead(_8); // scope 3 at $DIR/invalid_constant.rs:+20:74: +20:75
+ StorageLive(_9); // scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22
+ nop; // scope 0 at $DIR/invalid_constant.rs:+0:11: +27:2
+ StorageDead(_9); // scope 5 at $DIR/invalid_constant.rs:+27:1: +27:2
+ StorageDead(_6); // scope 3 at $DIR/invalid_constant.rs:+27:1: +27:2
+ StorageDead(_3); // scope 1 at $DIR/invalid_constant.rs:+27:1: +27:2
+ StorageDead(_1); // scope 0 at $DIR/invalid_constant.rs:+27:1: +27:2
+ return; // scope 0 at $DIR/invalid_constant.rs:+27:2: +27:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/invalid_constant.rs b/src/test/mir-opt/const_prop/invalid_constant.rs
new file mode 100644
index 000000000..0337a7ca8
--- /dev/null
+++ b/src/test/mir-opt/const_prop/invalid_constant.rs
@@ -0,0 +1,42 @@
+// Verify that we can pretty print invalid constants.
+
+#![feature(adt_const_params)]
+#![feature(inline_const)]
+#![allow(incomplete_features)]
+
+#[derive(Copy, Clone)]
+#[repr(u32)]
+enum E { A, B, C }
+
+#[derive(Copy, Clone)]
+enum Empty {}
+
+// EMIT_MIR invalid_constant.main.ConstProp.diff
+fn main() {
+ // An invalid char.
+ union InvalidChar {
+ int: u32,
+ chr: char,
+ }
+ let _invalid_char = unsafe { InvalidChar { int: 0x110001 }.chr };
+
+ // An enum with an invalid tag. Regression test for #93688.
+ union InvalidTag {
+ int: u32,
+ e: E,
+ }
+ let _invalid_tag = [unsafe { InvalidTag { int: 4 }.e }];
+
+ // An enum without variants. Regression test for #94073.
+ union NoVariants {
+ int: u32,
+ empty: Empty,
+ }
+ let _enum_without_variants = [unsafe { NoVariants { int: 0 }.empty }];
+
+ // A non-UTF-8 string slice. Regression test for #75763 and #78520.
+ struct Str<const S: &'static str>;
+ let _non_utf8_str: Str::<{
+ unsafe { std::mem::transmute::<&[u8], &str>(&[0xC0, 0xC1, 0xF5]) }
+ }>;
+}
diff --git a/src/test/mir-opt/const_prop/issue-66971.rs b/src/test/mir-opt/const_prop/issue-66971.rs
new file mode 100644
index 000000000..81eccae46
--- /dev/null
+++ b/src/test/mir-opt/const_prop/issue-66971.rs
@@ -0,0 +1,17 @@
+// compile-flags: -Z mir-opt-level=3
+
+// Due to a bug in propagating scalar pairs the assertion below used to fail. In the expected
+// outputs below, after ConstProp this is how _2 would look like with the bug:
+//
+// _2 = (const Scalar(0x00) : (), const 0u8);
+//
+// Which has the wrong type.
+
+fn encode(this: ((), u8, u8)) {
+ assert!(this.2 == 0);
+}
+
+// EMIT_MIR issue_66971.main.ConstProp.diff
+fn main() {
+ encode(((), 0, 0));
+}
diff --git a/src/test/mir-opt/const_prop/issue-67019.rs b/src/test/mir-opt/const_prop/issue-67019.rs
new file mode 100644
index 000000000..c78b8b971
--- /dev/null
+++ b/src/test/mir-opt/const_prop/issue-67019.rs
@@ -0,0 +1,12 @@
+// compile-flags: -Z mir-opt-level=3
+
+// This used to ICE in const-prop
+
+fn test(this: ((u8, u8),)) {
+ assert!((this.0).0 == 1);
+}
+
+// EMIT_MIR issue_67019.main.ConstProp.diff
+fn main() {
+ test(((1, 2),));
+}
diff --git a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff
new file mode 100644
index 000000000..b3d5980aa
--- /dev/null
+++ b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff
@@ -0,0 +1,33 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-66971.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/issue-66971.rs:+1:5: +1:23
+ let mut _2: ((), u8, u8); // in scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
+ let mut _3: (); // in scope 0 at $DIR/issue-66971.rs:+1:13: +1:15
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-66971.rs:+1:5: +1:23
+ StorageLive(_2); // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
+ StorageLive(_3); // scope 0 at $DIR/issue-66971.rs:+1:13: +1:15
+ nop; // scope 0 at $DIR/issue-66971.rs:+1:13: +1:15
+ Deinit(_2); // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
+ nop; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
+ (_2.1: u8) = const 0_u8; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
+ (_2.2: u8) = const 0_u8; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
+ StorageDead(_3); // scope 0 at $DIR/issue-66971.rs:+1:21: +1:22
+ _1 = encode(move _2) -> bb1; // scope 0 at $DIR/issue-66971.rs:+1:5: +1:23
+ // mir::Constant
+ // + span: $DIR/issue-66971.rs:16:5: 16:11
+ // + literal: Const { ty: fn(((), u8, u8)) {encode}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 0 at $DIR/issue-66971.rs:+1:22: +1:23
+ StorageDead(_1); // scope 0 at $DIR/issue-66971.rs:+1:23: +1:24
+ nop; // scope 0 at $DIR/issue-66971.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/issue-66971.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
new file mode 100644
index 000000000..8330b5052
--- /dev/null
+++ b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
@@ -0,0 +1,34 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-67019.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/issue-67019.rs:+1:5: +1:20
+ let mut _2: ((u8, u8),); // in scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
+ let mut _3: (u8, u8); // in scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-67019.rs:+1:5: +1:20
+ StorageLive(_2); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
+ StorageLive(_3); // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
+ Deinit(_3); // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
+ (_3.0: u8) = const 1_u8; // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
+ (_3.1: u8) = const 2_u8; // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
+ Deinit(_2); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
+- (_2.0: (u8, u8)) = move _3; // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
++ (_2.0: (u8, u8)) = const (1_u8, 2_u8); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
+ StorageDead(_3); // scope 0 at $DIR/issue-67019.rs:+1:18: +1:19
+ _1 = test(move _2) -> bb1; // scope 0 at $DIR/issue-67019.rs:+1:5: +1:20
+ // mir::Constant
+ // + span: $DIR/issue-67019.rs:11:5: 11:9
+ // + literal: Const { ty: fn(((u8, u8),)) {test}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 0 at $DIR/issue-67019.rs:+1:19: +1:20
+ StorageDead(_1); // scope 0 at $DIR/issue-67019.rs:+1:20: +1:21
+ nop; // scope 0 at $DIR/issue-67019.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/issue-67019.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..96de39258
--- /dev/null
+++ b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff
@@ -0,0 +1,37 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/large_array_index.rs:+0:11: +0:11
+ let _1: u8; // in scope 0 at $DIR/large_array_index.rs:+2:9: +2:10
+ let mut _2: [u8; 5000]; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:29
+ let _3: usize; // in scope 0 at $DIR/large_array_index.rs:+2:30: +2:31
+ let mut _4: usize; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ let mut _5: bool; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/large_array_index.rs:+2:9: +2:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/large_array_index.rs:+2:9: +2:10
+ StorageLive(_2); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29
+ _2 = [const 0_u8; 5000]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29
+ StorageLive(_3); // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31
+ _3 = const 2_usize; // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31
+ _4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+- _5 = Lt(_3, _4); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
++ _5 = const true; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ }
+
+ bb1: {
+ _1 = _2[_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
+ nop; // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2
+ StorageDead(_1); // scope 0 at $DIR/large_array_index.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/large_array_index.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..96de39258
--- /dev/null
+++ b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff
@@ -0,0 +1,37 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/large_array_index.rs:+0:11: +0:11
+ let _1: u8; // in scope 0 at $DIR/large_array_index.rs:+2:9: +2:10
+ let mut _2: [u8; 5000]; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:29
+ let _3: usize; // in scope 0 at $DIR/large_array_index.rs:+2:30: +2:31
+ let mut _4: usize; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ let mut _5: bool; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/large_array_index.rs:+2:9: +2:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/large_array_index.rs:+2:9: +2:10
+ StorageLive(_2); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29
+ _2 = [const 0_u8; 5000]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29
+ StorageLive(_3); // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31
+ _3 = const 2_usize; // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31
+ _4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+- _5 = Lt(_3, _4); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
++ _5 = const true; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ }
+
+ bb1: {
+ _1 = _2[_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
+ nop; // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2
+ StorageDead(_1); // scope 0 at $DIR/large_array_index.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/large_array_index.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/large_array_index.rs b/src/test/mir-opt/const_prop/large_array_index.rs
new file mode 100644
index 000000000..48d134376
--- /dev/null
+++ b/src/test/mir-opt/const_prop/large_array_index.rs
@@ -0,0 +1,7 @@
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
+// EMIT_MIR large_array_index.main.ConstProp.diff
+fn main() {
+ // check that we don't propagate this, because it's too large
+ let x: u8 = [0_u8; 5000][2];
+}
diff --git a/src/test/mir-opt/const_prop/mult_by_zero.rs b/src/test/mir-opt/const_prop/mult_by_zero.rs
new file mode 100644
index 000000000..b0ecdf181
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mult_by_zero.rs
@@ -0,0 +1,10 @@
+// compile-flags: -O -Zmir-opt-level=4
+
+// EMIT_MIR mult_by_zero.test.ConstProp.diff
+fn test(x : i32) -> i32 {
+ x * 0
+}
+
+fn main() {
+ test(10);
+}
diff --git a/src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff b/src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff
new file mode 100644
index 000000000..629c8e601
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff
@@ -0,0 +1,18 @@
+- // MIR for `test` before ConstProp
++ // MIR for `test` after ConstProp
+
+ fn test(_1: i32) -> i32 {
+ debug x => _1; // in scope 0 at $DIR/mult_by_zero.rs:+0:9: +0:10
+ let mut _0: i32; // return place in scope 0 at $DIR/mult_by_zero.rs:+0:21: +0:24
+ let mut _2: i32; // in scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:4
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:4
+ _2 = _1; // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:4
+- _0 = Mul(move _2, const 0_i32); // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:8
++ _0 = const 0_i32; // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:8
+ StorageDead(_2); // scope 0 at $DIR/mult_by_zero.rs:+1:7: +1:8
+ return; // scope 0 at $DIR/mult_by_zero.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff
new file mode 100644
index 000000000..3bbd6a87f
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff
@@ -0,0 +1,28 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/mutable_variable.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/mutable_variable.rs:+1:9: +1:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/mutable_variable.rs:+1:9: +1:14
+ let _2: i32; // in scope 1 at $DIR/mutable_variable.rs:+3:9: +3:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/mutable_variable.rs:+3:9: +3:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/mutable_variable.rs:+1:9: +1:14
+ _1 = const 42_i32; // scope 0 at $DIR/mutable_variable.rs:+1:17: +1:19
+ _1 = const 99_i32; // scope 1 at $DIR/mutable_variable.rs:+2:5: +2:11
+ StorageLive(_2); // scope 1 at $DIR/mutable_variable.rs:+3:9: +3:10
+- _2 = _1; // scope 1 at $DIR/mutable_variable.rs:+3:13: +3:14
++ _2 = const 99_i32; // scope 1 at $DIR/mutable_variable.rs:+3:13: +3:14
+ nop; // scope 0 at $DIR/mutable_variable.rs:+0:11: +4:2
+ StorageDead(_2); // scope 1 at $DIR/mutable_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/mutable_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/mutable_variable.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable.rs b/src/test/mir-opt/const_prop/mutable_variable.rs
new file mode 100644
index 000000000..801e7a9fc
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable.rs
@@ -0,0 +1,8 @@
+// compile-flags: -O
+
+// EMIT_MIR mutable_variable.main.ConstProp.diff
+fn main() {
+ let mut x = 42;
+ x = 99;
+ let y = x;
+}
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff
new file mode 100644
index 000000000..fed6a98b9
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff
@@ -0,0 +1,30 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_aggregate.rs:+0:11: +0:11
+ let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
+ let _2: (i32, i32); // in scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
+ Deinit(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25
+ (_1.0: i32) = const 42_i32; // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25
+ (_1.1: i32) = const 43_i32; // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25
+ (_1.1: i32) = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate.rs:+2:5: +2:13
+ StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
+- _2 = _1; // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14
++ _2 = const (42_i32, 99_i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14
+ nop; // scope 0 at $DIR/mutable_variable_aggregate.rs:+0:11: +4:2
+ StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs
new file mode 100644
index 000000000..e0b4b77ba
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs
@@ -0,0 +1,8 @@
+// compile-flags: -O
+
+// EMIT_MIR mutable_variable_aggregate.main.ConstProp.diff
+fn main() {
+ let mut x = (42, 43);
+ x.1 = 99;
+ let y = x;
+}
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff
new file mode 100644
index 000000000..90eebd8fe
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff
@@ -0,0 +1,36 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+0:11: +0:11
+ let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:9: +1:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:9: +1:14
+ let _2: &mut (i32, i32); // in scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10
+ scope 2 {
+ debug z => _2; // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10
+ let _3: (i32, i32); // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
+ scope 3 {
+ debug y => _3; // in scope 3 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:9: +1:14
+ Deinit(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:17: +1:25
+ (_1.0: i32) = const 42_i32; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:17: +1:25
+ (_1.1: i32) = const 43_i32; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:17: +1:25
+ StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10
+ _2 = &mut _1; // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:13: +2:19
+ ((*_2).1: i32) = const 99_i32; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+3:5: +3:13
+ StorageLive(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
+ _3 = _1; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14
+ nop; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+0:11: +5:2
+ StorageDead(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2
+ StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs
new file mode 100644
index 000000000..79ac497c7
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs
@@ -0,0 +1,9 @@
+// compile-flags: -O
+
+// EMIT_MIR mutable_variable_aggregate_mut_ref.main.ConstProp.diff
+fn main() {
+ let mut x = (42, 43);
+ let z = &mut x;
+ z.1 = 99;
+ let y = x;
+}
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff
new file mode 100644
index 000000000..c678f7b03
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff
@@ -0,0 +1,35 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+0:11: +0:11
+ let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14
+ let _2: i32; // in scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14
+ _1 = foo() -> bb1; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:29: +1:34
+ // mir::Constant
+ // + span: $DIR/mutable_variable_aggregate_partial_read.rs:5:29: 5:32
+ // + literal: Const { ty: fn() -> (i32, i32) {foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ (_1.1: i32) = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+2:5: +2:13
+ (_1.0: i32) = const 42_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+3:5: +3:13
+ StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10
+- _2 = (_1.1: i32); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:13: +4:16
++ _2 = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:13: +4:16
+ nop; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+0:11: +5:2
+ StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs
new file mode 100644
index 000000000..9bb62b897
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs
@@ -0,0 +1,14 @@
+// compile-flags: -O
+
+// EMIT_MIR mutable_variable_aggregate_partial_read.main.ConstProp.diff
+fn main() {
+ let mut x: (i32, i32) = foo();
+ x.1 = 99;
+ x.0 = 42;
+ let y = x.1;
+}
+
+#[inline(never)]
+fn foo() -> (i32, i32) {
+ unimplemented!()
+}
diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff
new file mode 100644
index 000000000..4c2ba9a09
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff
@@ -0,0 +1,48 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_no_prop.rs:+0:11: +0:11
+ let mut _1: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+1:9: +1:14
+ let _2: (); // in scope 0 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6
+ let mut _3: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ let mut _4: *mut u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/mutable_variable_no_prop.rs:+1:9: +1:14
+ let _5: u32; // in scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10
+ scope 2 {
+ }
+ scope 3 {
+ debug y => _5; // in scope 3 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/mutable_variable_no_prop.rs:+1:9: +1:14
+ _1 = const 42_u32; // scope 0 at $DIR/mutable_variable_no_prop.rs:+1:17: +1:19
+ StorageLive(_2); // scope 1 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6
+ StorageLive(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ StorageLive(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ _4 = const {alloc1: *mut u32}; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ // mir::Constant
+ // + span: $DIR/mutable_variable_no_prop.rs:9:13: 9:19
+ // + literal: Const { ty: *mut u32, val: Value(Scalar(alloc1)) }
+ _3 = (*_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ _1 = move _3; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:9: +3:19
+ StorageDead(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:18: +3:19
+ StorageDead(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:19: +3:20
+ nop; // scope 2 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6
+ StorageDead(_2); // scope 1 at $DIR/mutable_variable_no_prop.rs:+4:5: +4:6
+ StorageLive(_5); // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10
+ _5 = _1; // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:13: +5:14
+ nop; // scope 0 at $DIR/mutable_variable_no_prop.rs:+0:11: +6:2
+ StorageDead(_5); // scope 1 at $DIR/mutable_variable_no_prop.rs:+6:1: +6:2
+ StorageDead(_1); // scope 0 at $DIR/mutable_variable_no_prop.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/mutable_variable_no_prop.rs:+6:2: +6:2
+ }
+ }
+
+ alloc1 (static: STATIC, size: 4, align: 4) {
+ 2a 00 00 00 │ *...
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs b/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs
new file mode 100644
index 000000000..4126fb3c6
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs
@@ -0,0 +1,12 @@
+// compile-flags: -O
+
+static mut STATIC: u32 = 42;
+
+// EMIT_MIR mutable_variable_no_prop.main.ConstProp.diff
+fn main() {
+ let mut x = 42;
+ unsafe {
+ x = STATIC;
+ }
+ let y = x;
+}
diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
new file mode 100644
index 000000000..5328792b3
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
@@ -0,0 +1,53 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10
+ let mut _3: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10
+ let mut _2: (i32, i32); // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ scope 2 {
+ debug x => _2; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ let _4: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
+ scope 3 {
+ debug y => _4; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
+ let _5: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
+ scope 4 {
+ debug z => _5; // in scope 4 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10
+ _1 = foo() -> bb1; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:13: +1:18
+ // mir::Constant
+ // + span: $DIR/mutable_variable_unprop_assign.rs:5:13: 5:16
+ // + literal: Const { ty: fn() -> i32 {foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ Deinit(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ (_2.0: i32) = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ (_2.1: i32) = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
+ _3 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
+ (_2.1: i32) = move _3; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12
+ StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
+ StorageLive(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
+ _4 = (_2.1: i32); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16
+ StorageLive(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
+ _5 = (_2.0: i32); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16
+ nop; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +6:2
+ StorageDead(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ StorageDead(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ StorageDead(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ StorageDead(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs
new file mode 100644
index 000000000..13f1b3f47
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs
@@ -0,0 +1,15 @@
+// compile-flags: -O
+
+// EMIT_MIR mutable_variable_unprop_assign.main.ConstProp.diff
+fn main() {
+ let a = foo();
+ let mut x: (i32, i32) = (1, 2);
+ x.1 = a;
+ let y = x.1;
+ let z = x.0; // this could theoretically be allowed, but we can't handle it right now
+}
+
+#[inline(never)]
+fn foo() -> i32 {
+ unimplemented!()
+}
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..94aadfaf8
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff
@@ -0,0 +1,68 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let mut _2: (i32, bool); // in scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ let mut _4: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
++ _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ }
+
+ bb1: {
+- _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
++ _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ _5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ _6 = const 6_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+- _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
++ _7 = const true; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ }
+
+ bb2: {
+- _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
++ _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
+ StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
+ StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ Deinit(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ (_9.0: u32) = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ (_9.1: u32) = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
++ _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
+ StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
+ nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2
+ StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..94aadfaf8
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff
@@ -0,0 +1,68 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let mut _2: (i32, bool); // in scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ let mut _4: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
++ _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ }
+
+ bb1: {
+- _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
++ _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ _5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ _6 = const 6_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+- _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
++ _7 = const true; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ }
+
+ bb2: {
+- _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
++ _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
+ StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
+ StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ Deinit(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ (_9.0: u32) = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ (_9.1: u32) = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
++ _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
+ StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
+ nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2
+ StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir
new file mode 100644
index 000000000..75cea8ad2
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir
@@ -0,0 +1,27 @@
+// MIR for `main` after SimplifyLocals
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
+ }
+}
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir
new file mode 100644
index 000000000..75cea8ad2
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir
@@ -0,0 +1,27 @@
+// MIR for `main` after SimplifyLocals
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
+ }
+}
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.rs b/src/test/mir-opt/const_prop/optimizes_into_variable.rs
new file mode 100644
index 000000000..17265b7eb
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.rs
@@ -0,0 +1,15 @@
+// compile-flags: -C overflow-checks=on
+
+struct Point {
+ x: u32,
+ y: u32,
+}
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR optimizes_into_variable.main.ConstProp.diff
+// EMIT_MIR optimizes_into_variable.main.SimplifyLocals.after.mir
+fn main() {
+ let x = 2 + 2;
+ let y = [0, 1, 2, 3, 4, 5][3];
+ let z = (Point { x: 12, y: 42}).y;
+}
diff --git a/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff
new file mode 100644
index 000000000..89f43d751
--- /dev/null
+++ b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff
@@ -0,0 +1,48 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/read_immutable_static.rs:+0:11: +0:11
+ let _1: u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:9: +1:10
+ let mut _2: u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ let mut _3: &u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ let mut _4: u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+ let mut _5: &u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/read_immutable_static.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/read_immutable_static.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ StorageLive(_3); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ _3 = const {alloc1: &u8}; // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ // mir::Constant
+ // + span: $DIR/read_immutable_static.rs:7:13: 7:16
+ // + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }
+- _2 = (*_3); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
++ _2 = const 2_u8; // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ StorageLive(_4); // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+ StorageLive(_5); // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+ _5 = const {alloc1: &u8}; // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+ // mir::Constant
+ // + span: $DIR/read_immutable_static.rs:7:19: 7:22
+ // + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }
+- _4 = (*_5); // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+- _1 = Add(move _2, move _4); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:22
++ _4 = const 2_u8; // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
++ _1 = const 4_u8; // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:22
+ StorageDead(_4); // scope 0 at $DIR/read_immutable_static.rs:+1:21: +1:22
+ StorageDead(_2); // scope 0 at $DIR/read_immutable_static.rs:+1:21: +1:22
+ StorageDead(_5); // scope 0 at $DIR/read_immutable_static.rs:+1:22: +1:23
+ StorageDead(_3); // scope 0 at $DIR/read_immutable_static.rs:+1:22: +1:23
+ nop; // scope 0 at $DIR/read_immutable_static.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/read_immutable_static.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/read_immutable_static.rs:+2:2: +2:2
+ }
+ }
+
+ alloc1 (static: FOO, size: 1, align: 1) {
+ 02 │ .
+ }
+
diff --git a/src/test/mir-opt/const_prop/read_immutable_static.rs b/src/test/mir-opt/const_prop/read_immutable_static.rs
new file mode 100644
index 000000000..8a5f12c6f
--- /dev/null
+++ b/src/test/mir-opt/const_prop/read_immutable_static.rs
@@ -0,0 +1,8 @@
+// compile-flags: -O
+
+static FOO: u8 = 2;
+
+// EMIT_MIR read_immutable_static.main.ConstProp.diff
+fn main() {
+ let x = FOO + FOO;
+}
diff --git a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff
new file mode 100644
index 000000000..c8b09220f
--- /dev/null
+++ b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff
@@ -0,0 +1,27 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/ref_deref.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+ let mut _2: &i32; // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ let _3: i32; // in scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
+ let mut _4: &i32; // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+ StorageLive(_2); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ // mir::Constant
+ // + span: $DIR/ref_deref.rs:5:6: 5:10
+ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
+ _2 = _4; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+- _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
++ _1 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+ StorageDead(_2); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
+ StorageDead(_1); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
+ nop; // scope 0 at $DIR/ref_deref.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/ref_deref.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
new file mode 100644
index 000000000..d141d2cf8
--- /dev/null
+++ b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
@@ -0,0 +1,30 @@
+- // MIR for `main` before PromoteTemps
++ // MIR for `main` after PromoteTemps
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/ref_deref.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+ let mut _2: &i32; // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ let _3: i32; // in scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
++ let mut _4: &i32; // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+ StorageLive(_2); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+- StorageLive(_3); // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
+- _3 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
+- _2 = &_3; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
++ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
++ // mir::Constant
++ // + span: $DIR/ref_deref.rs:5:6: 5:10
++ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
++ _2 = &(*_4); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+- StorageDead(_3); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
+ StorageDead(_2); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
+ StorageDead(_1); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
+ _0 = const (); // scope 0 at $DIR/ref_deref.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/ref_deref.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/ref_deref.rs b/src/test/mir-opt/const_prop/ref_deref.rs
new file mode 100644
index 000000000..30ec97663
--- /dev/null
+++ b/src/test/mir-opt/const_prop/ref_deref.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR ref_deref.main.PromoteTemps.diff
+// EMIT_MIR ref_deref.main.ConstProp.diff
+
+fn main() {
+ *(&4);
+}
diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
new file mode 100644
index 000000000..f0c89caea
--- /dev/null
+++ b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
@@ -0,0 +1,26 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/ref_deref_project.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+ let mut _2: &i32; // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ let _3: (i32, i32); // in scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
+ let mut _4: &(i32, i32); // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+ StorageLive(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ // mir::Constant
+ // + span: $DIR/ref_deref_project.rs:5:6: 5:17
+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
+ _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+ StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
+ StorageDead(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
+ nop; // scope 0 at $DIR/ref_deref_project.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/ref_deref_project.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
new file mode 100644
index 000000000..d25540287
--- /dev/null
+++ b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
@@ -0,0 +1,30 @@
+- // MIR for `main` before PromoteTemps
++ // MIR for `main` after PromoteTemps
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/ref_deref_project.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+ let mut _2: &i32; // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ let _3: (i32, i32); // in scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
++ let mut _4: &(i32, i32); // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+ StorageLive(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+- StorageLive(_3); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
+- _3 = (const 4_i32, const 5_i32); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
+- _2 = &(_3.1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
++ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
++ // mir::Constant
++ // + span: $DIR/ref_deref_project.rs:5:6: 5:17
++ // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
++ _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+- StorageDead(_3); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
+ StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
+ StorageDead(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
+ _0 = const (); // scope 0 at $DIR/ref_deref_project.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/ref_deref_project.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/ref_deref_project.rs b/src/test/mir-opt/const_prop/ref_deref_project.rs
new file mode 100644
index 000000000..c7cc73651
--- /dev/null
+++ b/src/test/mir-opt/const_prop/ref_deref_project.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR ref_deref_project.main.PromoteTemps.diff
+// EMIT_MIR ref_deref_project.main.ConstProp.diff
+
+fn main() {
+ *(&(4, 5).1); // This does not currently propagate (#67862)
+}
diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
new file mode 100644
index 000000000..237a6f94a
--- /dev/null
+++ b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
@@ -0,0 +1,29 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/reify_fn_ptr.rs:+0:11: +0:11
+ let mut _1: *const fn(); // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41
+ let mut _2: usize; // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26
+ let mut _3: fn(); // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41
+ StorageLive(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26
+ StorageLive(_3); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17
+ _3 = main as fn() (Pointer(ReifyFnPointer)); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17
+ // mir::Constant
+ // + span: $DIR/reify_fn_ptr.rs:4:13: 4:17
+ // + literal: Const { ty: fn() {main}, val: Value(<ZST>) }
+ _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26
+ StorageDead(_3); // scope 0 at $DIR/reify_fn_ptr.rs:+1:25: +1:26
+ _1 = move _2 as *const fn() (PointerFromExposedAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41
+ StorageDead(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:40: +1:41
+ StorageDead(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:41: +1:42
+ nop; // scope 0 at $DIR/reify_fn_ptr.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/reify_fn_ptr.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr.rs b/src/test/mir-opt/const_prop/reify_fn_ptr.rs
new file mode 100644
index 000000000..bfe2563ad
--- /dev/null
+++ b/src/test/mir-opt/const_prop/reify_fn_ptr.rs
@@ -0,0 +1,5 @@
+// EMIT_MIR reify_fn_ptr.main.ConstProp.diff
+
+fn main() {
+ let _ = main as usize as *const fn();
+}
diff --git a/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..7c4977996
--- /dev/null
+++ b/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff
@@ -0,0 +1,43 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/repeat.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/repeat.rs:+1:9: +1:10
+ let mut _2: u32; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ let mut _3: [u32; 8]; // in scope 0 at $DIR/repeat.rs:+1:18: +1:25
+ let _4: usize; // in scope 0 at $DIR/repeat.rs:+1:26: +1:27
+ let mut _5: usize; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ let mut _6: bool; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/repeat.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/repeat.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ StorageLive(_3); // scope 0 at $DIR/repeat.rs:+1:18: +1:25
+ _3 = [const 42_u32; 8]; // scope 0 at $DIR/repeat.rs:+1:18: +1:25
+ StorageLive(_4); // scope 0 at $DIR/repeat.rs:+1:26: +1:27
+ _4 = const 2_usize; // scope 0 at $DIR/repeat.rs:+1:26: +1:27
+ _5 = const 8_usize; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+- _6 = Lt(_4, _5); // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
++ _6 = const true; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ }
+
+ bb1: {
+- _2 = _3[_4]; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+- _1 = Add(move _2, const 0_u32); // scope 0 at $DIR/repeat.rs:+1:18: +1:32
++ _2 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
++ _1 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:32
+ StorageDead(_2); // scope 0 at $DIR/repeat.rs:+1:31: +1:32
+ StorageDead(_4); // scope 0 at $DIR/repeat.rs:+1:32: +1:33
+ StorageDead(_3); // scope 0 at $DIR/repeat.rs:+1:32: +1:33
+ nop; // scope 0 at $DIR/repeat.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/repeat.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/repeat.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..7c4977996
--- /dev/null
+++ b/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff
@@ -0,0 +1,43 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/repeat.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/repeat.rs:+1:9: +1:10
+ let mut _2: u32; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ let mut _3: [u32; 8]; // in scope 0 at $DIR/repeat.rs:+1:18: +1:25
+ let _4: usize; // in scope 0 at $DIR/repeat.rs:+1:26: +1:27
+ let mut _5: usize; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ let mut _6: bool; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/repeat.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/repeat.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ StorageLive(_3); // scope 0 at $DIR/repeat.rs:+1:18: +1:25
+ _3 = [const 42_u32; 8]; // scope 0 at $DIR/repeat.rs:+1:18: +1:25
+ StorageLive(_4); // scope 0 at $DIR/repeat.rs:+1:26: +1:27
+ _4 = const 2_usize; // scope 0 at $DIR/repeat.rs:+1:26: +1:27
+ _5 = const 8_usize; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+- _6 = Lt(_4, _5); // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
++ _6 = const true; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ }
+
+ bb1: {
+- _2 = _3[_4]; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+- _1 = Add(move _2, const 0_u32); // scope 0 at $DIR/repeat.rs:+1:18: +1:32
++ _2 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
++ _1 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:32
+ StorageDead(_2); // scope 0 at $DIR/repeat.rs:+1:31: +1:32
+ StorageDead(_4); // scope 0 at $DIR/repeat.rs:+1:32: +1:33
+ StorageDead(_3); // scope 0 at $DIR/repeat.rs:+1:32: +1:33
+ nop; // scope 0 at $DIR/repeat.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/repeat.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/repeat.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/repeat.rs b/src/test/mir-opt/const_prop/repeat.rs
new file mode 100644
index 000000000..36d9b9fc6
--- /dev/null
+++ b/src/test/mir-opt/const_prop/repeat.rs
@@ -0,0 +1,7 @@
+// compile-flags: -O
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR repeat.main.ConstProp.diff
+fn main() {
+ let x: u32 = [42; 8][2] + 0;
+}
diff --git a/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff b/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff
new file mode 100644
index 000000000..5ebd8a520
--- /dev/null
+++ b/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff
@@ -0,0 +1,21 @@
+- // MIR for `add` before ConstProp
++ // MIR for `add` after ConstProp
+
+ fn add() -> u32 {
+ let mut _0: u32; // return place in scope 0 at $DIR/return_place.rs:+0:13: +0:16
+ let mut _1: (u32, bool); // in scope 0 at $DIR/return_place.rs:+1:5: +1:10
+
+ bb0: {
+- _1 = CheckedAdd(const 2_u32, const 2_u32); // scope 0 at $DIR/return_place.rs:+1:5: +1:10
+- assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:+1:5: +1:10
++ _1 = const (4_u32, false); // scope 0 at $DIR/return_place.rs:+1:5: +1:10
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:+1:5: +1:10
+ }
+
+ bb1: {
+- _0 = move (_1.0: u32); // scope 0 at $DIR/return_place.rs:+1:5: +1:10
++ _0 = const 4_u32; // scope 0 at $DIR/return_place.rs:+1:5: +1:10
+ return; // scope 0 at $DIR/return_place.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir b/src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir
new file mode 100644
index 000000000..ececd9942
--- /dev/null
+++ b/src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir
@@ -0,0 +1,10 @@
+// MIR for `add` before PreCodegen
+
+fn add() -> u32 {
+ let mut _0: u32; // return place in scope 0 at $DIR/return_place.rs:+0:13: +0:16
+
+ bb0: {
+ _0 = const 4_u32; // scope 0 at $DIR/return_place.rs:+1:5: +1:10
+ return; // scope 0 at $DIR/return_place.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/const_prop/return_place.rs b/src/test/mir-opt/const_prop/return_place.rs
new file mode 100644
index 000000000..06a853696
--- /dev/null
+++ b/src/test/mir-opt/const_prop/return_place.rs
@@ -0,0 +1,11 @@
+// compile-flags: -C overflow-checks=on
+
+// EMIT_MIR return_place.add.ConstProp.diff
+// EMIT_MIR return_place.add.PreCodegen.before.mir
+fn add() -> u32 {
+ 2 + 2
+}
+
+fn main() {
+ add();
+}
diff --git a/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff b/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff
new file mode 100644
index 000000000..5920937e0
--- /dev/null
+++ b/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff
@@ -0,0 +1,35 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/scalar_literal_propagation.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10
+ let _2: (); // in scope 0 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15
+ let mut _3: u32; // in scope 0 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10
+ _1 = const 1_u32; // scope 0 at $DIR/scalar_literal_propagation.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15
+ StorageLive(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14
+- _3 = _1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14
+- _2 = consume(move _3) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15
++ _3 = const 1_u32; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14
++ _2 = consume(const 1_u32) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15
+ // mir::Constant
+ // + span: $DIR/scalar_literal_propagation.rs:4:5: 4:12
+ // + literal: Const { ty: fn(u32) {consume}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:14: +2:15
+ StorageDead(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:15: +2:16
+ nop; // scope 0 at $DIR/scalar_literal_propagation.rs:+0:11: +3:2
+ StorageDead(_1); // scope 0 at $DIR/scalar_literal_propagation.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/scalar_literal_propagation.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/scalar_literal_propagation.rs b/src/test/mir-opt/const_prop/scalar_literal_propagation.rs
new file mode 100644
index 000000000..8724e4d57
--- /dev/null
+++ b/src/test/mir-opt/const_prop/scalar_literal_propagation.rs
@@ -0,0 +1,8 @@
+// EMIT_MIR scalar_literal_propagation.main.ConstProp.diff
+fn main() {
+ let x = 1;
+ consume(x);
+}
+
+#[inline(never)]
+fn consume(_: u32) { }
diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..0ebfbca21
--- /dev/null
+++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
@@ -0,0 +1,53 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/slice_len.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ let mut _2: &[u32]; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:30
+ let mut _3: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ let _4: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ let _5: [u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:7: +1:19
+ let _6: usize; // in scope 0 at $DIR/slice_len.rs:+1:31: +1:32
+ let mut _7: usize; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ let mut _8: bool; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ let mut _9: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ let mut _10: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30
+ StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ // mir::Constant
+ // + span: $DIR/slice_len.rs:5:6: 5:19
+ // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
+ _4 = _9; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _3 = _4; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ StorageLive(_10); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _10 = _3; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ StorageDead(_3); // scope 0 at $DIR/slice_len.rs:+1:18: +1:19
+ StorageLive(_6); // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
+ _6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
+ _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ StorageDead(_10); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+- _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++ _8 = const true; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ }
+
+ bb1: {
+- _1 = (*_2)[_6]; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++ _1 = const 2_u32; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ StorageDead(_6); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ StorageDead(_4); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ StorageDead(_2); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ StorageDead(_1); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ nop; // scope 0 at $DIR/slice_len.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/slice_len.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..0ebfbca21
--- /dev/null
+++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
@@ -0,0 +1,53 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/slice_len.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ let mut _2: &[u32]; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:30
+ let mut _3: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ let _4: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ let _5: [u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:7: +1:19
+ let _6: usize; // in scope 0 at $DIR/slice_len.rs:+1:31: +1:32
+ let mut _7: usize; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ let mut _8: bool; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ let mut _9: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ let mut _10: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30
+ StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ // mir::Constant
+ // + span: $DIR/slice_len.rs:5:6: 5:19
+ // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
+ _4 = _9; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _3 = _4; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ StorageLive(_10); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _10 = _3; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ StorageDead(_3); // scope 0 at $DIR/slice_len.rs:+1:18: +1:19
+ StorageLive(_6); // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
+ _6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
+ _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ StorageDead(_10); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+- _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++ _8 = const true; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ }
+
+ bb1: {
+- _1 = (*_2)[_6]; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++ _1 = const 2_u32; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ StorageDead(_6); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ StorageDead(_4); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ StorageDead(_2); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ StorageDead(_1); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ nop; // scope 0 at $DIR/slice_len.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/slice_len.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/slice_len.rs b/src/test/mir-opt/const_prop/slice_len.rs
new file mode 100644
index 000000000..fa9eafa8b
--- /dev/null
+++ b/src/test/mir-opt/const_prop/slice_len.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
+// EMIT_MIR slice_len.main.ConstProp.diff
+fn main() {
+ (&[1u32, 2, 3] as &[u32])[1];
+}
diff --git a/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff b/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff
new file mode 100644
index 000000000..9d7c2784d
--- /dev/null
+++ b/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff
@@ -0,0 +1,34 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/switch_int.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/switch_int.rs:+1:11: +1:12
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/switch_int.rs:+1:11: +1:12
+ _1 = const 1_i32; // scope 0 at $DIR/switch_int.rs:+1:11: +1:12
+- switchInt(_1) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12
++ switchInt(const 1_i32) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = foo(const -1_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+3:14: +3:21
+ // mir::Constant
+ // + span: $DIR/switch_int.rs:9:14: 9:17
+ // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ _0 = foo(const 0_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+2:14: +2:20
+ // mir::Constant
+ // + span: $DIR/switch_int.rs:8:14: 8:17
+ // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_1); // scope 0 at $DIR/switch_int.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/switch_int.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff b/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff
new file mode 100644
index 000000000..74f9eafe4
--- /dev/null
+++ b/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff
@@ -0,0 +1,34 @@
+- // MIR for `main` before SimplifyConstCondition-after-const-prop
++ // MIR for `main` after SimplifyConstCondition-after-const-prop
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/switch_int.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/switch_int.rs:+1:11: +1:12
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/switch_int.rs:+1:11: +1:12
+ _1 = const 1_i32; // scope 0 at $DIR/switch_int.rs:+1:11: +1:12
+- switchInt(const 1_i32) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12
++ goto -> bb2; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = foo(const -1_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+3:14: +3:21
+ // mir::Constant
+ // + span: $DIR/switch_int.rs:9:14: 9:17
+ // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ _0 = foo(const 0_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+2:14: +2:20
+ // mir::Constant
+ // + span: $DIR/switch_int.rs:8:14: 8:17
+ // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_1); // scope 0 at $DIR/switch_int.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/switch_int.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/switch_int.rs b/src/test/mir-opt/const_prop/switch_int.rs
new file mode 100644
index 000000000..d7319eca1
--- /dev/null
+++ b/src/test/mir-opt/const_prop/switch_int.rs
@@ -0,0 +1,11 @@
+#[inline(never)]
+fn foo(_: i32) { }
+
+// EMIT_MIR switch_int.main.ConstProp.diff
+// EMIT_MIR switch_int.main.SimplifyConstCondition-after-const-prop.diff
+fn main() {
+ match 1 {
+ 1 => foo(0),
+ _ => foo(-1),
+ }
+}
diff --git a/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff
new file mode 100644
index 000000000..a0603c60d
--- /dev/null
+++ b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff
@@ -0,0 +1,36 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/tuple_literal_propagation.rs:+0:11: +0:11
+ let _1: (u32, u32); // in scope 0 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10
+ let _2: (); // in scope 0 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15
+ let mut _3: (u32, u32); // in scope 0 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10
+ Deinit(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19
+ (_1.0: u32) = const 1_u32; // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19
+ (_1.1: u32) = const 2_u32; // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19
+ StorageLive(_2); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15
+ StorageLive(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14
+- _3 = _1; // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14
++ _3 = const (1_u32, 2_u32); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14
+ _2 = consume(move _3) -> bb1; // scope 1 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15
+ // mir::Constant
+ // + span: $DIR/tuple_literal_propagation.rs:5:5: 5:12
+ // + literal: Const { ty: fn((u32, u32)) {consume}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:14: +3:15
+ StorageDead(_2); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:15: +3:16
+ nop; // scope 0 at $DIR/tuple_literal_propagation.rs:+0:11: +4:2
+ StorageDead(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/tuple_literal_propagation.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/tuple_literal_propagation.rs b/src/test/mir-opt/const_prop/tuple_literal_propagation.rs
new file mode 100644
index 000000000..e644baec4
--- /dev/null
+++ b/src/test/mir-opt/const_prop/tuple_literal_propagation.rs
@@ -0,0 +1,9 @@
+// EMIT_MIR tuple_literal_propagation.main.ConstProp.diff
+fn main() {
+ let x = (1, 2);
+
+ consume(x);
+}
+
+#[inline(never)]
+fn consume(_: (u32, u32)) { }
diff --git a/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff b/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff
new file mode 100644
index 000000000..459da2e33
--- /dev/null
+++ b/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff
@@ -0,0 +1,42 @@
+- // MIR for `bar` before ConstProp
++ // MIR for `bar` after ConstProp
+
+ fn bar() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +0:10
+ let mut _1: (i32,); // in scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
+ let _2: (); // in scope 0 at $DIR/const_prop_miscompile.rs:+2:5: +4:6
+ let mut _3: *mut i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
+ let mut _5: i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+5:13: +5:20
+ scope 1 {
+ debug v => _1; // in scope 1 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
+ let _4: bool; // in scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10
+ scope 2 {
+ }
+ scope 3 {
+ debug y => _4; // in scope 3 at $DIR/const_prop_miscompile.rs:+5:9: +5:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
+ Deinit(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
+ (_1.0: i32) = const 1_i32; // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
+ StorageLive(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+2:5: +4:6
+ StorageLive(_3); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
+ _3 = &raw mut (_1.0: i32); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
+ (*_3) = const 5_i32; // scope 2 at $DIR/const_prop_miscompile.rs:+3:9: +3:26
+ StorageDead(_3); // scope 2 at $DIR/const_prop_miscompile.rs:+3:26: +3:27
+ nop; // scope 2 at $DIR/const_prop_miscompile.rs:+2:5: +4:6
+ StorageDead(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+4:5: +4:6
+ StorageLive(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10
+ StorageLive(_5); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:20
+ _5 = (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:15: +5:18
+ _4 = Eq(move _5, const 5_i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:25
+ StorageDead(_5); // scope 1 at $DIR/const_prop_miscompile.rs:+5:24: +5:25
+ nop; // scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +6:2
+ StorageDead(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+6:1: +6:2
+ StorageDead(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/const_prop_miscompile.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff b/src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff
new file mode 100644
index 000000000..e8bd98cf8
--- /dev/null
+++ b/src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff
@@ -0,0 +1,36 @@
+- // MIR for `foo` before ConstProp
++ // MIR for `foo` after ConstProp
+
+ fn foo() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +0:10
+ let mut _1: (i32,); // in scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
+ let mut _2: &mut i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+2:6: +2:14
+ let mut _4: i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+3:13: +3:20
+ scope 1 {
+ debug u => _1; // in scope 1 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
+ let _3: bool; // in scope 1 at $DIR/const_prop_miscompile.rs:+3:9: +3:10
+ scope 2 {
+ debug y => _3; // in scope 2 at $DIR/const_prop_miscompile.rs:+3:9: +3:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
+ Deinit(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
+ (_1.0: i32) = const 1_i32; // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
+ StorageLive(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+2:6: +2:14
+ _2 = &mut (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+2:6: +2:14
+ (*_2) = const 5_i32; // scope 1 at $DIR/const_prop_miscompile.rs:+2:5: +2:18
+ StorageDead(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+2:18: +2:19
+ StorageLive(_3); // scope 1 at $DIR/const_prop_miscompile.rs:+3:9: +3:10
+ StorageLive(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+3:13: +3:20
+ _4 = (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+3:15: +3:18
+ _3 = Eq(move _4, const 5_i32); // scope 1 at $DIR/const_prop_miscompile.rs:+3:13: +3:25
+ StorageDead(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+3:24: +3:25
+ nop; // scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +4:2
+ StorageDead(_3); // scope 1 at $DIR/const_prop_miscompile.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/const_prop_miscompile.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop_miscompile.rs b/src/test/mir-opt/const_prop_miscompile.rs
new file mode 100644
index 000000000..bc54556b3
--- /dev/null
+++ b/src/test/mir-opt/const_prop_miscompile.rs
@@ -0,0 +1,22 @@
+#![feature(raw_ref_op)]
+
+// EMIT_MIR const_prop_miscompile.foo.ConstProp.diff
+fn foo() {
+ let mut u = (1,);
+ *&mut u.0 = 5;
+ let y = { u.0 } == 5;
+}
+
+// EMIT_MIR const_prop_miscompile.bar.ConstProp.diff
+fn bar() {
+ let mut v = (1,);
+ unsafe {
+ *&raw mut v.0 = 5;
+ }
+ let y = { v.0 } == 5;
+}
+
+fn main() {
+ foo();
+ bar();
+}
diff --git a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot
new file mode 100644
index 000000000..c00eae96e
--- /dev/null
+++ b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot
@@ -0,0 +1,6 @@
+digraph Cov_0_4 {
+ graph [fontname="Courier, monospace"];
+ node [fontname="Courier, monospace"];
+ edge [fontname="Courier, monospace"];
+ bcb0__Cov_0_4 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 18:1-20:2<br/> 19:5-19:9: @0[0]: Coverage::Counter(1) for $DIR/coverage_graphviz.rs:18:1 - 20:2<br/> 20:2-20:2: @0.Return: return</td></tr><tr><td align="left" balign="left">bb0: Return</td></tr></table>>];
+}
diff --git a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot
new file mode 100644
index 000000000..ca0eb7e84
--- /dev/null
+++ b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot
@@ -0,0 +1,13 @@
+digraph Cov_0_3 {
+ graph [fontname="Courier, monospace"];
+ node [fontname="Courier, monospace"];
+ edge [fontname="Courier, monospace"];
+ bcb3__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb3</td></tr><tr><td align="left" balign="left">Counter(bcb3) at 13:10-13:10<br/> 13:10-13:10: @5[0]: Coverage::Counter(2) for $DIR/coverage_graphviz.rs:13:10 - 13:11</td></tr><tr><td align="left" balign="left">bb5: Goto</td></tr></table>>];
+ bcb2__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb2</td></tr><tr><td align="left" balign="left">Expression(bcb1:(bcb0 + bcb3) - bcb3) at 12:13-12:18<br/> 12:13-12:18: @4[0]: Coverage::Expression(4294967293) = 4294967294 + 0 for $DIR/coverage_graphviz.rs:15:1 - 15:2<br/>Expression(bcb2:(bcb1:(bcb0 + bcb3) - bcb3) + 0) at 15:2-15:2<br/> 15:2-15:2: @4.Return: return</td></tr><tr><td align="left" balign="left">bb4: Return</td></tr></table>>];
+ bcb1__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb1</td></tr><tr><td align="left" balign="left">Expression(bcb0 + bcb3) at 10:5-11:17<br/> 11:12-11:17: @2.Call: _2 = bar() -&gt; [return: bb3, unwind: bb6]</td></tr><tr><td align="left" balign="left">bb1: FalseUnwind<br/>bb2: Call</td></tr><tr><td align="left" balign="left">bb3: SwitchInt</td></tr></table>>];
+ bcb0__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 9:1-9:11<br/> </td></tr><tr><td align="left" balign="left">bb0: Goto</td></tr></table>>];
+ bcb3__Cov_0_3 -> bcb1__Cov_0_3 [label=<>];
+ bcb1__Cov_0_3 -> bcb3__Cov_0_3 [label=<false>];
+ bcb1__Cov_0_3 -> bcb2__Cov_0_3 [label=<otherwise>];
+ bcb0__Cov_0_3 -> bcb1__Cov_0_3 [label=<>];
+}
diff --git a/src/test/mir-opt/coverage_graphviz.rs b/src/test/mir-opt/coverage_graphviz.rs
new file mode 100644
index 000000000..09403bb3a
--- /dev/null
+++ b/src/test/mir-opt/coverage_graphviz.rs
@@ -0,0 +1,20 @@
+// Test that `-C instrument-coverage` with `-Z dump-mir-graphviz` generates a graphviz (.dot file)
+// rendering of the `BasicCoverageBlock` coverage control flow graph, with counters and
+// expressions.
+
+// needs-profiler-support
+// compile-flags: -C instrument-coverage -Z dump-mir-graphviz
+// EMIT_MIR coverage_graphviz.main.InstrumentCoverage.0.dot
+// EMIT_MIR coverage_graphviz.bar.InstrumentCoverage.0.dot
+fn main() {
+ loop {
+ if bar() {
+ break;
+ }
+ }
+}
+
+#[inline(never)]
+fn bar() -> bool {
+ true
+}
diff --git a/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff
new file mode 100644
index 000000000..58dd788b6
--- /dev/null
+++ b/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff
@@ -0,0 +1,75 @@
+- // MIR for `cycle` before DeadStoreElimination
++ // MIR for `cycle` after DeadStoreElimination
+
+ fn cycle(_1: i32, _2: i32, _3: i32) -> () {
+ debug x => _1; // in scope 0 at $DIR/cycle.rs:+0:10: +0:15
+ debug y => _2; // in scope 0 at $DIR/cycle.rs:+0:22: +0:27
+ debug z => _3; // in scope 0 at $DIR/cycle.rs:+0:34: +0:39
+ let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:46: +0:46
+ let mut _4: (); // in scope 0 at $DIR/cycle.rs:+0:1: +9:2
+ let mut _5: bool; // in scope 0 at $DIR/cycle.rs:+3:11: +3:17
+ let _6: i32; // in scope 0 at $DIR/cycle.rs:+4:13: +4:17
+ let mut _7: i32; // in scope 0 at $DIR/cycle.rs:+5:13: +5:14
+ let mut _8: i32; // in scope 0 at $DIR/cycle.rs:+6:13: +6:14
+ let mut _9: i32; // in scope 0 at $DIR/cycle.rs:+7:13: +7:17
+ let mut _10: !; // in scope 0 at $DIR/cycle.rs:+3:5: +8:6
+ let _11: (); // in scope 0 at $DIR/cycle.rs:+3:5: +8:6
+ let mut _12: !; // in scope 0 at $DIR/cycle.rs:+3:5: +8:6
+ scope 1 {
+ debug temp => _6; // in scope 1 at $DIR/cycle.rs:+4:13: +4:17
+ }
+
+ bb0: {
+ goto -> bb1; // scope 0 at $DIR/cycle.rs:+3:5: +8:6
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 0 at $DIR/cycle.rs:+3:11: +3:17
+ _5 = cond() -> bb2; // scope 0 at $DIR/cycle.rs:+3:11: +3:17
+ // mir::Constant
+ // + span: $DIR/cycle.rs:12:11: 12:15
+ // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ switchInt(move _5) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17
+ }
+
+ bb3: {
+ StorageLive(_6); // scope 0 at $DIR/cycle.rs:+4:13: +4:17
+- _6 = _3; // scope 0 at $DIR/cycle.rs:+4:20: +4:21
++ nop; // scope 0 at $DIR/cycle.rs:+4:20: +4:21
+ StorageLive(_7); // scope 1 at $DIR/cycle.rs:+5:13: +5:14
+- _7 = _2; // scope 1 at $DIR/cycle.rs:+5:13: +5:14
+- _3 = move _7; // scope 1 at $DIR/cycle.rs:+5:9: +5:14
++ nop; // scope 1 at $DIR/cycle.rs:+5:13: +5:14
++ nop; // scope 1 at $DIR/cycle.rs:+5:9: +5:14
+ StorageDead(_7); // scope 1 at $DIR/cycle.rs:+5:13: +5:14
+ StorageLive(_8); // scope 1 at $DIR/cycle.rs:+6:13: +6:14
+- _8 = _1; // scope 1 at $DIR/cycle.rs:+6:13: +6:14
+- _2 = move _8; // scope 1 at $DIR/cycle.rs:+6:9: +6:14
++ nop; // scope 1 at $DIR/cycle.rs:+6:13: +6:14
++ nop; // scope 1 at $DIR/cycle.rs:+6:9: +6:14
+ StorageDead(_8); // scope 1 at $DIR/cycle.rs:+6:13: +6:14
+ StorageLive(_9); // scope 1 at $DIR/cycle.rs:+7:13: +7:17
+- _9 = _6; // scope 1 at $DIR/cycle.rs:+7:13: +7:17
+- _1 = move _9; // scope 1 at $DIR/cycle.rs:+7:9: +7:17
++ nop; // scope 1 at $DIR/cycle.rs:+7:13: +7:17
++ nop; // scope 1 at $DIR/cycle.rs:+7:9: +7:17
+ StorageDead(_9); // scope 1 at $DIR/cycle.rs:+7:16: +7:17
+- _4 = const (); // scope 0 at $DIR/cycle.rs:+3:18: +8:6
++ nop; // scope 0 at $DIR/cycle.rs:+3:18: +8:6
+ StorageDead(_6); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
+ StorageDead(_5); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
+ goto -> bb1; // scope 0 at $DIR/cycle.rs:+3:5: +8:6
+ }
+
+ bb4: {
+ StorageLive(_11); // scope 0 at $DIR/cycle.rs:+3:5: +8:6
+ _0 = const (); // scope 0 at $DIR/cycle.rs:+3:5: +8:6
+ StorageDead(_11); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
+ StorageDead(_5); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
+ return; // scope 0 at $DIR/cycle.rs:+9:2: +9:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dead-store-elimination/cycle.rs b/src/test/mir-opt/dead-store-elimination/cycle.rs
new file mode 100644
index 000000000..b35ce0bcb
--- /dev/null
+++ b/src/test/mir-opt/dead-store-elimination/cycle.rs
@@ -0,0 +1,22 @@
+// unit-test: DeadStoreElimination
+
+#[inline(never)]
+fn cond() -> bool {
+ false
+}
+
+// EMIT_MIR cycle.cycle.DeadStoreElimination.diff
+fn cycle(mut x: i32, mut y: i32, mut z: i32) {
+ // This example is interesting because the non-transitive version of `MaybeLiveLocals` would
+ // report that *all* of these stores are live.
+ while cond() {
+ let temp = z;
+ z = y;
+ y = x;
+ x = temp;
+ }
+}
+
+fn main() {
+ cycle(1, 2, 3);
+}
diff --git a/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff
new file mode 100644
index 000000000..89f1846b4
--- /dev/null
+++ b/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff
@@ -0,0 +1,35 @@
+- // MIR for `pointer_to_int` before DeadStoreElimination
++ // MIR for `pointer_to_int` after DeadStoreElimination
+
+ fn pointer_to_int(_1: *mut i32) -> () {
+ debug p => _1; // in scope 0 at $DIR/provenance_soundness.rs:+0:19: +0:20
+ let mut _0: (); // return place in scope 0 at $DIR/provenance_soundness.rs:+0:32: +0:32
+ let _2: usize; // in scope 0 at $DIR/provenance_soundness.rs:+1:9: +1:11
+ let mut _3: *mut i32; // in scope 0 at $DIR/provenance_soundness.rs:+1:14: +1:15
+ let mut _5: *mut i32; // in scope 0 at $DIR/provenance_soundness.rs:+2:14: +2:15
+ scope 1 {
+ debug _x => _2; // in scope 1 at $DIR/provenance_soundness.rs:+1:9: +1:11
+ let _4: isize; // in scope 1 at $DIR/provenance_soundness.rs:+2:9: +2:11
+ scope 2 {
+ debug _y => _4; // in scope 2 at $DIR/provenance_soundness.rs:+2:9: +2:11
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/provenance_soundness.rs:+1:9: +1:11
+ StorageLive(_3); // scope 0 at $DIR/provenance_soundness.rs:+1:14: +1:15
+ _3 = _1; // scope 0 at $DIR/provenance_soundness.rs:+1:14: +1:15
+ _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/provenance_soundness.rs:+1:14: +1:24
+ StorageDead(_3); // scope 0 at $DIR/provenance_soundness.rs:+1:23: +1:24
+ StorageLive(_4); // scope 1 at $DIR/provenance_soundness.rs:+2:9: +2:11
+ StorageLive(_5); // scope 1 at $DIR/provenance_soundness.rs:+2:14: +2:15
+ _5 = _1; // scope 1 at $DIR/provenance_soundness.rs:+2:14: +2:15
+ _4 = move _5 as isize (PointerExposeAddress); // scope 1 at $DIR/provenance_soundness.rs:+2:14: +2:24
+ StorageDead(_5); // scope 1 at $DIR/provenance_soundness.rs:+2:23: +2:24
+ _0 = const (); // scope 0 at $DIR/provenance_soundness.rs:+0:32: +3:2
+ StorageDead(_4); // scope 1 at $DIR/provenance_soundness.rs:+3:1: +3:2
+ StorageDead(_2); // scope 0 at $DIR/provenance_soundness.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/provenance_soundness.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff
new file mode 100644
index 000000000..300f0d5dc
--- /dev/null
+++ b/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff
@@ -0,0 +1,14 @@
+- // MIR for `retags` before DeadStoreElimination
++ // MIR for `retags` after DeadStoreElimination
+
+ fn retags(_1: &mut i32) -> () {
+ debug _r => _1; // in scope 0 at $DIR/provenance_soundness.rs:+0:11: +0:13
+ let mut _0: (); // return place in scope 0 at $DIR/provenance_soundness.rs:+0:25: +0:25
+
+ bb0: {
+ Retag([fn entry] _1); // scope 0 at $DIR/provenance_soundness.rs:+0:1: +0:27
+ _0 = const (); // scope 0 at $DIR/provenance_soundness.rs:+0:25: +0:27
+ return; // scope 0 at $DIR/provenance_soundness.rs:+0:27: +0:27
+ }
+ }
+
diff --git a/src/test/mir-opt/dead-store-elimination/provenance_soundness.rs b/src/test/mir-opt/dead-store-elimination/provenance_soundness.rs
new file mode 100644
index 000000000..11314e990
--- /dev/null
+++ b/src/test/mir-opt/dead-store-elimination/provenance_soundness.rs
@@ -0,0 +1,18 @@
+// unit-test: DeadStoreElimination
+// compile-flags: -Zmir-emit-retag
+
+// Test that we don't remove pointer to int casts or retags
+
+// EMIT_MIR provenance_soundness.pointer_to_int.DeadStoreElimination.diff
+fn pointer_to_int(p: *mut i32) {
+ let _x = p as usize;
+ let _y = p as isize;
+}
+
+// EMIT_MIR provenance_soundness.retags.DeadStoreElimination.diff
+fn retags(_r: &mut i32) {}
+
+fn main() {
+ pointer_to_int(&mut 5 as *mut _);
+ retags(&mut 5);
+}
diff --git a/src/test/mir-opt/deaggregator_test.bar.Deaggregator.diff b/src/test/mir-opt/deaggregator_test.bar.Deaggregator.diff
new file mode 100644
index 000000000..db136485a
--- /dev/null
+++ b/src/test/mir-opt/deaggregator_test.bar.Deaggregator.diff
@@ -0,0 +1,21 @@
+- // MIR for `bar` before Deaggregator
++ // MIR for `bar` after Deaggregator
+
+ fn bar(_1: usize) -> Baz {
+ debug a => _1; // in scope 0 at $DIR/deaggregator_test.rs:+0:8: +0:9
+ let mut _0: Baz; // return place in scope 0 at $DIR/deaggregator_test.rs:+0:21: +0:24
+ let mut _2: usize; // in scope 0 at $DIR/deaggregator_test.rs:+1:14: +1:15
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/deaggregator_test.rs:+1:14: +1:15
+ _2 = _1; // scope 0 at $DIR/deaggregator_test.rs:+1:14: +1:15
+- _0 = Baz { x: move _2, y: const 0f32, z: const false }; // scope 0 at $DIR/deaggregator_test.rs:+1:5: +1:35
++ Deinit(_0); // scope 0 at $DIR/deaggregator_test.rs:+1:5: +1:35
++ (_0.0: usize) = move _2; // scope 0 at $DIR/deaggregator_test.rs:+1:5: +1:35
++ (_0.1: f32) = const 0f32; // scope 0 at $DIR/deaggregator_test.rs:+1:5: +1:35
++ (_0.2: bool) = const false; // scope 0 at $DIR/deaggregator_test.rs:+1:5: +1:35
+ StorageDead(_2); // scope 0 at $DIR/deaggregator_test.rs:+1:34: +1:35
+ return; // scope 0 at $DIR/deaggregator_test.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/deaggregator_test.rs b/src/test/mir-opt/deaggregator_test.rs
new file mode 100644
index 000000000..342e22243
--- /dev/null
+++ b/src/test/mir-opt/deaggregator_test.rs
@@ -0,0 +1,15 @@
+struct Baz {
+ x: usize,
+ y: f32,
+ z: bool,
+}
+
+// EMIT_MIR deaggregator_test.bar.Deaggregator.diff
+fn bar(a: usize) -> Baz {
+ Baz { x: a, y: 0.0, z: false }
+}
+
+fn main() {
+ // Make sure the function actually gets instantiated.
+ bar(0);
+}
diff --git a/src/test/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff b/src/test/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff
new file mode 100644
index 000000000..f28c2b482
--- /dev/null
+++ b/src/test/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff
@@ -0,0 +1,20 @@
+- // MIR for `bar` before Deaggregator
++ // MIR for `bar` after Deaggregator
+
+ fn bar(_1: usize) -> Baz {
+ debug a => _1; // in scope 0 at $DIR/deaggregator_test_enum.rs:+0:8: +0:9
+ let mut _0: Baz; // return place in scope 0 at $DIR/deaggregator_test_enum.rs:+0:21: +0:24
+ let mut _2: usize; // in scope 0 at $DIR/deaggregator_test_enum.rs:+1:19: +1:20
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/deaggregator_test_enum.rs:+1:19: +1:20
+ _2 = _1; // scope 0 at $DIR/deaggregator_test_enum.rs:+1:19: +1:20
+- _0 = Baz::Foo { x: move _2 }; // scope 0 at $DIR/deaggregator_test_enum.rs:+1:5: +1:22
++ Deinit(_0); // scope 0 at $DIR/deaggregator_test_enum.rs:+1:5: +1:22
++ ((_0 as Foo).0: usize) = move _2; // scope 0 at $DIR/deaggregator_test_enum.rs:+1:5: +1:22
++ discriminant(_0) = 1; // scope 0 at $DIR/deaggregator_test_enum.rs:+1:5: +1:22
+ StorageDead(_2); // scope 0 at $DIR/deaggregator_test_enum.rs:+1:21: +1:22
+ return; // scope 0 at $DIR/deaggregator_test_enum.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/deaggregator_test_enum.rs b/src/test/mir-opt/deaggregator_test_enum.rs
new file mode 100644
index 000000000..02b63a1f5
--- /dev/null
+++ b/src/test/mir-opt/deaggregator_test_enum.rs
@@ -0,0 +1,17 @@
+enum Baz {
+ Empty,
+ Foo { x: usize },
+}
+
+// EMIT_MIR deaggregator_test_enum.bar.Deaggregator.diff
+fn bar(a: usize) -> Baz {
+ Baz::Foo { x: a }
+}
+
+fn main() {
+ let x = bar(10);
+ match x {
+ Baz::Empty => println!("empty"),
+ Baz::Foo { x } => println!("{}", x),
+ };
+}
diff --git a/src/test/mir-opt/deaggregator_test_enum_2.rs b/src/test/mir-opt/deaggregator_test_enum_2.rs
new file mode 100644
index 000000000..489854ff0
--- /dev/null
+++ b/src/test/mir-opt/deaggregator_test_enum_2.rs
@@ -0,0 +1,20 @@
+// Test that deaggregate fires in more than one basic block
+
+enum Foo {
+ A(i32),
+ B(i32),
+}
+
+// EMIT_MIR deaggregator_test_enum_2.test1.Deaggregator.diff
+fn test1(x: bool, y: i32) -> Foo {
+ if x {
+ Foo::A(y)
+ } else {
+ Foo::B(y)
+ }
+}
+
+fn main() {
+ // Make sure the function actually gets instantiated.
+ test1(false, 0);
+}
diff --git a/src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff b/src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff
new file mode 100644
index 000000000..fb18089e0
--- /dev/null
+++ b/src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff
@@ -0,0 +1,45 @@
+- // MIR for `test1` before Deaggregator
++ // MIR for `test1` after Deaggregator
+
+ fn test1(_1: bool, _2: i32) -> Foo {
+ debug x => _1; // in scope 0 at $DIR/deaggregator_test_enum_2.rs:+0:10: +0:11
+ debug y => _2; // in scope 0 at $DIR/deaggregator_test_enum_2.rs:+0:19: +0:20
+ let mut _0: Foo; // return place in scope 0 at $DIR/deaggregator_test_enum_2.rs:+0:30: +0:33
+ let mut _3: bool; // in scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:8: +1:9
+ let mut _4: i32; // in scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:16: +2:17
+ let mut _5: i32; // in scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:16: +4:17
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:8: +1:9
+ switchInt(move _3) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:8: +1:9
+ }
+
+ bb1: {
+ StorageLive(_4); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:16: +2:17
+ _4 = _2; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:16: +2:17
+- _0 = Foo::A(move _4); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:9: +2:18
++ Deinit(_0); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:9: +2:18
++ ((_0 as A).0: i32) = move _4; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:9: +2:18
++ discriminant(_0) = 0; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:9: +2:18
+ StorageDead(_4); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:17: +2:18
+ goto -> bb3; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:5: +5:6
+ }
+
+ bb2: {
+ StorageLive(_5); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:16: +4:17
+ _5 = _2; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:16: +4:17
+- _0 = Foo::B(move _5); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:9: +4:18
++ Deinit(_0); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:9: +4:18
++ ((_0 as B).0: i32) = move _5; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:9: +4:18
++ discriminant(_0) = 1; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:9: +4:18
+ StorageDead(_5); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:17: +4:18
+ goto -> bb3; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:5: +5:6
+ }
+
+ bb3: {
+ StorageDead(_3); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+5:5: +5:6
+ return; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/deaggregator_test_multiple.rs b/src/test/mir-opt/deaggregator_test_multiple.rs
new file mode 100644
index 000000000..9730b9aa8
--- /dev/null
+++ b/src/test/mir-opt/deaggregator_test_multiple.rs
@@ -0,0 +1,16 @@
+// Test that deaggregate fires more than once per block
+
+enum Foo {
+ A(i32),
+ B,
+}
+
+// EMIT_MIR deaggregator_test_multiple.test.Deaggregator.diff
+fn test(x: i32) -> [Foo; 2] {
+ [Foo::A(x), Foo::A(x)]
+}
+
+fn main() {
+ // Make sure the function actually gets instantiated.
+ test(0);
+}
diff --git a/src/test/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff b/src/test/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff
new file mode 100644
index 000000000..cf5da273c
--- /dev/null
+++ b/src/test/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff
@@ -0,0 +1,35 @@
+- // MIR for `test` before Deaggregator
++ // MIR for `test` after Deaggregator
+
+ fn test(_1: i32) -> [Foo; 2] {
+ debug x => _1; // in scope 0 at $DIR/deaggregator_test_multiple.rs:+0:9: +0:10
+ let mut _0: [Foo; 2]; // return place in scope 0 at $DIR/deaggregator_test_multiple.rs:+0:20: +0:28
+ let mut _2: Foo; // in scope 0 at $DIR/deaggregator_test_multiple.rs:+1:6: +1:15
+ let mut _3: i32; // in scope 0 at $DIR/deaggregator_test_multiple.rs:+1:13: +1:14
+ let mut _4: Foo; // in scope 0 at $DIR/deaggregator_test_multiple.rs:+1:17: +1:26
+ let mut _5: i32; // in scope 0 at $DIR/deaggregator_test_multiple.rs:+1:24: +1:25
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:6: +1:15
+ StorageLive(_3); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:13: +1:14
+ _3 = _1; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:13: +1:14
+- _2 = Foo::A(move _3); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:6: +1:15
++ Deinit(_2); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:6: +1:15
++ ((_2 as A).0: i32) = move _3; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:6: +1:15
++ discriminant(_2) = 0; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:6: +1:15
+ StorageDead(_3); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:14: +1:15
+ StorageLive(_4); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:17: +1:26
+ StorageLive(_5); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:24: +1:25
+ _5 = _1; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:24: +1:25
+- _4 = Foo::A(move _5); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:17: +1:26
++ Deinit(_4); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:17: +1:26
++ ((_4 as A).0: i32) = move _5; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:17: +1:26
++ discriminant(_4) = 0; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:17: +1:26
+ StorageDead(_5); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:25: +1:26
+ _0 = [move _2, move _4]; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:5: +1:27
+ StorageDead(_4); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:26: +1:27
+ StorageDead(_2); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:26: +1:27
+ return; // scope 0 at $DIR/deaggregator_test_multiple.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff b/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff
new file mode 100644
index 000000000..01864ba24
--- /dev/null
+++ b/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff
@@ -0,0 +1,107 @@
+- // MIR for `is_line_doc_comment_2` before DeduplicateBlocks
++ // MIR for `is_line_doc_comment_2` after DeduplicateBlocks
+
+ fn is_line_doc_comment_2(_1: &str) -> bool {
+ debug s => _1; // in scope 0 at $DIR/deduplicate_blocks.rs:+0:36: +0:37
+ let mut _0: bool; // return place in scope 0 at $DIR/deduplicate_blocks.rs:+0:48: +0:52
+ let mut _2: &[u8]; // in scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
+ let mut _3: &str; // in scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
+ let mut _4: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ let mut _5: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ let mut _6: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ let mut _7: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ scope 1 (inlined core::str::<impl str>::as_bytes) { // at $DIR/deduplicate_blocks.rs:3:11: 3:23
+ debug self => _3; // in scope 1 at $SRC_DIR/core/src/str/mod.rs:LL:COL
+ let mut _8: &str; // in scope 1 at $SRC_DIR/core/src/str/mod.rs:LL:COL
+ scope 2 {
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
+ StorageLive(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
+ _3 = _1; // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
+ StorageLive(_8); // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL
+ _8 = _3; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL
+- _2 = transmute::<&str, &[u8]>(move _8) -> bb14; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL
++ _2 = transmute::<&str, &[u8]>(move _8) -> bb12; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/str/mod.rs:LL:COL
+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&str) -> &[u8] {transmute::<&str, &[u8]>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ switchInt((*_2)[0 of 4]) -> [47_u8: bb2, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb2: {
+ switchInt((*_2)[1 of 4]) -> [47_u8: bb3, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb3: {
+ switchInt((*_2)[2 of 4]) -> [47_u8: bb4, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb4: {
+- switchInt((*_2)[3 of 4]) -> [47_u8: bb10, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
++ switchInt((*_2)[3 of 4]) -> [47_u8: bb9, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb5: {
+ _4 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ _5 = Ge(move _4, const 3_usize); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ switchInt(move _5) -> [false: bb9, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ }
+
+ bb6: {
+ switchInt((*_2)[0 of 3]) -> [47_u8: bb7, otherwise: bb9]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb7: {
+ switchInt((*_2)[1 of 3]) -> [47_u8: bb8, otherwise: bb9]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb8: {
+- switchInt((*_2)[2 of 3]) -> [47_u8: bb11, 33_u8: bb12, otherwise: bb9]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
++ switchInt((*_2)[2 of 3]) -> [47_u8: bb10, 33_u8: bb10, otherwise: bb9]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb9: {
+- _0 = const false; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19
+- goto -> bb13; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19
+- }
+-
+- bb10: {
+ _0 = const false; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46
+- goto -> bb13; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46
++ goto -> bb11; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46
+ }
+
+- bb11: {
+- _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39
+- goto -> bb13; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39
+- }
+-
+- bb12: {
++ bb10: {
+ _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39
+- goto -> bb13; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39
++ goto -> bb11; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39
+ }
+
+- bb13: {
++ bb11: {
+ StorageDead(_2); // scope 0 at $DIR/deduplicate_blocks.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/deduplicate_blocks.rs:+7:2: +7:2
+ }
+
+- bb14: {
++ bb12: {
+ StorageDead(_8); // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL
+ StorageDead(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:22: +1:23
+ _6 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ _7 = Ge(move _6, const 4_usize); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ switchInt(move _7) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ }
+ }
+
diff --git a/src/test/mir-opt/deduplicate_blocks.rs b/src/test/mir-opt/deduplicate_blocks.rs
new file mode 100644
index 000000000..f8f7361dc
--- /dev/null
+++ b/src/test/mir-opt/deduplicate_blocks.rs
@@ -0,0 +1,13 @@
+// EMIT_MIR deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff
+pub const fn is_line_doc_comment_2(s: &str) -> bool {
+ match s.as_bytes() {
+ [b'/', b'/', b'/', b'/', ..] => false,
+ [b'/', b'/', b'/', ..] => true,
+ [b'/', b'/', b'!', ..] => true,
+ _ => false,
+ }
+}
+
+fn main() {
+ is_line_doc_comment_2("asd");
+}
diff --git a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff
new file mode 100644
index 000000000..de0c03bb7
--- /dev/null
+++ b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff
@@ -0,0 +1,107 @@
+- // MIR for `main` before Derefer
++ // MIR for `main` after Derefer
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/derefer_complex_case.rs:+0:11: +0:11
+ let mut _1: std::slice::Iter<i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ let mut _2: &[i32; 2]; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ let _3: [i32; 2]; // in scope 0 at $DIR/derefer_complex_case.rs:+1:18: +1:26
+ let mut _4: std::slice::Iter<i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ let mut _5: (); // in scope 0 at $DIR/derefer_complex_case.rs:+0:1: +2:2
+ let _6: (); // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ let mut _7: std::option::Option<&i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ let mut _8: &mut std::slice::Iter<i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ let mut _9: &mut std::slice::Iter<i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ let mut _10: isize; // in scope 0 at $DIR/derefer_complex_case.rs:+1:5: +1:40
+ let mut _11: !; // in scope 0 at $DIR/derefer_complex_case.rs:+1:5: +1:40
+ let mut _13: i32; // in scope 0 at $DIR/derefer_complex_case.rs:+1:34: +1:37
+ let mut _14: &[i32; 2]; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
++ let mut _15: &i32; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ scope 1 {
+ debug iter => _4; // in scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ let _12: i32; // in scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13
+ scope 2 {
+ debug foo => _12; // in scope 2 at $DIR/derefer_complex_case.rs:+1:10: +1:13
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ StorageLive(_2); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ _14 = const main::promoted[0]; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ // mir::Constant
+ // + span: $DIR/derefer_complex_case.rs:5:17: 5:26
+ // + literal: Const { ty: &[i32; 2], val: Unevaluated(main, [], Some(promoted[0])) }
+ _2 = &(*_14); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ _1 = <&[i32; 2] as IntoIterator>::into_iter(move _2) -> bb1; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ // mir::Constant
+ // + span: $DIR/derefer_complex_case.rs:5:17: 5:26
+ // + literal: Const { ty: fn(&[i32; 2]) -> <&[i32; 2] as IntoIterator>::IntoIter {<&[i32; 2] as IntoIterator>::into_iter}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 0 at $DIR/derefer_complex_case.rs:+1:25: +1:26
+ StorageLive(_4); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ _4 = move _1; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ goto -> bb2; // scope 1 at $DIR/derefer_complex_case.rs:+1:5: +1:40
+ }
+
+ bb2: {
+ StorageLive(_6); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ StorageLive(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ StorageLive(_8); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ StorageLive(_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ _9 = &mut _4; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ _8 = &mut (*_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ _7 = <std::slice::Iter<i32> as Iterator>::next(move _8) -> bb3; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ // mir::Constant
+ // + span: $DIR/derefer_complex_case.rs:5:17: 5:26
+ // + literal: Const { ty: for<'r> fn(&'r mut std::slice::Iter<i32>) -> Option<<std::slice::Iter<i32> as Iterator>::Item> {<std::slice::Iter<i32> as Iterator>::next}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_8); // scope 1 at $DIR/derefer_complex_case.rs:+1:25: +1:26
+ _10 = discriminant(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ }
+
+ bb4: {
+ StorageLive(_12); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13
+- _12 = (*((_7 as Some).0: &i32)); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13
++ StorageLive(_15); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13
++ _15 = deref_copy ((_7 as Some).0: &i32); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13
++ _12 = (*_15); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13
++ StorageDead(_15); // scope 2 at $DIR/derefer_complex_case.rs:+1:34: +1:37
+ StorageLive(_13); // scope 2 at $DIR/derefer_complex_case.rs:+1:34: +1:37
+ _13 = _12; // scope 2 at $DIR/derefer_complex_case.rs:+1:34: +1:37
+ _6 = std::mem::drop::<i32>(move _13) -> bb7; // scope 2 at $DIR/derefer_complex_case.rs:+1:29: +1:38
+ // mir::Constant
+ // + span: $DIR/derefer_complex_case.rs:5:29: 5:33
+ // + literal: Const { ty: fn(i32) {std::mem::drop::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ unreachable; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ }
+
+ bb6: {
+ _0 = const (); // scope 1 at $DIR/derefer_complex_case.rs:+1:5: +1:40
+ StorageDead(_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40
+ StorageDead(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40
+ StorageDead(_6); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40
+ StorageDead(_4); // scope 0 at $DIR/derefer_complex_case.rs:+1:39: +1:40
+ StorageDead(_1); // scope 0 at $DIR/derefer_complex_case.rs:+1:39: +1:40
+ return; // scope 0 at $DIR/derefer_complex_case.rs:+2:2: +2:2
+ }
+
+ bb7: {
+ StorageDead(_13); // scope 2 at $DIR/derefer_complex_case.rs:+1:37: +1:38
+ StorageDead(_12); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40
+ StorageDead(_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40
+ StorageDead(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40
+ StorageDead(_6); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40
+ _5 = const (); // scope 1 at $DIR/derefer_complex_case.rs:+1:5: +1:40
+ goto -> bb2; // scope 1 at $DIR/derefer_complex_case.rs:+1:5: +1:40
+ }
+ }
+
diff --git a/src/test/mir-opt/derefer_complex_case.rs b/src/test/mir-opt/derefer_complex_case.rs
new file mode 100644
index 000000000..48bec3907
--- /dev/null
+++ b/src/test/mir-opt/derefer_complex_case.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR derefer_complex_case.main.Derefer.diff
+// ignore-wasm32
+
+fn main() {
+ for &foo in &[42, 43] { drop(foo) }
+}
diff --git a/src/test/mir-opt/derefer_inline_test.main.Derefer.diff b/src/test/mir-opt/derefer_inline_test.main.Derefer.diff
new file mode 100644
index 000000000..ce6ffaa56
--- /dev/null
+++ b/src/test/mir-opt/derefer_inline_test.main.Derefer.diff
@@ -0,0 +1,61 @@
+- // MIR for `main` before Derefer
++ // MIR for `main` after Derefer
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/derefer_inline_test.rs:+0:11: +0:11
+ let _1: std::boxed::Box<std::boxed::Box<u32>>; // in scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12
+ let mut _2: usize; // in scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12
+ let mut _3: usize; // in scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12
+ let mut _4: *mut u8; // in scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12
+ let mut _5: std::boxed::Box<std::boxed::Box<u32>>; // in scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12
+ _2 = SizeOf(std::boxed::Box<u32>); // scope 1 at $DIR/derefer_inline_test.rs:+1:5: +1:12
+ _3 = AlignOf(std::boxed::Box<u32>); // scope 1 at $DIR/derefer_inline_test.rs:+1:5: +1:12
+ _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/derefer_inline_test.rs:+1:5: +1:12
+ // mir::Constant
+ // + span: $DIR/derefer_inline_test.rs:10:5: 10:12
+ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12
+ _5 = ShallowInitBox(move _4, std::boxed::Box<u32>); // scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12
+ (*_5) = f() -> [return: bb2, unwind: bb6]; // scope 0 at $DIR/derefer_inline_test.rs:+1:9: +1:12
+ // mir::Constant
+ // + span: $DIR/derefer_inline_test.rs:10:9: 10:10
+ // + literal: Const { ty: fn() -> Box<u32> {f}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ _1 = move _5; // scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12
+ drop(_5) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/derefer_inline_test.rs:+1:11: +1:12
+ }
+
+ bb3: {
+ StorageDead(_5); // scope 0 at $DIR/derefer_inline_test.rs:+1:11: +1:12
+ drop(_1) -> bb4; // scope 0 at $DIR/derefer_inline_test.rs:+1:12: +1:13
+ }
+
+ bb4: {
+ StorageDead(_1); // scope 0 at $DIR/derefer_inline_test.rs:+1:12: +1:13
+ _0 = const (); // scope 0 at $DIR/derefer_inline_test.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/derefer_inline_test.rs:+2:2: +2:2
+ }
+
+ bb5 (cleanup): {
+ drop(_1) -> bb7; // scope 0 at $DIR/derefer_inline_test.rs:+1:12: +1:13
+ }
+
+ bb6 (cleanup): {
+ drop(_5) -> bb7; // scope 0 at $DIR/derefer_inline_test.rs:+1:11: +1:12
+ }
+
+ bb7 (cleanup): {
+ resume; // scope 0 at $DIR/derefer_inline_test.rs:+0:1: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/derefer_inline_test.rs b/src/test/mir-opt/derefer_inline_test.rs
new file mode 100644
index 000000000..191a8cbbe
--- /dev/null
+++ b/src/test/mir-opt/derefer_inline_test.rs
@@ -0,0 +1,11 @@
+// EMIT_MIR derefer_inline_test.main.Derefer.diff
+// ignore-wasm32 compiled with panic=abort by default
+
+#![feature(box_syntax)]
+#[inline]
+fn f() -> Box<u32> {
+ box 0
+}
+fn main() {
+ box f();
+}
diff --git a/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff
new file mode 100644
index 000000000..0a56ee5e4
--- /dev/null
+++ b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff
@@ -0,0 +1,99 @@
+- // MIR for `main` before Derefer
++ // MIR for `main` after Derefer
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/derefer_terminator_test.rs:+0:11: +0:11
+ let _1: bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+1:9: +1:10
+ let _3: (); // in scope 0 at $DIR/derefer_terminator_test.rs:+3:5: +6:6
+ let mut _4: &&&&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:15: +3:22
+ let _5: &&&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:17: +3:21
+ let _6: &&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:18: +3:21
+ let _7: &bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:19: +3:21
++ let mut _10: &&&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:15: +3:22
++ let mut _11: &&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:15: +3:22
++ let mut _12: &bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:15: +3:22
+ scope 1 {
+ debug b => _1; // in scope 1 at $DIR/derefer_terminator_test.rs:+1:9: +1:10
+ let _2: bool; // in scope 1 at $DIR/derefer_terminator_test.rs:+2:9: +2:10
+ scope 2 {
+ debug d => _2; // in scope 2 at $DIR/derefer_terminator_test.rs:+2:9: +2:10
+ let _8: i32; // in scope 2 at $DIR/derefer_terminator_test.rs:+4:22: +4:23
+ let _9: i32; // in scope 2 at $DIR/derefer_terminator_test.rs:+7:9: +7:10
+ scope 3 {
+ debug x => _8; // in scope 3 at $DIR/derefer_terminator_test.rs:+4:22: +4:23
+ }
+ scope 4 {
+ debug y => _9; // in scope 4 at $DIR/derefer_terminator_test.rs:+7:9: +7:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/derefer_terminator_test.rs:+1:9: +1:10
+ _1 = foo() -> bb1; // scope 0 at $DIR/derefer_terminator_test.rs:+1:13: +1:18
+ // mir::Constant
+ // + span: $DIR/derefer_terminator_test.rs:5:13: 5:16
+ // + literal: Const { ty: fn() -> bool {foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_2); // scope 1 at $DIR/derefer_terminator_test.rs:+2:9: +2:10
+ _2 = foo() -> bb2; // scope 1 at $DIR/derefer_terminator_test.rs:+2:13: +2:18
+ // mir::Constant
+ // + span: $DIR/derefer_terminator_test.rs:6:13: 6:16
+ // + literal: Const { ty: fn() -> bool {foo}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageLive(_3); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +6:6
+ StorageLive(_4); // scope 2 at $DIR/derefer_terminator_test.rs:+3:15: +3:22
+ StorageLive(_5); // scope 2 at $DIR/derefer_terminator_test.rs:+3:17: +3:21
+ StorageLive(_6); // scope 2 at $DIR/derefer_terminator_test.rs:+3:18: +3:21
+ StorageLive(_7); // scope 2 at $DIR/derefer_terminator_test.rs:+3:19: +3:21
+ _7 = &_1; // scope 2 at $DIR/derefer_terminator_test.rs:+3:19: +3:21
+ _6 = &_7; // scope 2 at $DIR/derefer_terminator_test.rs:+3:18: +3:21
+ _5 = &_6; // scope 2 at $DIR/derefer_terminator_test.rs:+3:17: +3:21
+ _4 = &_5; // scope 2 at $DIR/derefer_terminator_test.rs:+3:15: +3:22
+- switchInt((*(*(*(*_4))))) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
++ StorageLive(_10); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
++ _10 = deref_copy (*_4); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
++ StorageLive(_11); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
++ _11 = deref_copy (*_10); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
++ StorageDead(_10); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
++ StorageLive(_12); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
++ _12 = deref_copy (*_11); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
++ StorageDead(_11); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
++ switchInt((*_12)) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
+ }
+
+ bb3: {
++ StorageDead(_12); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
+ _3 = const (); // scope 2 at $DIR/derefer_terminator_test.rs:+5:18: +5:20
+ goto -> bb5; // scope 2 at $DIR/derefer_terminator_test.rs:+5:18: +5:20
+ }
+
+ bb4: {
++ StorageDead(_12); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
+ StorageLive(_8); // scope 2 at $DIR/derefer_terminator_test.rs:+4:22: +4:23
+ _8 = const 5_i32; // scope 2 at $DIR/derefer_terminator_test.rs:+4:26: +4:27
+ _3 = const (); // scope 2 at $DIR/derefer_terminator_test.rs:+4:17: +4:29
+ StorageDead(_8); // scope 2 at $DIR/derefer_terminator_test.rs:+4:28: +4:29
+ goto -> bb5; // scope 2 at $DIR/derefer_terminator_test.rs:+4:28: +4:29
+ }
+
+ bb5: {
+ StorageDead(_7); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6
+ StorageDead(_6); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6
+ StorageDead(_5); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6
+ StorageDead(_4); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6
+ StorageDead(_3); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6
+ StorageLive(_9); // scope 2 at $DIR/derefer_terminator_test.rs:+7:9: +7:10
+ _9 = const 42_i32; // scope 2 at $DIR/derefer_terminator_test.rs:+7:13: +7:15
+ _0 = const (); // scope 0 at $DIR/derefer_terminator_test.rs:+0:11: +8:2
+ StorageDead(_9); // scope 2 at $DIR/derefer_terminator_test.rs:+8:1: +8:2
+ StorageDead(_2); // scope 1 at $DIR/derefer_terminator_test.rs:+8:1: +8:2
+ StorageDead(_1); // scope 0 at $DIR/derefer_terminator_test.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/derefer_terminator_test.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/derefer_terminator_test.rs b/src/test/mir-opt/derefer_terminator_test.rs
new file mode 100644
index 000000000..787b14ae7
--- /dev/null
+++ b/src/test/mir-opt/derefer_terminator_test.rs
@@ -0,0 +1,16 @@
+// EMIT_MIR derefer_terminator_test.main.Derefer.diff
+// ignore-wasm32
+
+fn main() {
+ let b = foo();
+ let d = foo();
+ match ****(&&&&b) {
+ true => {let x = 5;},
+ false => {}
+ }
+ let y = 42;
+}
+
+fn foo() -> bool {
+ true
+}
diff --git a/src/test/mir-opt/derefer_test.main.Derefer.diff b/src/test/mir-opt/derefer_test.main.Derefer.diff
new file mode 100644
index 000000000..6c2047e21
--- /dev/null
+++ b/src/test/mir-opt/derefer_test.main.Derefer.diff
@@ -0,0 +1,54 @@
+- // MIR for `main` before Derefer
++ // MIR for `main` after Derefer
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/derefer_test.rs:+0:11: +0:11
+ let mut _1: (i32, i32); // in scope 0 at $DIR/derefer_test.rs:+1:9: +1:14
+ let mut _3: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:+2:22: +2:28
++ let mut _6: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:+2:9: +2:14
++ let mut _7: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:+2:9: +2:14
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/derefer_test.rs:+1:9: +1:14
+ let mut _2: (i32, &mut (i32, i32)); // in scope 1 at $DIR/derefer_test.rs:+2:9: +2:14
+ scope 2 {
+ debug b => _2; // in scope 2 at $DIR/derefer_test.rs:+2:9: +2:14
+ let _4: &mut i32; // in scope 2 at $DIR/derefer_test.rs:+3:9: +3:10
+ scope 3 {
+ debug x => _4; // in scope 3 at $DIR/derefer_test.rs:+3:9: +3:10
+ let _5: &mut i32; // in scope 3 at $DIR/derefer_test.rs:+4:9: +4:10
+ scope 4 {
+ debug y => _5; // in scope 4 at $DIR/derefer_test.rs:+4:9: +4:10
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/derefer_test.rs:+1:9: +1:14
+ _1 = (const 42_i32, const 43_i32); // scope 0 at $DIR/derefer_test.rs:+1:17: +1:24
+ StorageLive(_2); // scope 1 at $DIR/derefer_test.rs:+2:9: +2:14
+ StorageLive(_3); // scope 1 at $DIR/derefer_test.rs:+2:22: +2:28
+ _3 = &mut _1; // scope 1 at $DIR/derefer_test.rs:+2:22: +2:28
+ _2 = (const 99_i32, move _3); // scope 1 at $DIR/derefer_test.rs:+2:17: +2:29
+ StorageDead(_3); // scope 1 at $DIR/derefer_test.rs:+2:28: +2:29
+ StorageLive(_4); // scope 2 at $DIR/derefer_test.rs:+3:9: +3:10
+- _4 = &mut ((*(_2.1: &mut (i32, i32))).0: i32); // scope 2 at $DIR/derefer_test.rs:+3:13: +3:26
++ StorageLive(_6); // scope 2 at $DIR/derefer_test.rs:+3:13: +3:26
++ _6 = deref_copy (_2.1: &mut (i32, i32)); // scope 2 at $DIR/derefer_test.rs:+3:13: +3:26
++ _4 = &mut ((*_6).0: i32); // scope 2 at $DIR/derefer_test.rs:+3:13: +3:26
++ StorageDead(_6); // scope 3 at $DIR/derefer_test.rs:+4:9: +4:10
+ StorageLive(_5); // scope 3 at $DIR/derefer_test.rs:+4:9: +4:10
+- _5 = &mut ((*(_2.1: &mut (i32, i32))).1: i32); // scope 3 at $DIR/derefer_test.rs:+4:13: +4:26
++ StorageLive(_7); // scope 3 at $DIR/derefer_test.rs:+4:13: +4:26
++ _7 = deref_copy (_2.1: &mut (i32, i32)); // scope 3 at $DIR/derefer_test.rs:+4:13: +4:26
++ _5 = &mut ((*_7).1: i32); // scope 3 at $DIR/derefer_test.rs:+4:13: +4:26
++ StorageDead(_7); // scope 0 at $DIR/derefer_test.rs:+0:11: +5:2
+ _0 = const (); // scope 0 at $DIR/derefer_test.rs:+0:11: +5:2
+ StorageDead(_5); // scope 3 at $DIR/derefer_test.rs:+5:1: +5:2
+ StorageDead(_4); // scope 2 at $DIR/derefer_test.rs:+5:1: +5:2
+ StorageDead(_2); // scope 1 at $DIR/derefer_test.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/derefer_test.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/derefer_test.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/derefer_test.rs b/src/test/mir-opt/derefer_test.rs
new file mode 100644
index 000000000..2ebc0d343
--- /dev/null
+++ b/src/test/mir-opt/derefer_test.rs
@@ -0,0 +1,7 @@
+// EMIT_MIR derefer_test.main.Derefer.diff
+fn main() {
+ let mut a = (42,43);
+ let mut b = (99, &mut a);
+ let x = &mut (*b.1).0;
+ let y = &mut (*b.1).1;
+}
diff --git a/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff b/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff
new file mode 100644
index 000000000..e2dceecfd
--- /dev/null
+++ b/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff
@@ -0,0 +1,92 @@
+- // MIR for `main` before Derefer
++ // MIR for `main` after Derefer
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/derefer_test_multiple.rs:+0:12: +0:12
+ let mut _1: (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:+1:9: +1:14
+ let mut _3: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:+2:22: +2:28
+ let mut _5: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:+3:22: +3:28
+ let mut _7: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:22: +4:28
++ let mut _10: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:9: +4:14
++ let mut _11: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:9: +4:14
++ let mut _12: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:9: +4:14
++ let mut _13: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:9: +4:14
++ let mut _14: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:9: +4:14
++ let mut _15: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:9: +4:14
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/derefer_test_multiple.rs:+1:9: +1:14
+ let mut _2: (i32, &mut (i32, i32)); // in scope 1 at $DIR/derefer_test_multiple.rs:+2:9: +2:14
+ scope 2 {
+ debug b => _2; // in scope 2 at $DIR/derefer_test_multiple.rs:+2:9: +2:14
+ let mut _4: (i32, &mut (i32, &mut (i32, i32))); // in scope 2 at $DIR/derefer_test_multiple.rs:+3:9: +3:14
+ scope 3 {
+ debug c => _4; // in scope 3 at $DIR/derefer_test_multiple.rs:+3:9: +3:14
+ let mut _6: (i32, &mut (i32, &mut (i32, &mut (i32, i32)))); // in scope 3 at $DIR/derefer_test_multiple.rs:+4:9: +4:14
+ scope 4 {
+ debug d => _6; // in scope 4 at $DIR/derefer_test_multiple.rs:+4:9: +4:14
+ let _8: &mut i32; // in scope 4 at $DIR/derefer_test_multiple.rs:+5:9: +5:10
+ scope 5 {
+ debug x => _8; // in scope 5 at $DIR/derefer_test_multiple.rs:+5:9: +5:10
+ let _9: &mut i32; // in scope 5 at $DIR/derefer_test_multiple.rs:+6:9: +6:10
+ scope 6 {
+ debug y => _9; // in scope 6 at $DIR/derefer_test_multiple.rs:+6:9: +6:10
+ }
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/derefer_test_multiple.rs:+1:9: +1:14
+ _1 = (const 42_i32, const 43_i32); // scope 0 at $DIR/derefer_test_multiple.rs:+1:17: +1:25
+ StorageLive(_2); // scope 1 at $DIR/derefer_test_multiple.rs:+2:9: +2:14
+ StorageLive(_3); // scope 1 at $DIR/derefer_test_multiple.rs:+2:22: +2:28
+ _3 = &mut _1; // scope 1 at $DIR/derefer_test_multiple.rs:+2:22: +2:28
+ _2 = (const 99_i32, move _3); // scope 1 at $DIR/derefer_test_multiple.rs:+2:17: +2:29
+ StorageDead(_3); // scope 1 at $DIR/derefer_test_multiple.rs:+2:28: +2:29
+ StorageLive(_4); // scope 2 at $DIR/derefer_test_multiple.rs:+3:9: +3:14
+ StorageLive(_5); // scope 2 at $DIR/derefer_test_multiple.rs:+3:22: +3:28
+ _5 = &mut _2; // scope 2 at $DIR/derefer_test_multiple.rs:+3:22: +3:28
+ _4 = (const 11_i32, move _5); // scope 2 at $DIR/derefer_test_multiple.rs:+3:17: +3:29
+ StorageDead(_5); // scope 2 at $DIR/derefer_test_multiple.rs:+3:28: +3:29
+ StorageLive(_6); // scope 3 at $DIR/derefer_test_multiple.rs:+4:9: +4:14
+ StorageLive(_7); // scope 3 at $DIR/derefer_test_multiple.rs:+4:22: +4:28
+ _7 = &mut _4; // scope 3 at $DIR/derefer_test_multiple.rs:+4:22: +4:28
+ _6 = (const 13_i32, move _7); // scope 3 at $DIR/derefer_test_multiple.rs:+4:17: +4:29
+ StorageDead(_7); // scope 3 at $DIR/derefer_test_multiple.rs:+4:28: +4:29
+ StorageLive(_8); // scope 4 at $DIR/derefer_test_multiple.rs:+5:9: +5:10
+- _8 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
++ StorageLive(_10); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
++ _10 = deref_copy (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
++ StorageLive(_11); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
++ _11 = deref_copy ((*_10).1: &mut (i32, &mut (i32, i32))); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
++ StorageDead(_10); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
++ StorageLive(_12); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
++ _12 = deref_copy ((*_11).1: &mut (i32, i32)); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
++ StorageDead(_11); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
++ _8 = &mut ((*_12).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
++ StorageDead(_12); // scope 5 at $DIR/derefer_test_multiple.rs:+6:9: +6:10
+ StorageLive(_9); // scope 5 at $DIR/derefer_test_multiple.rs:+6:9: +6:10
+- _9 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
++ StorageLive(_13); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
++ _13 = deref_copy (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
++ StorageLive(_14); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
++ _14 = deref_copy ((*_13).1: &mut (i32, &mut (i32, i32))); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
++ StorageDead(_13); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
++ StorageLive(_15); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
++ _15 = deref_copy ((*_14).1: &mut (i32, i32)); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
++ StorageDead(_14); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
++ _9 = &mut ((*_15).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
++ StorageDead(_15); // scope 0 at $DIR/derefer_test_multiple.rs:+0:12: +7:2
+ _0 = const (); // scope 0 at $DIR/derefer_test_multiple.rs:+0:12: +7:2
+ StorageDead(_9); // scope 5 at $DIR/derefer_test_multiple.rs:+7:1: +7:2
+ StorageDead(_8); // scope 4 at $DIR/derefer_test_multiple.rs:+7:1: +7:2
+ StorageDead(_6); // scope 3 at $DIR/derefer_test_multiple.rs:+7:1: +7:2
+ StorageDead(_4); // scope 2 at $DIR/derefer_test_multiple.rs:+7:1: +7:2
+ StorageDead(_2); // scope 1 at $DIR/derefer_test_multiple.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/derefer_test_multiple.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/derefer_test_multiple.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/src/test/mir-opt/derefer_test_multiple.rs b/src/test/mir-opt/derefer_test_multiple.rs
new file mode 100644
index 000000000..a27363447
--- /dev/null
+++ b/src/test/mir-opt/derefer_test_multiple.rs
@@ -0,0 +1,9 @@
+// EMIT_MIR derefer_test_multiple.main.Derefer.diff
+fn main () {
+ let mut a = (42, 43);
+ let mut b = (99, &mut a);
+ let mut c = (11, &mut b);
+ let mut d = (13, &mut c);
+ let x = &mut (*d.1).1.1.1;
+ let y = &mut (*d.1).1.1.1;
+}
diff --git a/src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff
new file mode 100644
index 000000000..8929f2cc7
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff
@@ -0,0 +1,65 @@
+- // MIR for `main` before DestinationPropagation
++ // MIR for `main` after DestinationPropagation
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/branch.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/branch.rs:+1:9: +1:10
+ let mut _3: bool; // in scope 0 at $DIR/branch.rs:+3:16: +3:22
+ let _4: i32; // in scope 0 at $DIR/branch.rs:+6:9: +6:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/branch.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/branch.rs:+3:9: +3:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/branch.rs:+3:9: +3:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/branch.rs:+1:9: +1:10
+ _1 = val() -> bb1; // scope 0 at $DIR/branch.rs:+1:13: +1:18
+ // mir::Constant
+ // + span: $DIR/branch.rs:13:13: 13:16
+ // + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_2); // scope 1 at $DIR/branch.rs:+3:9: +3:10
+ StorageLive(_3); // scope 1 at $DIR/branch.rs:+3:16: +3:22
+ _3 = cond() -> bb2; // scope 1 at $DIR/branch.rs:+3:16: +3:22
+ // mir::Constant
+ // + span: $DIR/branch.rs:15:16: 15:20
+ // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ switchInt(move _3) -> [false: bb4, otherwise: bb3]; // scope 1 at $DIR/branch.rs:+3:16: +3:22
+ }
+
+ bb3: {
+ nop; // scope 1 at $DIR/branch.rs:+4:9: +4:10
+ goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6
+ }
+
+ bb4: {
+ StorageLive(_4); // scope 1 at $DIR/branch.rs:+6:9: +6:14
+ _4 = val() -> bb5; // scope 1 at $DIR/branch.rs:+6:9: +6:14
+ // mir::Constant
+ // + span: $DIR/branch.rs:18:9: 18:12
+ // + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ StorageDead(_4); // scope 1 at $DIR/branch.rs:+6:14: +6:15
+ nop; // scope 1 at $DIR/branch.rs:+7:9: +7:10
+ goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6
+ }
+
+ bb6: {
+ StorageDead(_3); // scope 1 at $DIR/branch.rs:+8:5: +8:6
+ nop; // scope 0 at $DIR/branch.rs:+0:11: +9:2
+ StorageDead(_2); // scope 1 at $DIR/branch.rs:+9:1: +9:2
+ StorageDead(_1); // scope 0 at $DIR/branch.rs:+9:1: +9:2
+ return; // scope 0 at $DIR/branch.rs:+9:2: +9:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/branch.rs b/src/test/mir-opt/dest-prop/branch.rs
new file mode 100644
index 000000000..fffcf82b3
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/branch.rs
@@ -0,0 +1,21 @@
+//! Tests that assignment in both branches of an `if` are eliminated.
+// compile-flags: -Zunsound-mir-opts
+fn val() -> i32 {
+ 1
+}
+
+fn cond() -> bool {
+ true
+}
+
+// EMIT_MIR branch.main.DestinationPropagation.diff
+fn main() {
+ let x = val();
+
+ let y = if cond() {
+ x
+ } else {
+ val();
+ x
+ };
+}
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff
new file mode 100644
index 000000000..f28bc72df
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff
@@ -0,0 +1,26 @@
+- // MIR for `arg_src` before DestinationPropagation
++ // MIR for `arg_src` after DestinationPropagation
+
+ fn arg_src(_1: i32) -> i32 {
+ debug x => const 123_i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:12: +0: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 => _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
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
++ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
+ nop; // 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
++ nop; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
++ nop; // 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/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff
new file mode 100644
index 000000000..a8a7e9ab6
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff
@@ -0,0 +1,28 @@
+- // MIR for `bar` before DestinationPropagation
++ // MIR for `bar` after DestinationPropagation
+
+ fn bar(_1: u8) -> () {
+ debug x => const 5_u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
+ let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19
+ let _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
+ let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
+ StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
+ _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
+ _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
+ // mir::Constant
+ // + span: $DIR/copy_propagation_arg.rs:16:5: 16:10
+ // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:12: +1:13
+ StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2
+ return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff
new file mode 100644
index 000000000..ce9be4c27
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff
@@ -0,0 +1,18 @@
+- // MIR for `baz` before DestinationPropagation
++ // MIR for `baz` after DestinationPropagation
+
+ fn baz(_1: i32) -> () {
+ debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
+ let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:20: +0:20
+ let mut _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
+ StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+0:20: +3:2
+ return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff
new file mode 100644
index 000000000..d7a0b950f
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff
@@ -0,0 +1,28 @@
+- // MIR for `foo` before DestinationPropagation
++ // MIR for `foo` after DestinationPropagation
+
+ fn foo(_1: u8) -> () {
+ debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
+ let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19
+ let mut _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
+ let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
+ StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
+ _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
+ _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
+ // mir::Constant
+ // + span: $DIR/copy_propagation_arg.rs:11:9: 11:14
+ // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:17
+ StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2
+ return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.rs b/src/test/mir-opt/dest-prop/copy_propagation_arg.rs
new file mode 100644
index 000000000..a5fb0f640
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.rs
@@ -0,0 +1,39 @@
+// Check that DestinationPropagation does not propagate an assignment to a function argument
+// (doing so can break usages of the original argument value)
+// compile-flags: -Zunsound-mir-opts
+fn dummy(x: u8) -> u8 {
+ x
+}
+
+// EMIT_MIR copy_propagation_arg.foo.DestinationPropagation.diff
+fn foo(mut x: u8) {
+ // calling `dummy` to make a use of `x` that copyprop cannot eliminate
+ x = dummy(x); // this will assign a local to `x`
+}
+
+// EMIT_MIR copy_propagation_arg.bar.DestinationPropagation.diff
+fn bar(mut x: u8) {
+ dummy(x);
+ x = 5;
+}
+
+// EMIT_MIR copy_propagation_arg.baz.DestinationPropagation.diff
+fn baz(mut x: i32) {
+ // self-assignment to a function argument should be eliminated
+ x = x;
+}
+
+// EMIT_MIR copy_propagation_arg.arg_src.DestinationPropagation.diff
+fn arg_src(mut x: i32) -> i32 {
+ let y = x;
+ x = 123; // Don't propagate this assignment to `y`
+ y
+}
+
+fn main() {
+ // Make sure the function actually gets instantiated.
+ foo(0);
+ bar(0);
+ baz(0);
+ arg_src(0);
+}
diff --git a/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff
new file mode 100644
index 000000000..8eeb0d354
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff
@@ -0,0 +1,53 @@
+- // MIR for `main` before DestinationPropagation
++ // MIR for `main` after DestinationPropagation
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/cycle.rs:+1:9: +1:14
+ let mut _4: i32; // in scope 0 at $DIR/cycle.rs:+4:9: +4:10
+ let _5: (); // in scope 0 at $DIR/cycle.rs:+6:5: +6:12
+ let mut _6: i32; // in scope 0 at $DIR/cycle.rs:+6:10: +6:11
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/cycle.rs:+1:9: +1:14
+ let _2: i32; // in scope 1 at $DIR/cycle.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/cycle.rs:+2:9: +2:10
+ let _3: i32; // in scope 2 at $DIR/cycle.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _3; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10
+ scope 4 (inlined std::mem::drop::<i32>) { // at $DIR/cycle.rs:14:5: 14:12
+ debug _x => _6; // in scope 4 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:9: +1:14
+ _1 = val() -> bb1; // scope 0 at $DIR/cycle.rs:+1:17: +1:22
+ // mir::Constant
+ // + span: $DIR/cycle.rs:9:17: 9:20
+ // + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_2); // scope 1 at $DIR/cycle.rs:+2:9: +2:10
+ nop; // scope 1 at $DIR/cycle.rs:+2:13: +2:14
+ StorageLive(_3); // scope 2 at $DIR/cycle.rs:+3:9: +3:10
+ nop; // scope 2 at $DIR/cycle.rs:+3:13: +3:14
+ StorageLive(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+ nop; // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+ nop; // scope 3 at $DIR/cycle.rs:+4:5: +4:10
+ StorageDead(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+ StorageLive(_5); // scope 3 at $DIR/cycle.rs:+6:5: +6:12
+ StorageLive(_6); // scope 3 at $DIR/cycle.rs:+6:10: +6:11
+ nop; // scope 3 at $DIR/cycle.rs:+6:10: +6:11
+ StorageDead(_6); // scope 3 at $DIR/cycle.rs:+6:11: +6:12
+ StorageDead(_5); // scope 3 at $DIR/cycle.rs:+6:12: +6:13
+ StorageDead(_3); // scope 2 at $DIR/cycle.rs:+7:1: +7:2
+ StorageDead(_2); // scope 1 at $DIR/cycle.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/cycle.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/cycle.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/cycle.rs b/src/test/mir-opt/dest-prop/cycle.rs
new file mode 100644
index 000000000..c9187d408
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/cycle.rs
@@ -0,0 +1,15 @@
+//! Tests that cyclic assignments don't hang DestinationPropagation, and result in reasonable code.
+// compile-flags: -Zunsound-mir-opts
+fn val() -> i32 {
+ 1
+}
+
+// EMIT_MIR cycle.main.DestinationPropagation.diff
+fn main() {
+ let mut x = val();
+ let y = x;
+ let z = y;
+ x = z;
+
+ drop(x);
+}
diff --git a/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff
new file mode 100644
index 000000000..a20a172af
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff
@@ -0,0 +1,39 @@
+- // MIR for `nrvo` before DestinationPropagation
++ // MIR for `nrvo` after DestinationPropagation
+
+ fn nrvo(_1: for<'r> fn(&'r mut [u8; 1024])) -> [u8; 1024] {
+ debug init => _1; // in scope 0 at $DIR/simple.rs:+0:9: +0:13
+ let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/simple.rs:+0:39: +0:49
+ let mut _2: [u8; 1024]; // in scope 0 at $DIR/simple.rs:+1:9: +1:16
+ let _3: (); // in scope 0 at $DIR/simple.rs:+2:5: +2:19
+ let mut _4: for<'r> fn(&'r mut [u8; 1024]); // in scope 0 at $DIR/simple.rs:+2:5: +2:9
+ let mut _5: &mut [u8; 1024]; // in scope 0 at $DIR/simple.rs:+2:10: +2:18
+ let mut _6: &mut [u8; 1024]; // in scope 0 at $DIR/simple.rs:+2:10: +2:18
+ scope 1 {
+ debug buf => _2; // in scope 1 at $DIR/simple.rs:+1:9: +1:16
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/simple.rs:+1:9: +1:16
+ _2 = [const 0_u8; 1024]; // scope 0 at $DIR/simple.rs:+1:19: +1:28
+ StorageLive(_3); // scope 1 at $DIR/simple.rs:+2:5: +2:19
+ StorageLive(_4); // scope 1 at $DIR/simple.rs:+2:5: +2:9
+ _4 = _1; // scope 1 at $DIR/simple.rs:+2:5: +2:9
+ StorageLive(_5); // scope 1 at $DIR/simple.rs:+2:10: +2:18
+ StorageLive(_6); // scope 1 at $DIR/simple.rs:+2:10: +2:18
+ _6 = &mut _2; // scope 1 at $DIR/simple.rs:+2:10: +2:18
+ _5 = &mut (*_6); // scope 1 at $DIR/simple.rs:+2:10: +2:18
+ _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/simple.rs:+2:5: +2:19
+ }
+
+ bb1: {
+ StorageDead(_5); // scope 1 at $DIR/simple.rs:+2:18: +2:19
+ StorageDead(_4); // scope 1 at $DIR/simple.rs:+2:18: +2:19
+ StorageDead(_6); // scope 1 at $DIR/simple.rs:+2:19: +2:20
+ StorageDead(_3); // scope 1 at $DIR/simple.rs:+2:19: +2:20
+ _0 = _2; // scope 1 at $DIR/simple.rs:+3:5: +3:8
+ StorageDead(_2); // scope 0 at $DIR/simple.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/simple.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/simple.rs b/src/test/mir-opt/dest-prop/simple.rs
new file mode 100644
index 000000000..3627d479a
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/simple.rs
@@ -0,0 +1,14 @@
+//! Copy of `nrvo-simple.rs`, to ensure that full dest-prop handles it too.
+// compile-flags: -Zunsound-mir-opts
+// EMIT_MIR simple.nrvo.DestinationPropagation.diff
+fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] {
+ let mut buf = [0; 1024];
+ init(&mut buf);
+ buf
+}
+
+fn main() {
+ let _ = nrvo(|buf| {
+ buf[4] = 4;
+ });
+}
diff --git a/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff
new file mode 100644
index 000000000..accdb0085
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff
@@ -0,0 +1,41 @@
+- // MIR for `main` before DestinationPropagation
++ // MIR for `main` after DestinationPropagation
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/union.rs:+0:11: +0:11
+ let _1: main::Un; // in scope 0 at $DIR/union.rs:+5:9: +5:11
+ let mut _2: u32; // in scope 0 at $DIR/union.rs:+5:23: +5:28
+ let _3: (); // in scope 0 at $DIR/union.rs:+7:5: +7:27
+ let mut _4: u32; // in scope 0 at $DIR/union.rs:+7:10: +7:26
+ scope 1 {
+ debug un => _1; // in scope 1 at $DIR/union.rs:+5:9: +5:11
+ scope 2 {
+ }
+ scope 3 (inlined std::mem::drop::<u32>) { // at $DIR/union.rs:15:5: 15:27
+ debug _x => _4; // in scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/union.rs:+5:9: +5:11
+ StorageLive(_2); // scope 0 at $DIR/union.rs:+5:23: +5:28
+ _2 = val() -> bb1; // scope 0 at $DIR/union.rs:+5:23: +5:28
+ // mir::Constant
+ // + span: $DIR/union.rs:13:23: 13:26
+ // + literal: Const { ty: fn() -> u32 {val}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ nop; // scope 0 at $DIR/union.rs:+5:14: +5:30
+ nop; // scope 0 at $DIR/union.rs:+5:14: +5:30
+ StorageDead(_2); // scope 0 at $DIR/union.rs:+5:29: +5:30
+ StorageLive(_3); // scope 1 at $DIR/union.rs:+7:5: +7:27
+ StorageLive(_4); // scope 1 at $DIR/union.rs:+7:10: +7:26
+ nop; // scope 2 at $DIR/union.rs:+7:19: +7:24
+ StorageDead(_4); // scope 1 at $DIR/union.rs:+7:26: +7:27
+ StorageDead(_3); // scope 1 at $DIR/union.rs:+7:27: +7:28
+ StorageDead(_1); // scope 0 at $DIR/union.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/union.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/union.rs b/src/test/mir-opt/dest-prop/union.rs
new file mode 100644
index 000000000..68c834dfb
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/union.rs
@@ -0,0 +1,16 @@
+//! Tests that we can propogate into places that are projections into unions
+// compile-flags: -Zunsound-mir-opts
+fn val() -> u32 {
+ 1
+}
+
+// EMIT_MIR union.main.DestinationPropagation.diff
+fn main() {
+ union Un {
+ us: u32,
+ }
+
+ let un = Un { us: val() };
+
+ drop(unsafe { un.us });
+}
diff --git a/src/test/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..89d8106ae
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff
@@ -0,0 +1,78 @@
+- // MIR for `opt1` before EarlyOtherwiseBranch
++ // MIR for `opt1` after EarlyOtherwiseBranch
+
+ fn opt1(_1: Option<u32>, _2: Option<u32>) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/early_otherwise_branch.rs:+0:9: +0:10
+ debug y => _2; // in scope 0 at $DIR/early_otherwise_branch.rs:+0:25: +0:26
+ let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch.rs:+0:44: +0:47
+ let mut _3: (std::option::Option<u32>, std::option::Option<u32>); // in scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ let mut _4: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13
+ let mut _5: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16
+ let mut _6: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:19: +2:26
+ let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:10: +2:17
+ let _8: u32; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16
+ let _9: u32; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25
++ let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ let mut _11: bool; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+ scope 1 {
+ debug a => _8; // in scope 1 at $DIR/early_otherwise_branch.rs:+2:15: +2:16
+ debug b => _9; // in scope 1 at $DIR/early_otherwise_branch.rs:+2:24: +2:25
+ }
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13
+ _4 = _1; // scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13
+ StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16
+ _5 = _2; // scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16
+ Deinit(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ (_3.0: std::option::Option<u32>) = move _4; // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ (_3.1: std::option::Option<u32>) = move _5; // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17
+ StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17
+ _7 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+- switchInt(move _7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ StorageLive(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ _10 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ _11 = Ne(_7, move _10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ StorageDead(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ switchInt(move _11) -> [false: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+ }
+
+ bb1: {
++ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15
+ _0 = const 1_u32; // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15
+- goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15
++ goto -> bb3; // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15
+ }
+
+ bb2: {
+- _6 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+- switchInt(move _6) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+- }
+-
+- bb3: {
+ StorageLive(_8); // scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16
+ _8 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16
+ StorageLive(_9); // scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25
+ _9 = (((_3.1: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25
+ _0 = const 0_u32; // scope 1 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
+ StorageDead(_9); // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
+ StorageDead(_8); // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
+- goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
++ goto -> bb3; // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
+ }
+
+- bb4: {
++ bb3: {
+ StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/early_otherwise_branch.rs:+5:2: +5:2
++ }
++
++ bb4: {
++ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ switchInt(_7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+ }
+ }
+
diff --git a/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..1a9efa930
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff
@@ -0,0 +1,92 @@
+- // MIR for `opt2` before EarlyOtherwiseBranch
++ // MIR for `opt2` after EarlyOtherwiseBranch
+
+ fn opt2(_1: Option<u32>, _2: Option<u32>) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/early_otherwise_branch.rs:+0:9: +0:10
+ debug y => _2; // in scope 0 at $DIR/early_otherwise_branch.rs:+0:25: +0:26
+ let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch.rs:+0:44: +0:47
+ let mut _3: (std::option::Option<u32>, std::option::Option<u32>); // in scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ let mut _4: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13
+ let mut _5: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16
+ let mut _6: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+3:16: +3:20
+ let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:19: +2:26
+ let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:10: +2:17
+ let _9: u32; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16
+ let _10: u32; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25
++ let mut _11: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ let mut _12: bool; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+ scope 1 {
+ debug a => _9; // in scope 1 at $DIR/early_otherwise_branch.rs:+2:15: +2:16
+ debug b => _10; // in scope 1 at $DIR/early_otherwise_branch.rs:+2:24: +2:25
+ }
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13
+ _4 = _1; // scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13
+ StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16
+ _5 = _2; // scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16
+ Deinit(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ (_3.0: std::option::Option<u32>) = move _4; // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ (_3.1: std::option::Option<u32>) = move _5; // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17
+ StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17
+ _8 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+- switchInt(move _8) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ _11 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ _12 = Ne(_8, move _11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ switchInt(move _12) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+ }
+
+ bb1: {
+- _6 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+- switchInt(move _6) -> [0_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+- }
+-
+- bb2: {
++ StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch.rs:+4:14: +4:15
+ _0 = const 1_u32; // scope 0 at $DIR/early_otherwise_branch.rs:+4:14: +4:15
+- goto -> bb6; // scope 0 at $DIR/early_otherwise_branch.rs:+4:14: +4:15
++ goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+4:14: +4:15
+ }
+
+- bb3: {
+- _7 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+- switchInt(move _7) -> [1_isize: bb4, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+- }
+-
+- bb4: {
++ bb2: {
+ StorageLive(_9); // scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16
+ _9 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16
+ StorageLive(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25
+ _10 = (((_3.1: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25
+ _0 = const 0_u32; // scope 1 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
+ StorageDead(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
+ StorageDead(_9); // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
+- goto -> bb6; // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
++ goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
+ }
+
+- bb5: {
++ bb3: {
+ _0 = const 0_u32; // scope 0 at $DIR/early_otherwise_branch.rs:+3:25: +3:26
+- goto -> bb6; // scope 0 at $DIR/early_otherwise_branch.rs:+3:25: +3:26
++ goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+3:25: +3:26
+ }
+
+- bb6: {
++ bb4: {
+ StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/early_otherwise_branch.rs:+6:2: +6:2
++ }
++
++ bb5: {
++ StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ switchInt(_8) -> [0_isize: bb3, 1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+ }
+ }
+
diff --git a/src/test/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..309a72ae5
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff
@@ -0,0 +1,78 @@
+- // MIR for `opt3` before EarlyOtherwiseBranch
++ // MIR for `opt3` after EarlyOtherwiseBranch
+
+ fn opt3(_1: Option<u32>, _2: Option<bool>) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/early_otherwise_branch.rs:+0:9: +0:10
+ debug y => _2; // in scope 0 at $DIR/early_otherwise_branch.rs:+0:25: +0:26
+ let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch.rs:+0:45: +0:48
+ let mut _3: (std::option::Option<u32>, std::option::Option<bool>); // in scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ let mut _4: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13
+ let mut _5: std::option::Option<bool>; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16
+ let mut _6: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:19: +2:26
+ let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:10: +2:17
+ let _8: u32; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16
+ let _9: bool; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25
++ let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ let mut _11: bool; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+ scope 1 {
+ debug a => _8; // in scope 1 at $DIR/early_otherwise_branch.rs:+2:15: +2:16
+ debug b => _9; // in scope 1 at $DIR/early_otherwise_branch.rs:+2:24: +2:25
+ }
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13
+ _4 = _1; // scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13
+ StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16
+ _5 = _2; // scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16
+ Deinit(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ (_3.0: std::option::Option<u32>) = move _4; // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ (_3.1: std::option::Option<bool>) = move _5; // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17
+ StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17
+ _7 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+- switchInt(move _7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ StorageLive(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ _10 = discriminant((_3.1: std::option::Option<bool>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ _11 = Ne(_7, move _10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ StorageDead(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ switchInt(move _11) -> [false: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+ }
+
+ bb1: {
++ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15
+ _0 = const 1_u32; // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15
+- goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15
++ goto -> bb3; // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15
+ }
+
+ bb2: {
+- _6 = discriminant((_3.1: std::option::Option<bool>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17
+- switchInt(move _6) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+- }
+-
+- bb3: {
+ StorageLive(_8); // scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16
+ _8 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16
+ StorageLive(_9); // scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25
+ _9 = (((_3.1: std::option::Option<bool>) as Some).0: bool); // scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25
+ _0 = const 0_u32; // scope 1 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
+ StorageDead(_9); // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
+ StorageDead(_8); // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
+- goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
++ goto -> bb3; // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32
+ }
+
+- bb4: {
++ bb3: {
+ StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/early_otherwise_branch.rs:+5:2: +5:2
++ }
++
++ bb4: {
++ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
++ switchInt(_7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+ }
+ }
+
diff --git a/src/test/mir-opt/early_otherwise_branch.rs b/src/test/mir-opt/early_otherwise_branch.rs
new file mode 100644
index 000000000..7be9fbd03
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch.rs
@@ -0,0 +1,32 @@
+// unit-test: EarlyOtherwiseBranch
+// EMIT_MIR early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff
+fn opt1(x: Option<u32>, y: Option<u32>) -> u32 {
+ match (x, y) {
+ (Some(a), Some(b)) => 0,
+ _ => 1,
+ }
+}
+
+// EMIT_MIR early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff
+fn opt2(x: Option<u32>, y: Option<u32>) -> u32 {
+ match (x, y) {
+ (Some(a), Some(b)) => 0,
+ (None, None) => 0,
+ _ => 1,
+ }
+}
+
+// optimize despite different types
+// EMIT_MIR early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff
+fn opt3(x: Option<u32>, y: Option<bool>) -> u32 {
+ match (x, y) {
+ (Some(a), Some(b)) => 0,
+ _ => 1,
+ }
+}
+
+fn main() {
+ opt1(None, Some(0));
+ opt2(None, Some(0));
+ opt3(None, Some(false));
+}
diff --git a/src/test/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..9574f32f7
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff
@@ -0,0 +1,100 @@
+- // MIR for `opt1` before EarlyOtherwiseBranch
++ // MIR for `opt1` after EarlyOtherwiseBranch
+
+ fn opt1(_1: Option<u32>, _2: Option<u32>, _3: Option<u32>) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+0:9: +0:10
+ debug y => _2; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+0:25: +0:26
+ debug z => _3; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+0:41: +0:42
+ let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+0:60: +0:63
+ let mut _4: (std::option::Option<u32>, std::option::Option<u32>, std::option::Option<u32>); // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20
+ let mut _5: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:12: +1:13
+ let mut _6: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:15: +1:16
+ let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:18: +1:19
+ let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:28: +2:35
+ let mut _9: isize; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:19: +2:26
+ let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:10: +2:17
+ let _11: u32; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:15: +2:16
+ let _12: u32; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:24: +2:25
+ let _13: u32; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:33: +2:34
++ let mut _14: isize; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
++ let mut _15: bool; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
++ let mut _16: isize; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
++ let mut _17: bool; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
+ scope 1 {
+ debug a => _11; // in scope 1 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:15: +2:16
+ debug b => _12; // in scope 1 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:24: +2:25
+ debug c => _13; // in scope 1 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:33: +2:34
+ }
+
+ bb0: {
+ StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20
+ StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:12: +1:13
+ _5 = _1; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:12: +1:13
+ StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:15: +1:16
+ _6 = _2; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:15: +1:16
+ StorageLive(_7); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:18: +1:19
+ _7 = _3; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:18: +1:19
+ Deinit(_4); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20
+ (_4.0: std::option::Option<u32>) = move _5; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20
+ (_4.1: std::option::Option<u32>) = move _6; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20
+ (_4.2: std::option::Option<u32>) = move _7; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20
+ StorageDead(_7); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:19: +1:20
+ StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:19: +1:20
+ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:19: +1:20
+ _10 = discriminant((_4.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20
+- switchInt(move _10) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
++ StorageLive(_14); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
++ _14 = discriminant((_4.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
++ StorageLive(_15); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
++ _15 = Ne(_10, move _14); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
++ StorageDead(_14); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
++ switchInt(move _15) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
+ }
+
+ bb1: {
++ StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+3:14: +3:15
++ StorageDead(_15); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+3:14: +3:15
+ _0 = const 1_u32; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+3:14: +3:15
+- goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+3:14: +3:15
++ goto -> bb4; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+3:14: +3:15
+ }
+
+ bb2: {
+- _9 = discriminant((_4.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20
+- switchInt(move _9) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
+- }
+-
+- bb3: {
+ _8 = discriminant((_4.2: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20
+- switchInt(move _8) -> [1_isize: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
++ switchInt(move _8) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
+ }
+
+- bb4: {
++ bb3: {
+ StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:15: +2:16
+ _11 = (((_4.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:15: +2:16
+ StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:24: +2:25
+ _12 = (((_4.1: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:24: +2:25
+ StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:33: +2:34
+ _13 = (((_4.2: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:33: +2:34
+ _0 = const 0_u32; // scope 1 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:40: +2:41
+ StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:40: +2:41
+ StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:40: +2:41
+ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:40: +2:41
+- goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:40: +2:41
++ goto -> bb4; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:40: +2:41
+ }
+
+- bb5: {
++ bb4: {
+ StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+5:2: +5:2
++ }
++
++ bb5: {
++ StorageDead(_15); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
++ switchInt(_10) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
+ }
+ }
+
diff --git a/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs
new file mode 100644
index 000000000..76055e133
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs
@@ -0,0 +1,13 @@
+// unit-test: EarlyOtherwiseBranch
+
+// EMIT_MIR early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff
+fn opt1(x: Option<u32>, y: Option<u32>, z: Option<u32>) -> u32 {
+ match (x, y, z) {
+ (Some(a), Some(b), Some(c)) => 0,
+ _ => 1,
+ }
+}
+
+fn main() {
+ opt1(None, Some(0), None);
+}
diff --git a/src/test/mir-opt/early_otherwise_branch_68867.rs b/src/test/mir-opt/early_otherwise_branch_68867.rs
new file mode 100644
index 000000000..ca298e921
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch_68867.rs
@@ -0,0 +1,32 @@
+// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts
+
+// example from #68867
+type CSSFloat = f32;
+
+pub enum ViewportPercentageLength {
+ Vw(CSSFloat),
+ Vh(CSSFloat),
+ Vmin(CSSFloat),
+ Vmax(CSSFloat),
+}
+
+// EMIT_MIR early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
+// EMIT_MIR early_otherwise_branch_68867.try_sum EarlyOtherwiseBranch.before SimplifyConstCondition-final.after
+#[no_mangle]
+pub extern "C" fn try_sum(
+ x: &ViewportPercentageLength,
+ other: &ViewportPercentageLength,
+) -> Result<ViewportPercentageLength, ()> {
+ use self::ViewportPercentageLength::*;
+ Ok(match (x, other) {
+ (&Vw(one), &Vw(other)) => Vw(one + other),
+ (&Vh(one), &Vh(other)) => Vh(one + other),
+ (&Vmin(one), &Vmin(other)) => Vmin(one + other),
+ (&Vmax(one), &Vmax(other)) => Vmax(one + other),
+ _ => return Err(()),
+ })
+}
+
+fn main() {
+ try_sum(&ViewportPercentageLength::Vw(1.0), &ViewportPercentageLength::Vw(2.0));
+}
diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff
new file mode 100644
index 000000000..4e6852ad7
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff
@@ -0,0 +1,344 @@
+- // MIR for `try_sum` before EarlyOtherwiseBranch
++ // MIR for `try_sum` after SimplifyConstCondition-final
+
+ fn try_sum(_1: &ViewportPercentageLength, _2: &ViewportPercentageLength) -> Result<ViewportPercentageLength, ()> {
+ debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+1:5: +1:6
+ debug other => _2; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+2:5: +2:10
+ let mut _0: std::result::Result<ViewportPercentageLength, ()>; // return place in scope 0 at $DIR/early_otherwise_branch_68867.rs:+3:6: +3:42
+ let mut _3: ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6
+ let mut _4: (&ViewportPercentageLength, &ViewportPercentageLength); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _5: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
+ let mut _6: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23
+ let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:21: +6:30
+ let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:21: +7:30
+ let mut _9: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:23: +8:34
+ let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:23: +9:34
+ let mut _11: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:11: +6:18
+ let _12: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ let _13: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ let mut _14: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
+ let mut _15: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
+ let mut _16: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
+ let _17: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ let _18: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ let mut _19: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
+ let mut _20: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
+ let mut _21: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
+ let _22: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ let _23: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ let mut _24: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
+ let mut _25: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
+ let mut _26: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
+ let _27: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ let _28: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ let mut _29: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
+ let mut _30: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
+ let mut _31: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
+ let mut _32: !; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:14: +10:28
+ let mut _33: (); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
+ let mut _34: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _35: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _36: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _37: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _38: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _39: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _40: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _41: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _42: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _43: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _44: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _45: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _46: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ scope 1 {
+- debug one => _12; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+- debug other => _13; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
++ debug one => _15; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
++ debug other => _16; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ }
+ scope 2 {
+- debug one => _17; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+- debug other => _18; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
++ debug one => _20; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
++ debug other => _21; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ }
+ scope 3 {
+- debug one => _22; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+- debug other => _23; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
++ debug one => _25; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
++ debug other => _26; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ }
+ scope 4 {
+- debug one => _27; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+- debug other => _28; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
++ debug one => _30; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
++ debug other => _31; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ }
+
+ bb0: {
+- StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6
+- StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+- StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
+- _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
++ (_4.0: &ViewportPercentageLength) = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
+ StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23
+ _6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23
+ Deinit(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+- (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
+- StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
+ StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _34 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb1: {
+ StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _35 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _7 = discriminant((*_35)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb2: {
+ StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
+ Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
+ discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
+ StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:27: +10:28
+- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
+- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
+ return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
+ }
+
+ bb3: {
+ StorageLive(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _36 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _8 = discriminant((*_36)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageDead(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb4: {
+ StorageLive(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _37 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _9 = discriminant((*_37)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageDead(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb5: {
+ StorageLive(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _38 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _10 = discriminant((*_38)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageDead(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb6: {
+- StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ StorageLive(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ _39 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+- _12 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
++ _15 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ StorageDead(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+- StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ StorageLive(_40); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ _40 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+- _13 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
++ _16 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ StorageDead(_40); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
+- StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
+- StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
+- _15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
+- StorageLive(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
+- _16 = _13; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
+- _14 = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
+- StorageDead(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
+- StorageDead(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
+- Deinit(_3); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
+- ((_3 as Vw).0: f32) = move _14; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
+- discriminant(_3) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
+- StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
+- StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
+- StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
++ ((((_0 as Ok).0: ViewportPercentageLength) as Vw).0: f32) = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
++ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
+ goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
+ }
+
+ bb7: {
+- StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ StorageLive(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ _41 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+- _17 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
++ _20 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ StorageDead(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+- StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ StorageLive(_42); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ _42 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+- _18 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
++ _21 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ StorageDead(_42); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
+- StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
+- StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
+- _20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
+- StorageLive(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
+- _21 = _18; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
+- _19 = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
+- StorageDead(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
+- StorageDead(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
+- Deinit(_3); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
+- ((_3 as Vh).0: f32) = move _19; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
+- discriminant(_3) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
+- StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
+- StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
+- StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
++ ((((_0 as Ok).0: ViewportPercentageLength) as Vh).0: f32) = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
++ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
+ goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
+ }
+
+ bb8: {
+- StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ StorageLive(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ _43 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+- _22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
++ _25 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ StorageDead(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+- StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ StorageLive(_44); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ _44 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+- _23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
++ _26 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ StorageDead(_44); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
+- StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
+- StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
+- _25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
+- StorageLive(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
+- _26 = _23; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
+- _24 = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
+- StorageDead(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
+- StorageDead(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
+- Deinit(_3); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
+- ((_3 as Vmin).0: f32) = move _24; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
+- discriminant(_3) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
+- StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
+- StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
+- StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
++ ((((_0 as Ok).0: ViewportPercentageLength) as Vmin).0: f32) = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
++ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
+ goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
+ }
+
+ bb9: {
+- StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ StorageLive(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ _45 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+- _27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
++ _30 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ StorageDead(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+- StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ StorageLive(_46); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ _46 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+- _28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
++ _31 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ StorageDead(_46); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
+- StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
+- StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
+- _30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
+- StorageLive(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
+- _31 = _28; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
+- _29 = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
+- StorageDead(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
+- StorageDead(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
+- Deinit(_3); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
+- ((_3 as Vmax).0: f32) = move _29; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
+- discriminant(_3) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
+- StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
+- StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
+- StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
++ ((((_0 as Ok).0: ViewportPercentageLength) as Vmax).0: f32) = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
++ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
+ goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
+ }
+
+ bb10: {
+ Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
+- ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
+ discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
+- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
+- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
+ return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
+ }
+ }
+
diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..2519f79f8
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
@@ -0,0 +1,253 @@
+- // MIR for `try_sum` before EarlyOtherwiseBranch
++ // MIR for `try_sum` after EarlyOtherwiseBranch
+
+ fn try_sum(_1: &ViewportPercentageLength, _2: &ViewportPercentageLength) -> Result<ViewportPercentageLength, ()> {
+ debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+1:5: +1:6
+ debug other => _2; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+2:5: +2:10
+ let mut _0: std::result::Result<ViewportPercentageLength, ()>; // return place in scope 0 at $DIR/early_otherwise_branch_68867.rs:+3:6: +3:42
+ let mut _3: ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6
+ let mut _4: (&ViewportPercentageLength, &ViewportPercentageLength); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _5: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
+ let mut _6: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23
+ let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:21: +6:30
+ let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:21: +7:30
+ let mut _9: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:23: +8:34
+ let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:23: +9:34
+ let mut _11: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:11: +6:18
+ let _12: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ let _13: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ let mut _14: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
+ let mut _15: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
+ let mut _16: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
+ let _17: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ let _18: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ let mut _19: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
+ let mut _20: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
+ let mut _21: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
+ let _22: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ let _23: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ let mut _24: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
+ let mut _25: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
+ let mut _26: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
+ let _27: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ let _28: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ let mut _29: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
+ let mut _30: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
+ let mut _31: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
+ let mut _32: !; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:14: +10:28
+ let mut _33: (); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
+ let mut _34: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _35: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _36: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _37: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _38: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _39: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _40: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _41: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _42: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _43: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _44: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _45: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ let mut _46: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ scope 1 {
+ debug one => _12; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ debug other => _13; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ }
+ scope 2 {
+ debug one => _17; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ debug other => _18; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ }
+ scope 3 {
+ debug one => _22; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ debug other => _23; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ }
+ scope 4 {
+ debug one => _27; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ debug other => _28; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ }
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6
+ StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
+ _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
+ StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23
+ _6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23
+ Deinit(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
+ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
+ StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _34 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb1: {
+ StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _35 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _7 = discriminant((*_35)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb2: {
+ StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
+ Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
+ discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
+ StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:27: +10:28
+ StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
+ StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
+ return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
+ }
+
+ bb3: {
+ StorageLive(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _36 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _8 = discriminant((*_36)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageDead(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb4: {
+ StorageLive(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _37 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _9 = discriminant((*_37)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageDead(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb5: {
+ StorageLive(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _38 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ _10 = discriminant((*_38)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ StorageDead(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb6: {
+ StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ StorageLive(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ _39 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ _12 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ StorageDead(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ StorageLive(_40); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ _40 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ _13 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ StorageDead(_40); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
+ StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
+ StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
+ _15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
+ StorageLive(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
+ _16 = _13; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
+ _14 = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
+ StorageDead(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
+ StorageDead(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
+ Deinit(_3); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
+ ((_3 as Vw).0: f32) = move _14; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
+ discriminant(_3) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
+ StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
+ StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
+ StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
+ goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
+ }
+
+ bb7: {
+ StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ StorageLive(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ _41 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ _17 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ StorageDead(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ StorageLive(_42); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ _42 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ _18 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ StorageDead(_42); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
+ StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
+ StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
+ _20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
+ StorageLive(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
+ _21 = _18; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
+ _19 = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
+ StorageDead(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
+ StorageDead(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
+ Deinit(_3); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
+ ((_3 as Vh).0: f32) = move _19; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
+ discriminant(_3) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
+ StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
+ StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
+ StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
+ goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
+ }
+
+ bb8: {
+ StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ StorageLive(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ _43 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ _22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ StorageDead(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ StorageLive(_44); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ _44 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ _23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ StorageDead(_44); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
+ StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
+ StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
+ _25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
+ StorageLive(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
+ _26 = _23; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
+ _24 = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
+ StorageDead(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
+ StorageDead(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
+ Deinit(_3); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
+ ((_3 as Vmin).0: f32) = move _24; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
+ discriminant(_3) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
+ StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
+ StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
+ StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
+ goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
+ }
+
+ bb9: {
+ StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ StorageLive(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ _45 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ _27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ StorageDead(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ StorageLive(_46); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ _46 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ _28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ StorageDead(_46); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
+ StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
+ StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
+ _30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
+ StorageLive(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
+ _31 = _28; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
+ _29 = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
+ StorageDead(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
+ StorageDead(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
+ Deinit(_3); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
+ ((_3 as Vmax).0: f32) = move _29; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
+ discriminant(_3) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
+ StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
+ StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
+ StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
+ goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
+ }
+
+ bb10: {
+ Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
+ ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
+ discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
+ StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
+ StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
+ return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
+ }
+ }
+
diff --git a/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..321f57951
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff
@@ -0,0 +1,95 @@
+- // MIR for `noopt1` before EarlyOtherwiseBranch
++ // MIR for `noopt1` after EarlyOtherwiseBranch
+
+ fn noopt1(_1: Option<u32>, _2: Option<u32>) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+0:11: +0:12
+ debug y => _2; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+0:27: +0:28
+ let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+0:46: +0:49
+ let mut _3: (std::option::Option<u32>, std::option::Option<u32>); // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17
+ let mut _4: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:12: +1:13
+ let mut _5: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:15: +1:16
+ let mut _6: isize; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+4:16: +4:23
+ let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:19: +2:26
+ let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:10: +2:17
+ let _9: u32; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:15: +2:16
+ let _10: u32; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:24: +2:25
+ let _11: u32; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+3:15: +3:16
+ let _12: u32; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+4:21: +4:22
+ scope 1 {
+ debug a => _9; // in scope 1 at $DIR/early_otherwise_branch_noopt.rs:+2:15: +2:16
+ debug b => _10; // in scope 1 at $DIR/early_otherwise_branch_noopt.rs:+2:24: +2:25
+ }
+ scope 2 {
+ debug a => _11; // in scope 2 at $DIR/early_otherwise_branch_noopt.rs:+3:15: +3:16
+ }
+ scope 3 {
+ debug b => _12; // in scope 3 at $DIR/early_otherwise_branch_noopt.rs:+4:21: +4:22
+ }
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17
+ StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:12: +1:13
+ _4 = _1; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:12: +1:13
+ StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:15: +1:16
+ _5 = _2; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:15: +1:16
+ Deinit(_3); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17
+ (_3.0: std::option::Option<u32>) = move _4; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17
+ (_3.1: std::option::Option<u32>) = move _5; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17
+ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:16: +1:17
+ StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:16: +1:17
+ _8 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17
+ switchInt(move _8) -> [0_isize: bb1, 1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:5: +1:17
+ }
+
+ bb1: {
+ _6 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17
+ switchInt(move _6) -> [0_isize: bb2, 1_isize: bb7, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:5: +1:17
+ }
+
+ bb2: {
+ _0 = const 3_u32; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+5:25: +5:26
+ goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+5:25: +5:26
+ }
+
+ bb3: {
+ unreachable; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17
+ }
+
+ bb4: {
+ _7 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17
+ switchInt(move _7) -> [0_isize: bb6, 1_isize: bb5, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:5: +1:17
+ }
+
+ bb5: {
+ StorageLive(_9); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:15: +2:16
+ _9 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:15: +2:16
+ StorageLive(_10); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:24: +2:25
+ _10 = (((_3.1: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:24: +2:25
+ _0 = const 0_u32; // scope 1 at $DIR/early_otherwise_branch_noopt.rs:+2:31: +2:32
+ StorageDead(_10); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:31: +2:32
+ StorageDead(_9); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:31: +2:32
+ goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:31: +2:32
+ }
+
+ bb6: {
+ StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+3:15: +3:16
+ _11 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+3:15: +3:16
+ _0 = const 1_u32; // scope 2 at $DIR/early_otherwise_branch_noopt.rs:+3:28: +3:29
+ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+3:28: +3:29
+ goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+3:28: +3:29
+ }
+
+ bb7: {
+ StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+4:21: +4:22
+ _12 = (((_3.1: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+4:21: +4:22
+ _0 = const 2_u32; // scope 3 at $DIR/early_otherwise_branch_noopt.rs:+4:28: +4:29
+ StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+4:28: +4:29
+ goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+4:28: +4:29
+ }
+
+ bb8: {
+ StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/src/test/mir-opt/early_otherwise_branch_noopt.rs b/src/test/mir-opt/early_otherwise_branch_noopt.rs
new file mode 100644
index 000000000..ef766bbd4
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch_noopt.rs
@@ -0,0 +1,18 @@
+// unit-test: EarlyOtherwiseBranch
+
+// must not optimize as it does not follow the pattern of
+// left and right hand side being the same variant
+
+// EMIT_MIR early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff
+fn noopt1(x: Option<u32>, y: Option<u32>) -> u32 {
+ match (x, y) {
+ (Some(a), Some(b)) => 0,
+ (Some(a), None) => 1,
+ (None, Some(b)) => 2,
+ (None, None) => 3,
+ }
+}
+
+fn main() {
+ noopt1(None, Some(0));
+}
diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..8b556acb2
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff
@@ -0,0 +1,47 @@
+- // MIR for `no_deref_ptr` before EarlyOtherwiseBranch
++ // MIR for `no_deref_ptr` after EarlyOtherwiseBranch
+
+ fn no_deref_ptr(_1: Option<i32>, _2: *const Option<i32>) -> i32 {
+ debug a => _1; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+0:24: +0:25
+ debug b => _2; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+0:40: +0:41
+ let mut _0: i32; // return place in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+0:66: +0:69
+ let mut _3: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+3:9: +3:16
+ let mut _4: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+4:13: +4:20
+ let _5: i32; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+4:18: +4:19
+ scope 1 {
+ debug v => _5; // in scope 1 at $DIR/early_otherwise_branch_soundness.rs:+4:18: +4:19
+ }
+
+ bb0: {
+ _3 = discriminant(_1); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:11: +1:12
+ switchInt(move _3) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = const 0_i32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+7:14: +7:15
+ goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+7:14: +7:15
+ }
+
+ bb2: {
+ _4 = discriminant((*_2)); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+3:26: +3:28
+ switchInt(move _4) -> [1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+3:20: +3:28
+ }
+
+ bb3: {
+ _0 = const 0_i32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+5:18: +5:19
+ goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+5:18: +5:19
+ }
+
+ bb4: {
+ StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+4:18: +4:19
+ _5 = (((*_2) as Some).0: i32); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+4:18: +4:19
+ _0 = _5; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+4:24: +4:25
+ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+4:24: +4:25
+ goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+4:24: +4:25
+ }
+
+ bb5: {
+ return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+9:2: +9:2
+ }
+ }
+
diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..3d7b3f75a
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
@@ -0,0 +1,40 @@
+- // MIR for `no_downcast` before EarlyOtherwiseBranch
++ // MIR for `no_downcast` after EarlyOtherwiseBranch
+
+ fn no_downcast(_1: &E) -> u32 {
+ debug e => _1; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+0:16: +0:17
+ let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+0:26: +0:29
+ let mut _2: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:20: +1:30
+ let mut _3: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
+ let mut _4: &E; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+0:16: +0:17
+ scope 1 {
+ }
+
+ bb0: {
+ _3 = discriminant((*_1)); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
+ switchInt(move _3) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
+ }
+
+ bb1: {
+ StorageLive(_4); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
+ _4 = deref_copy (((*_1) as Some).0: &E); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
+ _2 = discriminant((*_4)); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
+ StorageDead(_4); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
+ switchInt(move _2) -> [1_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
+ }
+
+ bb2: {
+ _0 = const 1_u32; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:38: +1:39
+ goto -> bb4; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:5: +1:52
+ }
+
+ bb3: {
+ _0 = const 2_u32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:49: +1:50
+ goto -> bb4; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:5: +1:52
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.rs b/src/test/mir-opt/early_otherwise_branch_soundness.rs
new file mode 100644
index 000000000..cd4589232
--- /dev/null
+++ b/src/test/mir-opt/early_otherwise_branch_soundness.rs
@@ -0,0 +1,32 @@
+// unit-test: EarlyOtherwiseBranch
+
+// Tests various cases that the `early_otherwise_branch` opt should *not* optimize
+
+// From #78496
+enum E<'a> {
+ Empty,
+ Some(&'a E<'a>),
+}
+
+// EMIT_MIR early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
+fn no_downcast(e: &E) -> u32 {
+ if let E::Some(E::Some(_)) = e { 1 } else { 2 }
+}
+
+// SAFETY: if `a` is `Some`, `b` must point to a valid, initialized value
+// EMIT_MIR early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff
+unsafe fn no_deref_ptr(a: Option<i32>, b: *const Option<i32>) -> i32 {
+ match a {
+ // `*b` being correct depends on `a == Some(_)`
+ Some(_) => match *b {
+ Some(v) => v,
+ _ => 0,
+ },
+ _ => 0,
+ }
+}
+
+fn main() {
+ no_downcast(&E::Empty);
+ unsafe { no_deref_ptr(None, std::ptr::null()) };
+}
diff --git a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
new file mode 100644
index 000000000..afca2fd29
--- /dev/null
+++ b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
@@ -0,0 +1,13 @@
+// MIR for `bar` 0 mir_map
+
+fn bar(_1: Bar) -> usize {
+ debug bar => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
+ let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
+ let mut _2: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
new file mode 100644
index 000000000..c79596d78
--- /dev/null
+++ b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
@@ -0,0 +1,13 @@
+// MIR for `boo` 0 mir_map
+
+fn boo(_1: Boo) -> usize {
+ debug boo => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
+ let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
+ let mut _2: u8; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
new file mode 100644
index 000000000..8ced136db
--- /dev/null
+++ b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
@@ -0,0 +1,54 @@
+// MIR for `droppy` 0 mir_map
+
+fn droppy() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/enum_cast.rs:+0:13: +0:13
+ let _1: (); // in scope 0 at $DIR/enum_cast.rs:+1:5: +6:6
+ let _2: Droppy; // in scope 0 at $DIR/enum_cast.rs:+2:13: +2:14
+ let mut _4: isize; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
+ let _5: Droppy; // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+ scope 1 {
+ debug x => _2; // in scope 1 at $DIR/enum_cast.rs:+2:13: +2:14
+ scope 2 {
+ debug y => _3; // in scope 2 at $DIR/enum_cast.rs:+5:13: +5:14
+ }
+ scope 3 {
+ let _3: usize; // in scope 3 at $DIR/enum_cast.rs:+5:13: +5:14
+ }
+ }
+ scope 4 {
+ debug z => _5; // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +6:6
+ StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+2:13: +2:14
+ _2 = Droppy::C; // scope 0 at $DIR/enum_cast.rs:+2:17: +2:26
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/enum_cast.rs:+2:13: +2:14
+ StorageLive(_3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14
+ _4 = discriminant(_2); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ _3 = move _4 as usize (Misc); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ FakeRead(ForLet(None), _3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14
+ _1 = const (); // scope 0 at $DIR/enum_cast.rs:+1:5: +6:6
+ StorageDead(_3); // scope 1 at $DIR/enum_cast.rs:+6:5: +6:6
+ drop(_2) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+ StorageDead(_1); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+ StorageLive(_5); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+ _5 = Droppy::B; // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22
+ FakeRead(ForLet(None), _5); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+ _0 = const (); // scope 0 at $DIR/enum_cast.rs:+0:13: +8:2
+ drop(_5) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
+ }
+
+ bb2: {
+ StorageDead(_5); // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/enum_cast.rs:+8:2: +8:2
+ }
+
+ bb3 (cleanup): {
+ resume; // scope 0 at $DIR/enum_cast.rs:+0:1: +8:2
+ }
+}
diff --git a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
new file mode 100644
index 000000000..39d6adeba
--- /dev/null
+++ b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
@@ -0,0 +1,13 @@
+// MIR for `foo` 0 mir_map
+
+fn foo(_1: Foo) -> usize {
+ debug foo => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
+ let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
+ let mut _2: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/enum_cast.rs b/src/test/mir-opt/enum_cast.rs
new file mode 100644
index 000000000..090142aaf
--- /dev/null
+++ b/src/test/mir-opt/enum_cast.rs
@@ -0,0 +1,50 @@
+// EMIT_MIR enum_cast.foo.mir_map.0.mir
+// EMIT_MIR enum_cast.bar.mir_map.0.mir
+// EMIT_MIR enum_cast.boo.mir_map.0.mir
+
+enum Foo {
+ A
+}
+
+enum Bar {
+ A, B
+}
+
+#[repr(u8)]
+enum Boo {
+ A, B
+}
+
+fn foo(foo: Foo) -> usize {
+ foo as usize
+}
+
+fn bar(bar: Bar) -> usize {
+ bar as usize
+}
+
+fn boo(boo: Boo) -> usize {
+ boo as usize
+}
+
+// EMIT_MIR enum_cast.droppy.mir_map.0.mir
+enum Droppy {
+ A, B, C
+}
+
+impl Drop for Droppy {
+ fn drop(&mut self) {}
+}
+
+fn droppy() {
+ {
+ let x = Droppy::C;
+ // remove this entire test once `cenum_impl_drop_cast` becomes a hard error
+ #[allow(cenum_impl_drop_cast)]
+ let y = x as usize;
+ }
+ let z = Droppy::B;
+}
+
+fn main() {
+}
diff --git a/src/test/mir-opt/equal_true.opt.InstCombine.diff b/src/test/mir-opt/equal_true.opt.InstCombine.diff
new file mode 100644
index 000000000..89982308e
--- /dev/null
+++ b/src/test/mir-opt/equal_true.opt.InstCombine.diff
@@ -0,0 +1,35 @@
+- // MIR for `opt` before InstCombine
++ // MIR for `opt` after InstCombine
+
+ fn opt(_1: bool) -> i32 {
+ debug x => _1; // in scope 0 at $DIR/equal_true.rs:+0:8: +0:9
+ let mut _0: i32; // return place in scope 0 at $DIR/equal_true.rs:+0:20: +0:23
+ let mut _2: bool; // in scope 0 at $DIR/equal_true.rs:+1:8: +1:17
+ let mut _3: bool; // in scope 0 at $DIR/equal_true.rs:+1:8: +1:9
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/equal_true.rs:+1:8: +1:17
+ StorageLive(_3); // scope 0 at $DIR/equal_true.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/equal_true.rs:+1:8: +1:9
+- _2 = Eq(move _3, const true); // scope 0 at $DIR/equal_true.rs:+1:8: +1:17
++ _2 = move _3; // scope 0 at $DIR/equal_true.rs:+1:8: +1:17
+ StorageDead(_3); // scope 0 at $DIR/equal_true.rs:+1:16: +1:17
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/equal_true.rs:+1:8: +1:17
+ }
+
+ bb1: {
+ _0 = const 0_i32; // scope 0 at $DIR/equal_true.rs:+1:20: +1:21
+ goto -> bb3; // scope 0 at $DIR/equal_true.rs:+1:5: +1:34
+ }
+
+ bb2: {
+ _0 = const 1_i32; // scope 0 at $DIR/equal_true.rs:+1:31: +1:32
+ goto -> bb3; // scope 0 at $DIR/equal_true.rs:+1:5: +1:34
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/equal_true.rs:+1:33: +1:34
+ return; // scope 0 at $DIR/equal_true.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/equal_true.rs b/src/test/mir-opt/equal_true.rs
new file mode 100644
index 000000000..994cd194a
--- /dev/null
+++ b/src/test/mir-opt/equal_true.rs
@@ -0,0 +1,9 @@
+// EMIT_MIR equal_true.opt.InstCombine.diff
+
+fn opt(x: bool) -> i32 {
+ if x == true { 0 } else { 1 }
+}
+
+fn main() {
+ opt(true);
+}
diff --git a/src/test/mir-opt/exponential-or.rs b/src/test/mir-opt/exponential-or.rs
new file mode 100644
index 000000000..0b8be8385
--- /dev/null
+++ b/src/test/mir-opt/exponential-or.rs
@@ -0,0 +1,11 @@
+// Test that simple or-patterns don't get expanded to exponentially large CFGs
+
+// EMIT_MIR exponential_or.match_tuple.SimplifyCfg-initial.after.mir
+fn match_tuple(x: (u32, bool, Option<i32>, u32)) -> u32 {
+ match x {
+ (y @ (1 | 4), true | false, Some(1 | 8) | None, z @ (6..=9 | 13..=16)) => y ^ z,
+ _ => 0,
+ }
+}
+
+fn main() {}
diff --git a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
new file mode 100644
index 000000000..d39145973
--- /dev/null
+++ b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
@@ -0,0 +1,83 @@
+// MIR for `match_tuple` after SimplifyCfg-initial
+
+fn match_tuple(_1: (u32, bool, Option<i32>, u32)) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/exponential-or.rs:+0:16: +0:17
+ let mut _0: u32; // return place in scope 0 at $DIR/exponential-or.rs:+0:53: +0:56
+ let mut _2: isize; // in scope 0 at $DIR/exponential-or.rs:+2:37: +2:48
+ let mut _3: bool; // in scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
+ let mut _4: bool; // in scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
+ let mut _5: bool; // in scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
+ let mut _6: bool; // in scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
+ let _7: u32; // in scope 0 at $DIR/exponential-or.rs:+2:10: +2:21
+ let _8: u32; // in scope 0 at $DIR/exponential-or.rs:+2:57: +2:78
+ let mut _9: u32; // in scope 0 at $DIR/exponential-or.rs:+2:83: +2:84
+ let mut _10: u32; // in scope 0 at $DIR/exponential-or.rs:+2:87: +2:88
+ scope 1 {
+ debug y => _7; // in scope 1 at $DIR/exponential-or.rs:+2:10: +2:21
+ debug z => _8; // in scope 1 at $DIR/exponential-or.rs:+2:57: +2:78
+ }
+
+ bb0: {
+ FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/exponential-or.rs:+1:11: +1:12
+ switchInt((_1.0: u32)) -> [1_u32: bb2, 4_u32: bb2, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:15: +2:20
+ }
+
+ bb1: {
+ _0 = const 0_u32; // scope 0 at $DIR/exponential-or.rs:+3:14: +3:15
+ goto -> bb10; // scope 0 at $DIR/exponential-or.rs:+3:14: +3:15
+ }
+
+ bb2: {
+ _2 = discriminant((_1.2: std::option::Option<i32>)); // scope 0 at $DIR/exponential-or.rs:+2:37: +2:55
+ switchInt(move _2) -> [0_isize: bb4, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:37: +2:55
+ }
+
+ bb3: {
+ switchInt((((_1.2: std::option::Option<i32>) as Some).0: i32)) -> [1_i32: bb4, 8_i32: bb4, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:37: +2:55
+ }
+
+ bb4: {
+ _5 = Le(const 6_u32, (_1.3: u32)); // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
+ switchInt(move _5) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
+ }
+
+ bb5: {
+ _6 = Le((_1.3: u32), const 9_u32); // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
+ switchInt(move _6) -> [false: bb6, otherwise: bb8]; // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
+ }
+
+ bb6: {
+ _3 = Le(const 13_u32, (_1.3: u32)); // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
+ switchInt(move _3) -> [false: bb1, otherwise: bb7]; // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
+ }
+
+ bb7: {
+ _4 = Le((_1.3: u32), const 16_u32); // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
+ switchInt(move _4) -> [false: bb1, otherwise: bb8]; // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
+ }
+
+ bb8: {
+ falseEdge -> [real: bb9, imaginary: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:9: +2:79
+ }
+
+ bb9: {
+ StorageLive(_7); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:21
+ _7 = (_1.0: u32); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:21
+ StorageLive(_8); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:78
+ _8 = (_1.3: u32); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:78
+ StorageLive(_9); // scope 1 at $DIR/exponential-or.rs:+2:83: +2:84
+ _9 = _7; // scope 1 at $DIR/exponential-or.rs:+2:83: +2:84
+ StorageLive(_10); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88
+ _10 = _8; // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88
+ _0 = BitXor(move _9, move _10); // scope 1 at $DIR/exponential-or.rs:+2:83: +2:88
+ StorageDead(_10); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88
+ StorageDead(_9); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88
+ StorageDead(_8); // scope 0 at $DIR/exponential-or.rs:+2:87: +2:88
+ StorageDead(_7); // scope 0 at $DIR/exponential-or.rs:+2:87: +2:88
+ goto -> bb10; // scope 0 at $DIR/exponential-or.rs:+2:87: +2:88
+ }
+
+ bb10: {
+ return; // scope 0 at $DIR/exponential-or.rs:+5:2: +5:2
+ }
+}
diff --git a/src/test/mir-opt/fn-ptr-shim.rs b/src/test/mir-opt/fn-ptr-shim.rs
new file mode 100644
index 000000000..64fbdc9de
--- /dev/null
+++ b/src/test/mir-opt/fn-ptr-shim.rs
@@ -0,0 +1,15 @@
+// compile-flags: -Zmir-opt-level=0
+
+// Tests that the `<fn() as Fn>` shim does not create a `Call` terminator with a `Self` callee
+// (as only `FnDef` and `FnPtr` callees are allowed in MIR).
+
+// EMIT_MIR core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir
+fn main() {
+ call(noop as fn());
+}
+
+fn noop() {}
+
+fn call<F: Fn()>(f: F) {
+ f();
+}
diff --git a/src/test/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir b/src/test/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir
new file mode 100644
index 000000000..c63433d36
--- /dev/null
+++ b/src/test/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir
@@ -0,0 +1,13 @@
+// MIR for `std::ops::Fn::call` before AddMovesForPackedDrops
+
+fn std::ops::Fn::call(_1: *const fn(), _2: ()) -> <fn() as FnOnce<()>>::Output {
+ let mut _0: <fn() as std::ops::FnOnce<()>>::Output; // return place in scope 0 at $SRC_DIR/core/src/ops/function.rs:+0:5: +0:67
+
+ bb0: {
+ _0 = move (*_1)() -> bb1; // scope 0 at $SRC_DIR/core/src/ops/function.rs:+0:5: +0:67
+ }
+
+ bb1: {
+ return; // scope 0 at $SRC_DIR/core/src/ops/function.rs:+0:5: +0:67
+ }
+}
diff --git a/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff b/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff
new file mode 100644
index 000000000..dca36b1a7
--- /dev/null
+++ b/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff
@@ -0,0 +1,146 @@
+- // MIR for `float_to_exponential_common` before ConstProp
++ // MIR for `float_to_exponential_common` after ConstProp
+
+ fn float_to_exponential_common(_1: &mut Formatter, _2: &T, _3: bool) -> Result<(), std::fmt::Error> {
+ debug fmt => _1; // in scope 0 at $DIR/funky_arms.rs:+0:35: +0:38
+ debug num => _2; // in scope 0 at $DIR/funky_arms.rs:+0:60: +0:63
+ debug upper => _3; // in scope 0 at $DIR/funky_arms.rs:+0:69: +0:74
+ let mut _0: std::result::Result<(), std::fmt::Error>; // return place in scope 0 at $DIR/funky_arms.rs:+0:85: +0:91
+ let _4: bool; // in scope 0 at $DIR/funky_arms.rs:+4:9: +4:19
+ let mut _5: &std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:+4:22: +4:37
+ let mut _7: std::option::Option<usize>; // in scope 0 at $DIR/funky_arms.rs:+13:30: +13:45
+ let mut _8: &std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:+13:30: +13:45
+ let mut _9: isize; // in scope 0 at $DIR/funky_arms.rs:+13:12: +13:27
+ let mut _11: &mut std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:+15:43: +15:46
+ let mut _12: &T; // in scope 0 at $DIR/funky_arms.rs:+15:48: +15:51
+ let mut _13: core::num::flt2dec::Sign; // in scope 0 at $DIR/funky_arms.rs:+15:53: +15:57
+ let mut _14: u32; // in scope 0 at $DIR/funky_arms.rs:+15:59: +15:79
+ let mut _15: u32; // in scope 0 at $DIR/funky_arms.rs:+15:59: +15:75
+ let mut _16: usize; // in scope 0 at $DIR/funky_arms.rs:+15:59: +15:68
+ let mut _17: bool; // in scope 0 at $DIR/funky_arms.rs:+15:81: +15:86
+ let mut _18: &mut std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:+17:46: +17:49
+ let mut _19: &T; // in scope 0 at $DIR/funky_arms.rs:+17:51: +17:54
+ let mut _20: core::num::flt2dec::Sign; // in scope 0 at $DIR/funky_arms.rs:+17:56: +17:60
+ let mut _21: bool; // in scope 0 at $DIR/funky_arms.rs:+17:62: +17:67
+ scope 1 {
+ debug force_sign => _4; // in scope 1 at $DIR/funky_arms.rs:+4:9: +4:19
+ let _6: core::num::flt2dec::Sign; // in scope 1 at $DIR/funky_arms.rs:+8:9: +8:13
+ scope 2 {
+ debug sign => _6; // in scope 2 at $DIR/funky_arms.rs:+8:9: +8:13
+ scope 3 {
+ debug precision => _10; // in scope 3 at $DIR/funky_arms.rs:+13:17: +13:26
+ let _10: usize; // in scope 3 at $DIR/funky_arms.rs:+13:17: +13:26
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_4); // scope 0 at $DIR/funky_arms.rs:+4:9: +4:19
+ StorageLive(_5); // scope 0 at $DIR/funky_arms.rs:+4:22: +4:37
+ _5 = &(*_1); // scope 0 at $DIR/funky_arms.rs:+4:22: +4:37
+ _4 = Formatter::sign_plus(move _5) -> bb1; // scope 0 at $DIR/funky_arms.rs:+4:22: +4:37
+ // mir::Constant
+ // + span: $DIR/funky_arms.rs:15:26: 15:35
+ // + literal: Const { ty: for<'r> fn(&'r Formatter) -> bool {Formatter::sign_plus}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_5); // scope 0 at $DIR/funky_arms.rs:+4:36: +4:37
+ StorageLive(_6); // scope 1 at $DIR/funky_arms.rs:+8:9: +8:13
+ switchInt(_4) -> [false: bb3, otherwise: bb2]; // scope 1 at $DIR/funky_arms.rs:+8:16: +8:32
+ }
+
+ bb2: {
+ Deinit(_6); // scope 1 at $DIR/funky_arms.rs:+10:17: +10:41
+ discriminant(_6) = 1; // scope 1 at $DIR/funky_arms.rs:+10:17: +10:41
+ goto -> bb4; // scope 1 at $DIR/funky_arms.rs:+10:17: +10:41
+ }
+
+ bb3: {
+ Deinit(_6); // scope 1 at $DIR/funky_arms.rs:+9:18: +9:38
+ discriminant(_6) = 0; // scope 1 at $DIR/funky_arms.rs:+9:18: +9:38
+ goto -> bb4; // scope 1 at $DIR/funky_arms.rs:+9:18: +9:38
+ }
+
+ bb4: {
+ StorageLive(_7); // scope 3 at $DIR/funky_arms.rs:+13:30: +13:45
+ StorageLive(_8); // scope 3 at $DIR/funky_arms.rs:+13:30: +13:45
+ _8 = &(*_1); // scope 3 at $DIR/funky_arms.rs:+13:30: +13:45
+ _7 = Formatter::precision(move _8) -> bb5; // scope 3 at $DIR/funky_arms.rs:+13:30: +13:45
+ // mir::Constant
+ // + span: $DIR/funky_arms.rs:24:34: 24:43
+ // + literal: Const { ty: for<'r> fn(&'r Formatter) -> Option<usize> {Formatter::precision}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ StorageDead(_8); // scope 3 at $DIR/funky_arms.rs:+13:44: +13:45
+ _9 = discriminant(_7); // scope 3 at $DIR/funky_arms.rs:+13:12: +13:27
+ switchInt(move _9) -> [1_isize: bb6, otherwise: bb8]; // scope 3 at $DIR/funky_arms.rs:+13:12: +13:27
+ }
+
+ bb6: {
+ StorageLive(_10); // scope 3 at $DIR/funky_arms.rs:+13:17: +13:26
+ _10 = ((_7 as Some).0: usize); // scope 3 at $DIR/funky_arms.rs:+13:17: +13:26
+ StorageLive(_11); // scope 3 at $DIR/funky_arms.rs:+15:43: +15:46
+ _11 = &mut (*_1); // scope 3 at $DIR/funky_arms.rs:+15:43: +15:46
+ StorageLive(_12); // scope 3 at $DIR/funky_arms.rs:+15:48: +15:51
+ _12 = _2; // scope 3 at $DIR/funky_arms.rs:+15:48: +15:51
+ StorageLive(_13); // scope 3 at $DIR/funky_arms.rs:+15:53: +15:57
+ _13 = _6; // scope 3 at $DIR/funky_arms.rs:+15:53: +15:57
+ StorageLive(_14); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:79
+ StorageLive(_15); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75
+ StorageLive(_16); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:68
+ _16 = _10; // scope 3 at $DIR/funky_arms.rs:+15:59: +15:68
+ _15 = move _16 as u32 (Misc); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75
+ StorageDead(_16); // scope 3 at $DIR/funky_arms.rs:+15:74: +15:75
+ _14 = Add(move _15, const 1_u32); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:79
+ StorageDead(_15); // scope 3 at $DIR/funky_arms.rs:+15:78: +15:79
+ StorageLive(_17); // scope 3 at $DIR/funky_arms.rs:+15:81: +15:86
+ _17 = _3; // scope 3 at $DIR/funky_arms.rs:+15:81: +15:86
+ _0 = float_to_exponential_common_exact::<T>(move _11, move _12, move _13, move _14, move _17) -> bb7; // scope 3 at $DIR/funky_arms.rs:+15:9: +15:87
+ // mir::Constant
+ // + span: $DIR/funky_arms.rs:26:9: 26:42
+ // + literal: Const { ty: for<'r, 's, 't0> fn(&'r mut Formatter<'s>, &'t0 T, Sign, u32, bool) -> Result<(), std::fmt::Error> {float_to_exponential_common_exact::<T>}, val: Value(<ZST>) }
+ }
+
+ bb7: {
+ StorageDead(_17); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87
+ StorageDead(_14); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87
+ StorageDead(_13); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87
+ StorageDead(_12); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87
+ StorageDead(_11); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87
+ StorageDead(_10); // scope 2 at $DIR/funky_arms.rs:+16:5: +16:6
+ goto -> bb10; // scope 2 at $DIR/funky_arms.rs:+13:5: +18:6
+ }
+
+ bb8: {
+ StorageLive(_18); // scope 2 at $DIR/funky_arms.rs:+17:46: +17:49
+ _18 = &mut (*_1); // scope 2 at $DIR/funky_arms.rs:+17:46: +17:49
+ StorageLive(_19); // scope 2 at $DIR/funky_arms.rs:+17:51: +17:54
+ _19 = _2; // scope 2 at $DIR/funky_arms.rs:+17:51: +17:54
+ StorageLive(_20); // scope 2 at $DIR/funky_arms.rs:+17:56: +17:60
+ _20 = _6; // scope 2 at $DIR/funky_arms.rs:+17:56: +17:60
+ StorageLive(_21); // scope 2 at $DIR/funky_arms.rs:+17:62: +17:67
+ _21 = _3; // scope 2 at $DIR/funky_arms.rs:+17:62: +17:67
+ _0 = float_to_exponential_common_shortest::<T>(move _18, move _19, move _20, move _21) -> bb9; // scope 2 at $DIR/funky_arms.rs:+17:9: +17:68
+ // mir::Constant
+ // + span: $DIR/funky_arms.rs:28:9: 28:45
+ // + literal: Const { ty: for<'r, 's, 't0> fn(&'r mut Formatter<'s>, &'t0 T, Sign, bool) -> Result<(), std::fmt::Error> {float_to_exponential_common_shortest::<T>}, val: Value(<ZST>) }
+ }
+
+ bb9: {
+ StorageDead(_21); // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68
+ StorageDead(_20); // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68
+ StorageDead(_19); // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68
+ StorageDead(_18); // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68
+ goto -> bb10; // scope 2 at $DIR/funky_arms.rs:+13:5: +18:6
+ }
+
+ bb10: {
+ StorageDead(_6); // scope 1 at $DIR/funky_arms.rs:+19:1: +19:2
+ StorageDead(_4); // scope 0 at $DIR/funky_arms.rs:+19:1: +19:2
+ StorageDead(_7); // scope 0 at $DIR/funky_arms.rs:+19:1: +19:2
+ return; // scope 0 at $DIR/funky_arms.rs:+19:2: +19:2
+ }
+ }
+
diff --git a/src/test/mir-opt/funky_arms.rs b/src/test/mir-opt/funky_arms.rs
new file mode 100644
index 000000000..3e70d85e0
--- /dev/null
+++ b/src/test/mir-opt/funky_arms.rs
@@ -0,0 +1,56 @@
+// compile-flags: --crate-type lib -Cdebug-assertions=no
+
+#![feature(flt2dec)]
+
+extern crate core;
+
+use core::num::flt2dec;
+use std::fmt::{Formatter, Result};
+
+// EMIT_MIR funky_arms.float_to_exponential_common.ConstProp.diff
+fn float_to_exponential_common<T>(fmt: &mut Formatter<'_>, num: &T, upper: bool) -> Result
+where
+ T: flt2dec::DecodableFloat,
+{
+ let force_sign = fmt.sign_plus();
+ // A bug in const propagation (never reached master, but during dev of a PR) caused the
+ // `sign = Minus` assignment to get propagated into all future reads of `sign`. This is
+ // wrong because `sign` could also have `MinusPlus` value.
+ let sign = match force_sign {
+ false => flt2dec::Sign::Minus,
+ true => flt2dec::Sign::MinusPlus,
+ };
+
+ if let Some(precision) = fmt.precision() {
+ // 1 integral digit + `precision` fractional digits = `precision + 1` total digits
+ float_to_exponential_common_exact(fmt, num, sign, precision as u32 + 1, upper)
+ } else {
+ float_to_exponential_common_shortest(fmt, num, sign, upper)
+ }
+}
+#[inline(never)]
+fn float_to_exponential_common_exact<T>(
+ fmt: &mut Formatter<'_>,
+ num: &T,
+ sign: flt2dec::Sign,
+ precision: u32,
+ upper: bool,
+) -> Result
+where
+ T: flt2dec::DecodableFloat,
+{
+ unimplemented!()
+}
+
+#[inline(never)]
+fn float_to_exponential_common_shortest<T>(
+ fmt: &mut Formatter<'_>,
+ num: &T,
+ sign: flt2dec::Sign,
+ upper: bool,
+) -> Result
+where
+ T: flt2dec::DecodableFloat,
+{
+ unimplemented!()
+}
diff --git a/src/test/mir-opt/generator-drop-cleanup.rs b/src/test/mir-opt/generator-drop-cleanup.rs
new file mode 100644
index 000000000..82c1292cb
--- /dev/null
+++ b/src/test/mir-opt/generator-drop-cleanup.rs
@@ -0,0 +1,14 @@
+#![feature(generators, generator_trait)]
+
+// ignore-wasm32-bare compiled with panic=abort by default
+
+// Regression test for #58892, generator drop shims should not have blocks
+// spuriously marked as cleanup
+
+// EMIT_MIR generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
+fn main() {
+ let gen = || {
+ let _s = String::new();
+ yield;
+ };
+}
diff --git a/src/test/mir-opt/generator-storage-dead-unwind.rs b/src/test/mir-opt/generator-storage-dead-unwind.rs
new file mode 100644
index 000000000..b72170ade
--- /dev/null
+++ b/src/test/mir-opt/generator-storage-dead-unwind.rs
@@ -0,0 +1,29 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+
+// Test that we generate StorageDead on unwind paths for generators.
+//
+// Basic block and local names can safely change, but the StorageDead statements
+// should not go away.
+
+#![feature(generators, generator_trait)]
+
+struct Foo(i32);
+
+impl Drop for Foo {
+ fn drop(&mut self) {}
+}
+
+struct Bar(i32);
+
+fn take<T>(_x: T) {}
+
+// EMIT_MIR generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir
+fn main() {
+ let _gen = || {
+ let a = Foo(5);
+ let b = Bar(6);
+ yield;
+ take(a);
+ take(b);
+ };
+}
diff --git a/src/test/mir-opt/generator-tiny.rs b/src/test/mir-opt/generator-tiny.rs
new file mode 100644
index 000000000..7dad63a61
--- /dev/null
+++ b/src/test/mir-opt/generator-tiny.rs
@@ -0,0 +1,26 @@
+//! Tests that generators that cannot return or unwind don't have unnecessary
+//! panic branches.
+
+// compile-flags: -C panic=abort
+// no-prefer-dynamic
+
+#![feature(generators, generator_trait)]
+
+struct HasDrop;
+
+impl Drop for HasDrop {
+ fn drop(&mut self) {}
+}
+
+fn callee() {}
+
+// EMIT_MIR generator_tiny.main-{closure#0}.generator_resume.0.mir
+fn main() {
+ let _gen = |_x: u8| {
+ let _d = HasDrop;
+ loop {
+ yield;
+ callee();
+ }
+ };
+}
diff --git a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
new file mode 100644
index 000000000..09765c7b9
--- /dev/null
+++ b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
@@ -0,0 +1,84 @@
+// MIR for `main::{closure#0}` 0 generator_drop
+/* generator_layout = GeneratorLayout {
+ field_tys: {
+ _0: std::string::String,
+ },
+ variant_fields: {
+ Unresumed(0): [],
+ Returned (1): [],
+ Panicked (2): [],
+ Suspend0 (3): [_0],
+ },
+ storage_conflicts: BitMatrix(1x1) {
+ (_0, _0),
+ },
+} */
+
+fn main::{closure#0}(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: 10:17]) -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ let mut _2: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ let _3: std::string::String; // in scope 0 at $DIR/generator-drop-cleanup.rs:+1:13: +1:15
+ let _4: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+2:9: +2:14
+ let mut _5: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+2:9: +2:14
+ let mut _6: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:18: +0:18
+ let mut _7: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ let mut _8: u32; // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ scope 1 {
+ debug _s => (((*_1) as variant#3).0: std::string::String); // in scope 1 at $DIR/generator-drop-cleanup.rs:+1:13: +1:15
+ }
+
+ bb0: {
+ _8 = discriminant((*_1)); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ switchInt(move _8) -> [0_u32: bb7, 3_u32: bb10, otherwise: bb11]; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ }
+
+ bb1: {
+ StorageDead(_5); // scope 1 at $DIR/generator-drop-cleanup.rs:+2:13: +2:14
+ StorageDead(_4); // scope 1 at $DIR/generator-drop-cleanup.rs:+2:14: +2:15
+ drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6
+ }
+
+ bb2: {
+ nop; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6
+ goto -> bb8; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6
+ }
+
+ bb3: {
+ return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ }
+
+ bb4 (cleanup): {
+ resume; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ }
+
+ bb5 (cleanup): {
+ nop; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6
+ goto -> bb4; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6
+ }
+
+ bb6: {
+ return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ }
+
+ bb7: {
+ goto -> bb9; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ }
+
+ bb8: {
+ goto -> bb3; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6
+ }
+
+ bb9: {
+ goto -> bb6; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ }
+
+ bb10: {
+ StorageLive(_4); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ StorageLive(_5); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ goto -> bb1; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ }
+
+ bb11: {
+ return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ }
+}
diff --git a/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir b/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir
new file mode 100644
index 000000000..cb6ed3321
--- /dev/null
+++ b/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir
@@ -0,0 +1,114 @@
+// MIR for `main::{closure#0}` before StateTransform
+
+fn main::{closure#0}(_1: [generator@$DIR/generator-storage-dead-unwind.rs:22:16: 22:18], _2: ()) -> ()
+yields ()
+ {
+ let mut _0: (); // return place in scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:19: +0:19
+ let _3: Foo; // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14
+ let _5: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
+ let mut _6: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
+ let _7: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16
+ let mut _8: Foo; // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15
+ let _9: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16
+ let mut _10: Bar; // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15
+ scope 1 {
+ debug a => _3; // in scope 1 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14
+ let _4: Bar; // in scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14
+ scope 2 {
+ debug b => _4; // in scope 2 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14
+ }
+ }
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14
+ Deinit(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:17: +1:23
+ (_3.0: i32) = const 5_i32; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:17: +1:23
+ StorageLive(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14
+ Deinit(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:17: +2:23
+ (_4.0: i32) = const 6_i32; // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:17: +2:23
+ StorageLive(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
+ StorageLive(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
+ Deinit(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
+ _5 = yield(move _6) -> [resume: bb1, drop: bb5]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
+ }
+
+ bb1: {
+ StorageDead(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:13: +3:14
+ StorageDead(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:14: +3:15
+ StorageLive(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16
+ StorageLive(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15
+ _8 = move _3; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15
+ _7 = take::<Foo>(move _8) -> [return: bb2, unwind: bb9]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16
+ // mir::Constant
+ // + span: $DIR/generator-storage-dead-unwind.rs:26:9: 26:13
+ // + literal: Const { ty: fn(Foo) {take::<Foo>}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:15: +4:16
+ StorageDead(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:16: +4:17
+ StorageLive(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16
+ StorageLive(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15
+ _10 = move _4; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15
+ _9 = take::<Bar>(move _10) -> [return: bb3, unwind: bb8]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16
+ // mir::Constant
+ // + span: $DIR/generator-storage-dead-unwind.rs:27:9: 27:13
+ // + literal: Const { ty: fn(Bar) {take::<Bar>}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:15: +5:16
+ StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:16: +5:17
+ _0 = const (); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:19: +6:6
+ StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ drop(_1) -> [return: bb4, unwind: bb11]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:18: +0:18
+ }
+
+ bb5: {
+ StorageDead(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:13: +3:14
+ StorageDead(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:14: +3:15
+ StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ drop(_3) -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ }
+
+ bb6: {
+ StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ drop(_1) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ }
+
+ bb7: {
+ generator_drop; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +0:18
+ }
+
+ bb8 (cleanup): {
+ StorageDead(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:15: +5:16
+ StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:16: +5:17
+ goto -> bb10; // scope 2 at no-location
+ }
+
+ bb9 (cleanup): {
+ StorageDead(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:15: +4:16
+ StorageDead(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:16: +4:17
+ goto -> bb10; // scope 2 at no-location
+ }
+
+ bb10 (cleanup): {
+ StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ drop(_1) -> bb11; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ }
+
+ bb11 (cleanup): {
+ resume; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +0:18
+ }
+
+ bb12 (cleanup): {
+ StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ drop(_1) -> bb11; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ }
+}
diff --git a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir
new file mode 100644
index 000000000..62e7d7b2d
--- /dev/null
+++ b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir
@@ -0,0 +1,84 @@
+// MIR for `main::{closure#0}` 0 generator_resume
+/* generator_layout = GeneratorLayout {
+ field_tys: {
+ _0: HasDrop,
+ },
+ variant_fields: {
+ Unresumed(0): [],
+ Returned (1): [],
+ Panicked (2): [],
+ Suspend0 (3): [_0],
+ },
+ storage_conflicts: BitMatrix(1x1) {
+ (_0, _0),
+ },
+} */
+
+fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]>, _2: u8) -> GeneratorState<(), ()> {
+ debug _x => _10; // in scope 0 at $DIR/generator-tiny.rs:+0:17: +0:19
+ let mut _0: std::ops::GeneratorState<(), ()>; // return place in scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ let _3: HasDrop; // in scope 0 at $DIR/generator-tiny.rs:+1:13: +1:15
+ let mut _4: !; // in scope 0 at $DIR/generator-tiny.rs:+2:9: +5:10
+ let mut _5: (); // in scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ let _6: u8; // in scope 0 at $DIR/generator-tiny.rs:+3:13: +3:18
+ let mut _7: (); // in scope 0 at $DIR/generator-tiny.rs:+3:13: +3:18
+ let _8: (); // in scope 0 at $DIR/generator-tiny.rs:+4:13: +4:21
+ let mut _9: (); // in scope 0 at $DIR/generator-tiny.rs:+0:25: +0:25
+ let _10: u8; // in scope 0 at $DIR/generator-tiny.rs:+0:17: +0:19
+ let mut _11: u32; // in scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ scope 1 {
+ debug _d => (((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop); // in scope 1 at $DIR/generator-tiny.rs:+1:13: +1:15
+ }
+
+ bb0: {
+ _11 = discriminant((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]))); // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ switchInt(move _11) -> [0_u32: bb1, 3_u32: bb5, otherwise: bb6]; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ }
+
+ bb1: {
+ _10 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ nop; // scope 0 at $DIR/generator-tiny.rs:+1:13: +1:15
+ Deinit((((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop)); // scope 0 at $DIR/generator-tiny.rs:+1:18: +1:25
+ StorageLive(_4); // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10
+ goto -> bb2; // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10
+ }
+
+ bb2: {
+ StorageLive(_6); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
+ StorageLive(_7); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
+ Deinit(_7); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
+ Deinit(_0); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
+ ((_0 as Yielded).0: ()) = move _7; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
+ discriminant(_0) = 0; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
+ discriminant((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]))) = 3; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
+ return; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
+ }
+
+ bb3: {
+ StorageDead(_7); // scope 1 at $DIR/generator-tiny.rs:+3:17: +3:18
+ StorageDead(_6); // scope 1 at $DIR/generator-tiny.rs:+3:18: +3:19
+ StorageLive(_8); // scope 1 at $DIR/generator-tiny.rs:+4:13: +4:21
+ _8 = callee() -> bb4; // scope 1 at $DIR/generator-tiny.rs:+4:13: +4:21
+ // mir::Constant
+ // + span: $DIR/generator-tiny.rs:23:13: 23:19
+ // + literal: Const { ty: fn() {callee}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ StorageDead(_8); // scope 1 at $DIR/generator-tiny.rs:+4:21: +4:22
+ _5 = const (); // scope 1 at $DIR/generator-tiny.rs:+2:14: +5:10
+ goto -> bb2; // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10
+ }
+
+ bb5: {
+ StorageLive(_4); // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ StorageLive(_6); // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ StorageLive(_7); // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ _6 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ goto -> bb3; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ }
+
+ bb6: {
+ unreachable; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ }
+}
diff --git a/src/test/mir-opt/graphviz.main.mir_map.0.dot b/src/test/mir-opt/graphviz.main.mir_map.0.dot
new file mode 100644
index 000000000..8d1da7f1b
--- /dev/null
+++ b/src/test/mir-opt/graphviz.main.mir_map.0.dot
@@ -0,0 +1,7 @@
+digraph Mir_0_3 {
+ graph [fontname="Courier, monospace"];
+ node [fontname="Courier, monospace"];
+ edge [fontname="Courier, monospace"];
+ label=<fn main() -&gt; ()<br align="left"/>>;
+ bb0__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = const ()<br/></td></tr><tr><td align="left">return</td></tr></table>>];
+}
diff --git a/src/test/mir-opt/graphviz.rs b/src/test/mir-opt/graphviz.rs
new file mode 100644
index 000000000..074dba2c3
--- /dev/null
+++ b/src/test/mir-opt/graphviz.rs
@@ -0,0 +1,5 @@
+// Test graphviz output
+// compile-flags: -Z dump-mir-graphviz
+
+// EMIT_MIR graphviz.main.mir_map.0.dot
+fn main() {}
diff --git a/src/test/mir-opt/if-condition-int.rs b/src/test/mir-opt/if-condition-int.rs
new file mode 100644
index 000000000..398311e6b
--- /dev/null
+++ b/src/test/mir-opt/if-condition-int.rs
@@ -0,0 +1,65 @@
+// unit-test: SimplifyComparisonIntegral
+// EMIT_MIR if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
+// EMIT_MIR if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
+// EMIT_MIR if_condition_int.opt_char.SimplifyComparisonIntegral.diff
+// EMIT_MIR if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
+// EMIT_MIR if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff
+// EMIT_MIR if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
+// EMIT_MIR if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff
+// EMIT_MIR if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff
+
+fn opt_u32(x: u32) -> u32 {
+ if x == 42 { 0 } else { 1 }
+}
+
+// don't opt: it is already optimal to switch on the bool
+fn dont_opt_bool(x: bool) -> u32 {
+ if x { 0 } else { 1 }
+}
+
+fn opt_char(x: char) -> u32 {
+ if x == 'x' { 0 } else { 1 }
+}
+
+fn opt_i8(x: i8) -> u32 {
+ if x == 42 { 0 } else { 1 }
+}
+
+fn opt_negative(x: i32) -> u32 {
+ if x == -42 { 0 } else { 1 }
+}
+
+fn opt_multiple_ifs(x: u32) -> u32 {
+ if x == 42 {
+ 0
+ } else if x != 21 {
+ 1
+ } else {
+ 2
+ }
+}
+
+// test that we optimize, but do not remove the b statement, as that is used later on
+fn dont_remove_comparison(a: i8) -> i32 {
+ let b = a == 17;
+ match b {
+ false => 10 + b as i32,
+ true => 100 + b as i32,
+ }
+}
+
+// test that we do not optimize on floats
+fn dont_opt_floats(a: f32) -> i32 {
+ if a == -42.0 { 0 } else { 1 }
+}
+
+fn main() {
+ opt_u32(0);
+ opt_char('0');
+ opt_i8(22);
+ dont_opt_bool(false);
+ opt_negative(0);
+ opt_multiple_ifs(0);
+ dont_remove_comparison(11);
+ dont_opt_floats(1.0);
+}
diff --git a/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..19b5ab441
--- /dev/null
+++ b/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff
@@ -0,0 +1,30 @@
+- // MIR for `dont_opt_bool` before SimplifyComparisonIntegral
++ // MIR for `dont_opt_bool` after SimplifyComparisonIntegral
+
+ fn dont_opt_bool(_1: bool) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:18: +0:19
+ let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:30: +0:33
+ let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ _2 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ }
+
+ bb1: {
+ _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:12: +1:13
+ goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:26
+ }
+
+ bb2: {
+ _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:23: +1:24
+ goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:26
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:25: +1:26
+ return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..256af7b94
--- /dev/null
+++ b/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff
@@ -0,0 +1,34 @@
+- // MIR for `dont_opt_floats` before SimplifyComparisonIntegral
++ // MIR for `dont_opt_floats` after SimplifyComparisonIntegral
+
+ fn dont_opt_floats(_1: f32) -> i32 {
+ debug a => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:20: +0:21
+ let mut _0: i32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:31: +0:34
+ let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18
+ let mut _3: f32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18
+ StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ _2 = Eq(move _3, const -42f32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18
+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:17: +1:18
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18
+ }
+
+ bb1: {
+ _0 = const 0_i32; // scope 0 at $DIR/if-condition-int.rs:+1:21: +1:22
+ goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:35
+ }
+
+ bb2: {
+ _0 = const 1_i32; // scope 0 at $DIR/if-condition-int.rs:+1:32: +1:33
+ goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:35
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:34: +1:35
+ return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..3f612e03f
--- /dev/null
+++ b/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff
@@ -0,0 +1,58 @@
+- // MIR for `dont_remove_comparison` before SimplifyComparisonIntegral
++ // MIR for `dont_remove_comparison` after SimplifyComparisonIntegral
+
+ fn dont_remove_comparison(_1: i8) -> i32 {
+ debug a => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:27: +0:28
+ let mut _0: i32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:37: +0:40
+ let _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:9: +1:10
+ let mut _3: i8; // in scope 0 at $DIR/if-condition-int.rs:+1:13: +1:14
+ let mut _4: i32; // in scope 0 at $DIR/if-condition-int.rs:+3:23: +3:31
+ let mut _5: bool; // in scope 0 at $DIR/if-condition-int.rs:+3:23: +3:24
+ let mut _6: i32; // in scope 0 at $DIR/if-condition-int.rs:+4:23: +4:31
+ let mut _7: bool; // in scope 0 at $DIR/if-condition-int.rs:+4:23: +4:24
+ scope 1 {
+ debug b => _2; // in scope 1 at $DIR/if-condition-int.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:14
+ _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:14
+- _2 = Eq(move _3, const 17_i8); // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:20
+- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20
+- switchInt(_2) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12
++ _2 = Eq(_3, const 17_i8); // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:20
++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20
++ switchInt(move _3) -> [17_i8: bb1, otherwise: bb2]; // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12
+ }
+
+ bb1: {
++ StorageDead(_3); // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12
+ StorageLive(_6); // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:31
+ StorageLive(_7); // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:24
+ _7 = _2; // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:24
+ _6 = move _7 as i32 (Misc); // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:31
+ StorageDead(_7); // scope 1 at $DIR/if-condition-int.rs:+4:30: +4:31
+ _0 = Add(const 100_i32, move _6); // scope 1 at $DIR/if-condition-int.rs:+4:17: +4:31
+ StorageDead(_6); // scope 1 at $DIR/if-condition-int.rs:+4:30: +4:31
+ goto -> bb3; // scope 1 at $DIR/if-condition-int.rs:+4:30: +4:31
+ }
+
+ bb2: {
++ StorageDead(_3); // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12
+ StorageLive(_4); // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:31
+ StorageLive(_5); // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:24
+ _5 = _2; // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:24
+ _4 = move _5 as i32 (Misc); // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:31
+ StorageDead(_5); // scope 1 at $DIR/if-condition-int.rs:+3:30: +3:31
+ _0 = Add(const 10_i32, move _4); // scope 1 at $DIR/if-condition-int.rs:+3:18: +3:31
+ StorageDead(_4); // scope 1 at $DIR/if-condition-int.rs:+3:30: +3:31
+ goto -> bb3; // scope 1 at $DIR/if-condition-int.rs:+3:30: +3:31
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/if-condition-int.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..9b64c379f
--- /dev/null
+++ b/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff
@@ -0,0 +1,39 @@
+- // MIR for `opt_char` before SimplifyComparisonIntegral
++ // MIR for `opt_char` after SimplifyComparisonIntegral
+
+ fn opt_char(_1: char) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:13: +0:14
+ let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:25: +0:28
+ let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+ let mut _3: char; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+ StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+- _2 = Eq(move _3, const 'x'); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16
++ switchInt(move _3) -> ['x': bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+ }
+
+ bb1: {
++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+ _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20
+ goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33
+ }
+
+ bb2: {
++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+ _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:30: +1:31
+ goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:32: +1:33
+ return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..8042d63bb
--- /dev/null
+++ b/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
@@ -0,0 +1,39 @@
+- // MIR for `opt_i8` before SimplifyComparisonIntegral
++ // MIR for `opt_i8` after SimplifyComparisonIntegral
+
+ fn opt_i8(_1: i8) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:11: +0:12
+ let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:21: +0:24
+ let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ let mut _3: i8; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+- _2 = Eq(move _3, const 42_i8); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15
++ switchInt(move _3) -> [42_i8: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ }
+
+ bb1: {
++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:18: +1:19
+ goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32
+ }
+
+ bb2: {
++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:29: +1:30
+ goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:31: +1:32
+ return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..a408de1ef
--- /dev/null
+++ b/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
@@ -0,0 +1,65 @@
+- // MIR for `opt_multiple_ifs` before SimplifyComparisonIntegral
++ // MIR for `opt_multiple_ifs` after SimplifyComparisonIntegral
+
+ fn opt_multiple_ifs(_1: u32) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:21: +0:22
+ let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:32: +0:35
+ let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ let mut _3: u32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ let mut _4: bool; // in scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
+ let mut _5: u32; // in scope 0 at $DIR/if-condition-int.rs:+3:15: +3:16
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+- _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15
++ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ }
+
+ bb1: {
++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+2:9: +2:10
+ goto -> bb6; // scope 0 at $DIR/if-condition-int.rs:+1:5: +7:6
+ }
+
+ bb2: {
++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ StorageLive(_4); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
+ StorageLive(_5); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:16
+ _5 = _1; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:16
+- _4 = Ne(move _5, const 21_u32); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
+- StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:+3:21: +3:22
+- switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
++ nop; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
++ nop; // scope 0 at $DIR/if-condition-int.rs:+3:21: +3:22
++ switchInt(move _5) -> [21_u32: bb4, otherwise: bb3]; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
+ }
+
+ bb3: {
++ StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
+ _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+4:9: +4:10
+ goto -> bb5; // scope 0 at $DIR/if-condition-int.rs:+3:12: +7:6
+ }
+
+ bb4: {
++ StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
+ _0 = const 2_u32; // scope 0 at $DIR/if-condition-int.rs:+6:9: +6:10
+ goto -> bb5; // scope 0 at $DIR/if-condition-int.rs:+3:12: +7:6
+ }
+
+ bb5: {
+ StorageDead(_4); // scope 0 at $DIR/if-condition-int.rs:+7:5: +7:6
+ goto -> bb6; // scope 0 at $DIR/if-condition-int.rs:+1:5: +7:6
+ }
+
+ bb6: {
+ StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+7:5: +7:6
+ return; // scope 0 at $DIR/if-condition-int.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..6802f89d9
--- /dev/null
+++ b/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
@@ -0,0 +1,39 @@
+- // MIR for `opt_negative` before SimplifyComparisonIntegral
++ // MIR for `opt_negative` after SimplifyComparisonIntegral
+
+ fn opt_negative(_1: i32) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:17: +0:18
+ let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:28: +0:31
+ let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+ let mut _3: i32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+ StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+- _2 = Eq(move _3, const -42_i32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16
++ switchInt(move _3) -> [-42_i32: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+ }
+
+ bb1: {
++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+ _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20
+ goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33
+ }
+
+ bb2: {
++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+ _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:30: +1:31
+ goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:32: +1:33
+ return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..96387771d
--- /dev/null
+++ b/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
@@ -0,0 +1,39 @@
+- // MIR for `opt_u32` before SimplifyComparisonIntegral
++ // MIR for `opt_u32` after SimplifyComparisonIntegral
+
+ fn opt_u32(_1: u32) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:12: +0:13
+ let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:23: +0:26
+ let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ let mut _3: u32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+- _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15
++ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ }
+
+ bb1: {
++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:18: +1:19
+ goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32
+ }
+
+ bb2: {
++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:29: +1:30
+ goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:31: +1:32
+ return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/caller-with-trivial-bound.rs b/src/test/mir-opt/inline/caller-with-trivial-bound.rs
new file mode 100644
index 000000000..8545db894
--- /dev/null
+++ b/src/test/mir-opt/inline/caller-with-trivial-bound.rs
@@ -0,0 +1,26 @@
+// ignore-wasm32 compiled with panic=abort by default
+// needs-unwind
+
+#![crate_type = "lib"]
+pub trait Factory<T> {
+ type Item;
+}
+
+pub struct IntFactory;
+
+impl<T> Factory<T> for IntFactory {
+ type Item = usize;
+}
+
+// EMIT_MIR caller_with_trivial_bound.foo.Inline.diff
+pub fn foo<T>()
+where
+ IntFactory: Factory<T>,
+{
+ let mut x: <IntFactory as Factory<T>>::Item = bar::<T>();
+}
+
+#[inline(always)]
+pub fn bar<T>() -> <IntFactory as Factory<T>>::Item {
+ 0usize
+}
diff --git a/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff b/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff
new file mode 100644
index 000000000..d7deb9c66
--- /dev/null
+++ b/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff
@@ -0,0 +1,33 @@
+- // MIR for `foo` before Inline
++ // MIR for `foo` after Inline
+
+ fn foo() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/caller-with-trivial-bound.rs:+1:1: +1:1
+ let mut _1: <IntFactory as Factory<T>>::Item; // in scope 0 at $DIR/caller-with-trivial-bound.rs:+4:9: +4:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/caller-with-trivial-bound.rs:+4:9: +4:14
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/caller-with-trivial-bound.rs:+4:9: +4:14
+ _1 = bar::<T>() -> bb1; // scope 0 at $DIR/caller-with-trivial-bound.rs:+4:51: +4:61
+ // mir::Constant
+ // + span: $DIR/caller-with-trivial-bound.rs:20:51: 20:59
+ // + literal: Const { ty: fn() -> <IntFactory as Factory<T>>::Item {bar::<T>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ _0 = const (); // scope 0 at $DIR/caller-with-trivial-bound.rs:+3:1: +5:2
+ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/caller-with-trivial-bound.rs:+5:1: +5:2
+ }
+
+ bb2: {
+ StorageDead(_1); // scope 0 at $DIR/caller-with-trivial-bound.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/caller-with-trivial-bound.rs:+5:2: +5:2
+ }
+
+ bb3 (cleanup): {
+ resume; // scope 0 at $DIR/caller-with-trivial-bound.rs:+0:1: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/cycle.f.Inline.diff b/src/test/mir-opt/inline/cycle.f.Inline.diff
new file mode 100644
index 000000000..40fdd1cdb
--- /dev/null
+++ b/src/test/mir-opt/inline/cycle.f.Inline.diff
@@ -0,0 +1,43 @@
+- // MIR for `f` before Inline
++ // MIR for `f` after Inline
+
+ fn f(_1: impl Fn()) -> () {
+ debug g => _1; // in scope 0 at $DIR/cycle.rs:+0:6: +0:7
+ let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:20: +0:20
+ let _2: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:8
+ let mut _3: &impl Fn(); // in scope 0 at $DIR/cycle.rs:+1:5: +1:6
+ let mut _4: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:8
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:8
+ StorageLive(_3); // scope 0 at $DIR/cycle.rs:+1:5: +1:6
+ _3 = &_1; // scope 0 at $DIR/cycle.rs:+1:5: +1:6
+ StorageLive(_4); // scope 0 at $DIR/cycle.rs:+1:5: +1:8
+ Deinit(_4); // scope 0 at $DIR/cycle.rs:+1:5: +1:8
+ _2 = <impl Fn() as Fn<()>>::call(move _3, move _4) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/cycle.rs:+1:5: +1:8
+ // mir::Constant
+ // + span: $DIR/cycle.rs:6:5: 6:6
+ // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as FnOnce<()>>::Output {<impl Fn() as Fn<()>>::call}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_4); // scope 0 at $DIR/cycle.rs:+1:7: +1:8
+ StorageDead(_3); // scope 0 at $DIR/cycle.rs:+1:7: +1:8
+ StorageDead(_2); // scope 0 at $DIR/cycle.rs:+1:8: +1:9
+ _0 = const (); // scope 0 at $DIR/cycle.rs:+0:20: +2:2
+ drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/cycle.rs:+2:1: +2:2
+ }
+
+ bb2: {
+ return; // scope 0 at $DIR/cycle.rs:+2:2: +2:2
+ }
+
+ bb3 (cleanup): {
+ drop(_1) -> bb4; // scope 0 at $DIR/cycle.rs:+2:1: +2:2
+ }
+
+ bb4 (cleanup): {
+ resume; // scope 0 at $DIR/cycle.rs:+0:1: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/cycle.g.Inline.diff b/src/test/mir-opt/inline/cycle.g.Inline.diff
new file mode 100644
index 000000000..59f34d379
--- /dev/null
+++ b/src/test/mir-opt/inline/cycle.g.Inline.diff
@@ -0,0 +1,57 @@
+- // MIR for `g` before Inline
++ // MIR for `g` after Inline
+
+ fn g() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:8: +0:8
+ let _1: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:12
++ let mut _2: fn() {main}; // in scope 0 at $DIR/cycle.rs:+1:5: +1:12
++ scope 1 (inlined f::<fn() {main}>) { // at $DIR/cycle.rs:12:5: 12:12
++ debug g => _2; // in scope 1 at $DIR/cycle.rs:+0:6: +0:7
++ let _3: (); // in scope 1 at $DIR/cycle.rs:+0:5: +0:8
++ let mut _4: &fn() {main}; // in scope 1 at $DIR/cycle.rs:+0:5: +0:6
++ let mut _5: (); // in scope 1 at $DIR/cycle.rs:+0:5: +0:8
++ scope 2 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) { // at $DIR/cycle.rs:6:5: 6:8
++ }
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:5: +1:12
+- _1 = f::<fn() {main}>(main) -> bb1; // scope 0 at $DIR/cycle.rs:+1:5: +1:12
++ StorageLive(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:12
++ _2 = main; // scope 0 at $DIR/cycle.rs:+1:5: +1:12
+ // mir::Constant
+- // + span: $DIR/cycle.rs:12:5: 12:6
+- // + literal: Const { ty: fn(fn() {main}) {f::<fn() {main}>}, val: Value(<ZST>) }
+- // mir::Constant
+ // + span: $DIR/cycle.rs:12:7: 12:11
+ // + literal: Const { ty: fn() {main}, val: Value(<ZST>) }
++ StorageLive(_3); // scope 1 at $DIR/cycle.rs:+0:5: +0:8
++ StorageLive(_4); // scope 1 at $DIR/cycle.rs:+0:5: +0:6
++ _4 = &_2; // scope 1 at $DIR/cycle.rs:+0:5: +0:6
++ StorageLive(_5); // scope 1 at $DIR/cycle.rs:+0:5: +0:8
++ _3 = move (*_4)() -> [return: bb4, unwind: bb2]; // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL
+ }
+
+ bb1: {
++ StorageDead(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:12
+ StorageDead(_1); // scope 0 at $DIR/cycle.rs:+1:12: +1:13
+ _0 = const (); // scope 0 at $DIR/cycle.rs:+0:8: +2:2
+ return; // scope 0 at $DIR/cycle.rs:+2:2: +2:2
++ }
++
++ bb2 (cleanup): {
++ drop(_2) -> bb3; // scope 1 at $DIR/cycle.rs:+0:1: +0:2
++ }
++
++ bb3 (cleanup): {
++ resume; // scope 1 at $DIR/cycle.rs:+0:1: +0:2
++ }
++
++ bb4: {
++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:+0:7: +0:8
++ StorageDead(_4); // scope 1 at $DIR/cycle.rs:+0:7: +0:8
++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:+0:8: +0:9
++ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:+0:1: +0:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/cycle.main.Inline.diff b/src/test/mir-opt/inline/cycle.main.Inline.diff
new file mode 100644
index 000000000..6def7c3ee
--- /dev/null
+++ b/src/test/mir-opt/inline/cycle.main.Inline.diff
@@ -0,0 +1,74 @@
+- // MIR for `main` before Inline
++ // MIR for `main` after Inline
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:9
++ let mut _2: fn() {g}; // in scope 0 at $DIR/cycle.rs:+1:5: +1:9
++ scope 1 (inlined f::<fn() {g}>) { // at $DIR/cycle.rs:17:5: 17:9
++ debug g => _2; // in scope 1 at $DIR/cycle.rs:+0:6: +0:7
++ let _3: (); // in scope 1 at $DIR/cycle.rs:+0:5: +0:8
++ let mut _4: &fn() {g}; // in scope 1 at $DIR/cycle.rs:+0:5: +0:6
++ let mut _5: (); // in scope 1 at $DIR/cycle.rs:+0:5: +0:8
++ scope 2 (inlined <fn() {g} as Fn<()>>::call - shim(fn() {g})) { // at $DIR/cycle.rs:6:5: 6:8
++ scope 3 (inlined g) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL
++ let mut _6: fn() {main}; // in scope 3 at $DIR/cycle.rs:+0:5: +0:12
++ scope 4 (inlined f::<fn() {main}>) { // at $DIR/cycle.rs:12:5: 12:12
++ debug g => _6; // in scope 4 at $DIR/cycle.rs:+0:6: +0:7
++ let _7: (); // in scope 4 at $DIR/cycle.rs:+0:5: +0:8
++ let mut _8: &fn() {main}; // in scope 4 at $DIR/cycle.rs:+0:5: +0:6
++ scope 5 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) { // at $DIR/cycle.rs:6:5: 6:8
++ }
++ }
++ }
++ }
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:5: +1:9
+- _1 = f::<fn() {g}>(g) -> bb1; // scope 0 at $DIR/cycle.rs:+1:5: +1:9
++ StorageLive(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:9
++ _2 = g; // scope 0 at $DIR/cycle.rs:+1:5: +1:9
+ // mir::Constant
+- // + span: $DIR/cycle.rs:17:5: 17:6
+- // + literal: Const { ty: fn(fn() {g}) {f::<fn() {g}>}, val: Value(<ZST>) }
+- // mir::Constant
+ // + span: $DIR/cycle.rs:17:7: 17:8
+ // + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
++ StorageLive(_3); // scope 1 at $DIR/cycle.rs:+0:5: +0:8
++ StorageLive(_4); // scope 1 at $DIR/cycle.rs:+0:5: +0:6
++ _4 = &_2; // scope 1 at $DIR/cycle.rs:+0:5: +0:6
++ StorageLive(_5); // scope 1 at $DIR/cycle.rs:+0:5: +0:8
++ StorageLive(_6); // scope 3 at $DIR/cycle.rs:+0:5: +0:12
++ StorageLive(_7); // scope 4 at $DIR/cycle.rs:+0:5: +0:8
++ StorageLive(_8); // scope 4 at $DIR/cycle.rs:+0:5: +0:6
++ _8 = &_6; // scope 4 at $DIR/cycle.rs:+0:5: +0:6
++ _7 = move (*_8)() -> [return: bb4, unwind: bb2]; // scope 5 at $SRC_DIR/core/src/ops/function.rs:LL:COL
+ }
+
+ bb1: {
++ StorageDead(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:9
+ StorageDead(_1); // scope 0 at $DIR/cycle.rs:+1:9: +1:10
+ _0 = const (); // scope 0 at $DIR/cycle.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/cycle.rs:+2:2: +2:2
++ }
++
++ bb2 (cleanup): {
++ drop(_2) -> bb3; // scope 1 at $DIR/cycle.rs:+0:1: +0:2
++ }
++
++ bb3 (cleanup): {
++ resume; // scope 1 at $DIR/cycle.rs:+0:1: +0:2
++ }
++
++ bb4: {
++ StorageDead(_8); // scope 4 at $DIR/cycle.rs:+0:7: +0:8
++ StorageDead(_7); // scope 4 at $DIR/cycle.rs:+0:8: +0:9
++ StorageDead(_6); // scope 3 at $DIR/cycle.rs:+0:5: +0:12
++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:+0:7: +0:8
++ StorageDead(_4); // scope 1 at $DIR/cycle.rs:+0:7: +0:8
++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:+0:8: +0:9
++ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:+0:1: +0:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/cycle.rs b/src/test/mir-opt/inline/cycle.rs
new file mode 100644
index 000000000..9e8950d8a
--- /dev/null
+++ b/src/test/mir-opt/inline/cycle.rs
@@ -0,0 +1,18 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+
+// EMIT_MIR cycle.f.Inline.diff
+#[inline(always)]
+fn f(g: impl Fn()) {
+ g();
+}
+
+// EMIT_MIR cycle.g.Inline.diff
+#[inline(always)]
+fn g() {
+ f(main);
+}
+
+// EMIT_MIR cycle.main.Inline.diff
+fn main() {
+ f(g);
+}
diff --git a/src/test/mir-opt/inline/dyn-trait.rs b/src/test/mir-opt/inline/dyn-trait.rs
new file mode 100644
index 000000000..6a46e1e07
--- /dev/null
+++ b/src/test/mir-opt/inline/dyn-trait.rs
@@ -0,0 +1,35 @@
+#![crate_type = "lib"]
+
+use std::fmt::Debug;
+
+pub trait Cache {
+ type V: Debug;
+
+ fn store_nocache(&self);
+}
+
+pub trait Query {
+ type V;
+ type C: Cache<V = Self::V>;
+
+ fn cache<T>(s: &T) -> &Self::C;
+}
+
+// EMIT_MIR dyn_trait.mk_cycle.Inline.diff
+#[inline(always)]
+pub fn mk_cycle<V: Debug>(c: &dyn Cache<V = V>) {
+ c.store_nocache()
+}
+
+// EMIT_MIR dyn_trait.try_execute_query.Inline.diff
+#[inline(always)]
+pub fn try_execute_query<C: Cache>(c: &C) {
+ mk_cycle(c)
+}
+
+// EMIT_MIR dyn_trait.get_query.Inline.diff
+#[inline(always)]
+pub fn get_query<Q: Query, T>(t: &T) {
+ let c = Q::cache(t);
+ try_execute_query(c)
+}
diff --git a/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff
new file mode 100644
index 000000000..8eae04c4d
--- /dev/null
+++ b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff
@@ -0,0 +1,62 @@
+- // MIR for `get_query` before Inline
++ // MIR for `get_query` after Inline
+
+ fn get_query(_1: &T) -> () {
+ debug t => _1; // in scope 0 at $DIR/dyn-trait.rs:+0:31: +0:32
+ let mut _0: (); // return place in scope 0 at $DIR/dyn-trait.rs:+0:38: +0:38
+ let _2: &<Q as Query>::C; // in scope 0 at $DIR/dyn-trait.rs:+1:9: +1:10
+ let mut _3: &T; // in scope 0 at $DIR/dyn-trait.rs:+1:22: +1:23
+ let mut _4: &<Q as Query>::C; // in scope 0 at $DIR/dyn-trait.rs:+2:23: +2:24
+ scope 1 {
+ debug c => _2; // in scope 1 at $DIR/dyn-trait.rs:+1:9: +1:10
++ scope 2 (inlined try_execute_query::<<Q as Query>::C>) { // at $DIR/dyn-trait.rs:34:5: 34:25
++ debug c => _4; // in scope 2 at $DIR/dyn-trait.rs:+0:36: +0:37
++ let mut _5: &dyn Cache<V = <Q as Query>::V>; // in scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
++ let mut _6: &<Q as Query>::C; // in scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
++ scope 3 (inlined mk_cycle::<<Q as Query>::V>) { // at $DIR/dyn-trait.rs:27:5: 27:16
++ debug c => _5; // in scope 3 at $DIR/dyn-trait.rs:+0:27: +0:28
++ let mut _7: &dyn Cache<V = <Q as Query>::V>; // in scope 3 at $DIR/dyn-trait.rs:+0:5: +0:22
++ }
++ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/dyn-trait.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/dyn-trait.rs:+1:22: +1:23
+ _3 = &(*_1); // scope 0 at $DIR/dyn-trait.rs:+1:22: +1:23
+ _2 = <Q as Query>::cache::<T>(move _3) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:13: +1:24
+ // mir::Constant
+ // + span: $DIR/dyn-trait.rs:33:13: 33:21
+ // + user_ty: UserType(0)
+ // + literal: Const { ty: for<'r> fn(&'r T) -> &'r <Q as Query>::C {<Q as Query>::cache::<T>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 0 at $DIR/dyn-trait.rs:+1:23: +1:24
+ StorageLive(_4); // scope 1 at $DIR/dyn-trait.rs:+2:23: +2:24
+ _4 = &(*_2); // scope 1 at $DIR/dyn-trait.rs:+2:23: +2:24
+- _0 = try_execute_query::<<Q as Query>::C>(move _4) -> bb2; // scope 1 at $DIR/dyn-trait.rs:+2:5: +2:25
++ StorageLive(_5); // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
++ StorageLive(_6); // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
++ _6 = _4; // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
++ _5 = move _6 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
++ StorageDead(_6); // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
++ StorageLive(_7); // scope 3 at $DIR/dyn-trait.rs:+0:5: +0:22
++ _7 = _5; // scope 3 at $DIR/dyn-trait.rs:+0:5: +0:22
++ _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(move _7) -> bb2; // scope 3 at $DIR/dyn-trait.rs:+0:5: +0:22
+ // mir::Constant
+- // + span: $DIR/dyn-trait.rs:34:5: 34:22
+- // + literal: Const { ty: for<'r> fn(&'r <Q as Query>::C) {try_execute_query::<<Q as Query>::C>}, val: Value(<ZST>) }
++ // + span: $DIR/dyn-trait.rs:21:7: 21:20
++ // + literal: Const { ty: for<'r> fn(&'r dyn Cache<V = <Q as Query>::V>) {<dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache}, val: Value(<ZST>) }
+ }
+
+ bb2: {
++ StorageDead(_7); // scope 3 at $DIR/dyn-trait.rs:+0:21: +0:22
++ StorageDead(_5); // scope 2 at $DIR/dyn-trait.rs:+0:15: +0:16
+ StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:+2:24: +2:25
+ StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/dyn-trait.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff b/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff
new file mode 100644
index 000000000..994930ef4
--- /dev/null
+++ b/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff
@@ -0,0 +1,23 @@
+- // MIR for `mk_cycle` before Inline
++ // MIR for `mk_cycle` after Inline
+
+ fn mk_cycle(_1: &dyn Cache<V = V>) -> () {
+ debug c => _1; // in scope 0 at $DIR/dyn-trait.rs:+0:27: +0:28
+ let mut _0: (); // return place in scope 0 at $DIR/dyn-trait.rs:+0:49: +0:49
+ let mut _2: &dyn Cache<V = V>; // in scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22
+ _2 = &(*_1); // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22
+ _0 = <dyn Cache<V = V> as Cache>::store_nocache(move _2) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22
+ // mir::Constant
+ // + span: $DIR/dyn-trait.rs:21:7: 21:20
+ // + literal: Const { ty: for<'r> fn(&'r dyn Cache<V = V>) {<dyn Cache<V = V> as Cache>::store_nocache}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+1:21: +1:22
+ return; // scope 0 at $DIR/dyn-trait.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
new file mode 100644
index 000000000..e7c5972f4
--- /dev/null
+++ b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
@@ -0,0 +1,37 @@
+- // MIR for `try_execute_query` before Inline
++ // MIR for `try_execute_query` after Inline
+
+ fn try_execute_query(_1: &C) -> () {
+ debug c => _1; // in scope 0 at $DIR/dyn-trait.rs:+0:36: +0:37
+ let mut _0: (); // return place in scope 0 at $DIR/dyn-trait.rs:+0:43: +0:43
+ let mut _2: &dyn Cache<V = <C as Cache>::V>; // in scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
+ let mut _3: &C; // in scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
++ scope 1 (inlined mk_cycle::<<C as Cache>::V>) { // at $DIR/dyn-trait.rs:27:5: 27:16
++ debug c => _2; // in scope 1 at $DIR/dyn-trait.rs:+0:27: +0:28
++ let mut _4: &dyn Cache<V = <C as Cache>::V>; // in scope 1 at $DIR/dyn-trait.rs:+0:5: +0:22
++ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
+ StorageLive(_3); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
+ _3 = &(*_1); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
+ _2 = move _3 as &dyn Cache<V = <C as Cache>::V> (Pointer(Unsize)); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
+ StorageDead(_3); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
+- _0 = mk_cycle::<<C as Cache>::V>(move _2) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:16
++ StorageLive(_4); // scope 1 at $DIR/dyn-trait.rs:+0:5: +0:22
++ _4 = _2; // scope 1 at $DIR/dyn-trait.rs:+0:5: +0:22
++ _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(move _4) -> bb1; // scope 1 at $DIR/dyn-trait.rs:+0:5: +0:22
+ // mir::Constant
+- // + span: $DIR/dyn-trait.rs:27:5: 27:13
+- // + literal: Const { ty: for<'r> fn(&'r (dyn Cache<V = <C as Cache>::V> + 'r)) {mk_cycle::<<C as Cache>::V>}, val: Value(<ZST>) }
++ // + span: $DIR/dyn-trait.rs:21:7: 21:20
++ // + literal: Const { ty: for<'r> fn(&'r dyn Cache<V = <C as Cache>::V>) {<dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache}, val: Value(<ZST>) }
+ }
+
+ bb1: {
++ StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:+0:21: +0:22
+ StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+1:15: +1:16
+ return; // scope 0 at $DIR/dyn-trait.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline-any-operand.rs b/src/test/mir-opt/inline/inline-any-operand.rs
new file mode 100644
index 000000000..fb0de020f
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-any-operand.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Z span_free_formats
+
+// Tests that MIR inliner works for any operand
+
+fn main() {
+ println!("{}", bar());
+}
+
+// EMIT_MIR inline_any_operand.bar.Inline.after.mir
+fn bar() -> bool {
+ let f = foo;
+ f(1, -1)
+}
+
+#[inline(always)]
+fn foo(x: i32, y: i32) -> bool {
+ x == y
+}
diff --git a/src/test/mir-opt/inline/inline-async.rs b/src/test/mir-opt/inline/inline-async.rs
new file mode 100644
index 000000000..5c838159b
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-async.rs
@@ -0,0 +1,18 @@
+// Checks that inliner doesn't introduce cycles when optimizing generators.
+// The outcome of optimization is not verfied, just the absence of the cycle.
+// Regression test for #76181.
+//
+// edition:2018
+
+#![crate_type = "lib"]
+
+pub struct S;
+
+impl S {
+ pub async fn g(&mut self) {
+ self.h();
+ }
+ pub fn h(&mut self) {
+ let _ = self.g();
+ }
+}
diff --git a/src/test/mir-opt/inline/inline-closure-borrows-arg.rs b/src/test/mir-opt/inline/inline-closure-borrows-arg.rs
new file mode 100644
index 000000000..d76bc33f5
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-closure-borrows-arg.rs
@@ -0,0 +1,17 @@
+// compile-flags: -Z span_free_formats -Zunsound-mir-opts
+
+// Tests that MIR inliner can handle closure arguments,
+// even when (#45894)
+
+fn main() {
+ println!("{}", foo(0, &14));
+}
+
+// EMIT_MIR inline_closure_borrows_arg.foo.Inline.after.mir
+fn foo<T: Copy>(_t: T, q: &i32) -> i32 {
+ let x = |r: &i32, _s: &i32| {
+ let variable = &*r;
+ *variable
+ };
+ x(q, q)
+}
diff --git a/src/test/mir-opt/inline/inline-closure-captures.rs b/src/test/mir-opt/inline/inline-closure-captures.rs
new file mode 100644
index 000000000..52b6817e4
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-closure-captures.rs
@@ -0,0 +1,13 @@
+// compile-flags: -Z span_free_formats
+
+// Tests that MIR inliner can handle closure captures.
+
+fn main() {
+ println!("{:?}", foo(0, 14));
+}
+
+// EMIT_MIR inline_closure_captures.foo.Inline.after.mir
+fn foo<T: Copy>(t: T, q: i32) -> (i32, T) {
+ let x = |_q| (q, t);
+ x(q)
+}
diff --git a/src/test/mir-opt/inline/inline-closure.rs b/src/test/mir-opt/inline/inline-closure.rs
new file mode 100644
index 000000000..715fd0138
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-closure.rs
@@ -0,0 +1,13 @@
+// compile-flags: -Z span_free_formats
+
+// Tests that MIR inliner can handle closure arguments. (#45894)
+
+fn main() {
+ println!("{}", foo(0, 14));
+}
+
+// EMIT_MIR inline_closure.foo.Inline.after.mir
+fn foo<T: Copy>(_t: T, q: i32) -> i32 {
+ let x = |_t, _q| _t;
+ x(q, q)
+}
diff --git a/src/test/mir-opt/inline/inline-compatibility.rs b/src/test/mir-opt/inline/inline-compatibility.rs
new file mode 100644
index 000000000..30aff0a64
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-compatibility.rs
@@ -0,0 +1,55 @@
+// Checks that only functions with compatible attributes are inlined.
+//
+// only-x86_64
+
+#![crate_type = "lib"]
+#![feature(no_sanitize)]
+#![feature(target_feature_11)]
+#![feature(c_variadic)]
+
+// EMIT_MIR inline_compatibility.inlined_target_feature.Inline.diff
+#[target_feature(enable = "sse2")]
+pub unsafe fn inlined_target_feature() {
+ target_feature();
+}
+
+// EMIT_MIR inline_compatibility.not_inlined_target_feature.Inline.diff
+pub unsafe fn not_inlined_target_feature() {
+ target_feature();
+}
+
+// EMIT_MIR inline_compatibility.inlined_no_sanitize.Inline.diff
+#[no_sanitize(address)]
+pub unsafe fn inlined_no_sanitize() {
+ no_sanitize();
+}
+
+// EMIT_MIR inline_compatibility.not_inlined_no_sanitize.Inline.diff
+pub unsafe fn not_inlined_no_sanitize() {
+ no_sanitize();
+}
+
+#[inline]
+#[target_feature(enable = "sse2")]
+pub unsafe fn target_feature() {}
+
+#[inline]
+#[no_sanitize(address)]
+pub unsafe fn no_sanitize() {}
+
+// EMIT_MIR inline_compatibility.not_inlined_c_variadic.Inline.diff
+pub unsafe fn not_inlined_c_variadic() {
+ let s = sum(4u32, 4u32, 30u32, 200u32, 1000u32);
+}
+
+#[no_mangle]
+#[inline(always)]
+unsafe extern "C" fn sum(n: u32, mut vs: ...) -> u32 {
+ let mut s = 0;
+ let mut i = 0;
+ while i != n {
+ s += vs.arg::<u32>();
+ i += 1;
+ }
+ s
+}
diff --git a/src/test/mir-opt/inline/inline-cycle-generic.rs b/src/test/mir-opt/inline/inline-cycle-generic.rs
new file mode 100644
index 000000000..24b4f3793
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-cycle-generic.rs
@@ -0,0 +1,40 @@
+// Check that inliner handles various forms of recursion and doesn't fall into
+// an infinite inlining cycle. The particular outcome of inlining is not
+// crucial otherwise.
+//
+// Regression test for issue #78573.
+
+// EMIT_MIR inline_cycle_generic.main.Inline.diff
+fn main() {
+ <C as Call>::call();
+}
+
+pub trait Call {
+ fn call();
+}
+
+pub struct A;
+pub struct B<T>(T);
+pub struct C;
+
+impl Call for A {
+ #[inline]
+ fn call() {
+ <B<C> as Call>::call()
+ }
+}
+
+
+impl<T: Call> Call for B<T> {
+ #[inline]
+ fn call() {
+ <T as Call>::call()
+ }
+}
+
+impl Call for C {
+ #[inline]
+ fn call() {
+ <B<A> as Call>::call()
+ }
+}
diff --git a/src/test/mir-opt/inline/inline-cycle.rs b/src/test/mir-opt/inline/inline-cycle.rs
new file mode 100644
index 000000000..63ad57de1
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-cycle.rs
@@ -0,0 +1,60 @@
+// Check that inliner handles various forms of recursion and doesn't fall into
+// an infinite inlining cycle. The particular outcome of inlining is not
+// crucial otherwise.
+//
+// Regression test for issue #78573.
+
+fn main() {
+ one();
+ two();
+}
+
+// EMIT_MIR inline_cycle.one.Inline.diff
+fn one() {
+ <C as Call>::call();
+}
+
+pub trait Call {
+ fn call();
+}
+
+pub struct A<T>(T);
+pub struct B<T>(T);
+pub struct C;
+
+impl<T: Call> Call for A<T> {
+ #[inline]
+ fn call() {
+ <B<T> as Call>::call()
+ }
+}
+
+
+impl<T: Call> Call for B<T> {
+ #[inline]
+ fn call() {
+ <T as Call>::call()
+ }
+}
+
+impl Call for C {
+ #[inline]
+ fn call() {
+ A::<C>::call()
+ }
+}
+
+// EMIT_MIR inline_cycle.two.Inline.diff
+fn two() {
+ call(f);
+}
+
+#[inline]
+fn call<F: FnOnce()>(f: F) {
+ f();
+}
+
+#[inline]
+fn f() {
+ call(f);
+}
diff --git a/src/test/mir-opt/inline/inline-diverging.rs b/src/test/mir-opt/inline/inline-diverging.rs
new file mode 100644
index 000000000..ae6f814c2
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-diverging.rs
@@ -0,0 +1,40 @@
+// Tests inlining of diverging calls.
+//
+// ignore-wasm32-bare compiled with panic=abort by default
+#![crate_type = "lib"]
+
+// EMIT_MIR inline_diverging.f.Inline.diff
+pub fn f() {
+ sleep();
+}
+
+// EMIT_MIR inline_diverging.g.Inline.diff
+pub fn g(i: i32) -> u32 {
+ if i > 0 {
+ i as u32
+ } else {
+ panic();
+ }
+}
+
+// EMIT_MIR inline_diverging.h.Inline.diff
+pub fn h() {
+ call_twice(sleep);
+}
+
+#[inline(always)]
+pub fn call_twice<R, F: Fn() -> R>(f: F) -> (R, R) {
+ let a = f();
+ let b = f();
+ (a, b)
+}
+
+#[inline(always)]
+fn panic() -> ! {
+ panic!();
+}
+
+#[inline(always)]
+fn sleep() -> ! {
+ loop {}
+}
diff --git a/src/test/mir-opt/inline/inline-generator.rs b/src/test/mir-opt/inline/inline-generator.rs
new file mode 100644
index 000000000..d11b3e548
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-generator.rs
@@ -0,0 +1,16 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+#![feature(generators, generator_trait)]
+
+use std::ops::Generator;
+use std::pin::Pin;
+
+// EMIT_MIR inline_generator.main.Inline.diff
+fn main() {
+ let _r = Pin::new(&mut g()).resume(false);
+}
+
+#[inline(always)]
+pub fn g() -> impl Generator<bool> {
+ #[inline(always)]
+ |a| { yield if a { 7 } else { 13 } }
+}
diff --git a/src/test/mir-opt/inline/inline-instruction-set.rs b/src/test/mir-opt/inline/inline-instruction-set.rs
new file mode 100644
index 000000000..be36ff50c
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-instruction-set.rs
@@ -0,0 +1,54 @@
+// Checks that only functions with the compatible instruction_set attributes are inlined.
+//
+// compile-flags: --target thumbv4t-none-eabi
+// needs-llvm-components: arm
+
+#![crate_type = "lib"]
+#![feature(rustc_attrs)]
+#![feature(no_core, lang_items)]
+#![feature(isa_attribute)]
+#![no_core]
+
+#[rustc_builtin_macro]
+#[macro_export]
+macro_rules! asm {
+ ("assembly template",
+ $(operands,)*
+ $(options($(option),*))?
+ ) => {
+ /* compiler built-in */
+ };
+}
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+#[instruction_set(arm::a32)]
+#[inline]
+fn instruction_set_a32() {}
+
+#[instruction_set(arm::t32)]
+#[inline]
+fn instruction_set_t32() {}
+
+#[inline]
+fn instruction_set_default() {}
+
+// EMIT_MIR inline_instruction_set.t32.Inline.diff
+#[instruction_set(arm::t32)]
+pub fn t32() {
+ instruction_set_a32();
+ instruction_set_t32();
+ // The default instruction set is currently
+ // conservatively assumed to be incompatible.
+ instruction_set_default();
+}
+
+// EMIT_MIR inline_instruction_set.default.Inline.diff
+pub fn default() {
+ instruction_set_a32();
+ instruction_set_t32();
+ instruction_set_default();
+}
diff --git a/src/test/mir-opt/inline/inline-into-box-place.rs b/src/test/mir-opt/inline/inline-into-box-place.rs
new file mode 100644
index 000000000..049a97816
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-into-box-place.rs
@@ -0,0 +1,9 @@
+// ignore-endian-big
+// ignore-wasm32-bare compiled with panic=abort by default
+// compile-flags: -Z mir-opt-level=4
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+#![feature(box_syntax)]
+// EMIT_MIR inline_into_box_place.main.Inline.diff
+fn main() {
+ let _x: Box<Vec<u32>> = box Vec::new();
+}
diff --git a/src/test/mir-opt/inline/inline-options.rs b/src/test/mir-opt/inline/inline-options.rs
new file mode 100644
index 000000000..477f050b6
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-options.rs
@@ -0,0 +1,19 @@
+// Checks that inlining threshold can be controlled with
+// inline-mir-threshold and inline-hint-threshold options.
+//
+// compile-flags: -Zinline-mir-threshold=90
+// compile-flags: -Zinline-mir-hint-threshold=50
+
+// EMIT_MIR inline_options.main.Inline.after.mir
+fn main() {
+ not_inlined();
+ inlined::<u32>();
+}
+
+// Cost is approximately 3 * 25 + 5 = 80.
+#[inline]
+pub fn not_inlined() { g(); g(); g(); }
+pub fn inlined<T>() { g(); g(); g(); }
+
+#[inline(never)]
+fn g() {}
diff --git a/src/test/mir-opt/inline/inline-retag.rs b/src/test/mir-opt/inline/inline-retag.rs
new file mode 100644
index 000000000..c6950f269
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-retag.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Z span_free_formats -Z mir-emit-retag
+
+// Tests that MIR inliner fixes up `Retag`'s `fn_entry` flag
+
+fn main() {
+ println!("{}", bar());
+}
+
+// EMIT_MIR inline_retag.bar.Inline.after.mir
+fn bar() -> bool {
+ let f = foo;
+ f(&1, &-1)
+}
+
+#[inline(always)]
+fn foo(x: &i32, y: &i32) -> bool {
+ *x == *y
+}
diff --git a/src/test/mir-opt/inline/inline-shims.rs b/src/test/mir-opt/inline/inline-shims.rs
new file mode 100644
index 000000000..7c8618f71
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-shims.rs
@@ -0,0 +1,13 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+#![crate_type = "lib"]
+
+// EMIT_MIR inline_shims.clone.Inline.diff
+pub fn clone<A, B>(f: fn(A, B)) -> fn(A, B) {
+ f.clone()
+}
+
+// EMIT_MIR inline_shims.drop.Inline.diff
+pub fn drop<A, B>(a: *mut Vec<A>, b: *mut Option<B>) {
+ unsafe { std::ptr::drop_in_place(a) }
+ unsafe { std::ptr::drop_in_place(b) }
+}
diff --git a/src/test/mir-opt/inline/inline-specialization.rs b/src/test/mir-opt/inline/inline-specialization.rs
new file mode 100644
index 000000000..87275b4e5
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-specialization.rs
@@ -0,0 +1,15 @@
+#![feature(specialization)]
+
+// EMIT_MIR inline_specialization.main.Inline.diff
+fn main() {
+ let x = <Vec::<()> as Foo>::bar();
+}
+
+trait Foo {
+ fn bar() -> u32;
+}
+
+impl<T> Foo for Vec<T> {
+ #[inline(always)]
+ default fn bar() -> u32 { 123 }
+}
diff --git a/src/test/mir-opt/inline/inline-trait-method.rs b/src/test/mir-opt/inline/inline-trait-method.rs
new file mode 100644
index 000000000..74be53f55
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-trait-method.rs
@@ -0,0 +1,22 @@
+// compile-flags: -Z span_free_formats
+
+fn main() {
+ println!("{}", test(&()));
+}
+
+// EMIT_MIR inline_trait_method.test.Inline.after.mir
+fn test(x: &dyn X) -> u32 {
+ x.y()
+}
+
+trait X {
+ fn y(&self) -> u32 {
+ 1
+ }
+}
+
+impl X for () {
+ fn y(&self) -> u32 {
+ 2
+ }
+}
diff --git a/src/test/mir-opt/inline/inline-trait-method_2.rs b/src/test/mir-opt/inline/inline-trait-method_2.rs
new file mode 100644
index 000000000..378e71a25
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-trait-method_2.rs
@@ -0,0 +1,27 @@
+// compile-flags: -Z span_free_formats -Z mir-opt-level=4
+
+// EMIT_MIR inline_trait_method_2.test2.Inline.after.mir
+fn test2(x: &dyn X) -> bool {
+ test(x)
+}
+
+#[inline]
+fn test(x: &dyn X) -> bool {
+ x.y()
+}
+
+trait X {
+ fn y(&self) -> bool {
+ false
+ }
+}
+
+impl X for () {
+ fn y(&self) -> bool {
+ true
+ }
+}
+
+fn main() {
+ println!("Should be true: {}", test2(&()));
+}
diff --git a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
new file mode 100644
index 000000000..630225258
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
@@ -0,0 +1,44 @@
+// MIR for `bar` after Inline
+
+fn bar() -> bool {
+ let mut _0: bool; // return place in scope 0 at $DIR/inline-any-operand.rs:+0:13: +0:17
+ let _1: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline-any-operand.rs:+1:9: +1:10
+ let mut _2: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline-any-operand.rs:+2:5: +2:6
+ let mut _3: i32; // in scope 0 at $DIR/inline-any-operand.rs:+2:5: +2:13
+ let mut _4: i32; // in scope 0 at $DIR/inline-any-operand.rs:+2:5: +2:13
+ scope 1 {
+ debug f => _1; // in scope 1 at $DIR/inline-any-operand.rs:+1:9: +1:10
+ scope 2 (inlined foo) { // at $DIR/inline-any-operand.rs:12:5: 12:13
+ debug x => _3; // in scope 2 at $DIR/inline-any-operand.rs:+6:8: +6:9
+ debug y => _4; // in scope 2 at $DIR/inline-any-operand.rs:+6:16: +6:17
+ let mut _5: i32; // in scope 2 at $DIR/inline-any-operand.rs:+7:5: +7:6
+ let mut _6: i32; // in scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-any-operand.rs:+1:9: +1:10
+ _1 = foo; // scope 0 at $DIR/inline-any-operand.rs:+1:13: +1:16
+ // mir::Constant
+ // + span: $DIR/inline-any-operand.rs:11:13: 11:16
+ // + literal: Const { ty: fn(i32, i32) -> bool {foo}, val: Value(<ZST>) }
+ StorageLive(_2); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:6
+ _2 = _1; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:6
+ StorageLive(_3); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
+ _3 = const 1_i32; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
+ StorageLive(_4); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
+ _4 = const -1_i32; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
+ StorageLive(_5); // scope 2 at $DIR/inline-any-operand.rs:+7:5: +7:6
+ _5 = _3; // scope 2 at $DIR/inline-any-operand.rs:+7:5: +7:6
+ StorageLive(_6); // scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11
+ _6 = _4; // scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11
+ _0 = Eq(move _5, move _6); // scope 2 at $DIR/inline-any-operand.rs:+7:5: +7:11
+ StorageDead(_6); // scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11
+ StorageDead(_5); // scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11
+ StorageDead(_4); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
+ StorageDead(_3); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
+ StorageDead(_2); // scope 1 at $DIR/inline-any-operand.rs:+2:12: +2:13
+ StorageDead(_1); // scope 0 at $DIR/inline-any-operand.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/inline-any-operand.rs:+3:2: +3:2
+ }
+}
diff --git a/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir
new file mode 100644
index 000000000..1fadd2464
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir
@@ -0,0 +1,49 @@
+// MIR for `foo` after Inline
+
+fn foo(_1: T, _2: i32) -> i32 {
+ debug _t => _1; // in scope 0 at $DIR/inline-closure.rs:+0:17: +0:19
+ debug q => _2; // in scope 0 at $DIR/inline-closure.rs:+0:24: +0:25
+ let mut _0: i32; // return place in scope 0 at $DIR/inline-closure.rs:+0:35: +0:38
+ let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure.rs:+1:9: +1:10
+ let mut _4: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:6
+ let mut _5: (i32, i32); // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:12
+ let mut _6: i32; // in scope 0 at $DIR/inline-closure.rs:+2:7: +2:8
+ let mut _7: i32; // in scope 0 at $DIR/inline-closure.rs:+2:10: +2:11
+ let mut _8: i32; // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:12
+ let mut _9: i32; // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:12
+ scope 1 {
+ debug x => _3; // in scope 1 at $DIR/inline-closure.rs:+1:9: +1:10
+ scope 2 (inlined foo::<T>::{closure#0}) { // at $DIR/inline-closure.rs:12:5: 12:12
+ debug _t => _8; // in scope 2 at $DIR/inline-closure.rs:+1:14: +1:16
+ debug _q => _9; // in scope 2 at $DIR/inline-closure.rs:+1:18: +1:20
+ }
+ }
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/inline-closure.rs:+1:9: +1:10
+ Deinit(_3); // scope 0 at $DIR/inline-closure.rs:+1:13: +1:24
+ StorageLive(_4); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:6
+ _4 = &_3; // scope 1 at $DIR/inline-closure.rs:+2:5: +2:6
+ StorageLive(_5); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
+ StorageLive(_6); // scope 1 at $DIR/inline-closure.rs:+2:7: +2:8
+ _6 = _2; // scope 1 at $DIR/inline-closure.rs:+2:7: +2:8
+ StorageLive(_7); // scope 1 at $DIR/inline-closure.rs:+2:10: +2:11
+ _7 = _2; // scope 1 at $DIR/inline-closure.rs:+2:10: +2:11
+ Deinit(_5); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
+ (_5.0: i32) = move _6; // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
+ (_5.1: i32) = move _7; // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
+ StorageLive(_8); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
+ _8 = move (_5.0: i32); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
+ StorageLive(_9); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
+ _9 = move (_5.1: i32); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
+ _0 = _8; // scope 2 at $DIR/inline-closure.rs:+1:22: +1:24
+ StorageDead(_9); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
+ StorageDead(_8); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
+ StorageDead(_7); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12
+ StorageDead(_6); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12
+ StorageDead(_5); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12
+ StorageDead(_4); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12
+ StorageDead(_3); // scope 0 at $DIR/inline-closure.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/inline-closure.rs:+3:2: +3:2
+ }
+}
diff --git a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir
new file mode 100644
index 000000000..4069e9f89
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir
@@ -0,0 +1,56 @@
+// MIR for `foo` after Inline
+
+fn foo(_1: T, _2: &i32) -> i32 {
+ debug _t => _1; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+0:17: +0:19
+ debug q => _2; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+0:24: +0:25
+ let mut _0: i32; // return place in scope 0 at $DIR/inline-closure-borrows-arg.rs:+0:36: +0:39
+ let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+1:9: +1:10
+ let mut _4: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:6
+ let mut _5: (&i32, &i32); // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ let mut _6: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:7: +5:8
+ let mut _7: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:10: +5:11
+ let mut _8: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ let mut _9: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ scope 1 {
+ debug x => _3; // in scope 1 at $DIR/inline-closure-borrows-arg.rs:+1:9: +1:10
+ scope 2 (inlined foo::<T>::{closure#0}) { // at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12
+ debug r => _8; // in scope 2 at $DIR/inline-closure-borrows-arg.rs:+1:14: +1:15
+ debug _s => _9; // in scope 2 at $DIR/inline-closure-borrows-arg.rs:+1:23: +1:25
+ let _10: &i32; // in scope 2 at $DIR/inline-closure-borrows-arg.rs:+2:13: +2:21
+ scope 3 {
+ debug variable => _10; // in scope 3 at $DIR/inline-closure-borrows-arg.rs:+2:13: +2:21
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:+1:9: +1:10
+ Deinit(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:+1:13: +4:6
+ StorageLive(_4); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:6
+ _4 = &_3; // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:6
+ StorageLive(_5); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ StorageLive(_6); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:7: +5:8
+ _6 = &(*_2); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:7: +5:8
+ StorageLive(_7); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:10: +5:11
+ _7 = &(*_2); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:10: +5:11
+ Deinit(_5); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ (_5.0: &i32) = move _6; // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ (_5.1: &i32) = move _7; // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ StorageLive(_8); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ _8 = move (_5.0: &i32); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ StorageLive(_9); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ _9 = move (_5.1: &i32); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ StorageLive(_10); // scope 2 at $DIR/inline-closure-borrows-arg.rs:+2:13: +2:21
+ _10 = _8; // scope 2 at $DIR/inline-closure-borrows-arg.rs:+2:24: +2:27
+ _0 = (*_10); // scope 3 at $DIR/inline-closure-borrows-arg.rs:+3:9: +3:18
+ StorageDead(_10); // scope 2 at $DIR/inline-closure-borrows-arg.rs:+4:5: +4:6
+ StorageDead(_9); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ StorageDead(_8); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ StorageDead(_7); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12
+ StorageDead(_6); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12
+ StorageDead(_5); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12
+ StorageDead(_4); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12
+ StorageDead(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/inline-closure-borrows-arg.rs:+6:2: +6:2
+ }
+}
diff --git a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
new file mode 100644
index 000000000..d60b06460
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
@@ -0,0 +1,69 @@
+// MIR for `foo` after Inline
+
+fn foo(_1: T, _2: i32) -> (i32, T) {
+ debug t => _1; // in scope 0 at $DIR/inline-closure-captures.rs:+0:17: +0:18
+ debug q => _2; // in scope 0 at $DIR/inline-closure-captures.rs:+0:23: +0:24
+ let mut _0: (i32, T); // return place in scope 0 at $DIR/inline-closure-captures.rs:+0:34: +0:42
+ let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-captures.rs:+1:9: +1:10
+ let mut _4: &i32; // in scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
+ let mut _5: &T; // in scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
+ let mut _6: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-captures.rs:+2:5: +2:6
+ let mut _7: (i32,); // in scope 0 at $DIR/inline-closure-captures.rs:+2:5: +2:9
+ let mut _8: i32; // in scope 0 at $DIR/inline-closure-captures.rs:+2:7: +2:8
+ let mut _9: i32; // in scope 0 at $DIR/inline-closure-captures.rs:+2:5: +2:9
+ scope 1 {
+ debug x => _3; // in scope 1 at $DIR/inline-closure-captures.rs:+1:9: +1:10
+ scope 2 (inlined foo::<T>::{closure#0}) { // at $DIR/inline-closure-captures.rs:12:5: 12:9
+ debug _q => _9; // in scope 2 at $DIR/inline-closure-captures.rs:+1:14: +1:16
+ debug q => (*((*_6).0: &i32)); // in scope 2 at $DIR/inline-closure-captures.rs:+0:23: +0:24
+ debug t => (*((*_6).1: &T)); // in scope 2 at $DIR/inline-closure-captures.rs:+0:17: +0:18
+ let mut _10: i32; // in scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
+ let mut _11: T; // in scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
+ let mut _12: &i32; // in scope 2 at $DIR/inline-closure-captures.rs:+1:13: +1:17
+ let mut _13: &T; // in scope 2 at $DIR/inline-closure-captures.rs:+1:13: +1:17
+ }
+ }
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/inline-closure-captures.rs:+1:9: +1:10
+ StorageLive(_4); // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
+ _4 = &_2; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
+ StorageLive(_5); // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
+ _5 = &_1; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
+ Deinit(_3); // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
+ (_3.0: &i32) = move _4; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
+ (_3.1: &T) = move _5; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
+ StorageDead(_5); // scope 0 at $DIR/inline-closure-captures.rs:+1:16: +1:17
+ StorageDead(_4); // scope 0 at $DIR/inline-closure-captures.rs:+1:16: +1:17
+ StorageLive(_6); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:6
+ _6 = &_3; // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:6
+ StorageLive(_7); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
+ StorageLive(_8); // scope 1 at $DIR/inline-closure-captures.rs:+2:7: +2:8
+ _8 = _2; // scope 1 at $DIR/inline-closure-captures.rs:+2:7: +2:8
+ Deinit(_7); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
+ (_7.0: i32) = move _8; // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
+ StorageLive(_9); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
+ _9 = move (_7.0: i32); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
+ StorageLive(_10); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
+ StorageLive(_12); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
+ _12 = deref_copy ((*_6).0: &i32); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
+ _10 = (*_12); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
+ StorageDead(_12); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
+ StorageLive(_11); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
+ StorageLive(_13); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
+ _13 = deref_copy ((*_6).1: &T); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
+ _11 = (*_13); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
+ StorageDead(_13); // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24
+ Deinit(_0); // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24
+ (_0.0: i32) = move _10; // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24
+ (_0.1: T) = move _11; // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24
+ StorageDead(_11); // scope 2 at $DIR/inline-closure-captures.rs:+1:23: +1:24
+ StorageDead(_10); // scope 2 at $DIR/inline-closure-captures.rs:+1:23: +1:24
+ StorageDead(_9); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
+ StorageDead(_8); // scope 1 at $DIR/inline-closure-captures.rs:+2:8: +2:9
+ StorageDead(_7); // scope 1 at $DIR/inline-closure-captures.rs:+2:8: +2:9
+ StorageDead(_6); // scope 1 at $DIR/inline-closure-captures.rs:+2:8: +2:9
+ StorageDead(_3); // scope 0 at $DIR/inline-closure-captures.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/inline-closure-captures.rs:+3:2: +3:2
+ }
+}
diff --git a/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff
new file mode 100644
index 000000000..cf800ba11
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff
@@ -0,0 +1,24 @@
+- // MIR for `inlined_no_sanitize` before Inline
++ // MIR for `inlined_no_sanitize` after Inline
+
+ fn inlined_no_sanitize() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:37: +0:37
+ let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18
++ scope 1 (inlined no_sanitize) { // at $DIR/inline-compatibility.rs:24:5: 24:18
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18
+- _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18
+- // mir::Constant
+- // + span: $DIR/inline-compatibility.rs:24:5: 24:16
+- // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value(<ZST>) }
+- }
+-
+- bb1: {
+ StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:18: +1:19
+ _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:37: +2:2
+ return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff
new file mode 100644
index 000000000..a45f95902
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff
@@ -0,0 +1,24 @@
+- // MIR for `inlined_target_feature` before Inline
++ // MIR for `inlined_target_feature` after Inline
+
+ fn inlined_target_feature() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:40: +0:40
+ let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
++ scope 1 (inlined target_feature) { // at $DIR/inline-compatibility.rs:13:5: 13:21
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
+- _1 = target_feature() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
+- // mir::Constant
+- // + span: $DIR/inline-compatibility.rs:13:5: 13:19
+- // + literal: Const { ty: unsafe fn() {target_feature}, val: Value(<ZST>) }
+- }
+-
+- bb1: {
+ StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:21: +1:22
+ _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:40: +2:2
+ return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff
new file mode 100644
index 000000000..49aea431e
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff
@@ -0,0 +1,25 @@
+- // MIR for `not_inlined_c_variadic` before Inline
++ // MIR for `not_inlined_c_variadic` after Inline
+
+ fn not_inlined_c_variadic() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:40: +0:40
+ let _1: u32; // in scope 0 at $DIR/inline-compatibility.rs:+1:9: +1:10
+ scope 1 {
+ debug s => _1; // in scope 1 at $DIR/inline-compatibility.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:9: +1:10
+ _1 = sum(const 4_u32, const 4_u32, const 30_u32, const 200_u32, const 1000_u32) -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:13: +1:52
+ // mir::Constant
+ // + span: $DIR/inline-compatibility.rs:42:13: 42:16
+ // + literal: Const { ty: unsafe extern "C" fn(u32, ...) -> u32 {sum}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:40: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff
new file mode 100644
index 000000000..94ce574a9
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff
@@ -0,0 +1,22 @@
+- // MIR for `not_inlined_no_sanitize` before Inline
++ // MIR for `not_inlined_no_sanitize` after Inline
+
+ fn not_inlined_no_sanitize() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:41: +0:41
+ let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18
+ _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18
+ // mir::Constant
+ // + span: $DIR/inline-compatibility.rs:29:5: 29:16
+ // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:18: +1:19
+ _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:41: +2:2
+ return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff
new file mode 100644
index 000000000..8506e257b
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff
@@ -0,0 +1,22 @@
+- // MIR for `not_inlined_target_feature` before Inline
++ // MIR for `not_inlined_target_feature` after Inline
+
+ fn not_inlined_target_feature() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:44: +0:44
+ let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
+ _1 = target_feature() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
+ // mir::Constant
+ // + span: $DIR/inline-compatibility.rs:18:5: 18:19
+ // + literal: Const { ty: unsafe fn() {target_feature}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:21: +1:22
+ _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:44: +2:2
+ return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_cycle.one.Inline.diff b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff
new file mode 100644
index 000000000..b1c476362
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff
@@ -0,0 +1,30 @@
+- // MIR for `one` before Inline
++ // MIR for `one` after Inline
+
+ fn one() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-cycle.rs:+0:10: +0:10
+ let _1: (); // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24
++ scope 1 (inlined <C as Call>::call) { // at $DIR/inline-cycle.rs:14:5: 14:24
++ scope 2 (inlined <A<C> as Call>::call) { // at $DIR/inline-cycle.rs:43:9: 43:23
++ scope 3 (inlined <B<C> as Call>::call) { // at $DIR/inline-cycle.rs:28:9: 28:31
++ }
++ }
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24
+- _1 = <C as Call>::call() -> bb1; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24
++ _1 = <C as Call>::call() -> bb1; // scope 3 at $DIR/inline-cycle.rs:+23:9: +23:28
+ // mir::Constant
+- // + span: $DIR/inline-cycle.rs:14:5: 14:22
++ // + span: $DIR/inline-cycle.rs:36:9: 36:26
+ // + literal: Const { ty: fn() {<C as Call>::call}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:+1:24: +1:25
+ _0 = const (); // scope 0 at $DIR/inline-cycle.rs:+0:10: +2:2
+ return; // scope 0 at $DIR/inline-cycle.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_cycle.two.Inline.diff b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff
new file mode 100644
index 000000000..dc890a365
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff
@@ -0,0 +1,55 @@
+- // MIR for `two` before Inline
++ // MIR for `two` after Inline
+
+ fn two() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-cycle.rs:+0:10: +0:10
+ let _1: (); // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
++ let mut _2: fn() {f}; // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
++ scope 1 (inlined call::<fn() {f}>) { // at $DIR/inline-cycle.rs:49:5: 49:12
++ debug f => _2; // in scope 1 at $DIR/inline-cycle.rs:+5:22: +5:23
++ let _3: (); // in scope 1 at $DIR/inline-cycle.rs:+6:5: +6:8
++ let mut _4: fn() {f}; // in scope 1 at $DIR/inline-cycle.rs:+6:5: +6:6
++ let mut _5: (); // in scope 1 at $DIR/inline-cycle.rs:+6:5: +6:8
++ scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) { // at $DIR/inline-cycle.rs:54:5: 54:8
++ scope 3 (inlined f) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL
++ let _6: (); // in scope 3 at $DIR/inline-cycle.rs:+11:5: +11:12
++ }
++ }
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
+- _1 = call::<fn() {f}>(f) -> bb1; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
++ StorageLive(_2); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
++ _2 = f; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
+ // mir::Constant
+- // + span: $DIR/inline-cycle.rs:49:5: 49:9
++ // + span: $DIR/inline-cycle.rs:49:10: 49:11
++ // + literal: Const { ty: fn() {f}, val: Value(<ZST>) }
++ StorageLive(_3); // scope 1 at $DIR/inline-cycle.rs:+6:5: +6:8
++ StorageLive(_4); // scope 1 at $DIR/inline-cycle.rs:+6:5: +6:6
++ _4 = move _2; // scope 1 at $DIR/inline-cycle.rs:+6:5: +6:6
++ StorageLive(_5); // scope 1 at $DIR/inline-cycle.rs:+6:5: +6:8
++ StorageLive(_6); // scope 3 at $DIR/inline-cycle.rs:+11:5: +11:12
++ _6 = call::<fn() {f}>(f) -> bb1; // scope 3 at $DIR/inline-cycle.rs:+11:5: +11:12
++ // mir::Constant
++ // + span: $DIR/inline-cycle.rs:59:5: 59:9
+ // + literal: Const { ty: fn(fn() {f}) {call::<fn() {f}>}, val: Value(<ZST>) }
+ // mir::Constant
+- // + span: $DIR/inline-cycle.rs:49:10: 49:11
++ // + span: $DIR/inline-cycle.rs:59:10: 59:11
+ // + literal: Const { ty: fn() {f}, val: Value(<ZST>) }
+ }
+
+ bb1: {
++ StorageDead(_6); // scope 3 at $DIR/inline-cycle.rs:+11:12: +11:13
++ StorageDead(_5); // scope 1 at $DIR/inline-cycle.rs:+6:7: +6:8
++ StorageDead(_4); // scope 1 at $DIR/inline-cycle.rs:+6:7: +6:8
++ StorageDead(_3); // scope 1 at $DIR/inline-cycle.rs:+6:8: +6:9
++ StorageDead(_2); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
+ StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:+1:12: +1:13
+ _0 = const (); // scope 0 at $DIR/inline-cycle.rs:+0:10: +2:2
+ return; // scope 0 at $DIR/inline-cycle.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff b/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff
new file mode 100644
index 000000000..082f57e59
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff
@@ -0,0 +1,32 @@
+- // MIR for `main` before Inline
++ // MIR for `main` after Inline
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-cycle-generic.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24
++ scope 1 (inlined <C as Call>::call) { // at $DIR/inline-cycle-generic.rs:9:5: 9:24
++ scope 2 (inlined <B<A> as Call>::call) { // at $DIR/inline-cycle-generic.rs:38:9: 38:31
++ scope 3 (inlined <A as Call>::call) { // at $DIR/inline-cycle-generic.rs:31:9: 31:28
++ scope 4 (inlined <B<C> as Call>::call) { // at $DIR/inline-cycle-generic.rs:23:9: 23:31
++ }
++ }
++ }
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24
+- _1 = <C as Call>::call() -> bb1; // scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24
++ _1 = <C as Call>::call() -> bb1; // scope 4 at $DIR/inline-cycle-generic.rs:+23:9: +23:28
+ // mir::Constant
+- // + span: $DIR/inline-cycle-generic.rs:9:5: 9:22
++ // + span: $DIR/inline-cycle-generic.rs:31:9: 31:26
+ // + literal: Const { ty: fn() {<C as Call>::call}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 0 at $DIR/inline-cycle-generic.rs:+1:24: +1:25
+ _0 = const (); // scope 0 at $DIR/inline-cycle-generic.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/inline-cycle-generic.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff
new file mode 100644
index 000000000..6b24b3e16
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff
@@ -0,0 +1,24 @@
+- // MIR for `f` before Inline
++ // MIR for `f` after Inline
+
+ fn f() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:+0:12: +0:12
+ let mut _1: !; // in scope 0 at $DIR/inline-diverging.rs:+0:12: +2:2
+ let _2: !; // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12
++ scope 1 (inlined sleep) { // at $DIR/inline-diverging.rs:8:5: 8:12
++ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12
+- _2 = sleep(); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12
+- // mir::Constant
+- // + span: $DIR/inline-diverging.rs:8:5: 8:10
+- // + literal: Const { ty: fn() -> ! {sleep}, val: Value(<ZST>) }
++ goto -> bb1; // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12
++ }
++
++ bb1: {
++ goto -> bb1; // scope 1 at $DIR/inline-diverging.rs:+32:5: +32:12
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff
new file mode 100644
index 000000000..a25f1454f
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff
@@ -0,0 +1,49 @@
+- // MIR for `g` before Inline
++ // MIR for `g` after Inline
+
+ fn g(_1: i32) -> u32 {
+ debug i => _1; // in scope 0 at $DIR/inline-diverging.rs:+0:10: +0:11
+ let mut _0: u32; // return place in scope 0 at $DIR/inline-diverging.rs:+0:21: +0:24
+ let mut _2: bool; // in scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13
+ let mut _3: i32; // in scope 0 at $DIR/inline-diverging.rs:+1:8: +1:9
+ let mut _4: i32; // in scope 0 at $DIR/inline-diverging.rs:+2:9: +2:10
+ let mut _5: !; // in scope 0 at $DIR/inline-diverging.rs:+3:12: +5:6
+ let _6: !; // in scope 0 at $DIR/inline-diverging.rs:+4:9: +4:16
++ scope 1 (inlined panic) { // at $DIR/inline-diverging.rs:16:9: 16:16
++ let mut _7: !; // in scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
++ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13
+ StorageLive(_3); // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:9
+ _2 = Gt(move _3, const 0_i32); // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13
+ StorageDead(_3); // scope 0 at $DIR/inline-diverging.rs:+1:12: +1:13
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13
+ }
+
+ bb1: {
+ StorageLive(_4); // scope 0 at $DIR/inline-diverging.rs:+2:9: +2:10
+ _4 = _1; // scope 0 at $DIR/inline-diverging.rs:+2:9: +2:10
+ _0 = move _4 as u32 (Misc); // scope 0 at $DIR/inline-diverging.rs:+2:9: +2:17
+ StorageDead(_4); // scope 0 at $DIR/inline-diverging.rs:+2:16: +2:17
+ StorageDead(_2); // scope 0 at $DIR/inline-diverging.rs:+5:5: +5:6
+ return; // scope 0 at $DIR/inline-diverging.rs:+6:2: +6:2
+ }
+
+ bb2: {
+ StorageLive(_6); // scope 0 at $DIR/inline-diverging.rs:+4:9: +4:16
+- _6 = panic(); // scope 0 at $DIR/inline-diverging.rs:+4:9: +4:16
++ StorageLive(_7); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
++ _7 = begin_panic::<&str>(const "explicit panic"); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
+ // mir::Constant
+- // + span: $DIR/inline-diverging.rs:16:9: 16:14
+- // + literal: Const { ty: fn() -> ! {panic}, val: Value(<ZST>) }
++ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
++ // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(<ZST>) }
++ // mir::Constant
++ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
++ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff
new file mode 100644
index 000000000..8759f3d02
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff
@@ -0,0 +1,56 @@
+- // MIR for `h` before Inline
++ // MIR for `h` after Inline
+
+ fn h() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:+0:12: +0:12
+ let _1: (!, !); // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
++ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
++ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) { // at $DIR/inline-diverging.rs:22:5: 22:22
++ debug f => _2; // in scope 1 at $DIR/inline-diverging.rs:+5:36: +5:37
++ let _3: !; // in scope 1 at $DIR/inline-diverging.rs:+6:9: +6:10
++ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:+6:13: +6:14
++ let mut _5: (); // in scope 1 at $DIR/inline-diverging.rs:+6:13: +6:16
++ let mut _7: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:+7:13: +7:14
++ let mut _8: (); // in scope 1 at $DIR/inline-diverging.rs:+7:13: +7:16
++ let mut _9: !; // in scope 1 at $DIR/inline-diverging.rs:+8:6: +8:7
++ let mut _10: !; // in scope 1 at $DIR/inline-diverging.rs:+8:9: +8:10
++ scope 2 {
++ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:+6:9: +6:10
++ let _6: !; // in scope 2 at $DIR/inline-diverging.rs:+7:9: +7:10
++ scope 3 {
++ debug b => _6; // in scope 3 at $DIR/inline-diverging.rs:+7:9: +7:10
++ }
++ scope 6 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:28:13: 28:16
++ scope 7 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL
++ }
++ }
++ }
++ scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:27:13: 27:16
++ scope 5 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL
++ }
++ }
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
+- _1 = call_twice::<!, fn() -> ! {sleep}>(sleep); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
++ StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
++ _2 = sleep; // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
+ // mir::Constant
+- // + span: $DIR/inline-diverging.rs:22:5: 22:15
+- // + literal: Const { ty: fn(fn() -> ! {sleep}) -> (!, !) {call_twice::<!, fn() -> ! {sleep}>}, val: Value(<ZST>) }
+- // mir::Constant
+ // + span: $DIR/inline-diverging.rs:22:16: 22:21
+ // + literal: Const { ty: fn() -> ! {sleep}, val: Value(<ZST>) }
++ StorageLive(_3); // scope 1 at $DIR/inline-diverging.rs:+6:9: +6:10
++ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:+6:13: +6:14
++ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:+6:13: +6:14
++ StorageLive(_5); // scope 1 at $DIR/inline-diverging.rs:+6:13: +6:16
++ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:+18:5: +18:12
++ }
++
++ bb1: {
++ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:+18:5: +18:12
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_generator.main.Inline.diff b/src/test/mir-opt/inline/inline_generator.main.Inline.diff
new file mode 100644
index 000000000..c7c2759cc
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_generator.main.Inline.diff
@@ -0,0 +1,156 @@
+- // MIR for `main` before Inline
++ // MIR for `main` after Inline
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-generator.rs:+0:11: +0:11
+ let _1: std::ops::GeneratorState<i32, bool>; // in scope 0 at $DIR/inline-generator.rs:+1:9: +1:11
+ let mut _2: std::pin::Pin<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>; // in scope 0 at $DIR/inline-generator.rs:+1:14: +1:32
+ let mut _3: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline-generator.rs:+1:23: +1:31
+ let mut _4: [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline-generator.rs:+1:28: +1:31
++ let mut _7: bool; // in scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
+ scope 1 {
+ debug _r => _1; // in scope 1 at $DIR/inline-generator.rs:+1:9: +1:11
+ }
++ scope 2 (inlined g) { // at $DIR/inline-generator.rs:9:28: 9:31
++ }
++ scope 3 (inlined Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new) { // at $DIR/inline-generator.rs:9:14: 9:32
++ debug pointer => _3; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL
++ let mut _5: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL
++ scope 4 {
++ scope 5 (inlined Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new_unchecked) { // at $SRC_DIR/core/src/pin.rs:LL:COL
++ debug pointer => _5; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
++ let mut _6: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
++ }
++ }
++ }
++ scope 6 (inlined g::{closure#0}) { // at $DIR/inline-generator.rs:9:14: 9:46
++ debug a => _11; // in scope 6 at $DIR/inline-generator.rs:+7:6: +7:7
++ let mut _8: i32; // in scope 6 at $DIR/inline-generator.rs:+7:17: +7:39
++ let mut _9: bool; // in scope 6 at $DIR/inline-generator.rs:+7:20: +7:21
++ let mut _10: bool; // in scope 6 at $DIR/inline-generator.rs:+7:9: +7:9
++ let _11: bool; // in scope 6 at $DIR/inline-generator.rs:+7:6: +7:7
++ let mut _12: u32; // in scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ let mut _13: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ let mut _14: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ let mut _15: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-generator.rs:+1:9: +1:11
+ StorageLive(_2); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:32
+ StorageLive(_3); // scope 0 at $DIR/inline-generator.rs:+1:23: +1:31
+ StorageLive(_4); // scope 0 at $DIR/inline-generator.rs:+1:28: +1:31
+- _4 = g() -> bb1; // scope 0 at $DIR/inline-generator.rs:+1:28: +1:31
+- // mir::Constant
+- // + span: $DIR/inline-generator.rs:9:28: 9:29
+- // + literal: Const { ty: fn() -> impl Generator<bool> {g}, val: Value(<ZST>) }
+- }
+-
+- bb1: {
++ Deinit(_4); // scope 2 at $DIR/inline-generator.rs:+7:5: +7:41
++ discriminant(_4) = 0; // scope 2 at $DIR/inline-generator.rs:+7:5: +7:41
+ _3 = &mut _4; // scope 0 at $DIR/inline-generator.rs:+1:23: +1:31
+- _2 = Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:32
+- // mir::Constant
+- // + span: $DIR/inline-generator.rs:9:14: 9:22
+- // + user_ty: UserType(0)
+- // + literal: Const { ty: fn(&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]) -> Pin<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]> {Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new}, val: Value(<ZST>) }
+- }
+-
+- bb2: {
++ StorageLive(_5); // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL
++ _5 = move _3; // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL
++ StorageLive(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
++ _6 = move _5; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
++ Deinit(_2); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
++ (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]) = move _6; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
++ StorageDead(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
++ StorageDead(_5); // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL
+ StorageDead(_3); // scope 0 at $DIR/inline-generator.rs:+1:31: +1:32
+- _1 = <[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
+- // mir::Constant
+- // + span: $DIR/inline-generator.rs:9:33: 9:39
+- // + literal: Const { ty: for<'r> fn(Pin<&'r mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>, bool) -> GeneratorState<<[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator<bool>>::Yield, <[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator<bool>>::Return> {<[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator<bool>>::resume}, val: Value(<ZST>) }
++ StorageLive(_7); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
++ _7 = const false; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
++ StorageLive(_10); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
++ StorageLive(_11); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
++ StorageLive(_12); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
++ StorageLive(_13); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ _13 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ _12 = discriminant((*_13)); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ StorageDead(_13); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ switchInt(move _12) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
+ }
+
+- bb3: {
++ bb1: {
++ StorageDead(_12); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
++ StorageDead(_11); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
++ StorageDead(_10); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
++ StorageDead(_7); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
+ StorageDead(_2); // scope 0 at $DIR/inline-generator.rs:+1:45: +1:46
+ StorageDead(_4); // scope 0 at $DIR/inline-generator.rs:+1:46: +1:47
+ _0 = const (); // scope 0 at $DIR/inline-generator.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline-generator.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/inline-generator.rs:+2:2: +2:2
+ }
+
+- bb4 (cleanup): {
++ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/inline-generator.rs:+0:1: +2:2
++ }
++
++ bb3: {
++ _11 = move _7; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:+7:17: +7:39
++ StorageLive(_9); // scope 6 at $DIR/inline-generator.rs:+7:20: +7:21
++ _9 = _11; // scope 6 at $DIR/inline-generator.rs:+7:20: +7:21
++ switchInt(move _9) -> [false: bb5, otherwise: bb4]; // scope 6 at $DIR/inline-generator.rs:+7:20: +7:21
++ }
++
++ bb4: {
++ _8 = const 7_i32; // scope 6 at $DIR/inline-generator.rs:+7:24: +7:25
++ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:+7:17: +7:39
++ }
++
++ bb5: {
++ _8 = const 13_i32; // scope 6 at $DIR/inline-generator.rs:+7:35: +7:37
++ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:+7:17: +7:39
++ }
++
++ bb6: {
++ StorageDead(_9); // scope 6 at $DIR/inline-generator.rs:+7:38: +7:39
++ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
++ ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
++ discriminant(_1) = 0; // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
++ StorageLive(_14); // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
++ _14 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
++ discriminant((*_14)) = 3; // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
++ StorageDead(_14); // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
++ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:+7:11: +7:39
++ }
++
++ bb7: {
++ StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ _10 = move _7; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ StorageDead(_8); // scope 6 at $DIR/inline-generator.rs:+7:38: +7:39
++ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
++ ((_1 as Complete).0: bool) = move _10; // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
++ discriminant(_1) = 1; // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
++ StorageLive(_15); // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
++ _15 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
++ discriminant((*_15)) = 1; // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
++ StorageDead(_15); // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
++ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:+7:8: +7:8
++ }
++
++ bb8: {
++ assert(const false, "generator resumed after completion") -> [success: bb8, unwind: bb2]; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ }
++
++ bb9: {
++ unreachable; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff b/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff
new file mode 100644
index 000000000..076509df3
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff
@@ -0,0 +1,44 @@
+- // MIR for `default` before Inline
++ // MIR for `default` after Inline
+
+ fn default() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-instruction-set.rs:+0:18: +0:18
+ let _1: (); // in scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26
+ let _2: (); // in scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26
+ let _3: (); // in scope 0 at $DIR/inline-instruction-set.rs:+3:5: +3:30
++ scope 1 (inlined instruction_set_default) { // at $DIR/inline-instruction-set.rs:53:5: 53:30
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26
+ _1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26
+ // mir::Constant
+ // + span: $DIR/inline-instruction-set.rs:51:5: 51:24
+ // + literal: Const { ty: fn() {instruction_set_a32}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:26: +1:27
+ StorageLive(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26
+ _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26
+ // mir::Constant
+ // + span: $DIR/inline-instruction-set.rs:52:5: 52:24
+ // + literal: Const { ty: fn() {instruction_set_t32}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:26: +2:27
+ StorageLive(_3); // scope 0 at $DIR/inline-instruction-set.rs:+3:5: +3:30
+- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline-instruction-set.rs:+3:5: +3:30
+- // mir::Constant
+- // + span: $DIR/inline-instruction-set.rs:53:5: 53:28
+- // + literal: Const { ty: fn() {instruction_set_default}, val: Value(<ZST>) }
+- }
+-
+- bb3: {
+ StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:+3:30: +3:31
+ _0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:+0:18: +4:2
+ return; // scope 0 at $DIR/inline-instruction-set.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff b/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff
new file mode 100644
index 000000000..b275d08e0
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff
@@ -0,0 +1,46 @@
+- // MIR for `t32` before Inline
++ // MIR for `t32` after Inline
+
+ fn t32() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-instruction-set.rs:+0:14: +0:14
+ let _1: (); // in scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26
+ let _2: (); // in scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26
+ let _3: (); // in scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30
++ scope 1 (inlined instruction_set_t32) { // at $DIR/inline-instruction-set.rs:43:5: 43:26
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26
+ _1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26
+ // mir::Constant
+ // + span: $DIR/inline-instruction-set.rs:42:5: 42:24
+ // + literal: Const { ty: fn() {instruction_set_a32}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:26: +1:27
+ StorageLive(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26
+- _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26
+- // mir::Constant
+- // + span: $DIR/inline-instruction-set.rs:43:5: 43:24
+- // + literal: Const { ty: fn() {instruction_set_t32}, val: Value(<ZST>) }
+- }
+-
+- bb2: {
+ StorageDead(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:26: +2:27
+ StorageLive(_3); // scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30
+- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30
++ _3 = instruction_set_default() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30
+ // mir::Constant
+ // + span: $DIR/inline-instruction-set.rs:46:5: 46:28
+ // + literal: Const { ty: fn() {instruction_set_default}, val: Value(<ZST>) }
+ }
+
+- bb3: {
++ bb2: {
+ StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:+5:30: +5:31
+ _0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:+0:14: +6:2
+ return; // scope 0 at $DIR/inline-instruction-set.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff
new file mode 100644
index 000000000..deaba70e0
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff
@@ -0,0 +1,86 @@
+- // MIR for `main` before Inline
++ // MIR for `main` after Inline
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-into-box-place.rs:+0:11: +0:11
+ let _1: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11
+ let mut _2: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ let mut _3: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ let mut _4: *mut u8; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ let mut _6: (); // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
+ let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ let mut _8: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
++ let mut _9: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ scope 1 {
+ debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11
+ }
+ scope 2 {
+ }
++ scope 3 (inlined Vec::<u32>::new) { // at $DIR/inline-into-box-place.rs:8:33: 8:43
++ let mut _10: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11
+ _2 = SizeOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ _3 = AlignOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ // mir::Constant
+ // + span: $DIR/inline-into-box-place.rs:8:29: 8:43
+ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ _5 = ShallowInitBox(move _4, std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ StorageLive(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ _7 = (((_5.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+- (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
++ StorageLive(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
++ _9 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
++ StorageLive(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ _10 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ // mir::Constant
+- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
+- // + user_ty: UserType(1)
+- // + literal: Const { ty: fn() -> Vec<u32> {Vec::<u32>::new}, val: Value(<ZST>) }
+- }
+-
+- bb2: {
++ // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ // + user_ty: UserType(0)
++ // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) }
++ Deinit((*_9)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ ((*_9).0: alloc::raw_vec::RawVec<u32>) = move _10; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ ((*_9).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ StorageDead(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ StorageDead(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ _1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
+ _0 = const (); // scope 0 at $DIR/inline-into-box-place.rs:+0:11: +2:2
+- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
++ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
+ }
+
+- bb3: {
++ bb2: {
+ StorageDead(_1); // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/inline-into-box-place.rs:+2:2: +2:2
+ }
+
+- bb4 (cleanup): {
+- StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+- _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb5; // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
+- // mir::Constant
+- // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
+- // + literal: Const { ty: unsafe fn(Unique<Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>}, val: Value(<ZST>) }
+- }
+-
+- bb5 (cleanup): {
++ bb3 (cleanup): {
+ resume; // scope 0 at $DIR/inline-into-box-place.rs:+0:1: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff
new file mode 100644
index 000000000..deaba70e0
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff
@@ -0,0 +1,86 @@
+- // MIR for `main` before Inline
++ // MIR for `main` after Inline
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-into-box-place.rs:+0:11: +0:11
+ let _1: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11
+ let mut _2: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ let mut _3: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ let mut _4: *mut u8; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ let mut _6: (); // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
+ let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ let mut _8: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
++ let mut _9: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ scope 1 {
+ debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11
+ }
+ scope 2 {
+ }
++ scope 3 (inlined Vec::<u32>::new) { // at $DIR/inline-into-box-place.rs:8:33: 8:43
++ let mut _10: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11
+ _2 = SizeOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ _3 = AlignOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ // mir::Constant
+ // + span: $DIR/inline-into-box-place.rs:8:29: 8:43
+ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ _5 = ShallowInitBox(move _4, std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ StorageLive(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ _7 = (((_5.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+- (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
++ StorageLive(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
++ _9 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
++ StorageLive(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ _10 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ // mir::Constant
+- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
+- // + user_ty: UserType(1)
+- // + literal: Const { ty: fn() -> Vec<u32> {Vec::<u32>::new}, val: Value(<ZST>) }
+- }
+-
+- bb2: {
++ // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ // + user_ty: UserType(0)
++ // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) }
++ Deinit((*_9)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ ((*_9).0: alloc::raw_vec::RawVec<u32>) = move _10; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ ((*_9).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ StorageDead(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ StorageDead(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ _1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
+ _0 = const (); // scope 0 at $DIR/inline-into-box-place.rs:+0:11: +2:2
+- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
++ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
+ }
+
+- bb3: {
++ bb2: {
+ StorageDead(_1); // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/inline-into-box-place.rs:+2:2: +2:2
+ }
+
+- bb4 (cleanup): {
+- StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+- _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb5; // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
+- // mir::Constant
+- // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
+- // + literal: Const { ty: unsafe fn(Unique<Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>}, val: Value(<ZST>) }
+- }
+-
+- bb5 (cleanup): {
++ bb3 (cleanup): {
+ resume; // scope 0 at $DIR/inline-into-box-place.rs:+0:1: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_options.main.Inline.after.mir b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir
new file mode 100644
index 000000000..275493066
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir
@@ -0,0 +1,55 @@
+// MIR for `main` after Inline
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-options.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/inline-options.rs:+1:5: +1:18
+ let _2: (); // in scope 0 at $DIR/inline-options.rs:+2:5: +2:21
+ scope 1 (inlined inlined::<u32>) { // at $DIR/inline-options.rs:10:5: 10:21
+ let _3: (); // in scope 1 at $DIR/inline-options.rs:+8:23: +8:26
+ let _4: (); // in scope 1 at $DIR/inline-options.rs:+8:28: +8:31
+ let _5: (); // in scope 1 at $DIR/inline-options.rs:+8:33: +8:36
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-options.rs:+1:5: +1:18
+ _1 = not_inlined() -> bb1; // scope 0 at $DIR/inline-options.rs:+1:5: +1:18
+ // mir::Constant
+ // + span: $DIR/inline-options.rs:9:5: 9:16
+ // + literal: Const { ty: fn() {not_inlined}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 0 at $DIR/inline-options.rs:+1:18: +1:19
+ StorageLive(_2); // scope 0 at $DIR/inline-options.rs:+2:5: +2:21
+ StorageLive(_3); // scope 1 at $DIR/inline-options.rs:+8:23: +8:26
+ _3 = g() -> bb2; // scope 1 at $DIR/inline-options.rs:+8:23: +8:26
+ // mir::Constant
+ // + span: $DIR/inline-options.rs:16:23: 16:24
+ // + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_3); // scope 1 at $DIR/inline-options.rs:+8:26: +8:27
+ StorageLive(_4); // scope 1 at $DIR/inline-options.rs:+8:28: +8:31
+ _4 = g() -> bb3; // scope 1 at $DIR/inline-options.rs:+8:28: +8:31
+ // mir::Constant
+ // + span: $DIR/inline-options.rs:16:28: 16:29
+ // + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_4); // scope 1 at $DIR/inline-options.rs:+8:31: +8:32
+ StorageLive(_5); // scope 1 at $DIR/inline-options.rs:+8:33: +8:36
+ _5 = g() -> bb4; // scope 1 at $DIR/inline-options.rs:+8:33: +8:36
+ // mir::Constant
+ // + span: $DIR/inline-options.rs:16:33: 16:34
+ // + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ StorageDead(_5); // scope 1 at $DIR/inline-options.rs:+8:36: +8:37
+ StorageDead(_2); // scope 0 at $DIR/inline-options.rs:+2:21: +2:22
+ _0 = const (); // scope 0 at $DIR/inline-options.rs:+0:11: +3:2
+ return; // scope 0 at $DIR/inline-options.rs:+3:2: +3:2
+ }
+}
diff --git a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir
new file mode 100644
index 000000000..768608564
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir
@@ -0,0 +1,72 @@
+// MIR for `bar` after Inline
+
+fn bar() -> bool {
+ let mut _0: bool; // return place in scope 0 at $DIR/inline-retag.rs:+0:13: +0:17
+ let _1: for<'r, 's> fn(&'r i32, &'s i32) -> bool {foo}; // in scope 0 at $DIR/inline-retag.rs:+1:9: +1:10
+ let mut _2: for<'r, 's> fn(&'r i32, &'s i32) -> bool {foo}; // in scope 0 at $DIR/inline-retag.rs:+2:5: +2:6
+ let mut _3: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:7: +2:9
+ let _4: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:7: +2:9
+ let _5: i32; // in scope 0 at $DIR/inline-retag.rs:+2:8: +2:9
+ let mut _6: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:11: +2:14
+ let _7: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:11: +2:14
+ let _8: i32; // in scope 0 at $DIR/inline-retag.rs:+2:12: +2:14
+ scope 1 {
+ debug f => _1; // in scope 1 at $DIR/inline-retag.rs:+1:9: +1:10
+ let mut _9: &i32; // in scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
+ let mut _10: &i32; // in scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
+ scope 2 (inlined foo) { // at $DIR/inline-retag.rs:12:5: 12:15
+ debug x => _3; // in scope 2 at $DIR/inline-retag.rs:+6:8: +6:9
+ debug y => _6; // in scope 2 at $DIR/inline-retag.rs:+6:17: +6:18
+ let mut _11: i32; // in scope 2 at $DIR/inline-retag.rs:+7:5: +7:7
+ let mut _12: i32; // in scope 2 at $DIR/inline-retag.rs:+7:11: +7:13
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-retag.rs:+1:9: +1:10
+ _1 = foo; // scope 0 at $DIR/inline-retag.rs:+1:13: +1:16
+ // mir::Constant
+ // + span: $DIR/inline-retag.rs:11:13: 11:16
+ // + literal: Const { ty: for<'r, 's> fn(&'r i32, &'s i32) -> bool {foo}, val: Value(<ZST>) }
+ StorageLive(_2); // scope 1 at $DIR/inline-retag.rs:+2:5: +2:6
+ _2 = _1; // scope 1 at $DIR/inline-retag.rs:+2:5: +2:6
+ StorageLive(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
+ StorageLive(_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
+ _10 = const bar::promoted[1]; // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
+ // mir::Constant
+ // + span: $DIR/inline-retag.rs:12:7: 12:9
+ // + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[1])) }
+ Retag(_10); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
+ _4 = &(*_10); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
+ Retag(_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
+ _3 = &(*_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
+ Retag(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
+ StorageLive(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
+ StorageLive(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
+ _9 = const bar::promoted[0]; // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
+ // mir::Constant
+ // + span: $DIR/inline-retag.rs:12:11: 12:14
+ // + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[0])) }
+ Retag(_9); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
+ _7 = &(*_9); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
+ Retag(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
+ _6 = &(*_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
+ Retag(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
+ Retag(_3); // scope 2 at $DIR/inline-retag.rs:+6:1: +8:2
+ Retag(_6); // scope 2 at $DIR/inline-retag.rs:+6:1: +8:2
+ StorageLive(_11); // scope 2 at $DIR/inline-retag.rs:+7:5: +7:7
+ _11 = (*_3); // scope 2 at $DIR/inline-retag.rs:+7:5: +7:7
+ StorageLive(_12); // scope 2 at $DIR/inline-retag.rs:+7:11: +7:13
+ _12 = (*_6); // scope 2 at $DIR/inline-retag.rs:+7:11: +7:13
+ _0 = Eq(move _11, move _12); // scope 2 at $DIR/inline-retag.rs:+7:5: +7:13
+ StorageDead(_12); // scope 2 at $DIR/inline-retag.rs:+7:12: +7:13
+ StorageDead(_11); // scope 2 at $DIR/inline-retag.rs:+7:12: +7:13
+ StorageDead(_6); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15
+ StorageDead(_3); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15
+ StorageDead(_2); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15
+ StorageDead(_1); // scope 0 at $DIR/inline-retag.rs:+3:1: +3:2
+ StorageDead(_7); // scope 0 at $DIR/inline-retag.rs:+3:1: +3:2
+ StorageDead(_4); // scope 0 at $DIR/inline-retag.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/inline-retag.rs:+3:2: +3:2
+ }
+}
diff --git a/src/test/mir-opt/inline/inline_shims.clone.Inline.diff b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff
new file mode 100644
index 000000000..25ca05893
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff
@@ -0,0 +1,26 @@
+- // MIR for `clone` before Inline
++ // MIR for `clone` after Inline
+
+ fn clone(_1: fn(A, B)) -> fn(A, B) {
+ debug f => _1; // in scope 0 at $DIR/inline-shims.rs:+0:20: +0:21
+ let mut _0: fn(A, B); // return place in scope 0 at $DIR/inline-shims.rs:+0:36: +0:44
+ let mut _2: &fn(A, B); // in scope 0 at $DIR/inline-shims.rs:+1:5: +1:14
++ scope 1 (inlined <fn(A, B) as Clone>::clone - shim(fn(A, B))) { // at $DIR/inline-shims.rs:6:5: 6:14
++ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/inline-shims.rs:+1:5: +1:14
+ _2 = &_1; // scope 0 at $DIR/inline-shims.rs:+1:5: +1:14
+- _0 = <fn(A, B) as Clone>::clone(move _2) -> bb1; // scope 0 at $DIR/inline-shims.rs:+1:5: +1:14
+- // mir::Constant
+- // + span: $DIR/inline-shims.rs:6:7: 6:12
+- // + literal: Const { ty: for<'r> fn(&'r fn(A, B)) -> fn(A, B) {<fn(A, B) as Clone>::clone}, val: Value(<ZST>) }
+- }
+-
+- bb1: {
++ _0 = (*_2); // scope 1 at $SRC_DIR/core/src/clone.rs:LL:COL
+ StorageDead(_2); // scope 0 at $DIR/inline-shims.rs:+1:13: +1:14
+ return; // scope 0 at $DIR/inline-shims.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_shims.drop.Inline.diff b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff
new file mode 100644
index 000000000..f7b1cde80
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff
@@ -0,0 +1,56 @@
+- // MIR for `drop` before Inline
++ // MIR for `drop` after Inline
+
+ fn drop(_1: *mut Vec<A>, _2: *mut Option<B>) -> () {
+ debug a => _1; // in scope 0 at $DIR/inline-shims.rs:+0:19: +0:20
+ debug b => _2; // in scope 0 at $DIR/inline-shims.rs:+0:35: +0:36
+ let mut _0: (); // return place in scope 0 at $DIR/inline-shims.rs:+0:54: +0:54
+ let _3: (); // in scope 0 at $DIR/inline-shims.rs:+1:14: +1:40
+ let mut _4: *mut std::vec::Vec<A>; // in scope 0 at $DIR/inline-shims.rs:+1:38: +1:39
+ let mut _5: *mut std::option::Option<B>; // in scope 0 at $DIR/inline-shims.rs:+2:38: +2:39
+ scope 1 {
+ }
+ scope 2 {
++ scope 3 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) { // at $DIR/inline-shims.rs:12:14: 12:40
++ let mut _6: isize; // in scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
++ let mut _7: isize; // in scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
++ }
+ }
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/inline-shims.rs:+1:5: +1:42
+ StorageLive(_4); // scope 1 at $DIR/inline-shims.rs:+1:38: +1:39
+ _4 = _1; // scope 1 at $DIR/inline-shims.rs:+1:38: +1:39
+ _3 = std::ptr::drop_in_place::<Vec<A>>(move _4) -> bb1; // scope 1 at $DIR/inline-shims.rs:+1:14: +1:40
+ // mir::Constant
+ // + span: $DIR/inline-shims.rs:11:14: 11:37
+ // + literal: Const { ty: unsafe fn(*mut Vec<A>) {std::ptr::drop_in_place::<Vec<A>>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_4); // scope 1 at $DIR/inline-shims.rs:+1:39: +1:40
+ StorageDead(_3); // scope 0 at $DIR/inline-shims.rs:+1:41: +1:42
+ StorageLive(_5); // scope 2 at $DIR/inline-shims.rs:+2:38: +2:39
+ _5 = _2; // scope 2 at $DIR/inline-shims.rs:+2:38: +2:39
+- _0 = std::ptr::drop_in_place::<Option<B>>(move _5) -> bb2; // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40
+- // mir::Constant
+- // + span: $DIR/inline-shims.rs:12:14: 12:37
+- // + literal: Const { ty: unsafe fn(*mut Option<B>) {std::ptr::drop_in_place::<Option<B>>}, val: Value(<ZST>) }
++ StorageLive(_6); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40
++ StorageLive(_7); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40
++ _6 = discriminant((*_5)); // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
++ switchInt(move _6) -> [0_isize: bb2, otherwise: bb3]; // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ }
+
+ bb2: {
++ StorageDead(_7); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40
++ StorageDead(_6); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40
+ StorageDead(_5); // scope 2 at $DIR/inline-shims.rs:+2:39: +2:40
+ return; // scope 0 at $DIR/inline-shims.rs:+3:2: +3:2
++ }
++
++ bb3: {
++ drop((((*_5) as Some).0: B)) -> bb2; // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_specialization.main.Inline.diff b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff
new file mode 100644
index 000000000..106291b36
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff
@@ -0,0 +1,28 @@
+- // MIR for `main` before Inline
++ // MIR for `main` after Inline
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inline-specialization.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/inline-specialization.rs:+1:9: +1:10
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/inline-specialization.rs:+1:9: +1:10
+ }
++ scope 2 (inlined <Vec<()> as Foo>::bar) { // at $DIR/inline-specialization.rs:5:13: 5:38
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inline-specialization.rs:+1:9: +1:10
+- _1 = <Vec<()> as Foo>::bar() -> bb1; // scope 0 at $DIR/inline-specialization.rs:+1:13: +1:38
+- // mir::Constant
+- // + span: $DIR/inline-specialization.rs:5:13: 5:36
+- // + literal: Const { ty: fn() -> u32 {<Vec<()> as Foo>::bar}, val: Value(<ZST>) }
+- }
+-
+- bb1: {
++ _1 = const 123_u32; // scope 2 at $DIR/inline-specialization.rs:+10:31: +10:34
+ _0 = const (); // scope 0 at $DIR/inline-specialization.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline-specialization.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/inline-specialization.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir
new file mode 100644
index 000000000..ed95edd16
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir
@@ -0,0 +1,21 @@
+// MIR for `test` after Inline
+
+fn test(_1: &dyn X) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/inline-trait-method.rs:+0:9: +0:10
+ let mut _0: u32; // return place in scope 0 at $DIR/inline-trait-method.rs:+0:23: +0:26
+ let mut _2: &dyn X; // in scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10
+ _2 = &(*_1); // scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10
+ _0 = <dyn X as X>::y(move _2) -> bb1; // scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10
+ // mir::Constant
+ // + span: $DIR/inline-trait-method.rs:9:7: 9:8
+ // + literal: Const { ty: for<'r> fn(&'r dyn X) -> u32 {<dyn X as X>::y}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 0 at $DIR/inline-trait-method.rs:+1:9: +1:10
+ return; // scope 0 at $DIR/inline-trait-method.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
new file mode 100644
index 000000000..116ae4e36
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
@@ -0,0 +1,32 @@
+// MIR for `test2` after Inline
+
+fn test2(_1: &dyn X) -> bool {
+ debug x => _1; // in scope 0 at $DIR/inline-trait-method_2.rs:+0:10: +0:11
+ let mut _0: bool; // return place in scope 0 at $DIR/inline-trait-method_2.rs:+0:24: +0:28
+ let mut _2: &dyn X; // in scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
+ let mut _3: &dyn X; // in scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
+ scope 1 (inlined test) { // at $DIR/inline-trait-method_2.rs:5:5: 5:12
+ debug x => _2; // in scope 1 at $DIR/inline-trait-method_2.rs:+5:9: +5:10
+ let mut _4: &dyn X; // in scope 1 at $DIR/inline-trait-method_2.rs:+6:5: +6:10
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
+ StorageLive(_3); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
+ _3 = &(*_1); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
+ _2 = move _3 as &dyn X (Pointer(Unsize)); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
+ StorageDead(_3); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
+ StorageLive(_4); // scope 1 at $DIR/inline-trait-method_2.rs:+6:5: +6:10
+ _4 = _2; // scope 1 at $DIR/inline-trait-method_2.rs:+6:5: +6:10
+ _0 = <dyn X as X>::y(move _4) -> bb1; // scope 1 at $DIR/inline-trait-method_2.rs:+6:5: +6:10
+ // mir::Constant
+ // + span: $DIR/inline-trait-method_2.rs:10:7: 10:8
+ // + literal: Const { ty: for<'r> fn(&'r dyn X) -> bool {<dyn X as X>::y}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_4); // scope 1 at $DIR/inline-trait-method_2.rs:+6:9: +6:10
+ StorageDead(_2); // scope 0 at $DIR/inline-trait-method_2.rs:+1:11: +1:12
+ return; // scope 0 at $DIR/inline-trait-method_2.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs
new file mode 100644
index 000000000..94f926d39
--- /dev/null
+++ b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs
@@ -0,0 +1,27 @@
+// EMIT_MIR issue_58867_inline_as_ref_as_mut.a.Inline.after.mir
+pub fn a<T>(x: &mut [T]) -> &mut [T] {
+ x.as_mut()
+}
+
+// EMIT_MIR issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
+pub fn b<T>(x: &mut Box<T>) -> &mut T {
+ x.as_mut()
+}
+
+// EMIT_MIR issue_58867_inline_as_ref_as_mut.c.Inline.after.mir
+pub fn c<T>(x: &[T]) -> &[T] {
+ x.as_ref()
+}
+
+// EMIT_MIR issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
+pub fn d<T>(x: &Box<T>) -> &T {
+ x.as_ref()
+}
+
+fn main() {
+ let mut boxed = Box::new(1);
+ println!("{:?}", a(&mut [1]));
+ println!("{:?}", b(&mut boxed));
+ println!("{:?}", c(&[1]));
+ println!("{:?}", d(&boxed));
+}
diff --git a/src/test/mir-opt/inline/issue-76997-inline-scopes-parenting.rs b/src/test/mir-opt/inline/issue-76997-inline-scopes-parenting.rs
new file mode 100644
index 000000000..76d806acc
--- /dev/null
+++ b/src/test/mir-opt/inline/issue-76997-inline-scopes-parenting.rs
@@ -0,0 +1,7 @@
+// Tests that MIR inliner can handle `SourceScopeData` parenting correctly. (#76997)
+
+// EMIT_MIR issue_76997_inline_scopes_parenting.main.Inline.after.mir
+fn main() {
+ let f = |x| { let y = x; y };
+ f(())
+}
diff --git a/src/test/mir-opt/inline/issue-78442.rs b/src/test/mir-opt/inline/issue-78442.rs
new file mode 100644
index 000000000..aa8ede2df
--- /dev/null
+++ b/src/test/mir-opt/inline/issue-78442.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Z mir-opt-level=3 -Z inline-mir
+// ignore-wasm32-bare compiled with panic=abort by default
+#![crate_type = "lib"]
+
+// EMIT_MIR issue_78442.bar.RevealAll.diff
+// EMIT_MIR issue_78442.bar.Inline.diff
+pub fn bar<P>(
+ // Error won't happen if "bar" is not generic
+ _baz: P,
+) {
+ hide_foo()();
+}
+
+fn hide_foo() -> impl Fn() {
+ // Error won't happen if "iterate" hasn't impl Trait or has generics
+ foo
+}
+
+fn foo() { // Error won't happen if "foo" isn't used in "iterate" or has generics
+}
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir
new file mode 100644
index 000000000..5168ae031
--- /dev/null
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir
@@ -0,0 +1,30 @@
+// MIR for `a` after Inline
+
+fn a(_1: &mut [T]) -> &mut [T] {
+ debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14
+ let mut _0: &mut [T]; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:29: +0:37
+ let mut _2: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ let mut _3: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ let mut _4: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ scope 1 (inlined <[T] as AsMut<[T]>>::as_mut) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15
+ debug self => _4; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ let mut _5: &mut [T]; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ _4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ _5 = &mut (*_4); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ _3 = &mut (*_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ StorageDead(_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ _2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15
+ _0 = &mut (*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
+ StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
new file mode 100644
index 000000000..4006dd15a
--- /dev/null
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
@@ -0,0 +1,42 @@
+// MIR for `b` after Inline
+
+fn b(_1: &mut Box<T>) -> &mut T {
+ debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14
+ let mut _0: &mut T; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:32: +0:38
+ let mut _2: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ let mut _3: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ let mut _4: &mut std::boxed::Box<T>; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ scope 1 (inlined <Box<T> as AsMut<T>>::as_mut) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15
+ debug self => _4; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ let mut _5: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ let mut _6: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ let mut _7: std::boxed::Box<T>; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ let mut _8: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ _4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ StorageLive(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ StorageLive(_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ _7 = deref_copy (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ StorageLive(_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ _8 = (((_7.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ _6 = &mut (*_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ StorageDead(_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ StorageDead(_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ _5 = &mut (*_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ _3 = &mut (*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ StorageDead(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ StorageDead(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ _2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15
+ _0 = &mut (*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
+ StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir
new file mode 100644
index 000000000..c7f20ff98
--- /dev/null
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir
@@ -0,0 +1,22 @@
+// MIR for `c` after Inline
+
+fn c(_1: &[T]) -> &[T] {
+ debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14
+ let mut _0: &[T]; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:25: +0:29
+ let _2: &[T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ let mut _3: &[T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ scope 1 (inlined <[T] as AsRef<[T]>>::as_ref) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:13:5: 13:15
+ debug self => _3; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ _3 = &(*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ _2 = _3; // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ _0 = &(*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15
+ StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
new file mode 100644
index 000000000..e516269c1
--- /dev/null
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
@@ -0,0 +1,30 @@
+// MIR for `d` after Inline
+
+fn d(_1: &Box<T>) -> &T {
+ debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14
+ let mut _0: &T; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:28: +0:30
+ let _2: &T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ let mut _3: &std::boxed::Box<T>; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ scope 1 (inlined <Box<T> as AsRef<T>>::as_ref) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
+ debug self => _3; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ let mut _4: std::boxed::Box<T>; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ let mut _5: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ _3 = &(*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ _4 = deref_copy (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ _5 = (((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ _2 = &(*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ StorageDead(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ StorageDead(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ _0 = &(*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15
+ StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir
new file mode 100644
index 000000000..fca53a72f
--- /dev/null
+++ b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir
@@ -0,0 +1,42 @@
+// MIR for `main` after Inline
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+0:11: +0:11
+ let _1: [closure@$DIR/issue-76997-inline-scopes-parenting.rs:5:13: 5:16]; // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:9: +1:10
+ let mut _2: &[closure@$DIR/issue-76997-inline-scopes-parenting.rs:5:13: 5:16]; // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:6
+ let mut _3: ((),); // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
+ let mut _4: (); // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:7: +2:9
+ let mut _5: (); // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
+ scope 1 {
+ debug f => _1; // in scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:9: +1:10
+ scope 2 (inlined main::{closure#0}) { // at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10
+ debug x => _5; // in scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:14: +1:15
+ let _6: (); // in scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:23: +1:24
+ scope 3 {
+ debug y => _6; // in scope 3 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:23: +1:24
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:9: +1:10
+ Deinit(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:13: +1:33
+ StorageLive(_2); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:6
+ _2 = &_1; // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:6
+ StorageLive(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
+ StorageLive(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:7: +2:9
+ Deinit(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:7: +2:9
+ Deinit(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
+ (_3.0: ()) = move _4; // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
+ StorageLive(_5); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
+ _5 = move (_3.0: ()); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
+ StorageLive(_6); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:23: +1:24
+ StorageDead(_6); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:32: +1:33
+ StorageDead(_5); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
+ StorageDead(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:9: +2:10
+ StorageDead(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:9: +2:10
+ StorageDead(_2); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:9: +2:10
+ StorageDead(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+3:2: +3:2
+ }
+}
diff --git a/src/test/mir-opt/inline/issue_78442.bar.Inline.diff b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff
new file mode 100644
index 000000000..c16dfdf39
--- /dev/null
+++ b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff
@@ -0,0 +1,68 @@
+- // MIR for `bar` before Inline
++ // MIR for `bar` after Inline
+
+ fn bar(_1: P) -> () {
+ debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:+2:5: +2:9
+ let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:+3:3: +3:3
+ let _2: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+ let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+ let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+ let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
++ scope 1 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) { // at $DIR/issue-78442.rs:11:5: 11:17
++ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+ StorageLive(_3); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+ StorageLive(_4); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+- _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
++ _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+ // mir::Constant
+ // + span: $DIR/issue-78442.rs:11:5: 11:13
+ // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ _3 = &_4; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+ StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+ Deinit(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+- _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+- // mir::Constant
+- // + span: $DIR/issue-78442.rs:11:5: 11:15
+- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r fn() {foo}, ()) -> <fn() {foo} as FnOnce<()>>::Output {<fn() {foo} as Fn<()>>::call}, val: Value(<ZST>) }
++ _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $SRC_DIR/core/src/ops/function.rs:LL:COL
+ }
+
+ bb2: {
+- StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17
+- StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17
+- StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18
+- StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18
+- _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2
+- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2
++ return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2
+ }
+
+- bb3: {
+- return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2
++ bb3 (cleanup): {
++ drop(_1) -> bb4; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2
+ }
+
+ bb4 (cleanup): {
+- drop(_1) -> bb5; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2
++ resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2
+ }
+
+- bb5 (cleanup): {
+- resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2
++ bb5: {
++ StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17
++ StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17
++ StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18
++ StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18
++ _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2
++ drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff
new file mode 100644
index 000000000..0faa522cb
--- /dev/null
+++ b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff
@@ -0,0 +1,57 @@
+- // MIR for `bar` before RevealAll
++ // MIR for `bar` after RevealAll
+
+ fn bar(_1: P) -> () {
+ debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:+2:5: +2:9
+ let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:+3:3: +3:3
+ let _2: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+- let mut _3: &impl Fn(); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+- let _4: impl Fn(); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
++ let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
++ let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+ let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+ StorageLive(_3); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+ StorageLive(_4); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+ _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+ // mir::Constant
+ // + span: $DIR/issue-78442.rs:11:5: 11:13
+ // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ _3 = &_4; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+ StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+ Deinit(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+- _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
++ _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+ // mir::Constant
+ // + span: $DIR/issue-78442.rs:11:5: 11:15
+- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as FnOnce<()>>::Output {<impl Fn() as Fn<()>>::call}, val: Value(<ZST>) }
++ // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r fn() {foo}, ()) -> <fn() {foo} as FnOnce<()>>::Output {<fn() {foo} as Fn<()>>::call}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17
+ StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17
+ StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18
+ StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18
+ _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2
+ drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2
+ }
+
+ bb3: {
+ return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2
+ }
+
+ bb4 (cleanup): {
+ drop(_1) -> bb5; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2
+ }
+
+ bb5 (cleanup): {
+ resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
new file mode 100644
index 000000000..b78ef36ea
--- /dev/null
+++ b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
@@ -0,0 +1,13 @@
+- // MIR for `bar` before InstrumentCoverage
++ // MIR for `bar` after InstrumentCoverage
+
+ fn bar() -> bool {
+ let mut _0: bool; // return place in scope 0 at /the/src/instrument_coverage.rs:+0:13: +0:17
+
+ bb0: {
++ Coverage::Counter(1) for /the/src/instrument_coverage.rs:19:1 - 21:2; // scope 0 at /the/src/instrument_coverage.rs:+2:2: +2:2
+ _0 = const true; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +1:9
+ return; // scope 0 at /the/src/instrument_coverage.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
new file mode 100644
index 000000000..0490c0df2
--- /dev/null
+++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
@@ -0,0 +1,51 @@
+- // MIR for `main` before InstrumentCoverage
++ // MIR for `main` after InstrumentCoverage
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at /the/src/instrument_coverage.rs:+0:11: +0:11
+ let mut _1: (); // in scope 0 at /the/src/instrument_coverage.rs:+0:1: +6:2
+ let mut _2: bool; // in scope 0 at /the/src/instrument_coverage.rs:+2:12: +2:17
+ let mut _3: !; // in scope 0 at /the/src/instrument_coverage.rs:+2:18: +4:10
+
+ bb0: {
++ Coverage::Counter(1) for /the/src/instrument_coverage.rs:10:1 - 10:11; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
+ goto -> bb1; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
+ }
+
+ bb1: {
++ Coverage::Expression(4294967295) = 1 + 2 for /the/src/instrument_coverage.rs:11:5 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
+ falseUnwind -> [real: bb2, cleanup: bb6]; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
+ }
+
+ bb2: {
+ StorageLive(_2); // scope 0 at /the/src/instrument_coverage.rs:+2:12: +2:17
+ _2 = bar() -> [return: bb3, unwind: bb6]; // scope 0 at /the/src/instrument_coverage.rs:+2:12: +2:17
+ // mir::Constant
+ // + span: /the/src/instrument_coverage.rs:12:12: 12:15
+ // + literal: Const { ty: fn() -> bool {bar}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at /the/src/instrument_coverage.rs:+2:12: +2:17
+ }
+
+ bb4: {
++ Coverage::Expression(4294967293) = 4294967294 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2
++ Coverage::Expression(4294967294) = 4294967295 - 2 for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2
+ _0 = const (); // scope 0 at /the/src/instrument_coverage.rs:+3:13: +3:18
+ StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:+4:9: +4:10
+ return; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2
+ }
+
+ bb5: {
++ Coverage::Counter(2) for /the/src/instrument_coverage.rs:14:10 - 14:11; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
+ _1 = const (); // scope 0 at /the/src/instrument_coverage.rs:+4:10: +4:10
+ StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:+4:9: +4:10
+ goto -> bb1; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
+ }
+
+ bb6 (cleanup): {
+ resume; // scope 0 at /the/src/instrument_coverage.rs:+0:1: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/instrument_coverage.rs b/src/test/mir-opt/instrument_coverage.rs
new file mode 100644
index 000000000..a748f2c5c
--- /dev/null
+++ b/src/test/mir-opt/instrument_coverage.rs
@@ -0,0 +1,36 @@
+// Test that `-C instrument-coverage` injects Coverage statements. The Coverage Counter statements
+// are later converted into LLVM instrprof.increment intrinsics, during codegen.
+
+// needs-profiler-support
+// ignore-windows
+// compile-flags: -C instrument-coverage --remap-path-prefix={{src-base}}=/the/src
+
+// EMIT_MIR instrument_coverage.main.InstrumentCoverage.diff
+// EMIT_MIR instrument_coverage.bar.InstrumentCoverage.diff
+fn main() {
+ loop {
+ if bar() {
+ break;
+ }
+ }
+}
+
+#[inline(never)]
+fn bar() -> bool {
+ true
+}
+
+// Note that the MIR with injected coverage intrinsics includes references to source locations,
+// including the source file absolute path. Typically, MIR pretty print output with file
+// references are safe because the file prefixes are substituted with `$DIR`, but in this case
+// the file references are encoded as function arguments, with an `Operand` type representation
+// (`Slice` `Allocation` interned byte array) that cannot be normalized by simple substitution.
+//
+// The first workaround is to use the `SourceMap`-supported `--remap-path-prefix` option; however,
+// the implementation of the `--remap-path-prefix` option currently joins the new prefix and the
+// remaining source path with an OS-specific path separator (`\` on Windows). This difference still
+// shows up in the byte array representation of the path, causing Windows tests to fail to match
+// blessed results baselined with a `/` path separator.
+//
+// Since this `mir-opt` test does not have any significant platform dependencies, other than the
+// path separator differences, the final workaround is to disable testing on Windows.
diff --git a/src/test/mir-opt/issue-38669.rs b/src/test/mir-opt/issue-38669.rs
new file mode 100644
index 000000000..db3f89472
--- /dev/null
+++ b/src/test/mir-opt/issue-38669.rs
@@ -0,0 +1,12 @@
+// check that we don't StorageDead booleans before they are used
+
+// EMIT_MIR issue_38669.main.SimplifyCfg-initial.after.mir
+fn main() {
+ let mut should_break = false;
+ loop {
+ if should_break {
+ break;
+ }
+ should_break = true;
+ }
+}
diff --git a/src/test/mir-opt/issue-41110.rs b/src/test/mir-opt/issue-41110.rs
new file mode 100644
index 000000000..638dc601e
--- /dev/null
+++ b/src/test/mir-opt/issue-41110.rs
@@ -0,0 +1,30 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+
+// check that we don't emit multiple drop flags when they are not needed.
+
+
+// EMIT_MIR issue_41110.main.ElaborateDrops.after.mir
+fn main() {
+ let x = S.other(S.id());
+}
+
+// no_mangle to make sure this gets instantiated even in an executable.
+#[no_mangle]
+// EMIT_MIR issue_41110.test.ElaborateDrops.after.mir
+pub fn test() {
+ let u = S;
+ let mut v = S;
+ drop(v);
+ v = u;
+}
+
+struct S;
+impl Drop for S {
+ fn drop(&mut self) {
+ }
+}
+
+impl S {
+ fn id(self) -> Self { self }
+ fn other(self, s: Self) {}
+}
diff --git a/src/test/mir-opt/issue-41697.rs b/src/test/mir-opt/issue-41697.rs
new file mode 100644
index 000000000..5c34d8e68
--- /dev/null
+++ b/src/test/mir-opt/issue-41697.rs
@@ -0,0 +1,40 @@
+// Regression test for #41697. Using dump-mir was triggering
+// artificial cycles: during type-checking, we had to get the MIR for
+// the constant expressions in `[u8; 2]`, which in turn would trigger
+// an attempt to get the def-path, which in turn would request the
+// types of the impl, which would trigger a cycle. We suppressed this
+// cycle now by forcing mir-dump to avoid asking for types of an impl.
+
+#![feature(rustc_attrs)]
+
+use std::sync::Arc;
+
+trait Foo {
+ fn get(&self) -> [u8; 2];
+}
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
+impl Foo for [u8; 1+1] {
+ fn get(&self) -> [u8; 2] {
+ *self
+ }
+}
+
+struct Bar<T: ?Sized>(T);
+
+fn unsize_fat_ptr<'a>(x: &'a Bar<Foo + Send + 'a>) -> &'a Bar<Foo + 'a> {
+ x
+}
+
+fn unsize_nested_fat_ptr(x: Arc<Foo + Send>) -> Arc<Foo> {
+ x
+}
+
+fn main() {
+ let x: Box<Bar<Foo + Send>> = Box::new(Bar([1,2]));
+ assert_eq!(unsize_fat_ptr(&*x).0.get(), [1, 2]);
+
+ let x: Arc<Foo + Send> = Arc::new([3, 4]);
+ assert_eq!(unsize_nested_fat_ptr(x).get(), [3, 4]);
+}
diff --git a/src/test/mir-opt/issue-41888.rs b/src/test/mir-opt/issue-41888.rs
new file mode 100644
index 000000000..c1046c14d
--- /dev/null
+++ b/src/test/mir-opt/issue-41888.rs
@@ -0,0 +1,24 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+// check that we clear the "ADT master drop flag" even when there are
+// no fields to be dropped.
+
+// EMIT_MIR issue_41888.main.ElaborateDrops.after.mir
+fn main() {
+ let e;
+ if cond() {
+ e = E::F(K);
+ if let E::F(_k) = e {
+ // older versions of rustc used to not clear the
+ // drop flag for `e` in this path.
+ }
+ }
+}
+
+fn cond() -> bool { false }
+
+struct K;
+
+enum E {
+ F(K),
+ G(Box<E>)
+}
diff --git a/src/test/mir-opt/issue-49232.rs b/src/test/mir-opt/issue-49232.rs
new file mode 100644
index 000000000..86494c76a
--- /dev/null
+++ b/src/test/mir-opt/issue-49232.rs
@@ -0,0 +1,15 @@
+// We must mark a variable whose initialization fails due to an
+// abort statement as StorageDead.
+
+// EMIT_MIR issue_49232.main.mir_map.0.mir
+fn main() {
+ loop {
+ let beacon = {
+ match true {
+ false => 4,
+ true => break,
+ }
+ };
+ drop(&beacon);
+ }
+}
diff --git a/src/test/mir-opt/issue-62289.rs b/src/test/mir-opt/issue-62289.rs
new file mode 100644
index 000000000..37e3390d5
--- /dev/null
+++ b/src/test/mir-opt/issue-62289.rs
@@ -0,0 +1,14 @@
+// check that we don't forget to drop the Box if we early return before
+// initializing it
+// ignore-wasm32-bare compiled with panic=abort by default
+
+#![feature(box_syntax)]
+
+// EMIT_MIR issue_62289.test.ElaborateDrops.before.mir
+fn test() -> Option<Box<u32>> {
+ Some(box (None?))
+}
+
+fn main() {
+ test();
+}
diff --git a/src/test/mir-opt/issue-72181-1.rs b/src/test/mir-opt/issue-72181-1.rs
new file mode 100644
index 000000000..91e98adbe
--- /dev/null
+++ b/src/test/mir-opt/issue-72181-1.rs
@@ -0,0 +1,21 @@
+// compile-flags: -Z mir-opt-level=1
+// Regression test for #72181, this ICE requires `-Z mir-opt-level=1` flags.
+
+#![feature(never_type)]
+#![allow(unused, invalid_value)]
+
+enum Void {}
+
+// EMIT_MIR issue_72181_1.f.mir_map.0.mir
+fn f(v: Void) -> ! {
+ match v {}
+}
+
+// EMIT_MIR issue_72181_1.main.mir_map.0.mir
+fn main() {
+ let v: Void = unsafe {
+ std::mem::transmute::<(), Void>(())
+ };
+
+ f(v);
+}
diff --git a/src/test/mir-opt/issue-72181.rs b/src/test/mir-opt/issue-72181.rs
new file mode 100644
index 000000000..844d53a4b
--- /dev/null
+++ b/src/test/mir-opt/issue-72181.rs
@@ -0,0 +1,28 @@
+// compile-flags: -Z mir-opt-level=1
+// Regression test for #72181, this ICE requires `-Z mir-opt-level=1` flags.
+
+use std::mem;
+
+#[derive(Copy, Clone)]
+enum Never {}
+
+union Foo {
+ a: u64,
+ b: Never
+}
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR issue_72181.foo.mir_map.0.mir
+fn foo(xs: [(Never, u32); 1]) -> u32 { xs[0].1 }
+
+// EMIT_MIR issue_72181.bar.mir_map.0.mir
+fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { x }
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR issue_72181.main.mir_map.0.mir
+fn main() {
+ let _ = mem::size_of::<Foo>();
+
+ let f = [Foo { a: 42 }, Foo { a: 10 }];
+ let _ = unsafe { f[0].a };
+}
diff --git a/src/test/mir-opt/issue-73223.rs b/src/test/mir-opt/issue-73223.rs
new file mode 100644
index 000000000..703b87612
--- /dev/null
+++ b/src/test/mir-opt/issue-73223.rs
@@ -0,0 +1,13 @@
+fn main() {
+ let split = match Some(1) {
+ Some(v) => v,
+ None => return,
+ };
+
+ let _prev = Some(split);
+ assert_eq!(split, 1);
+}
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR issue_73223.main.SimplifyArmIdentity.diff
+// EMIT_MIR issue_73223.main.PreCodegen.diff
diff --git a/src/test/mir-opt/issue-78192.rs b/src/test/mir-opt/issue-78192.rs
new file mode 100644
index 000000000..39f665402
--- /dev/null
+++ b/src/test/mir-opt/issue-78192.rs
@@ -0,0 +1,11 @@
+// compile-flags: -Zmir-opt-level=1 -Zinline-mir
+pub fn f<T>(a: &T) -> *const T {
+ let b: &*const T = &(a as *const T);
+ *b
+}
+
+fn main() {
+ f(&2);
+}
+
+// EMIT_MIR issue_78192.f.InstCombine.diff
diff --git a/src/test/mir-opt/issue-99325.rs b/src/test/mir-opt/issue-99325.rs
new file mode 100644
index 000000000..b79946ea8
--- /dev/null
+++ b/src/test/mir-opt/issue-99325.rs
@@ -0,0 +1,12 @@
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+pub fn function_with_bytes<const BYTES: &'static [u8; 4]>() -> &'static [u8] {
+ BYTES
+}
+
+// EMIT_MIR issue_99325.main.mir_map.0.mir
+pub fn main() {
+ assert_eq!(function_with_bytes::<b"AAAA">(), &[0x41, 0x41, 0x41, 0x41]);
+ assert_eq!(function_with_bytes::<{ &[0x41, 0x41, 0x41, 0x41] }>(), b"AAAA");
+}
diff --git a/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir
new file mode 100644
index 000000000..b13987f73
--- /dev/null
+++ b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir
@@ -0,0 +1,52 @@
+// MIR for `main` after SimplifyCfg-initial
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-38669.rs:+0:11: +0:11
+ let mut _1: bool; // in scope 0 at $DIR/issue-38669.rs:+1:9: +1:25
+ let mut _2: (); // in scope 0 at $DIR/issue-38669.rs:+0:1: +8:2
+ let _3: (); // in scope 0 at $DIR/issue-38669.rs:+3:9: +5:10
+ let mut _4: bool; // in scope 0 at $DIR/issue-38669.rs:+3:12: +3:24
+ let mut _5: !; // in scope 0 at $DIR/issue-38669.rs:+3:25: +5:10
+ scope 1 {
+ debug should_break => _1; // in scope 1 at $DIR/issue-38669.rs:+1:9: +1:25
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-38669.rs:+1:9: +1:25
+ _1 = const false; // scope 0 at $DIR/issue-38669.rs:+1:28: +1:33
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue-38669.rs:+1:9: +1:25
+ goto -> bb1; // scope 1 at $DIR/issue-38669.rs:+2:5: +7:6
+ }
+
+ bb1: {
+ falseUnwind -> [real: bb2, cleanup: bb5]; // scope 1 at $DIR/issue-38669.rs:+2:5: +7:6
+ }
+
+ bb2: {
+ StorageLive(_3); // scope 1 at $DIR/issue-38669.rs:+3:9: +5:10
+ StorageLive(_4); // scope 1 at $DIR/issue-38669.rs:+3:12: +3:24
+ _4 = _1; // scope 1 at $DIR/issue-38669.rs:+3:12: +3:24
+ switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 1 at $DIR/issue-38669.rs:+3:12: +3:24
+ }
+
+ bb3: {
+ _0 = const (); // scope 1 at $DIR/issue-38669.rs:+4:13: +4:18
+ StorageDead(_4); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10
+ StorageDead(_3); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10
+ StorageDead(_1); // scope 0 at $DIR/issue-38669.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/issue-38669.rs:+8:2: +8:2
+ }
+
+ bb4: {
+ _3 = const (); // scope 1 at $DIR/issue-38669.rs:+5:10: +5:10
+ StorageDead(_4); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10
+ StorageDead(_3); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10
+ _1 = const true; // scope 1 at $DIR/issue-38669.rs:+6:9: +6:28
+ _2 = const (); // scope 1 at $DIR/issue-38669.rs:+2:10: +7:6
+ goto -> bb1; // scope 1 at $DIR/issue-38669.rs:+2:5: +7:6
+ }
+
+ bb5 (cleanup): {
+ resume; // scope 0 at $DIR/issue-38669.rs:+0:1: +8:2
+ }
+}
diff --git a/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir
new file mode 100644
index 000000000..1d7cb91d6
--- /dev/null
+++ b/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir
@@ -0,0 +1,70 @@
+// MIR for `main` after ElaborateDrops
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-41110.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/issue-41110.rs:+1:9: +1:10
+ let mut _2: S; // in scope 0 at $DIR/issue-41110.rs:+1:13: +1:14
+ let mut _3: S; // in scope 0 at $DIR/issue-41110.rs:+1:21: +1:27
+ let mut _4: S; // in scope 0 at $DIR/issue-41110.rs:+1:21: +1:22
+ let mut _5: bool; // in scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/issue-41110.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ _5 = const false; // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10
+ StorageLive(_1); // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14
+ _5 = const true; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14
+ _2 = S; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14
+ StorageLive(_3); // scope 0 at $DIR/issue-41110.rs:+1:21: +1:27
+ StorageLive(_4); // scope 0 at $DIR/issue-41110.rs:+1:21: +1:22
+ _4 = S; // scope 0 at $DIR/issue-41110.rs:+1:21: +1:22
+ _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-41110.rs:+1:21: +1:27
+ // mir::Constant
+ // + span: $DIR/issue-41110.rs:8:23: 8:25
+ // + literal: Const { ty: fn(S) -> S {S::id}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_4); // scope 0 at $DIR/issue-41110.rs:+1:26: +1:27
+ _5 = const false; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:28
+ _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:28
+ // mir::Constant
+ // + span: $DIR/issue-41110.rs:8:15: 8:20
+ // + literal: Const { ty: fn(S, S) {S::other}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_3); // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ _5 = const false; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ StorageDead(_2); // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ _0 = const (); // scope 0 at $DIR/issue-41110.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/issue-41110.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/issue-41110.rs:+2:2: +2:2
+ }
+
+ bb3 (cleanup): {
+ goto -> bb5; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ }
+
+ bb4 (cleanup): {
+ goto -> bb5; // scope 0 at $DIR/issue-41110.rs:+1:26: +1:27
+ }
+
+ bb5 (cleanup): {
+ goto -> bb8; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ }
+
+ bb6 (cleanup): {
+ resume; // scope 0 at $DIR/issue-41110.rs:+0:1: +2:2
+ }
+
+ bb7 (cleanup): {
+ drop(_2) -> bb6; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ }
+
+ bb8 (cleanup): {
+ switchInt(_5) -> [false: bb6, otherwise: bb7]; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ }
+}
diff --git a/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir
new file mode 100644
index 000000000..b0e3496b2
--- /dev/null
+++ b/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir
@@ -0,0 +1,101 @@
+// MIR for `test` after ElaborateDrops
+
+fn test() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-41110.rs:+0:15: +0:15
+ let _1: S; // in scope 0 at $DIR/issue-41110.rs:+1:9: +1:10
+ let _3: (); // in scope 0 at $DIR/issue-41110.rs:+3:5: +3:12
+ let mut _4: S; // in scope 0 at $DIR/issue-41110.rs:+3:10: +3:11
+ let mut _5: S; // in scope 0 at $DIR/issue-41110.rs:+4:9: +4:10
+ let mut _6: bool; // in scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
+ scope 1 {
+ debug u => _1; // in scope 1 at $DIR/issue-41110.rs:+1:9: +1:10
+ let mut _2: S; // in scope 1 at $DIR/issue-41110.rs:+2:9: +2:14
+ scope 2 {
+ debug v => _2; // in scope 2 at $DIR/issue-41110.rs:+2:9: +2:14
+ }
+ }
+
+ bb0: {
+ _6 = const false; // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10
+ StorageLive(_1); // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10
+ _6 = const true; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14
+ _1 = S; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/issue-41110.rs:+2:9: +2:14
+ _2 = S; // scope 1 at $DIR/issue-41110.rs:+2:17: +2:18
+ StorageLive(_3); // scope 2 at $DIR/issue-41110.rs:+3:5: +3:12
+ StorageLive(_4); // scope 2 at $DIR/issue-41110.rs:+3:10: +3:11
+ _4 = move _2; // scope 2 at $DIR/issue-41110.rs:+3:10: +3:11
+ _3 = std::mem::drop::<S>(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue-41110.rs:+3:5: +3:12
+ // mir::Constant
+ // + span: $DIR/issue-41110.rs:17:5: 17:9
+ // + literal: Const { ty: fn(S) {std::mem::drop::<S>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_4); // scope 2 at $DIR/issue-41110.rs:+3:11: +3:12
+ StorageDead(_3); // scope 2 at $DIR/issue-41110.rs:+3:12: +3:13
+ StorageLive(_5); // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10
+ _6 = const false; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10
+ _5 = move _1; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10
+ goto -> bb12; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6
+ }
+
+ bb2: {
+ goto -> bb3; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10
+ }
+
+ bb3: {
+ StorageDead(_5); // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10
+ _0 = const (); // scope 0 at $DIR/issue-41110.rs:+0:15: +5:2
+ drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue-41110.rs:+5:1: +5:2
+ }
+
+ bb4: {
+ StorageDead(_2); // scope 1 at $DIR/issue-41110.rs:+5:1: +5:2
+ goto -> bb5; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
+ }
+
+ bb5: {
+ _6 = const false; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/issue-41110.rs:+5:2: +5:2
+ }
+
+ bb6 (cleanup): {
+ goto -> bb8; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10
+ }
+
+ bb7 (cleanup): {
+ goto -> bb8; // scope 2 at $DIR/issue-41110.rs:+3:11: +3:12
+ }
+
+ bb8 (cleanup): {
+ goto -> bb9; // scope 1 at $DIR/issue-41110.rs:+5:1: +5:2
+ }
+
+ bb9 (cleanup): {
+ goto -> bb14; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
+ }
+
+ bb10 (cleanup): {
+ resume; // scope 0 at $DIR/issue-41110.rs:+0:1: +5:2
+ }
+
+ bb11 (cleanup): {
+ _2 = move _5; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6
+ goto -> bb6; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6
+ }
+
+ bb12: {
+ _2 = move _5; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6
+ goto -> bb2; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6
+ }
+
+ bb13 (cleanup): {
+ drop(_1) -> bb10; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
+ }
+
+ bb14 (cleanup): {
+ switchInt(_6) -> [false: bb10, otherwise: bb13]; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
+ }
+}
diff --git a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir
new file mode 100644
index 000000000..047b24db4
--- /dev/null
+++ b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir
@@ -0,0 +1,20 @@
+// MIR for `<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}` after SimplifyCfg-promote-consts
+
+<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}: usize = {
+ let mut _0: usize; // return place in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ let mut _1: (usize, bool); // in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+
+ bb0: {
+ _1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ }
+
+ bb1: {
+ _0 = move (_1.0: usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ return; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ }
+}
diff --git a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir
new file mode 100644
index 000000000..047b24db4
--- /dev/null
+++ b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir
@@ -0,0 +1,20 @@
+// MIR for `<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}` after SimplifyCfg-promote-consts
+
+<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}: usize = {
+ let mut _0: usize; // return place in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ let mut _1: (usize, bool); // in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+
+ bb0: {
+ _1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ }
+
+ bb1: {
+ _0 = move (_1.0: usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ return; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ }
+}
diff --git a/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir
new file mode 100644
index 000000000..f95a0a1c0
--- /dev/null
+++ b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir
@@ -0,0 +1,152 @@
+// MIR for `main` after ElaborateDrops
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-41888.rs:+0:11: +0:11
+ let _1: E; // in scope 0 at $DIR/issue-41888.rs:+1:9: +1:10
+ let mut _2: bool; // in scope 0 at $DIR/issue-41888.rs:+2:8: +2:14
+ let mut _3: E; // in scope 0 at $DIR/issue-41888.rs:+3:13: +3:20
+ let mut _4: K; // in scope 0 at $DIR/issue-41888.rs:+3:18: +3:19
+ let mut _5: isize; // in scope 0 at $DIR/issue-41888.rs:+4:16: +4:24
+ let mut _7: bool; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ let mut _8: bool; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ let mut _9: bool; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ let mut _10: isize; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ let mut _11: isize; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ scope 1 {
+ debug e => _1; // in scope 1 at $DIR/issue-41888.rs:+1:9: +1:10
+ scope 2 {
+ debug _k => _6; // in scope 2 at $DIR/issue-41888.rs:+4:21: +4:23
+ let _6: K; // in scope 2 at $DIR/issue-41888.rs:+4:21: +4:23
+ }
+ }
+
+ bb0: {
+ _9 = const false; // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10
+ _7 = const false; // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10
+ _8 = const false; // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10
+ StorageLive(_1); // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10
+ StorageLive(_2); // scope 1 at $DIR/issue-41888.rs:+2:8: +2:14
+ _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue-41888.rs:+2:8: +2:14
+ // mir::Constant
+ // + span: $DIR/issue-41888.rs:8:8: 8:12
+ // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ switchInt(move _2) -> [false: bb7, otherwise: bb2]; // scope 1 at $DIR/issue-41888.rs:+2:8: +2:14
+ }
+
+ bb2: {
+ StorageLive(_3); // scope 1 at $DIR/issue-41888.rs:+3:13: +3:20
+ StorageLive(_4); // scope 1 at $DIR/issue-41888.rs:+3:18: +3:19
+ _4 = K; // scope 1 at $DIR/issue-41888.rs:+3:18: +3:19
+ _3 = E::F(move _4); // scope 1 at $DIR/issue-41888.rs:+3:13: +3:20
+ StorageDead(_4); // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20
+ goto -> bb14; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ }
+
+ bb3: {
+ goto -> bb4; // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20
+ }
+
+ bb4: {
+ StorageDead(_3); // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20
+ _5 = discriminant(_1); // scope 2 at $DIR/issue-41888.rs:+4:16: +4:24
+ switchInt(move _5) -> [0_isize: bb5, otherwise: bb6]; // scope 2 at $DIR/issue-41888.rs:+4:16: +4:24
+ }
+
+ bb5: {
+ StorageLive(_6); // scope 2 at $DIR/issue-41888.rs:+4:21: +4:23
+ _9 = const false; // scope 2 at $DIR/issue-41888.rs:+4:21: +4:23
+ _6 = move ((_1 as F).0: K); // scope 2 at $DIR/issue-41888.rs:+4:21: +4:23
+ _0 = const (); // scope 2 at $DIR/issue-41888.rs:+4:29: +7:10
+ StorageDead(_6); // scope 1 at $DIR/issue-41888.rs:+7:9: +7:10
+ goto -> bb8; // scope 1 at $DIR/issue-41888.rs:+4:9: +7:10
+ }
+
+ bb6: {
+ _0 = const (); // scope 1 at $DIR/issue-41888.rs:+7:10: +7:10
+ goto -> bb8; // scope 1 at $DIR/issue-41888.rs:+4:9: +7:10
+ }
+
+ bb7: {
+ _0 = const (); // scope 1 at $DIR/issue-41888.rs:+8:6: +8:6
+ goto -> bb8; // scope 1 at $DIR/issue-41888.rs:+2:5: +8:6
+ }
+
+ bb8: {
+ StorageDead(_2); // scope 1 at $DIR/issue-41888.rs:+8:5: +8:6
+ goto -> bb20; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ }
+
+ bb9: {
+ _7 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ _8 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ _9 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ StorageDead(_1); // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ return; // scope 0 at $DIR/issue-41888.rs:+9:2: +9:2
+ }
+
+ bb10 (cleanup): {
+ goto -> bb11; // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20
+ }
+
+ bb11 (cleanup): {
+ goto -> bb12; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ }
+
+ bb12 (cleanup): {
+ resume; // scope 0 at $DIR/issue-41888.rs:+0:1: +9:2
+ }
+
+ bb13 (cleanup): {
+ _7 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ _8 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ _9 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ _1 = move _3; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ goto -> bb10; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ }
+
+ bb14: {
+ _7 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ _8 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ _9 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ _1 = move _3; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ goto -> bb3; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ }
+
+ bb15: {
+ _7 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ goto -> bb9; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ }
+
+ bb16 (cleanup): {
+ goto -> bb12; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ }
+
+ bb17: {
+ drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ }
+
+ bb18 (cleanup): {
+ drop(_1) -> bb12; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ }
+
+ bb19: {
+ _10 = discriminant(_1); // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ switchInt(move _10) -> [0_isize: bb15, otherwise: bb17]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ }
+
+ bb20: {
+ switchInt(_7) -> [false: bb15, otherwise: bb19]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ }
+
+ bb21 (cleanup): {
+ _11 = discriminant(_1); // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ switchInt(move _11) -> [0_isize: bb16, otherwise: bb18]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ }
+
+ bb22 (cleanup): {
+ switchInt(_7) -> [false: bb12, otherwise: bb21]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ }
+}
diff --git a/src/test/mir-opt/issue_49232.main.mir_map.0.mir b/src/test/mir-opt/issue_49232.main.mir_map.0.mir
new file mode 100644
index 000000000..821323b5e
--- /dev/null
+++ b/src/test/mir-opt/issue_49232.main.mir_map.0.mir
@@ -0,0 +1,82 @@
+// MIR for `main` 0 mir_map
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-49232.rs:+0:11: +0:11
+ let mut _1: (); // in scope 0 at $DIR/issue-49232.rs:+0:1: +10:2
+ let _2: i32; // in scope 0 at $DIR/issue-49232.rs:+2:13: +2:19
+ let mut _3: bool; // in scope 0 at $DIR/issue-49232.rs:+3:19: +3:23
+ let mut _4: !; // in scope 0 at $DIR/issue-49232.rs:+5:25: +5:30
+ let _5: (); // in scope 0 at $DIR/issue-49232.rs:+8:9: +8:22
+ let mut _6: &i32; // in scope 0 at $DIR/issue-49232.rs:+8:14: +8:21
+ scope 1 {
+ debug beacon => _2; // in scope 1 at $DIR/issue-49232.rs:+2:13: +2:19
+ }
+
+ bb0: {
+ goto -> bb1; // scope 0 at $DIR/issue-49232.rs:+1:5: +9:6
+ }
+
+ bb1: {
+ falseUnwind -> [real: bb2, cleanup: bb11]; // scope 0 at $DIR/issue-49232.rs:+1:5: +9:6
+ }
+
+ bb2: {
+ StorageLive(_2); // scope 0 at $DIR/issue-49232.rs:+2:13: +2:19
+ StorageLive(_3); // scope 0 at $DIR/issue-49232.rs:+3:19: +3:23
+ _3 = const true; // scope 0 at $DIR/issue-49232.rs:+3:19: +3:23
+ FakeRead(ForMatchedPlace(None), _3); // scope 0 at $DIR/issue-49232.rs:+3:19: +3:23
+ switchInt(_3) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/issue-49232.rs:+3:13: +3:23
+ }
+
+ bb3: {
+ falseEdge -> [real: bb5, imaginary: bb4]; // scope 0 at $DIR/issue-49232.rs:+4:17: +4:22
+ }
+
+ bb4: {
+ _0 = const (); // scope 0 at $DIR/issue-49232.rs:+5:25: +5:30
+ goto -> bb10; // scope 0 at $DIR/issue-49232.rs:+5:25: +5:30
+ }
+
+ bb5: {
+ _2 = const 4_i32; // scope 0 at $DIR/issue-49232.rs:+4:26: +4:27
+ goto -> bb8; // scope 0 at $DIR/issue-49232.rs:+4:26: +4:27
+ }
+
+ bb6: {
+ unreachable; // scope 0 at $DIR/issue-49232.rs:+5:25: +5:30
+ }
+
+ bb7: {
+ goto -> bb8; // scope 0 at $DIR/issue-49232.rs:+6:13: +6:14
+ }
+
+ bb8: {
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-49232.rs:+2:13: +2:19
+ StorageDead(_3); // scope 0 at $DIR/issue-49232.rs:+7:10: +7:11
+ StorageLive(_5); // scope 1 at $DIR/issue-49232.rs:+8:9: +8:22
+ StorageLive(_6); // scope 1 at $DIR/issue-49232.rs:+8:14: +8:21
+ _6 = &_2; // scope 1 at $DIR/issue-49232.rs:+8:14: +8:21
+ _5 = std::mem::drop::<&i32>(move _6) -> [return: bb9, unwind: bb11]; // scope 1 at $DIR/issue-49232.rs:+8:9: +8:22
+ // mir::Constant
+ // + span: $DIR/issue-49232.rs:13:9: 13:13
+ // + literal: Const { ty: fn(&i32) {std::mem::drop::<&i32>}, val: Value(<ZST>) }
+ }
+
+ bb9: {
+ StorageDead(_6); // scope 1 at $DIR/issue-49232.rs:+8:21: +8:22
+ StorageDead(_5); // scope 1 at $DIR/issue-49232.rs:+8:22: +8:23
+ _1 = const (); // scope 0 at $DIR/issue-49232.rs:+1:10: +9:6
+ StorageDead(_2); // scope 0 at $DIR/issue-49232.rs:+9:5: +9:6
+ goto -> bb1; // scope 0 at $DIR/issue-49232.rs:+1:5: +9:6
+ }
+
+ bb10: {
+ StorageDead(_3); // scope 0 at $DIR/issue-49232.rs:+7:10: +7:11
+ StorageDead(_2); // scope 0 at $DIR/issue-49232.rs:+9:5: +9:6
+ return; // scope 0 at $DIR/issue-49232.rs:+10:2: +10:2
+ }
+
+ bb11 (cleanup): {
+ resume; // scope 0 at $DIR/issue-49232.rs:+0:1: +10:2
+ }
+}
diff --git a/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir
new file mode 100644
index 000000000..72603dc5d
--- /dev/null
+++ b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir
@@ -0,0 +1,122 @@
+// MIR for `test` before ElaborateDrops
+
+fn test() -> Option<Box<u32>> {
+ let mut _0: std::option::Option<std::boxed::Box<u32>>; // return place in scope 0 at $DIR/issue-62289.rs:+0:14: +0:30
+ let mut _1: std::boxed::Box<u32>; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
+ let mut _2: usize; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
+ let mut _3: usize; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
+ let mut _4: *mut u8; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
+ let mut _5: std::boxed::Box<u32>; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
+ let mut _6: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>; // in scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/issue-62289.rs:+1:15: +1:19
+ let mut _8: isize; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
+ let _9: std::option::Option<std::convert::Infallible>; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
+ let mut _10: !; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
+ let mut _11: std::option::Option<std::convert::Infallible>; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
+ let _12: u32; // in scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ scope 1 {
+ }
+ scope 2 {
+ debug residual => _9; // in scope 2 at $DIR/issue-62289.rs:+1:19: +1:20
+ scope 3 {
+ }
+ }
+ scope 4 {
+ debug val => _12; // in scope 4 at $DIR/issue-62289.rs:+1:15: +1:20
+ scope 5 {
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
+ _2 = SizeOf(u32); // scope 1 at $DIR/issue-62289.rs:+1:10: +1:21
+ _3 = AlignOf(u32); // scope 1 at $DIR/issue-62289.rs:+1:10: +1:21
+ _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/issue-62289.rs:+1:10: +1:21
+ // mir::Constant
+ // + span: $DIR/issue-62289.rs:9:10: 9:21
+ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
+ _5 = ShallowInitBox(move _4, u32); // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
+ StorageLive(_6); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ StorageLive(_7); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:19
+ _7 = Option::<u32>::None; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:19
+ _6 = <Option<u32> as Try>::branch(move _7) -> [return: bb2, unwind: bb12]; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ // mir::Constant
+ // + span: $DIR/issue-62289.rs:9:15: 9:20
+ // + literal: Const { ty: fn(Option<u32>) -> ControlFlow<<Option<u32> as Try>::Residual, <Option<u32> as Try>::Output> {<Option<u32> as Try>::branch}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_7); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
+ _8 = discriminant(_6); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ switchInt(move _8) -> [0_isize: bb3, 1_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ }
+
+ bb3: {
+ StorageLive(_12); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ _12 = ((_6 as Continue).0: u32); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ (*_5) = _12; // scope 5 at $DIR/issue-62289.rs:+1:15: +1:20
+ StorageDead(_12); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
+ _1 = move _5; // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
+ drop(_5) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21
+ }
+
+ bb4: {
+ unreachable; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ }
+
+ bb5: {
+ StorageLive(_9); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
+ _9 = ((_6 as Break).0: std::option::Option<std::convert::Infallible>); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
+ StorageLive(_11); // scope 3 at $DIR/issue-62289.rs:+1:19: +1:20
+ _11 = _9; // scope 3 at $DIR/issue-62289.rs:+1:19: +1:20
+ _0 = <Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _11) -> [return: bb6, unwind: bb12]; // scope 3 at $DIR/issue-62289.rs:+1:15: +1:20
+ // mir::Constant
+ // + span: $DIR/issue-62289.rs:9:19: 9:20
+ // + literal: Const { ty: fn(Option<Infallible>) -> Option<Box<u32>> {<Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual}, val: Value(<ZST>) }
+ }
+
+ bb6: {
+ StorageDead(_11); // scope 3 at $DIR/issue-62289.rs:+1:19: +1:20
+ StorageDead(_9); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
+ drop(_5) -> bb9; // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21
+ }
+
+ bb7: {
+ StorageDead(_5); // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21
+ _0 = Option::<Box<u32>>::Some(move _1); // scope 0 at $DIR/issue-62289.rs:+1:5: +1:22
+ drop(_1) -> bb8; // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22
+ }
+
+ bb8: {
+ StorageDead(_1); // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22
+ StorageDead(_6); // scope 0 at $DIR/issue-62289.rs:+2:1: +2:2
+ goto -> bb10; // scope 0 at $DIR/issue-62289.rs:+2:2: +2:2
+ }
+
+ bb9: {
+ StorageDead(_5); // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21
+ StorageDead(_1); // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22
+ StorageDead(_6); // scope 0 at $DIR/issue-62289.rs:+2:1: +2:2
+ goto -> bb10; // scope 0 at $DIR/issue-62289.rs:+2:2: +2:2
+ }
+
+ bb10: {
+ return; // scope 0 at $DIR/issue-62289.rs:+2:2: +2:2
+ }
+
+ bb11 (cleanup): {
+ drop(_1) -> bb13; // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22
+ }
+
+ bb12 (cleanup): {
+ drop(_5) -> bb13; // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21
+ }
+
+ bb13 (cleanup): {
+ resume; // scope 0 at $DIR/issue-62289.rs:+0:1: +2:2
+ }
+}
diff --git a/src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir
new file mode 100644
index 000000000..972ce1d50
--- /dev/null
+++ b/src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir
@@ -0,0 +1,17 @@
+// MIR for `bar` 0 mir_map
+
+fn bar(_1: [(Never, u32); 1]) -> u32 {
+ let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:40: +0:43
+ let _2: u32; // in scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
+ scope 1 {
+ debug x => _2; // in scope 1 at $DIR/issue-72181.rs:+0:13: +0:14
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
+ _2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
+ _0 = _2; // scope 1 at $DIR/issue-72181.rs:+0:46: +0:47
+ StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
+ return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
+ }
+}
diff --git a/src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir
new file mode 100644
index 000000000..972ce1d50
--- /dev/null
+++ b/src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir
@@ -0,0 +1,17 @@
+// MIR for `bar` 0 mir_map
+
+fn bar(_1: [(Never, u32); 1]) -> u32 {
+ let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:40: +0:43
+ let _2: u32; // in scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
+ scope 1 {
+ debug x => _2; // in scope 1 at $DIR/issue-72181.rs:+0:13: +0:14
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
+ _2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
+ _0 = _2; // scope 1 at $DIR/issue-72181.rs:+0:46: +0:47
+ StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
+ return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
+ }
+}
diff --git a/src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir
new file mode 100644
index 000000000..534f131ea
--- /dev/null
+++ b/src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir
@@ -0,0 +1,27 @@
+// MIR for `foo` 0 mir_map
+
+fn foo(_1: [(Never, u32); 1]) -> u32 {
+ debug xs => _1; // in scope 0 at $DIR/issue-72181.rs:+0:8: +0:10
+ let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:34: +0:37
+ let _2: usize; // in scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
+ let mut _3: usize; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+ let mut _4: bool; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
+ _2 = const 0_usize; // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
+ _3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+ _4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+ assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+ }
+
+ bb1: {
+ _0 = (_1[_2].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:47
+ StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
+ return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +0:49
+ }
+}
diff --git a/src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir
new file mode 100644
index 000000000..534f131ea
--- /dev/null
+++ b/src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir
@@ -0,0 +1,27 @@
+// MIR for `foo` 0 mir_map
+
+fn foo(_1: [(Never, u32); 1]) -> u32 {
+ debug xs => _1; // in scope 0 at $DIR/issue-72181.rs:+0:8: +0:10
+ let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:34: +0:37
+ let _2: usize; // in scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
+ let mut _3: usize; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+ let mut _4: bool; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
+ _2 = const 0_usize; // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
+ _3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+ _4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+ assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+ }
+
+ bb1: {
+ _0 = (_1[_2].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:47
+ StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
+ return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +0:49
+ }
+}
diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir
new file mode 100644
index 000000000..425906f84
--- /dev/null
+++ b/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir
@@ -0,0 +1,62 @@
+// MIR for `main` 0 mir_map
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-72181.rs:+0:11: +0:11
+ let mut _1: usize; // in scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
+ let mut _3: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:14: +3:27
+ let mut _4: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:29: +3:42
+ let mut _5: u64; // in scope 0 at $DIR/issue-72181.rs:+4:13: +4:30
+ let _6: usize; // in scope 0 at $DIR/issue-72181.rs:+4:24: +4:25
+ let mut _7: usize; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
+ let mut _8: bool; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
+ scope 1 {
+ let _2: [Foo; 2]; // in scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
+ scope 2 {
+ debug f => _2; // in scope 2 at $DIR/issue-72181.rs:+3:9: +3:10
+ scope 3 {
+ }
+ scope 4 {
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
+ _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
+ // mir::Constant
+ // + span: $DIR/issue-72181.rs:24:13: 24:32
+ // + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 0 at $DIR/issue-72181.rs:+1:34: +1:35
+ StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
+ StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
+ _3 = Foo { a: const 42_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
+ StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
+ _4 = Foo { a: const 10_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
+ _2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:+3:13: +3:43
+ StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
+ StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
+ FakeRead(ForLet(None), _2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
+ StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:+4:13: +4:30
+ StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
+ _6 = const 0_usize; // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
+ _7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
+ _8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
+ }
+
+ bb2: {
+ _5 = (_2[_6].0: u64); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:28
+ StorageDead(_6); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
+ StorageDead(_5); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
+ _0 = const (); // scope 0 at $DIR/issue-72181.rs:+0:11: +5:2
+ StorageDead(_2); // scope 1 at $DIR/issue-72181.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/issue-72181.rs:+5:2: +5:2
+ }
+
+ bb3 (cleanup): {
+ resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +5:2
+ }
+}
diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir
new file mode 100644
index 000000000..425906f84
--- /dev/null
+++ b/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir
@@ -0,0 +1,62 @@
+// MIR for `main` 0 mir_map
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-72181.rs:+0:11: +0:11
+ let mut _1: usize; // in scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
+ let mut _3: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:14: +3:27
+ let mut _4: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:29: +3:42
+ let mut _5: u64; // in scope 0 at $DIR/issue-72181.rs:+4:13: +4:30
+ let _6: usize; // in scope 0 at $DIR/issue-72181.rs:+4:24: +4:25
+ let mut _7: usize; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
+ let mut _8: bool; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
+ scope 1 {
+ let _2: [Foo; 2]; // in scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
+ scope 2 {
+ debug f => _2; // in scope 2 at $DIR/issue-72181.rs:+3:9: +3:10
+ scope 3 {
+ }
+ scope 4 {
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
+ _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
+ // mir::Constant
+ // + span: $DIR/issue-72181.rs:24:13: 24:32
+ // + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 0 at $DIR/issue-72181.rs:+1:34: +1:35
+ StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
+ StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
+ _3 = Foo { a: const 42_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
+ StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
+ _4 = Foo { a: const 10_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
+ _2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:+3:13: +3:43
+ StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
+ StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
+ FakeRead(ForLet(None), _2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
+ StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:+4:13: +4:30
+ StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
+ _6 = const 0_usize; // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
+ _7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
+ _8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
+ }
+
+ bb2: {
+ _5 = (_2[_6].0: u64); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:28
+ StorageDead(_6); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
+ StorageDead(_5); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
+ _0 = const (); // scope 0 at $DIR/issue-72181.rs:+0:11: +5:2
+ StorageDead(_2); // scope 1 at $DIR/issue-72181.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/issue-72181.rs:+5:2: +5:2
+ }
+
+ bb3 (cleanup): {
+ resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +5:2
+ }
+}
diff --git a/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir
new file mode 100644
index 000000000..e1a35d88b
--- /dev/null
+++ b/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir
@@ -0,0 +1,29 @@
+// MIR for `f` 0 mir_map
+
+fn f(_1: Void) -> ! {
+ debug v => _1; // in scope 0 at $DIR/issue-72181-1.rs:+0:6: +0:7
+ let mut _0: !; // return place in scope 0 at $DIR/issue-72181-1.rs:+0:18: +0:19
+ let mut _2: !; // in scope 0 at $DIR/issue-72181-1.rs:+0:20: +2:2
+ let mut _3: !; // in scope 0 at $DIR/issue-72181-1.rs:+1:5: +1:15
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:+0:20: +2:2
+ StorageLive(_3); // scope 0 at $DIR/issue-72181-1.rs:+1:5: +1:15
+ FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/issue-72181-1.rs:+1:11: +1:12
+ unreachable; // scope 0 at $DIR/issue-72181-1.rs:+1:11: +1:12
+ }
+
+ bb1: {
+ unreachable; // scope 0 at $DIR/issue-72181-1.rs:+1:5: +1:15
+ }
+
+ bb2: {
+ StorageDead(_3); // scope 0 at $DIR/issue-72181-1.rs:+1:14: +1:15
+ unreachable; // scope 0 at $DIR/issue-72181-1.rs:+0:20: +2:2
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/issue-72181-1.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/issue-72181-1.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir
new file mode 100644
index 000000000..336693337
--- /dev/null
+++ b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir
@@ -0,0 +1,57 @@
+// MIR for `main` 0 mir_map
+
+| User Type Annotations
+| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue-72181-1.rs:16:12: 16:16, inferred_ty: Void
+| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue-72181-1.rs:16:12: 16:16, inferred_ty: Void
+|
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-72181-1.rs:+0:11: +0:11
+ let mut _1: !; // in scope 0 at $DIR/issue-72181-1.rs:+0:11: +6:2
+ let _2: Void as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue-72181-1.rs:+1:9: +1:10
+ let mut _3: (); // in scope 0 at $DIR/issue-72181-1.rs:+2:41: +2:43
+ let _4: !; // in scope 0 at $DIR/issue-72181-1.rs:+5:5: +5:9
+ let mut _5: Void; // in scope 0 at $DIR/issue-72181-1.rs:+5:7: +5:8
+ scope 1 {
+ debug v => _2; // in scope 1 at $DIR/issue-72181-1.rs:+1:9: +1:10
+ }
+ scope 2 {
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:+1:9: +1:10
+ StorageLive(_3); // scope 2 at $DIR/issue-72181-1.rs:+2:41: +2:43
+ _3 = (); // scope 2 at $DIR/issue-72181-1.rs:+2:41: +2:43
+ _2 = transmute::<(), Void>(move _3) -> bb4; // scope 2 at $DIR/issue-72181-1.rs:+2:9: +2:44
+ // mir::Constant
+ // + span: $DIR/issue-72181-1.rs:17:9: 17:40
+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(()) -> Void {transmute::<(), Void>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 2 at $DIR/issue-72181-1.rs:+2:43: +2:44
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-72181-1.rs:+1:9: +1:10
+ AscribeUserType(_2, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue-72181-1.rs:+1:12: +1:16
+ StorageLive(_4); // scope 1 at $DIR/issue-72181-1.rs:+5:5: +5:9
+ StorageLive(_5); // scope 1 at $DIR/issue-72181-1.rs:+5:7: +5:8
+ _5 = move _2; // scope 1 at $DIR/issue-72181-1.rs:+5:7: +5:8
+ _4 = f(move _5) -> bb4; // scope 1 at $DIR/issue-72181-1.rs:+5:5: +5:9
+ // mir::Constant
+ // + span: $DIR/issue-72181-1.rs:20:5: 20:6
+ // + literal: Const { ty: fn(Void) -> ! {f}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_5); // scope 1 at $DIR/issue-72181-1.rs:+5:8: +5:9
+ StorageDead(_4); // scope 1 at $DIR/issue-72181-1.rs:+5:9: +5:10
+ StorageDead(_2); // scope 0 at $DIR/issue-72181-1.rs:+6:1: +6:2
+ unreachable; // scope 0 at $DIR/issue-72181-1.rs:+0:11: +6:2
+ }
+
+ bb3: {
+ return; // scope 0 at $DIR/issue-72181-1.rs:+6:2: +6:2
+ }
+
+ bb4 (cleanup): {
+ resume; // scope 0 at $DIR/issue-72181-1.rs:+0:1: +6:2
+ }
+}
diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff
new file mode 100644
index 000000000..be8e86a83
--- /dev/null
+++ b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff
@@ -0,0 +1,117 @@
+- // MIR for `main` before PreCodegen
++ // MIR for `main` after PreCodegen
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
+ let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ let _3: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+ let mut _5: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _6: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _12: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _14: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _15: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _16: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _17: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _19: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 1 {
+ debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
+ let _4: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
+ scope 3 {
+ debug _prev => _4; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
+ let _8: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _20: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 4 {
+ debug left_val => _8; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ debug right_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _13: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 5 {
+ debug kind => _13; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+ }
+ }
+ }
+ scope 2 {
+ debug v => _3; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
+ StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ StorageLive(_3); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+ _3 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+ _1 = _3; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21
+ StorageDead(_3); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21
+ StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
+ StorageLive(_4); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
+ StorageLive(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _6 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
+ _7 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ (_5.0: &i32) = move _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ (_5.1: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _8 = (_5.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _9 = (_5.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _12 = (*_8); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _11 = Eq(move _12, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _10 = Not(move _11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ switchInt(move _10) -> [false: bb2, otherwise: bb1]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb1: {
+ StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _16 = _8; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _15 = _16; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _18 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _17 = _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ discriminant(_19) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _14 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _15, move _17, move _19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
+ }
+
+ bb2: {
+ StorageDead(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_4); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
+ StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff
new file mode 100644
index 000000000..be8e86a83
--- /dev/null
+++ b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff
@@ -0,0 +1,117 @@
+- // MIR for `main` before PreCodegen
++ // MIR for `main` after PreCodegen
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
+ let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ let _3: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+ let mut _5: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _6: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _12: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _14: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _15: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _16: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _17: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _19: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 1 {
+ debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
+ let _4: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
+ scope 3 {
+ debug _prev => _4; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
+ let _8: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _20: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 4 {
+ debug left_val => _8; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ debug right_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _13: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 5 {
+ debug kind => _13; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+ }
+ }
+ }
+ scope 2 {
+ debug v => _3; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
+ StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ StorageLive(_3); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+ _3 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+ _1 = _3; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21
+ StorageDead(_3); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21
+ StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
+ StorageLive(_4); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
+ StorageLive(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _6 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
+ _7 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ (_5.0: &i32) = move _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ (_5.1: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _8 = (_5.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _9 = (_5.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _12 = (*_8); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _11 = Eq(move _12, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _10 = Not(move _11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ switchInt(move _10) -> [false: bb2, otherwise: bb1]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb1: {
+ StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _16 = _8; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _15 = _16; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _18 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _17 = _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ discriminant(_19) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _14 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _15, move _17, move _19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
+ }
+
+ bb2: {
+ StorageDead(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_4); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
+ StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff
new file mode 100644
index 000000000..50948180f
--- /dev/null
+++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff
@@ -0,0 +1,157 @@
+- // MIR for `main` before SimplifyArmIdentity
++ // MIR for `main` after SimplifyArmIdentity
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
+ let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ let mut _3: isize; // in scope 0 at $DIR/issue-73223.rs:+2:9: +2:16
+ let _4: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+ let mut _5: !; // in scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
+ let mut _7: i32; // in scope 0 at $DIR/issue-73223.rs:+6:22: +6:27
+ let _8: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _9: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _10: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _11: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _12: i32; // in scope 0 at $DIR/issue-73223.rs:+7:23: +7:24
+ let mut _15: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _16: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _17: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _18: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _19: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _21: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _22: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _23: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _24: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _25: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _26: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _27: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 1 {
+ debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
+ let _6: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
+ scope 3 {
+ debug _prev => _6; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
+ let _13: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _14: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _28: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 4 {
+ debug left_val => _13; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ debug right_val => _14; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _20: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 5 {
+ debug kind => _20; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+ }
+ }
+ }
+ scope 2 {
+ debug v => _4; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
+ StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ _3 = const 1_isize; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ goto -> bb2; // scope 0 at $DIR/issue-73223.rs:+1:17: +1:30
+ }
+
+ bb1: {
+ nop; // scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
+ StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
+ StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
+ }
+
+ bb2: {
+ StorageLive(_4); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+ _4 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+ _1 = _4; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21
+ StorageDead(_4); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21
+ StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
+ StorageLive(_6); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
+ StorageLive(_7); // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
+ _7 = _1; // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
+ Deinit(_6); // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
+ ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
+ discriminant(_6) = 1; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
+ StorageDead(_7); // scope 1 at $DIR/issue-73223.rs:+6:27: +6:28
+ StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
+ _11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ (_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ (_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _13 = (_9.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _14 = (_9.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _17 = (*_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _18 = const 1_i32; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _16 = Eq(move _17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _15 = Not(move _16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ switchInt(move _15) -> [false: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb3: {
+ StorageLive(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ discriminant(_20) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _22 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
+ StorageLive(_23); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_24); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _24 = _13; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _23 = _24; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_25); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_26); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _26 = _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _25 = _26; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ discriminant(_27) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _21 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _23, move _25, move _27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
+ }
+
+ bb4: {
+ nop; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ nop; // scope 0 at $DIR/issue-73223.rs:+0:11: +8:2
+ StorageDead(_6); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
+ StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff
new file mode 100644
index 000000000..50948180f
--- /dev/null
+++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff
@@ -0,0 +1,157 @@
+- // MIR for `main` before SimplifyArmIdentity
++ // MIR for `main` after SimplifyArmIdentity
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
+ let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ let mut _3: isize; // in scope 0 at $DIR/issue-73223.rs:+2:9: +2:16
+ let _4: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+ let mut _5: !; // in scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
+ let mut _7: i32; // in scope 0 at $DIR/issue-73223.rs:+6:22: +6:27
+ let _8: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _9: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _10: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _11: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _12: i32; // in scope 0 at $DIR/issue-73223.rs:+7:23: +7:24
+ let mut _15: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _16: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _17: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _18: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _19: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _21: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _22: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _23: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _24: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _25: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _26: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _27: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 1 {
+ debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
+ let _6: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
+ scope 3 {
+ debug _prev => _6; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
+ let _13: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _14: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _28: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 4 {
+ debug left_val => _13; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ debug right_val => _14; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _20: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 5 {
+ debug kind => _20; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+ }
+ }
+ }
+ scope 2 {
+ debug v => _4; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
+ StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ _3 = const 1_isize; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ goto -> bb2; // scope 0 at $DIR/issue-73223.rs:+1:17: +1:30
+ }
+
+ bb1: {
+ nop; // scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
+ StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
+ StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
+ }
+
+ bb2: {
+ StorageLive(_4); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+ _4 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+ _1 = _4; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21
+ StorageDead(_4); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21
+ StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
+ StorageLive(_6); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
+ StorageLive(_7); // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
+ _7 = _1; // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
+ Deinit(_6); // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
+ ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
+ discriminant(_6) = 1; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
+ StorageDead(_7); // scope 1 at $DIR/issue-73223.rs:+6:27: +6:28
+ StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
+ _11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ (_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ (_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _13 = (_9.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _14 = (_9.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _17 = (*_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _18 = const 1_i32; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _16 = Eq(move _17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _15 = Not(move _16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ switchInt(move _15) -> [false: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb3: {
+ StorageLive(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ discriminant(_20) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _22 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
+ StorageLive(_23); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_24); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _24 = _13; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _23 = _24; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_25); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_26); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _26 = _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _25 = _26; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ discriminant(_27) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _21 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _23, move _25, move _27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
+ }
+
+ bb4: {
+ nop; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ nop; // scope 0 at $DIR/issue-73223.rs:+0:11: +8:2
+ StorageDead(_6); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
+ StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/issue_76432.rs b/src/test/mir-opt/issue_76432.rs
new file mode 100644
index 000000000..c8b405ca8
--- /dev/null
+++ b/src/test/mir-opt/issue_76432.rs
@@ -0,0 +1,16 @@
+// Check that we do not insert StorageDead at each target if StorageDead was never seen
+
+// EMIT_MIR issue_76432.test.SimplifyComparisonIntegral.diff
+use std::fmt::Debug;
+
+fn test<T: Copy + Debug + PartialEq>(x: T) {
+ let v: &[T] = &[x, x, x];
+ match v {
+ [ref v1, ref v2, ref v3] => [v1 as *const _, v2 as *const _, v3 as *const _],
+ _ => unreachable!(),
+ };
+}
+
+fn main() {
+ test(0u32);
+}
diff --git a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..2368c021e
--- /dev/null
+++ b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
@@ -0,0 +1,115 @@
+- // MIR for `test` before SimplifyComparisonIntegral
++ // MIR for `test` after SimplifyComparisonIntegral
+
+ fn test(_1: T) -> () {
+ debug x => _1; // in scope 0 at $DIR/issue_76432.rs:+0:38: +0:39
+ let mut _0: (); // return place in scope 0 at $DIR/issue_76432.rs:+0:44: +0:44
+ let _2: &[T]; // in scope 0 at $DIR/issue_76432.rs:+1:9: +1:10
+ let mut _3: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
+ let _4: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
+ let _5: [T; 3]; // in scope 0 at $DIR/issue_76432.rs:+1:20: +1:29
+ let mut _6: T; // in scope 0 at $DIR/issue_76432.rs:+1:21: +1:22
+ let mut _7: T; // in scope 0 at $DIR/issue_76432.rs:+1:24: +1:25
+ let mut _8: T; // in scope 0 at $DIR/issue_76432.rs:+1:27: +1:28
+ let _9: [*const T; 3]; // in scope 0 at $DIR/issue_76432.rs:+2:5: +5:6
+ let mut _10: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33
+ let mut _11: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33
+ let mut _12: bool; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33
+ let mut _16: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:38: +3:52
+ let mut _17: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:38: +3:52
+ let mut _18: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:54: +3:68
+ let mut _19: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:54: +3:68
+ let mut _20: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:70: +3:84
+ let mut _21: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:70: +3:84
+ let mut _22: !; // in scope 0 at $SRC_DIR/core/src/panic.rs:LL:COL
+ let mut _23: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
+ scope 1 {
+ debug v => _2; // in scope 1 at $DIR/issue_76432.rs:+1:9: +1:10
+ let _13: &T; // in scope 1 at $DIR/issue_76432.rs:+3:10: +3:16
+ let _14: &T; // in scope 1 at $DIR/issue_76432.rs:+3:18: +3:24
+ let _15: &T; // in scope 1 at $DIR/issue_76432.rs:+3:26: +3:32
+ scope 2 {
+ debug v1 => _13; // in scope 2 at $DIR/issue_76432.rs:+3:10: +3:16
+ debug v2 => _14; // in scope 2 at $DIR/issue_76432.rs:+3:18: +3:24
+ debug v3 => _15; // in scope 2 at $DIR/issue_76432.rs:+3:26: +3:32
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue_76432.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
+ StorageLive(_4); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
+ StorageLive(_5); // scope 0 at $DIR/issue_76432.rs:+1:20: +1:29
+ StorageLive(_6); // scope 0 at $DIR/issue_76432.rs:+1:21: +1:22
+ _6 = _1; // scope 0 at $DIR/issue_76432.rs:+1:21: +1:22
+ StorageLive(_7); // scope 0 at $DIR/issue_76432.rs:+1:24: +1:25
+ _7 = _1; // scope 0 at $DIR/issue_76432.rs:+1:24: +1:25
+ StorageLive(_8); // scope 0 at $DIR/issue_76432.rs:+1:27: +1:28
+ _8 = _1; // scope 0 at $DIR/issue_76432.rs:+1:27: +1:28
+ _5 = [move _6, move _7, move _8]; // scope 0 at $DIR/issue_76432.rs:+1:20: +1:29
+ StorageDead(_8); // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29
+ StorageDead(_7); // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29
+ StorageDead(_6); // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29
+ _4 = &_5; // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
+ _3 = _4; // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
+ StorageLive(_23); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
+ _23 = _3; // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
+ _2 = move _3 as &[T] (Pointer(Unsize)); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
+ StorageDead(_3); // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29
+ StorageDead(_4); // scope 0 at $DIR/issue_76432.rs:+1:29: +1:30
+ StorageLive(_9); // scope 1 at $DIR/issue_76432.rs:+2:5: +5:6
+ _10 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+ StorageDead(_23); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+ _11 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+ _12 = const true; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+ goto -> bb2; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+ }
+
+ bb1: {
+ StorageLive(_22); // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL
+ _22 = core::panicking::panic(const "internal error: entered unreachable code"); // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/panic.rs:LL:COL
+ // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/panic.rs:LL:COL
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ }
+
+ bb2: {
+ StorageLive(_13); // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16
+ _13 = &(*_2)[0 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16
+ StorageLive(_14); // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24
+ _14 = &(*_2)[1 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24
+ StorageLive(_15); // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32
+ _15 = &(*_2)[2 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32
+ StorageLive(_16); // scope 2 at $DIR/issue_76432.rs:+3:38: +3:52
+ StorageLive(_17); // scope 2 at $DIR/issue_76432.rs:+3:38: +3:52
+ _17 = &raw const (*_13); // scope 2 at $DIR/issue_76432.rs:+3:38: +3:40
+ _16 = _17; // scope 2 at $DIR/issue_76432.rs:+3:38: +3:52
+ StorageLive(_18); // scope 2 at $DIR/issue_76432.rs:+3:54: +3:68
+ StorageLive(_19); // scope 2 at $DIR/issue_76432.rs:+3:54: +3:68
+ _19 = &raw const (*_14); // scope 2 at $DIR/issue_76432.rs:+3:54: +3:56
+ _18 = _19; // scope 2 at $DIR/issue_76432.rs:+3:54: +3:68
+ StorageLive(_20); // scope 2 at $DIR/issue_76432.rs:+3:70: +3:84
+ StorageLive(_21); // scope 2 at $DIR/issue_76432.rs:+3:70: +3:84
+ _21 = &raw const (*_15); // scope 2 at $DIR/issue_76432.rs:+3:70: +3:72
+ _20 = _21; // scope 2 at $DIR/issue_76432.rs:+3:70: +3:84
+ _9 = [move _16, move _18, move _20]; // scope 2 at $DIR/issue_76432.rs:+3:37: +3:85
+ StorageDead(_21); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85
+ StorageDead(_20); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85
+ StorageDead(_19); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85
+ StorageDead(_18); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85
+ StorageDead(_17); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85
+ StorageDead(_16); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85
+ StorageDead(_15); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85
+ 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(_9); // scope 1 at $DIR/issue_76432.rs:+5:6: +5:7
+ nop; // scope 0 at $DIR/issue_76432.rs:+0:44: +6:2
+ 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/src/test/mir-opt/issue_78192.f.InstCombine.diff b/src/test/mir-opt/issue_78192.f.InstCombine.diff
new file mode 100644
index 000000000..8ec94d65f
--- /dev/null
+++ b/src/test/mir-opt/issue_78192.f.InstCombine.diff
@@ -0,0 +1,29 @@
+- // MIR for `f` before InstCombine
++ // MIR for `f` after InstCombine
+
+ fn f(_1: &T) -> *const T {
+ debug a => _1; // in scope 0 at $DIR/issue-78192.rs:+0:13: +0:14
+ let mut _0: *const T; // return place in scope 0 at $DIR/issue-78192.rs:+0:23: +0:31
+ let _2: &*const T; // in scope 0 at $DIR/issue-78192.rs:+1:9: +1:10
+ let _3: &*const T; // in scope 0 at $DIR/issue-78192.rs:+1:24: +1:40
+ let _4: *const T; // in scope 0 at $DIR/issue-78192.rs:+1:25: +1:40
+ scope 1 {
+ debug b => _2; // in scope 1 at $DIR/issue-78192.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-78192.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40
+ StorageLive(_4); // scope 0 at $DIR/issue-78192.rs:+1:25: +1:40
+ _4 = &raw const (*_1); // scope 0 at $DIR/issue-78192.rs:+1:26: +1:27
+ _3 = &_4; // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40
+- _2 = &(*_3); // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40
++ _2 = _3; // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40
+ StorageDead(_3); // scope 0 at $DIR/issue-78192.rs:+1:40: +1:41
+ _0 = (*_2); // scope 1 at $DIR/issue-78192.rs:+2:5: +2:7
+ StorageDead(_4); // scope 0 at $DIR/issue-78192.rs:+3:1: +3:2
+ StorageDead(_2); // scope 0 at $DIR/issue-78192.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/issue-78192.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/issue_99325.main.mir_map.0.mir b/src/test/mir-opt/issue_99325.main.mir_map.0.mir
new file mode 100644
index 000000000..5bca9f0ea
--- /dev/null
+++ b/src/test/mir-opt/issue_99325.main.mir_map.0.mir
@@ -0,0 +1,295 @@
+// MIR for `main` 0 mir_map
+
+| User Type Annotations
+| 0: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 1: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[8f58]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[8f58]::function_with_bytes::BYTES)) }, substs: [], promoted: None }) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+|
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-99325.rs:+0:15: +0:15
+ let _1: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _2: (&&[u8], &&[u8; 4]); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _3: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _4: &[u8]; // in scope 0 at $DIR/issue-99325.rs:+1:16: +1:48
+ let mut _5: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _6: &[u8; 4]; // in scope 0 at $DIR/issue-99325.rs:+1:50: +1:75
+ let _7: [u8; 4]; // in scope 0 at $DIR/issue-99325.rs:+1:51: +1:75
+ let _8: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _9: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _12: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _13: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _14: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _16: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _17: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _18: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _19: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _20: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _21: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _22: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _23: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _24: (&&[u8], &&[u8; 4]); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _25: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _26: &[u8]; // in scope 0 at $DIR/issue-99325.rs:+2:16: +2:70
+ let mut _27: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _28: &[u8; 4]; // in scope 0 at $DIR/issue-99325.rs:+2:72: +2:79
+ let _29: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _30: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _31: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _32: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _33: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _34: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _35: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _37: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _38: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _39: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _40: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _41: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _42: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _43: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 1 {
+ debug left_val => _8; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ debug right_val => _9; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _15: core::panicking::AssertKind; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 2 {
+ debug kind => _15; // in scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+ }
+ scope 3 {
+ debug left_val => _29; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ debug right_val => _30; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _36: core::panicking::AssertKind; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 4 {
+ debug kind => _36; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_4); // scope 0 at $DIR/issue-99325.rs:+1:16: +1:48
+ _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb19]; // scope 0 at $DIR/issue-99325.rs:+1:16: +1:48
+ // mir::Constant
+ // + span: $DIR/issue-99325.rs:10:16: 10:46
+ // + user_ty: UserType(0)
+ // + literal: Const { ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ _3 = &_4; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_5); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_6); // scope 0 at $DIR/issue-99325.rs:+1:50: +1:75
+ StorageLive(_7); // scope 0 at $DIR/issue-99325.rs:+1:51: +1:75
+ _7 = [const 65_u8, const 65_u8, const 65_u8, const 65_u8]; // scope 0 at $DIR/issue-99325.rs:+1:51: +1:75
+ _6 = &_7; // scope 0 at $DIR/issue-99325.rs:+1:50: +1:75
+ _5 = &_6; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _2 = (move _3, move _5); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_5); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ FakeRead(ForMatchedPlace(None), _2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_8); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _8 = (_2.0: &&[u8]); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_9); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _9 = (_2.1: &&[u8; 4]); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_10); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_11); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_12); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _12 = &(*_8); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_13); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _13 = &(*_9); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _11 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _12, move _13) -> [return: bb2, unwind: bb19]; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r, 's> fn(&'r &[u8], &'s &[u8; 4]) -> bool {<&[u8] as PartialEq<&[u8; 4]>>::eq}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_13); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_12); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _10 = Not(move _11); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_11); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ switchInt(move _10) -> [false: bb4, otherwise: bb3]; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb3: {
+ StorageLive(_15); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _15 = core::panicking::AssertKind::Eq; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ FakeRead(ForLet(None), _15); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_16); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_17); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _17 = move _15; // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_18); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_19); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _19 = &(*_8); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _18 = &(*_19); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_20); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_21); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _21 = &(*_9); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _20 = &(*_21); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_22); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _22 = Option::<Arguments>::None; // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _16 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _17, move _18, move _20, move _22) -> bb19; // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r &[u8], &'s &[u8; 4], Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<&[u8], &[u8; 4]>}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ goto -> bb7; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb5: {
+ StorageDead(_22); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_20); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_18); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_17); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_21); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_19); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_16); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_15); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ unreachable; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb6: {
+ goto -> bb8; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb7: {
+ _1 = const (); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ goto -> bb8; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb8: {
+ StorageDead(_10); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_9); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_8); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ goto -> bb9; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb9: {
+ StorageDead(_7); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_6); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_1); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_23); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_24); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_25); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_26); // scope 0 at $DIR/issue-99325.rs:+2:16: +2:70
+ _26 = function_with_bytes::<&*b"AAAA">() -> [return: bb10, unwind: bb19]; // scope 0 at $DIR/issue-99325.rs:+2:16: +2:70
+ // mir::Constant
+ // + span: $DIR/issue-99325.rs:11:16: 11:68
+ // + user_ty: UserType(1)
+ // + literal: Const { ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}, val: Value(<ZST>) }
+ }
+
+ bb10: {
+ _25 = &_26; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_27); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_28); // scope 0 at $DIR/issue-99325.rs:+2:72: +2:79
+ _28 = const b"AAAA"; // scope 0 at $DIR/issue-99325.rs:+2:72: +2:79
+ // mir::Constant
+ // + span: $DIR/issue-99325.rs:11:72: 11:79
+ // + literal: Const { ty: &[u8; 4], val: Value(Scalar(alloc4)) }
+ _27 = &_28; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _24 = (move _25, move _27); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_27); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_25); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ FakeRead(ForMatchedPlace(None), _24); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_29); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _29 = (_24.0: &&[u8]); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_30); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _30 = (_24.1: &&[u8; 4]); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_31); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_33); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _33 = &(*_29); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_34); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _34 = &(*_30); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _32 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _33, move _34) -> [return: bb11, unwind: bb19]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r, 's> fn(&'r &[u8], &'s &[u8; 4]) -> bool {<&[u8] as PartialEq<&[u8; 4]>>::eq}, val: Value(<ZST>) }
+ }
+
+ bb11: {
+ StorageDead(_34); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_33); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _31 = Not(move _32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ switchInt(move _31) -> [false: bb13, otherwise: bb12]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb12: {
+ StorageLive(_36); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _36 = core::panicking::AssertKind::Eq; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ FakeRead(ForLet(None), _36); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_37); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_38); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _38 = move _36; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_39); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_40); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _40 = &(*_29); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _39 = &(*_40); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_41); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_42); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _42 = &(*_30); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _41 = &(*_42); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_43); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _43 = Option::<Arguments>::None; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _37 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _38, move _39, move _41, move _43) -> bb19; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r &[u8], &'s &[u8; 4], Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<&[u8], &[u8; 4]>}, val: Value(<ZST>) }
+ }
+
+ bb13: {
+ goto -> bb16; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb14: {
+ StorageDead(_43); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_41); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_39); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_38); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_42); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_40); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_37); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_36); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ unreachable; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb15: {
+ goto -> bb17; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb16: {
+ _23 = const (); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ goto -> bb17; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb17: {
+ StorageDead(_31); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_30); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_29); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ goto -> bb18; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb18: {
+ StorageDead(_28); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_26); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_24); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_23); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _0 = const (); // scope 0 at $DIR/issue-99325.rs:+0:15: +3:2
+ return; // scope 0 at $DIR/issue-99325.rs:+3:2: +3:2
+ }
+
+ bb19 (cleanup): {
+ resume; // scope 0 at $DIR/issue-99325.rs:+0:1: +3:2
+ }
+}
+
+alloc4 (size: 4, align: 1) {
+ 41 41 41 41 │ AAAA
+}
diff --git a/src/test/mir-opt/issues/issue-59352.rs b/src/test/mir-opt/issues/issue-59352.rs
new file mode 100644
index 000000000..1e0045555
--- /dev/null
+++ b/src/test/mir-opt/issues/issue-59352.rs
@@ -0,0 +1,19 @@
+// This test is a mirror of codegen/issue-59352.rs.
+// The LLVM inliner doesn't inline `char::method::is_digit()` and so it doesn't recognize this case
+// as effectively `if x.is_some() { x.unwrap() } else { 0 }`.
+//
+// Currently, the MIR optimizer isn't capable of removing the unreachable panic in this test case.
+// Once the optimizer can do that, this test case will need to be updated and codegen/issue-59352.rs
+// removed.
+
+// EMIT_MIR issue_59352.num_to_digit.PreCodegen.after.mir
+// compile-flags: -Z mir-opt-level=3 -Z span_free_formats
+
+pub fn num_to_digit(num: char) -> u32 {
+ // CHECK-NOT: panic
+ if num.is_digit(8) { num.to_digit(8).unwrap() } else { 0 }
+}
+
+pub fn main() {
+ num_to_digit('2');
+}
diff --git a/src/test/mir-opt/issues/issue-75439.rs b/src/test/mir-opt/issues/issue-75439.rs
new file mode 100644
index 000000000..ae2e03631
--- /dev/null
+++ b/src/test/mir-opt/issues/issue-75439.rs
@@ -0,0 +1,18 @@
+// EMIT_MIR issue_75439.foo.MatchBranchSimplification.diff
+
+use std::mem::transmute;
+
+pub fn foo(bytes: [u8; 16]) -> Option<[u8; 4]> {
+ // big endian `u32`s
+ let dwords: [u32; 4] = unsafe { transmute(bytes) };
+ const FF: u32 = 0x0000_ffff_u32.to_be();
+ if let [0, 0, 0 | FF, ip] = dwords {
+ Some(unsafe { transmute(ip) })
+ } else {
+ None
+ }
+}
+
+fn main() {
+ let _ = foo([0; 16]);
+}
diff --git a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir
new file mode 100644
index 000000000..86b38d4b7
--- /dev/null
+++ b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir
@@ -0,0 +1,109 @@
+// MIR for `num_to_digit` after PreCodegen
+
+fn num_to_digit(_1: char) -> u32 {
+ debug num => _1; // in scope 0 at $DIR/issue-59352.rs:+0:21: +0:24
+ let mut _0: u32; // return place in scope 0 at $DIR/issue-59352.rs:+0:35: +0:38
+ let mut _2: char; // in scope 0 at $DIR/issue-59352.rs:+2:8: +2:11
+ let mut _3: std::option::Option<u32>; // in scope 0 at $DIR/issue-59352.rs:+2:26: +2:41
+ let mut _4: char; // in scope 0 at $DIR/issue-59352.rs:+2:26: +2:29
+ let mut _5: u32; // in scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
+ let mut _12: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 1 (inlined char::methods::<impl char>::is_digit) { // at $DIR/issue-59352.rs:14:8: 14:23
+ debug self => _2; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ debug radix => _5; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ let mut _6: &std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ let _7: std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ let mut _8: char; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ scope 2 (inlined Option::<u32>::is_some) { // at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ debug self => _6; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL
+ let mut _9: isize; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL
+ }
+ }
+ scope 3 (inlined #[track_caller] Option::<u32>::unwrap) { // at $DIR/issue-59352.rs:14:26: 14:50
+ debug self => _3; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ let mut _10: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ let mut _11: !; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ scope 4 {
+ debug val => _0; // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:11
+ _2 = _1; // scope 0 at $DIR/issue-59352.rs:+2:8: +2:11
+ StorageLive(_5); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
+ StorageLive(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageLive(_7); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageLive(_8); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ _8 = _2; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ _7 = char::methods::<impl char>::to_digit(move _8, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/char/methods.rs:LL:COL
+ // + literal: Const { ty: fn(char, u32) -> Option<u32> {char::methods::<impl char>::to_digit}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_12); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
+ StorageLive(_3); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:41
+ StorageLive(_4); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:29
+ _4 = _1; // scope 0 at $DIR/issue-59352.rs:+2:26: +2:29
+ _3 = char::methods::<impl char>::to_digit(move _4, const 8_u32) -> bb2; // scope 0 at $DIR/issue-59352.rs:+2:26: +2:41
+ // mir::Constant
+ // + span: $DIR/issue-59352.rs:14:30: 14:38
+ // + literal: Const { ty: fn(char, u32) -> Option<u32> {char::methods::<impl char>::to_digit}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_4); // scope 0 at $DIR/issue-59352.rs:+2:40: +2:41
+ StorageLive(_10); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:50
+ _10 = discriminant(_3); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ switchInt(move _10) -> [0_isize: bb6, 1_isize: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ }
+
+ bb3: {
+ StorageDead(_12); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
+ _0 = const 0_u32; // scope 0 at $DIR/issue-59352.rs:+2:60: +2:61
+ goto -> bb4; // scope 0 at $DIR/issue-59352.rs:+2:5: +2:63
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/issue-59352.rs:+3:2: +3:2
+ }
+
+ bb5: {
+ _6 = &_7; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageDead(_8); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageLive(_9); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ _9 = discriminant((*_6)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL
+ StorageLive(_12); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _12 = move _9; // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_9); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageDead(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageDead(_7); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageDead(_5); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
+ StorageDead(_2); // scope 0 at $DIR/issue-59352.rs:+2:22: +2:23
+ switchInt(move _12) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
+ }
+
+ bb6: {
+ StorageLive(_11); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ _11 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value"); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/option.rs:LL:COL
+ // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/option.rs:LL:COL
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ }
+
+ bb7: {
+ unreachable; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ }
+
+ bb8: {
+ _0 = move ((_3 as Some).0: u32); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ StorageDead(_10); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:50
+ StorageDead(_3); // scope 0 at $DIR/issue-59352.rs:+2:49: +2:50
+ goto -> bb4; // scope 0 at $DIR/issue-59352.rs:+2:5: +2:63
+ }
+}
diff --git a/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
new file mode 100644
index 000000000..2ee4332ad
--- /dev/null
+++ b/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
@@ -0,0 +1,89 @@
+- // MIR for `foo` before MatchBranchSimplification
++ // MIR for `foo` after MatchBranchSimplification
+
+ fn foo(_1: [u8; 16]) -> Option<[u8; 4]> {
+ debug bytes => _1; // in scope 0 at $DIR/issue-75439.rs:+0:12: +0:17
+ let mut _0: std::option::Option<[u8; 4]>; // return place in scope 0 at $DIR/issue-75439.rs:+0:32: +0:47
+ let _2: [u32; 4]; // in scope 0 at $DIR/issue-75439.rs:+2:9: +2:15
+ let mut _3: [u8; 16]; // in scope 0 at $DIR/issue-75439.rs:+2:47: +2:52
+ let mut _5: [u8; 4]; // in scope 0 at $DIR/issue-75439.rs:+5:14: +5:38
+ let mut _6: u32; // in scope 0 at $DIR/issue-75439.rs:+5:33: +5:35
+ scope 1 {
+ debug dwords => _2; // in scope 1 at $DIR/issue-75439.rs:+2:9: +2:15
+ scope 3 {
+ debug ip => _4; // in scope 3 at $DIR/issue-75439.rs:+4:27: +4:29
+ let _4: u32; // in scope 3 at $DIR/issue-75439.rs:+4:27: +4:29
+ scope 4 {
+ }
+ }
+ }
+ scope 2 {
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-75439.rs:+2:9: +2:15
+ StorageLive(_3); // scope 2 at $DIR/issue-75439.rs:+2:47: +2:52
+ _3 = _1; // scope 2 at $DIR/issue-75439.rs:+2:47: +2:52
+ _2 = transmute::<[u8; 16], [u32; 4]>(move _3) -> bb1; // scope 2 at $DIR/issue-75439.rs:+2:37: +2:53
+ // mir::Constant
+ // + span: $DIR/issue-75439.rs:7:37: 7:46
+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn([u8; 16]) -> [u32; 4] {transmute::<[u8; 16], [u32; 4]>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 2 at $DIR/issue-75439.rs:+2:52: +2:53
+ switchInt(_2[0 of 4]) -> [0_u32: bb2, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30
+ }
+
+ bb2: {
+ switchInt(_2[1 of 4]) -> [0_u32: bb3, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30
+ }
+
+ bb3: {
+ switchInt(_2[2 of 4]) -> [0_u32: bb5, 4294901760_u32: bb6, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30
+ }
+
+ bb4: {
+ StorageLive(_5); // scope 3 at $DIR/issue-75439.rs:+5:14: +5:38
+ StorageLive(_6); // scope 4 at $DIR/issue-75439.rs:+5:33: +5:35
+ _6 = _4; // scope 4 at $DIR/issue-75439.rs:+5:33: +5:35
+ _5 = transmute::<u32, [u8; 4]>(move _6) -> bb7; // scope 4 at $DIR/issue-75439.rs:+5:23: +5:36
+ // mir::Constant
+ // + span: $DIR/issue-75439.rs:10:23: 10:32
+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u32) -> [u8; 4] {transmute::<u32, [u8; 4]>}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ StorageLive(_4); // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29
+ _4 = _2[3 of 4]; // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29
+ goto -> bb4; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30
+ }
+
+ bb6: {
+ StorageLive(_4); // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29
+ _4 = _2[3 of 4]; // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29
+ goto -> bb4; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30
+ }
+
+ bb7: {
+ StorageDead(_6); // scope 4 at $DIR/issue-75439.rs:+5:35: +5:36
+ Deinit(_0); // scope 3 at $DIR/issue-75439.rs:+5:9: +5:39
+ ((_0 as Some).0: [u8; 4]) = move _5; // scope 3 at $DIR/issue-75439.rs:+5:9: +5:39
+ discriminant(_0) = 1; // scope 3 at $DIR/issue-75439.rs:+5:9: +5:39
+ StorageDead(_5); // scope 3 at $DIR/issue-75439.rs:+5:38: +5:39
+ StorageDead(_4); // scope 1 at $DIR/issue-75439.rs:+6:5: +6:6
+ goto -> bb9; // scope 1 at $DIR/issue-75439.rs:+4:5: +8:6
+ }
+
+ bb8: {
+ Deinit(_0); // scope 1 at $DIR/issue-75439.rs:+7:9: +7:13
+ discriminant(_0) = 0; // scope 1 at $DIR/issue-75439.rs:+7:9: +7:13
+ goto -> bb9; // scope 1 at $DIR/issue-75439.rs:+4:5: +8:6
+ }
+
+ bb9: {
+ StorageDead(_2); // scope 0 at $DIR/issue-75439.rs:+9:1: +9:2
+ return; // scope 0 at $DIR/issue-75439.rs:+9:2: +9:2
+ }
+ }
+
diff --git a/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir
new file mode 100644
index 000000000..5981ab885
--- /dev/null
+++ b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir
@@ -0,0 +1,52 @@
+// MIR for `main` after SimplifyCfg-promote-consts
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/loop_test.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/loop_test.rs:+4:5: +6:6
+ let mut _2: bool; // in scope 0 at $DIR/loop_test.rs:+4:8: +4:12
+ let mut _3: !; // in scope 0 at $DIR/loop_test.rs:+4:13: +6:6
+ let mut _4: !; // in scope 0 at $DIR/loop_test.rs:+7:5: +10:6
+ let mut _5: (); // in scope 0 at $DIR/loop_test.rs:+0:1: +11:2
+ let _6: i32; // in scope 0 at $DIR/loop_test.rs:+8:13: +8:14
+ scope 1 {
+ debug x => _6; // in scope 1 at $DIR/loop_test.rs:+8:13: +8:14
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/loop_test.rs:+4:5: +6:6
+ StorageLive(_2); // scope 0 at $DIR/loop_test.rs:+4:8: +4:12
+ _2 = const true; // scope 0 at $DIR/loop_test.rs:+4:8: +4:12
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/loop_test.rs:+4:8: +4:12
+ }
+
+ bb1: {
+ _0 = const (); // scope 0 at $DIR/loop_test.rs:+5:9: +5:15
+ StorageDead(_2); // scope 0 at $DIR/loop_test.rs:+6:5: +6:6
+ StorageDead(_1); // scope 0 at $DIR/loop_test.rs:+6:5: +6:6
+ return; // scope 0 at $DIR/loop_test.rs:+11:2: +11:2
+ }
+
+ bb2: {
+ _1 = const (); // scope 0 at $DIR/loop_test.rs:+6:6: +6:6
+ StorageDead(_2); // scope 0 at $DIR/loop_test.rs:+6:5: +6:6
+ StorageDead(_1); // scope 0 at $DIR/loop_test.rs:+6:5: +6:6
+ StorageLive(_4); // scope 0 at $DIR/loop_test.rs:+7:5: +10:6
+ goto -> bb3; // scope 0 at $DIR/loop_test.rs:+7:5: +10:6
+ }
+
+ bb3: {
+ falseUnwind -> [real: bb4, cleanup: bb5]; // scope 0 at $DIR/loop_test.rs:+7:5: +10:6
+ }
+
+ bb4: {
+ StorageLive(_6); // scope 0 at $DIR/loop_test.rs:+8:13: +8:14
+ _6 = const 1_i32; // scope 0 at $DIR/loop_test.rs:+8:17: +8:18
+ FakeRead(ForLet(None), _6); // scope 0 at $DIR/loop_test.rs:+8:13: +8:14
+ StorageDead(_6); // scope 0 at $DIR/loop_test.rs:+10:5: +10:6
+ goto -> bb3; // scope 0 at no-location
+ }
+
+ bb5 (cleanup): {
+ resume; // scope 0 at $DIR/loop_test.rs:+0:1: +11:2
+ }
+}
diff --git a/src/test/mir-opt/loop_test.rs b/src/test/mir-opt/loop_test.rs
new file mode 100644
index 000000000..7ded5b575
--- /dev/null
+++ b/src/test/mir-opt/loop_test.rs
@@ -0,0 +1,17 @@
+// compile-flags: -Z identify_regions
+
+// Tests to make sure we correctly generate falseUnwind edges in loops
+
+// EMIT_MIR loop_test.main.SimplifyCfg-promote-consts.after.mir
+fn main() {
+ // Exit early at runtime. Since only care about the generated MIR
+ // and not the runtime behavior (which is exercised by other tests)
+ // we just bail early. Without this the test just loops infinitely.
+ if true {
+ return;
+ }
+ loop {
+ let x = 1;
+ continue;
+ }
+}
diff --git a/src/test/mir-opt/lower_array_len.array_bound.InstCombine.diff b/src/test/mir-opt/lower_array_len.array_bound.InstCombine.diff
new file mode 100644
index 000000000..2589c9f28
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.array_bound.InstCombine.diff
@@ -0,0 +1,66 @@
+- // MIR for `array_bound` before InstCombine
++ // MIR for `array_bound` after InstCombine
+
+ fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
+ debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:36: +0:41
+ debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:50: +0:55
+ let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:70: +0:72
+ let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ _7 = _2; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ _11 = _7; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
+- _5 = Len((*_11)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ }
+
+ bb1: {
+ StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+- _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ }
+
+ bb2: {
+ _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
+ goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
+ }
+
+ bb3: {
+ _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:11
+ goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
+ }
+
+ bb4: {
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+5:5: +5:6
+ return; // scope 0 at $DIR/lower_array_len.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff
new file mode 100644
index 000000000..049bbeac8
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff
@@ -0,0 +1,68 @@
+- // MIR for `array_bound` before NormalizeArrayLen
++ // MIR for `array_bound` after NormalizeArrayLen
+
+ fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
+ debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:36: +0:41
+ debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:50: +0:55
+ let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:70: +0:72
+ let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ _11 = _7; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
+- _5 = Len((*_6)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ _5 = Len((*_11)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ }
+
+ bb1: {
+ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ switchInt(move _3) -> [false: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ }
+
+ bb2: {
+ StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb3; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ }
+
+ bb3: {
+ _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
+ goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
+ }
+
+ bb4: {
+ _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:11
+ goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
+ }
+
+ bb5: {
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+5:5: +5:6
+ return; // scope 0 at $DIR/lower_array_len.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_array_len.array_bound.SimplifyLocals.diff b/src/test/mir-opt/lower_array_len.array_bound.SimplifyLocals.diff
new file mode 100644
index 000000000..8312db6b3
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.array_bound.SimplifyLocals.diff
@@ -0,0 +1,70 @@
+- // MIR for `array_bound` before SimplifyLocals
++ // MIR for `array_bound` after SimplifyLocals
+
+ fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
+ debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:36: +0:41
+ debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:50: +0:55
+ let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:70: +0:72
+ let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+- let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+- let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+- let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ let _6: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
++ let mut _7: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ let mut _8: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
+ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ }
+
+ bb1: {
+- StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+- _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+- _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+- _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
++ _6 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
++ _7 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ }
+
+ bb2: {
+- _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+- StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
++ _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
+ goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
+ }
+
+ bb3: {
+ _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:11
+ goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
+ }
+
+ bb4: {
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+5:5: +5:6
+ return; // scope 0 at $DIR/lower_array_len.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_array_len.array_bound_mut.InstCombine.diff b/src/test/mir-opt/lower_array_len.array_bound_mut.InstCombine.diff
new file mode 100644
index 000000000..401d4bac6
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.array_bound_mut.InstCombine.diff
@@ -0,0 +1,79 @@
+- // MIR for `array_bound_mut` before InstCombine
++ // MIR for `array_bound_mut` after InstCombine
+
+ fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
+ debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:40: +0:45
+ debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:54: +0:59
+ let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:78: +0:80
+ let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
+ let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ _14 = _7; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
+- _5 = Len((*_14)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ }
+
+ bb1: {
+ StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+- _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ }
+
+ bb2: {
+ _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
+ goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
+ }
+
+ bb3: {
+ StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
+ _11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
+- _12 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
++ _12 = const N; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ _13 = Lt(_11, _12); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> bb4; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ }
+
+ bb4: {
+ (*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22
+ StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23
+ _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+6:9: +6:11
+ goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
+ }
+
+ bb5: {
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+7:5: +7:6
+ return; // scope 0 at $DIR/lower_array_len.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff
new file mode 100644
index 000000000..40ec01eeb
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff
@@ -0,0 +1,81 @@
+- // MIR for `array_bound_mut` before NormalizeArrayLen
++ // MIR for `array_bound_mut` after NormalizeArrayLen
+
+ fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
+ debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:40: +0:45
+ debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:54: +0:59
+ let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:78: +0:80
+ let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
+ let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
++ let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ _14 = _7; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
+- _5 = Len((*_6)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ _5 = Len((*_14)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ }
+
+ bb1: {
+ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ switchInt(move _3) -> [false: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ }
+
+ bb2: {
+ StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb3; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ }
+
+ bb3: {
+ _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
+ goto -> bb6; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
+ }
+
+ bb4: {
+ StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
+ _11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
+ _12 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ _13 = Lt(_11, _12); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> bb5; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ }
+
+ bb5: {
+ (*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22
+ StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23
+ _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+6:9: +6:11
+ goto -> bb6; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
+ }
+
+ bb6: {
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+7:5: +7:6
+ return; // scope 0 at $DIR/lower_array_len.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_array_len.array_bound_mut.SimplifyLocals.diff b/src/test/mir-opt/lower_array_len.array_bound_mut.SimplifyLocals.diff
new file mode 100644
index 000000000..4f241d7c9
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.array_bound_mut.SimplifyLocals.diff
@@ -0,0 +1,93 @@
+- // MIR for `array_bound_mut` before SimplifyLocals
++ // MIR for `array_bound_mut` after SimplifyLocals
+
+ fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
+ debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:40: +0:45
+ debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:54: +0:59
+ let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:78: +0:80
+ let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+- let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+- let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+- let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
+- let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+- let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+- let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
++ let _6: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
++ let mut _7: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ let mut _8: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ let _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
++ let mut _10: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
++ let mut _11: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
+ StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
+ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+- StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
+ switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
+ }
+
+ bb1: {
+- StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+- _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+- _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+- _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
++ _6 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
++ _7 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ }
+
+ bb2: {
+- _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+- StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
++ _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
++ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
+ goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
+ }
+
+ bb3: {
+- StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
+- _11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
+- _12 = const N; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+- _13 = Lt(const 0_usize, _12); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
++ StorageLive(_9); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
++ _9 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
++ _10 = const N; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
++ _11 = Lt(const 0_usize, _10); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
++ assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ }
+
+ bb4: {
+- (*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22
+- StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23
++ (*_2)[_9] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22
++ StorageDead(_9); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23
+ _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+6:9: +6:11
+ goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
+ }
+
+ bb5: {
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+7:5: +7:6
+ return; // scope 0 at $DIR/lower_array_len.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_array_len.array_len.InstCombine.diff b/src/test/mir-opt/lower_array_len.array_len.InstCombine.diff
new file mode 100644
index 000000000..26f45be17
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.array_len.InstCombine.diff
@@ -0,0 +1,27 @@
+- // MIR for `array_len` before InstCombine
++ // MIR for `array_len` after InstCombine
+
+ fn array_len(_1: &[u8; N]) -> usize {
+ debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:34: +0:37
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:52: +0:57
+ let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- _3 = &(*_1); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ _3 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ _4 = _3; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
+- _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
+ return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff
new file mode 100644
index 000000000..3ed68f5f7
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff
@@ -0,0 +1,30 @@
+- // MIR for `array_len` before NormalizeArrayLen
++ // MIR for `array_len` after NormalizeArrayLen
+
+ fn array_len(_1: &[u8; N]) -> usize {
+ debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:34: +0:37
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:52: +0:57
+ let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ _3 = &(*_1); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ _4 = _3; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
+- _0 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
+ return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_array_len.array_len.SimplifyLocals.diff b/src/test/mir-opt/lower_array_len.array_len.SimplifyLocals.diff
new file mode 100644
index 000000000..09d571d20
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.array_len.SimplifyLocals.diff
@@ -0,0 +1,22 @@
+- // MIR for `array_len` before SimplifyLocals
++ // MIR for `array_len` after SimplifyLocals
+
+ fn array_len(_1: &[u8; N]) -> usize {
+ debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:34: +0:37
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:52: +0:57
+- let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+
+ bb0: {
+- StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
+ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
+ return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_array_len.array_len_by_value.InstCombine.diff b/src/test/mir-opt/lower_array_len.array_len_by_value.InstCombine.diff
new file mode 100644
index 000000000..843da758d
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.array_len_by_value.InstCombine.diff
@@ -0,0 +1,26 @@
+- // MIR for `array_len_by_value` before InstCombine
++ // MIR for `array_len_by_value` after InstCombine
+
+ fn array_len_by_value(_1: [u8; N]) -> usize {
+ debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:43: +0:46
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:60: +0:65
+ let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ _3 = &_1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ _4 = _3; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
+- _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
+ return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff
new file mode 100644
index 000000000..f0e0cdcfd
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff
@@ -0,0 +1,30 @@
+- // MIR for `array_len_by_value` before NormalizeArrayLen
++ // MIR for `array_len_by_value` after NormalizeArrayLen
+
+ fn array_len_by_value(_1: [u8; N]) -> usize {
+ debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:43: +0:46
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:60: +0:65
+ let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ _3 = &_1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ _4 = _3; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
+- _0 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
++ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
+ return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_array_len.array_len_by_value.SimplifyLocals.diff b/src/test/mir-opt/lower_array_len.array_len_by_value.SimplifyLocals.diff
new file mode 100644
index 000000000..dc1c00b69
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.array_len_by_value.SimplifyLocals.diff
@@ -0,0 +1,22 @@
+- // MIR for `array_len_by_value` before SimplifyLocals
++ // MIR for `array_len_by_value` after SimplifyLocals
+
+ fn array_len_by_value(_1: [u8; N]) -> usize {
+ debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:43: +0:46
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:60: +0:65
+- let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+
+ bb0: {
+- StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
+ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+- StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
+ return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_array_len.rs b/src/test/mir-opt/lower_array_len.rs
new file mode 100644
index 000000000..fc12ee75f
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len.rs
@@ -0,0 +1,47 @@
+// compile-flags: -Z mir-opt-level=4
+
+// EMIT_MIR lower_array_len.array_bound.NormalizeArrayLen.diff
+// EMIT_MIR lower_array_len.array_bound.SimplifyLocals.diff
+// EMIT_MIR lower_array_len.array_bound.InstCombine.diff
+pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 {
+ if index < slice.len() {
+ slice[index]
+ } else {
+ 42
+ }
+}
+
+// EMIT_MIR lower_array_len.array_bound_mut.NormalizeArrayLen.diff
+// EMIT_MIR lower_array_len.array_bound_mut.SimplifyLocals.diff
+// EMIT_MIR lower_array_len.array_bound_mut.InstCombine.diff
+pub fn array_bound_mut<const N: usize>(index: usize, slice: &mut [u8; N]) -> u8 {
+ if index < slice.len() {
+ slice[index]
+ } else {
+ slice[0] = 42;
+
+ 42
+ }
+}
+
+// EMIT_MIR lower_array_len.array_len.NormalizeArrayLen.diff
+// EMIT_MIR lower_array_len.array_len.SimplifyLocals.diff
+// EMIT_MIR lower_array_len.array_len.InstCombine.diff
+pub fn array_len<const N: usize>(arr: &[u8; N]) -> usize {
+ arr.len()
+}
+
+// EMIT_MIR lower_array_len.array_len_by_value.NormalizeArrayLen.diff
+// EMIT_MIR lower_array_len.array_len_by_value.SimplifyLocals.diff
+// EMIT_MIR lower_array_len.array_len_by_value.InstCombine.diff
+pub fn array_len_by_value<const N: usize>(arr: [u8; N]) -> usize {
+ arr.len()
+}
+
+fn main() {
+ let _ = array_bound(3, &[0, 1, 2, 3]);
+ let mut tmp = [0, 1, 2, 3, 4];
+ let _ = array_bound_mut(3, &mut [0, 1, 2, 3]);
+ let _ = array_len(&[0]);
+ let _ = array_len_by_value([0, 2]);
+}
diff --git a/src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff
new file mode 100644
index 000000000..5c635e222
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff
@@ -0,0 +1,20 @@
+- // MIR for `align_of` before LowerIntrinsics
++ // MIR for `align_of` after LowerIntrinsics
+
+ fn align_of() -> usize {
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:25: +0:30
+
+ bb0: {
+- _0 = std::intrinsics::min_align_of::<T>() -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:19:5: 19:40
+- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::min_align_of::<T>}, val: Value(<ZST>) }
++ _0 = AlignOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42
++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42
+ }
+
+ bb1: {
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
new file mode 100644
index 000000000..8a80de32f
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
@@ -0,0 +1,115 @@
+- // MIR for `discriminant` before LowerIntrinsics
++ // MIR for `discriminant` after LowerIntrinsics
+
+ fn discriminant(_1: T) -> () {
+ debug t => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:24: +0:25
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:30: +0:30
+ let _2: <T as std::marker::DiscriminantKind>::Discriminant; // in scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45
+ let mut _3: &T; // in scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44
+ let _4: &T; // in scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44
+ let _5: u8; // in scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
+ let mut _6: &i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
+ let _7: &i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
+ let _8: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:43: +2:44
+ let _9: u8; // in scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
+ let mut _10: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
+ let _11: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
+ let _12: (); // in scope 0 at $DIR/lower_intrinsics.rs:+3:43: +3:45
+ let _13: isize; // in scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
+ let mut _14: &E; // in scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
+ let _15: &E; // in scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
+ let _16: E; // in scope 0 at $DIR/lower_intrinsics.rs:+4:43: +4:47
+ let mut _17: &E; // in scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
+ let mut _18: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
+ let mut _19: &i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45
+ StorageLive(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44
+ StorageLive(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44
+ _4 = &_1; // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44
+ _3 = &(*_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44
+- _2 = discriminant_value::<T>(move _3) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:74:5: 74:41
+- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r T) -> <T as DiscriminantKind>::Discriminant {discriminant_value::<T>}, val: Value(<ZST>) }
++ _2 = discriminant((*_3)); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45
++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:44: +1:45
+ StorageDead(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46
+ StorageDead(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46
+ StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
+ StorageLive(_6); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
+ StorageLive(_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
+ _19 = const discriminant::<T>::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
+ // mir::Constant
+ // + span: $DIR/lower_intrinsics.rs:75:42: 75:44
+ // + literal: Const { ty: &i32, val: Unevaluated(discriminant, [T], Some(promoted[2])) }
+ _7 = &(*_19); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
+ _6 = &(*_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
+- _5 = discriminant_value::<i32>(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:75:5: 75:41
+- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r i32) -> <i32 as DiscriminantKind>::Discriminant {discriminant_value::<i32>}, val: Value(<ZST>) }
++ _5 = discriminant((*_6)); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
++ goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
+ }
+
+ bb2: {
+ StorageDead(_6); // scope 0 at $DIR/lower_intrinsics.rs:+2:44: +2:45
+ StorageDead(_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:45: +2:46
+ StorageDead(_5); // scope 0 at $DIR/lower_intrinsics.rs:+2:45: +2:46
+ StorageLive(_9); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
+ StorageLive(_10); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
+ StorageLive(_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
+ _18 = const discriminant::<T>::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
+ // mir::Constant
+ // + span: $DIR/lower_intrinsics.rs:76:42: 76:45
+ // + literal: Const { ty: &(), val: Unevaluated(discriminant, [T], Some(promoted[1])) }
+ _11 = &(*_18); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
+ _10 = &(*_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
+- _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:76:5: 76:41
+- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r ()) -> <() as DiscriminantKind>::Discriminant {discriminant_value::<()>}, val: Value(<ZST>) }
++ _9 = discriminant((*_10)); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
++ goto -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
+ }
+
+ bb3: {
+ StorageDead(_10); // scope 0 at $DIR/lower_intrinsics.rs:+3:45: +3:46
+ StorageDead(_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:46: +3:47
+ StorageDead(_9); // scope 0 at $DIR/lower_intrinsics.rs:+3:46: +3:47
+ StorageLive(_13); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
+ StorageLive(_14); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
+ StorageLive(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
+ _17 = const discriminant::<T>::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
+ // mir::Constant
+ // + span: $DIR/lower_intrinsics.rs:77:42: 77:47
+ // + literal: Const { ty: &E, val: Unevaluated(discriminant, [T], Some(promoted[0])) }
+ _15 = &(*_17); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
+ _14 = &(*_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
+- _13 = discriminant_value::<E>(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:77:5: 77:41
+- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r E) -> <E as DiscriminantKind>::Discriminant {discriminant_value::<E>}, val: Value(<ZST>) }
++ _13 = discriminant((*_14)); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
++ goto -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
+ }
+
+ bb4: {
+ StorageDead(_14); // scope 0 at $DIR/lower_intrinsics.rs:+4:47: +4:48
+ StorageDead(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:48: +4:49
+ StorageDead(_13); // scope 0 at $DIR/lower_intrinsics.rs:+4:48: +4:49
+ _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+0:30: +5:2
+ drop(_1) -> bb5; // scope 0 at $DIR/lower_intrinsics.rs:+5:1: +5:2
+ }
+
+ bb5: {
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir b/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir
new file mode 100644
index 000000000..9e4de2ac0
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir
@@ -0,0 +1,32 @@
+// MIR for `f_u64` before PreCodegen
+
+fn f_u64() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:16: +0:16
+ let mut _1: u64; // in scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21
+ scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics.rs:40:5: 40:21
+ debug t => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+5:22: +5:23
+ let _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:+9:9: +9:21
+ let mut _3: u64; // in scope 1 at $DIR/lower_intrinsics.rs:+9:19: +9:20
+ scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics.rs:45:8: 45:32
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21
+ _1 = const 0_u64; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21
+ StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+9:9: +9:21
+ StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+9:19: +9:20
+ _3 = move _1; // scope 1 at $DIR/lower_intrinsics.rs:+9:19: +9:20
+ _2 = f_non_zst::<u64>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+9:9: +9:21
+ // mir::Constant
+ // + span: $DIR/lower_intrinsics.rs:48:9: 48:18
+ // + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:+9:20: +9:21
+ StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+9:21: +9:22
+ StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/lower_intrinsics.f_unit.PreCodegen.before.mir b/src/test/mir-opt/lower_intrinsics.f_unit.PreCodegen.before.mir
new file mode 100644
index 000000000..9a6c0457f
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.f_unit.PreCodegen.before.mir
@@ -0,0 +1,30 @@
+// MIR for `f_unit` before PreCodegen
+
+fn f_unit() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:17
+ let mut _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:16: +1:18
+ scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics.rs:34:5: 34:19
+ debug t => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+11:22: +11:23
+ let _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:+13:9: +13:17
+ let mut _3: (); // in scope 1 at $DIR/lower_intrinsics.rs:+13:15: +13:16
+ scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics.rs:45:8: 45:32
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:16: +1:18
+ StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+13:9: +13:17
+ StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+13:15: +13:16
+ _2 = f_zst::<()>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+13:9: +13:17
+ // mir::Constant
+ // + span: $DIR/lower_intrinsics.rs:46:9: 46:14
+ // + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:+13:16: +13:17
+ StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+13:17: +13:18
+ StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:18: +1:19
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff
new file mode 100644
index 000000000..e6a2f6512
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff
@@ -0,0 +1,29 @@
+- // MIR for `forget` before LowerIntrinsics
++ // MIR for `forget` after LowerIntrinsics
+
+ fn forget(_1: T) -> () {
+ debug t => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:18: +0:19
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:24: +0:24
+ let mut _2: T; // in scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31
+ _2 = move _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31
+- _0 = std::intrinsics::forget::<T>(move _2) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:24:5: 24:29
+- // + literal: Const { ty: extern "rust-intrinsic" fn(T) {std::intrinsics::forget::<T>}, val: Value(<ZST>) }
++ _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32
++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:31: +1:32
+ goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:1: +2:2
+ }
+
+ bb2: {
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff
new file mode 100644
index 000000000..1ab2f2a0a
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff
@@ -0,0 +1,31 @@
+- // MIR for `non_const` before LowerIntrinsics
++ // MIR for `non_const` after LowerIntrinsics
+
+ fn non_const() -> usize {
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:26: +0:31
+ let _1: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}; // in scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:18
+ let mut _2: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}; // in scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:14
+ scope 1 {
+ debug size_of_t => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:18
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:18
+ _1 = std::intrinsics::size_of::<T>; // scope 0 at $DIR/lower_intrinsics.rs:+2:21: +2:51
+ // mir::Constant
+ // + span: $DIR/lower_intrinsics.rs:62:21: 62:51
+ // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}, val: Value(<ZST>) }
+ StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14
+ _2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14
+- _0 = move _2() -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:16
++ _0 = SizeOf(T); // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:16
++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:16
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+3:15: +3:16
+ StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_intrinsics.rs b/src/test/mir-opt/lower_intrinsics.rs
new file mode 100644
index 000000000..eab51b65f
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.rs
@@ -0,0 +1,78 @@
+// compile-flags: -Cpanic=abort
+#![feature(core_intrinsics)]
+#![crate_type = "lib"]
+
+// EMIT_MIR lower_intrinsics.wrapping.LowerIntrinsics.diff
+pub fn wrapping(a: i32, b: i32) {
+ let _x = core::intrinsics::wrapping_add(a, b);
+ let _y = core::intrinsics::wrapping_sub(a, b);
+ let _z = core::intrinsics::wrapping_mul(a, b);
+}
+
+// EMIT_MIR lower_intrinsics.size_of.LowerIntrinsics.diff
+pub fn size_of<T>() -> usize {
+ core::intrinsics::size_of::<T>()
+}
+
+// EMIT_MIR lower_intrinsics.align_of.LowerIntrinsics.diff
+pub fn align_of<T>() -> usize {
+ core::intrinsics::min_align_of::<T>()
+}
+
+// EMIT_MIR lower_intrinsics.forget.LowerIntrinsics.diff
+pub fn forget<T>(t: T) {
+ core::intrinsics::forget(t)
+}
+
+// EMIT_MIR lower_intrinsics.unreachable.LowerIntrinsics.diff
+pub fn unreachable() -> ! {
+ unsafe { core::intrinsics::unreachable() };
+}
+
+// EMIT_MIR lower_intrinsics.f_unit.PreCodegen.before.mir
+pub fn f_unit() {
+ f_dispatch(());
+}
+
+
+// EMIT_MIR lower_intrinsics.f_u64.PreCodegen.before.mir
+pub fn f_u64() {
+ f_dispatch(0u64);
+}
+
+#[inline(always)]
+pub fn f_dispatch<T>(t: T) {
+ if std::mem::size_of::<T>() == 0 {
+ f_zst(t);
+ } else {
+ f_non_zst(t);
+ }
+}
+
+#[inline(never)]
+pub fn f_zst<T>(_t: T) {
+}
+
+#[inline(never)]
+pub fn f_non_zst<T>(_t: T) {}
+
+// EMIT_MIR lower_intrinsics.non_const.LowerIntrinsics.diff
+pub fn non_const<T>() -> usize {
+ // Check that lowering works with non-const operand as a func.
+ let size_of_t = core::intrinsics::size_of::<T>;
+ size_of_t()
+}
+
+pub enum E {
+ A,
+ B,
+ C,
+}
+
+// EMIT_MIR lower_intrinsics.discriminant.LowerIntrinsics.diff
+pub fn discriminant<T>(t: T) {
+ core::intrinsics::discriminant_value(&t);
+ core::intrinsics::discriminant_value(&0);
+ core::intrinsics::discriminant_value(&());
+ core::intrinsics::discriminant_value(&E::B);
+}
diff --git a/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff
new file mode 100644
index 000000000..11b27976b
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff
@@ -0,0 +1,20 @@
+- // MIR for `size_of` before LowerIntrinsics
++ // MIR for `size_of` after LowerIntrinsics
+
+ fn size_of() -> usize {
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:24: +0:29
+
+ bb0: {
+- _0 = std::intrinsics::size_of::<T>() -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:14:5: 14:35
+- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}, val: Value(<ZST>) }
++ _0 = SizeOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37
++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37
+ }
+
+ bb1: {
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
new file mode 100644
index 000000000..ac077e85b
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
@@ -0,0 +1,22 @@
+- // MIR for `unreachable` before LowerIntrinsics
++ // MIR for `unreachable` after LowerIntrinsics
+
+ fn unreachable() -> ! {
+ let mut _0: !; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:25: +0:26
+ let mut _1: !; // in scope 0 at $DIR/lower_intrinsics.rs:+0:27: +2:2
+ let _2: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:45
+ let mut _3: !; // in scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:45
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:47
+ StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
+- _3 = std::intrinsics::unreachable(); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:29:14: 29:43
+- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value(<ZST>) }
++ unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff
new file mode 100644
index 000000000..e0a5416b2
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff
@@ -0,0 +1,83 @@
+- // MIR for `wrapping` before LowerIntrinsics
++ // MIR for `wrapping` after LowerIntrinsics
+
+ fn wrapping(_1: i32, _2: i32) -> () {
+ debug a => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:18
+ debug b => _2; // in scope 0 at $DIR/lower_intrinsics.rs:+0:25: +0:26
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:33: +0:33
+ let _3: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:11
+ let mut _4: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46
+ let mut _5: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49
+ let mut _7: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:45: +2:46
+ let mut _8: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:48: +2:49
+ let mut _10: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+3:45: +3:46
+ let mut _11: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+3:48: +3:49
+ scope 1 {
+ debug _x => _3; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:11
+ let _6: i32; // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11
+ scope 2 {
+ debug _y => _6; // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:11
+ let _9: i32; // in scope 2 at $DIR/lower_intrinsics.rs:+3:9: +3:11
+ scope 3 {
+ debug _z => _9; // in scope 3 at $DIR/lower_intrinsics.rs:+3:9: +3:11
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:11
+ StorageLive(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46
+ _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) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:7:14: 7:44
+- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_add::<i32>}, val: Value(<ZST>) }
++ _3 = Add(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
+ }
+
+ bb1: {
+ StorageDead(_5); // scope 0 at $DIR/lower_intrinsics.rs:+1:49: +1:50
+ StorageDead(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:49: +1:50
+ StorageLive(_6); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11
+ StorageLive(_7); // scope 1 at $DIR/lower_intrinsics.rs:+2:45: +2:46
+ _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) -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:8:14: 8:44
+- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_sub::<i32>}, val: Value(<ZST>) }
++ _6 = Sub(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
++ goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
+ }
+
+ bb2: {
+ StorageDead(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:49: +2:50
+ StorageDead(_7); // scope 1 at $DIR/lower_intrinsics.rs:+2:49: +2:50
+ StorageLive(_9); // scope 2 at $DIR/lower_intrinsics.rs:+3:9: +3:11
+ StorageLive(_10); // scope 2 at $DIR/lower_intrinsics.rs:+3:45: +3:46
+ _10 = _1; // scope 2 at $DIR/lower_intrinsics.rs:+3:45: +3:46
+ StorageLive(_11); // scope 2 at $DIR/lower_intrinsics.rs:+3:48: +3:49
+ _11 = _2; // scope 2 at $DIR/lower_intrinsics.rs:+3:48: +3:49
+- _9 = wrapping_mul::<i32>(move _10, move _11) -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:9:14: 9:44
+- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_mul::<i32>}, val: Value(<ZST>) }
++ _9 = Mul(move _10, move _11); // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50
++ goto -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50
+ }
+
+ bb3: {
+ StorageDead(_11); // scope 2 at $DIR/lower_intrinsics.rs:+3:49: +3:50
+ StorageDead(_10); // scope 2 at $DIR/lower_intrinsics.rs:+3:49: +3:50
+ _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+0:33: +4:2
+ StorageDead(_9); // scope 2 at $DIR/lower_intrinsics.rs:+4:1: +4:2
+ StorageDead(_6); // scope 1 at $DIR/lower_intrinsics.rs:+4:1: +4:2
+ StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff b/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff
new file mode 100644
index 000000000..46fccba56
--- /dev/null
+++ b/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff
@@ -0,0 +1,63 @@
+- // MIR for `bound` before LowerSliceLenCalls
++ // MIR for `bound` after LowerSliceLenCalls
+
+ fn bound(_1: usize, _2: &[u8]) -> u8 {
+ debug index => _1; // in scope 0 at $DIR/lower_slice_len.rs:+0:14: +0:19
+ debug slice => _2; // in scope 0 at $DIR/lower_slice_len.rs:+0:28: +0:33
+ let mut _0: u8; // return place in scope 0 at $DIR/lower_slice_len.rs:+0:45: +0:47
+ let mut _3: bool; // in scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27
+ let mut _4: usize; // in scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:13
+ let mut _5: usize; // in scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27
+ let mut _6: &[u8]; // in scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27
+ let _7: usize; // in scope 0 at $DIR/lower_slice_len.rs:+2:15: +2:20
+ let mut _8: usize; // in scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21
+ let mut _9: bool; // in scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27
+ StorageLive(_4); // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:13
+ _4 = _1; // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:13
+ StorageLive(_5); // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27
+ StorageLive(_6); // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27
+ _6 = &(*_2); // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27
+- _5 = core::slice::<impl [u8]>::len(move _6) -> bb1; // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27
+- // mir::Constant
+- // + span: $DIR/lower_slice_len.rs:5:22: 5:25
+- // + literal: Const { ty: for<'r> fn(&'r [u8]) -> usize {core::slice::<impl [u8]>::len}, val: Value(<ZST>) }
++ _5 = Len((*_6)); // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27
++ goto -> bb1; // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27
+ }
+
+ bb1: {
+ StorageDead(_6); // scope 0 at $DIR/lower_slice_len.rs:+1:26: +1:27
+ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27
+ StorageDead(_5); // scope 0 at $DIR/lower_slice_len.rs:+1:26: +1:27
+ StorageDead(_4); // scope 0 at $DIR/lower_slice_len.rs:+1:26: +1:27
+ switchInt(move _3) -> [false: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27
+ }
+
+ bb2: {
+ StorageLive(_7); // scope 0 at $DIR/lower_slice_len.rs:+2:15: +2:20
+ _7 = _1; // scope 0 at $DIR/lower_slice_len.rs:+2:15: +2:20
+ _8 = Len((*_2)); // scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21
+ _9 = Lt(_7, _8); // scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb3; // scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21
+ }
+
+ bb3: {
+ _0 = (*_2)[_7]; // scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21
+ StorageDead(_7); // scope 0 at $DIR/lower_slice_len.rs:+3:5: +3:6
+ goto -> bb5; // scope 0 at $DIR/lower_slice_len.rs:+1:5: +5:6
+ }
+
+ bb4: {
+ _0 = const 42_u8; // scope 0 at $DIR/lower_slice_len.rs:+4:9: +4:11
+ goto -> bb5; // scope 0 at $DIR/lower_slice_len.rs:+1:5: +5:6
+ }
+
+ bb5: {
+ StorageDead(_3); // scope 0 at $DIR/lower_slice_len.rs:+5:5: +5:6
+ return; // scope 0 at $DIR/lower_slice_len.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_slice_len.rs b/src/test/mir-opt/lower_slice_len.rs
new file mode 100644
index 000000000..12955aed1
--- /dev/null
+++ b/src/test/mir-opt/lower_slice_len.rs
@@ -0,0 +1,14 @@
+// unit-test: LowerSliceLenCalls
+
+// EMIT_MIR lower_slice_len.bound.LowerSliceLenCalls.diff
+pub fn bound(index: usize, slice: &[u8]) -> u8 {
+ if index < slice.len() {
+ slice[index]
+ } else {
+ 42
+ }
+}
+
+fn main() {
+ let _ = bound(1, &[1, 2, 3]);
+}
diff --git a/src/test/mir-opt/match-arm-scopes.rs b/src/test/mir-opt/match-arm-scopes.rs
new file mode 100644
index 000000000..7b7de7788
--- /dev/null
+++ b/src/test/mir-opt/match-arm-scopes.rs
@@ -0,0 +1,35 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+// Test that StorageDead and Drops are generated properly for bindings in
+// matches:
+// * The MIR should only contain a single drop of `s` and `t`: at the end
+// of their respective arms.
+// * StorageDead and StorageLive statements are correctly matched up on
+// non-unwind paths.
+// * The visibility scopes of the match arms should be disjoint, and contain.
+// all of the bindings for that scope.
+// * No drop flags are used.
+
+// EMIT_MIR match_arm_scopes.complicated_match SimplifyCfg-initial.after ElaborateDrops.after
+fn complicated_match(cond: bool, items: (bool, bool, String)) -> i32 {
+ match items {
+ (false, a, s) | (a, false, s) if if cond { return 3 } else { a } => 1,
+ (true, b, t) | (false, b, t) => 2,
+ }
+}
+
+const CASES: &[(bool, bool, bool, i32)] = &[
+ (false, false, false, 2),
+ (false, false, true, 1),
+ (false, true, false, 1),
+ (false, true, true, 2),
+ (true, false, false, 3),
+ (true, false, true, 3),
+ (true, true, false, 3),
+ (true, true, true, 2),
+];
+
+fn main() {
+ for &(cond, items_1, items_2, result) in CASES {
+ assert_eq!(complicated_match(cond, (items_1, items_2, String::new())), result,);
+ }
+}
diff --git a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff
new file mode 100644
index 000000000..25ab0c9f7
--- /dev/null
+++ b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -0,0 +1,272 @@
+- // MIR for `complicated_match` after SimplifyCfg-initial
++ // MIR for `complicated_match` after ElaborateDrops
+
+ fn complicated_match(_1: bool, _2: (bool, bool, String)) -> i32 {
+ debug cond => _1; // in scope 0 at $DIR/match-arm-scopes.rs:+0:22: +0:26
+ debug items => _2; // in scope 0 at $DIR/match-arm-scopes.rs:+0:34: +0:39
+ let mut _0: i32; // return place in scope 0 at $DIR/match-arm-scopes.rs:+0:66: +0:69
+ let mut _3: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
+ let mut _4: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
+ let _5: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18
+ let _6: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18
+ let _7: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21
+ let _8: &std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21
+ let mut _9: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
+ let mut _10: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
+ let mut _11: !; // in scope 0 at $DIR/match-arm-scopes.rs:+2:52: +2:60
+ let mut _12: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
+ let mut _13: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
+ let mut _14: !; // in scope 0 at $DIR/match-arm-scopes.rs:+2:52: +2:60
+ let _15: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+3:16: +3:17
+ let _16: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:+3:19: +3:20
+ scope 1 {
+ debug a => _5; // in scope 1 at $DIR/match-arm-scopes.rs:+2:17: +2:18
+ debug a => _6; // in scope 1 at $DIR/match-arm-scopes.rs:+2:17: +2:18
+ debug s => _7; // in scope 1 at $DIR/match-arm-scopes.rs:+2:20: +2:21
+ debug s => _8; // in scope 1 at $DIR/match-arm-scopes.rs:+2:20: +2:21
+ }
+ scope 2 {
+ debug b => _15; // in scope 2 at $DIR/match-arm-scopes.rs:+3:16: +3:17
+ debug t => _16; // in scope 2 at $DIR/match-arm-scopes.rs:+3:19: +3:20
+ }
+
+ bb0: {
+- FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
+- switchInt((_2.0: bool)) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16
++ switchInt((_2.0: bool)) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16
+ }
+
+ bb1: {
+- falseEdge -> [real: bb8, imaginary: bb3]; // scope 0 at $DIR/match-arm-scopes.rs:+2:9: +2:22
++ switchInt((_2.1: bool)) -> [false: bb10, otherwise: bb2]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16
+ }
+
+ bb2: {
+- switchInt((_2.1: bool)) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16
++ switchInt((_2.0: bool)) -> [false: bb3, otherwise: bb17]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16
+ }
+
+ bb3: {
+- falseEdge -> [real: bb13, imaginary: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:+2:25: +2:38
+- }
+-
+- bb4: {
+- switchInt((_2.0: bool)) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16
+- }
+-
+- bb5: {
+- falseEdge -> [real: bb20, imaginary: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:+3:9: +3:21
+- }
+-
+- bb6: {
+ StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:+3:32: +3:33
+ _15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+3:32: +3:33
+ StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:+3:35: +3:36
+ _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+3:35: +3:36
+- goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
++ goto -> bb16; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
+ }
+
+- bb7: {
++ bb4: {
+ _0 = const 1_i32; // scope 1 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+- drop(_7) -> [return: bb18, unwind: bb25]; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
++ drop(_7) -> [return: bb15, unwind: bb22]; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+ }
+
+- bb8: {
++ bb5: {
+ StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18
+ _6 = &(_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18
+ StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21
+ _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21
+- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
+- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
+ StorageLive(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
+ StorageLive(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
+ _10 = _1; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
+- switchInt(move _10) -> [false: bb10, otherwise: bb9]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
++ switchInt(move _10) -> [false: bb7, otherwise: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
+ }
+
+- bb9: {
++ bb6: {
+ _0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:+2:59: +2:60
+ StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+ StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+- goto -> bb23; // scope 0 at no-location
++ goto -> bb20; // scope 0 at no-location
+ }
+
+- bb10: {
++ bb7: {
+ _9 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:70: +2:71
+- switchInt(move _9) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
++ switchInt(move _9) -> [false: bb9, otherwise: bb8]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
+ }
+
+- bb11: {
++ bb8: {
+ StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+ StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+ StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18
+ _5 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18
+ StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21
+ _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21
+- goto -> bb7; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
++ goto -> bb4; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
+ }
+
+- bb12: {
++ bb9: {
+ StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+ StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+ StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+ StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+- falseEdge -> [real: bb2, imaginary: bb3]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
++ goto -> bb1; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
+ }
+
+- bb13: {
++ bb10: {
+ StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27
+ _6 = &(_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27
+ StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37
+ _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37
+- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
+- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
+ StorageLive(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
+ StorageLive(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
+ _13 = _1; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
+- switchInt(move _13) -> [false: bb15, otherwise: bb14]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
++ switchInt(move _13) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
+ }
+
+- bb14: {
++ bb11: {
+ _0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:+2:59: +2:60
+ StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+ StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+- goto -> bb23; // scope 0 at no-location
++ goto -> bb20; // scope 0 at no-location
+ }
+
+- bb15: {
++ bb12: {
+ _12 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:70: +2:71
+- switchInt(move _12) -> [false: bb17, otherwise: bb16]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
++ switchInt(move _12) -> [false: bb14, otherwise: bb13]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
+ }
+
+- bb16: {
++ bb13: {
+ StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+ StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+ StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27
+ _5 = (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27
+ StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37
+ _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37
+- goto -> bb7; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
++ goto -> bb4; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
+ }
+
+- bb17: {
++ bb14: {
+ StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+ StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+ StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+ StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+- falseEdge -> [real: bb4, imaginary: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
++ goto -> bb2; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
+ }
+
+- bb18: {
++ bb15: {
+ StorageDead(_7); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+ StorageDead(_5); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+ StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+ StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+- goto -> bb22; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
++ goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+ }
+
+- bb19: {
++ bb16: {
+ _0 = const 2_i32; // scope 2 at $DIR/match-arm-scopes.rs:+3:41: +3:42
+- drop(_16) -> [return: bb21, unwind: bb25]; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42
++ drop(_16) -> [return: bb18, unwind: bb22]; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42
+ }
+
+- bb20: {
++ bb17: {
+ StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:+3:16: +3:17
+ _15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+3:16: +3:17
+ StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:+3:19: +3:20
+ _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+3:19: +3:20
+- goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
++ goto -> bb16; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
+ }
+
+- bb21: {
++ bb18: {
+ StorageDead(_16); // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42
+ StorageDead(_15); // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42
+- goto -> bb22; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42
++ goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42
+ }
+
+- bb22: {
+- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
++ bb19: {
++ goto -> bb26; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
+ }
+
+- bb23: {
++ bb20: {
+ StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+ StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
++ drop(_2) -> [return: bb21, unwind: bb23]; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
+ }
+
+- bb24: {
++ bb21: {
+ return; // scope 0 at $DIR/match-arm-scopes.rs:+5:2: +5:2
+ }
+
+- bb25 (cleanup): {
+- drop(_2) -> bb26; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
++ bb22 (cleanup): {
++ goto -> bb27; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
+ }
+
+- bb26 (cleanup): {
++ bb23 (cleanup): {
+ resume; // scope 0 at $DIR/match-arm-scopes.rs:+0:1: +5:2
++ }
++
++ bb24: {
++ goto -> bb21; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
++ }
++
++ bb25 (cleanup): {
++ goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
++ }
++
++ bb26: {
++ goto -> bb24; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
++ }
++
++ bb27 (cleanup): {
++ goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir
new file mode 100644
index 000000000..c05ed00f7
--- /dev/null
+++ b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir
@@ -0,0 +1,113 @@
+// MIR for `full_tested_match` after PromoteTemps
+
+fn full_tested_match() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:+0:28: +0:28
+ let mut _1: (i32, i32); // in scope 0 at $DIR/match_false_edges.rs:+1:13: +5:6
+ let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ let mut _3: isize; // in scope 0 at $DIR/match_false_edges.rs:+2:9: +2:16
+ let mut _4: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ let _5: i32; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ let _6: &i32; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ let mut _7: bool; // in scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ let mut _8: i32; // in scope 0 at $DIR/match_false_edges.rs:+2:35: +2:36
+ let _9: i32; // in scope 0 at $DIR/match_false_edges.rs:+3:14: +3:15
+ let mut _10: i32; // in scope 0 at $DIR/match_false_edges.rs:+3:24: +3:25
+ let mut _11: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ scope 1 {
+ }
+ scope 2 {
+ debug x => _5; // in scope 2 at $DIR/match_false_edges.rs:+2:14: +2:15
+ debug x => _6; // in scope 2 at $DIR/match_false_edges.rs:+2:14: +2:15
+ }
+ scope 3 {
+ debug y => _9; // in scope 3 at $DIR/match_false_edges.rs:+3:14: +3:15
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:+1:13: +5:6
+ StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ _2 = Option::<i32>::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ _3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ switchInt(move _3) -> [0_isize: bb1, 1_isize: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:27
+ }
+
+ bb1: {
+ _1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:+4:17: +4:23
+ goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+4:17: +4:23
+ }
+
+ bb2: {
+ falseEdge -> [real: bb5, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+2:9: +2:16
+ }
+
+ bb3: {
+ falseEdge -> [real: bb9, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:16
+ }
+
+ bb4: {
+ unreachable; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ }
+
+ bb5: {
+ StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ _11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ // mir::Constant
+ // + span: $DIR/match_false_edges.rs:14:14: 14:15
+ // + literal: Const { ty: &Option<i32>, val: Unevaluated(full_tested_match, [], Some(promoted[0])) }
+ _6 = &(((*_11) as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ _4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ _7 = guard() -> [return: bb6, unwind: bb11]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ // mir::Constant
+ // + span: $DIR/match_false_edges.rs:14:20: 14:25
+ // + literal: Const { ty: fn() -> bool {guard}, val: Value(<ZST>) }
+ }
+
+ bb6: {
+ switchInt(move _7) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ }
+
+ bb7: {
+ StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27
+ FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27
+ FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27
+ StorageLive(_5); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ _5 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ StorageLive(_8); // scope 2 at $DIR/match_false_edges.rs:+2:35: +2:36
+ _8 = _5; // scope 2 at $DIR/match_false_edges.rs:+2:35: +2:36
+ _1 = (const 1_i32, move _8); // scope 2 at $DIR/match_false_edges.rs:+2:31: +2:37
+ StorageDead(_8); // scope 2 at $DIR/match_false_edges.rs:+2:36: +2:37
+ StorageDead(_5); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+ StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+ goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+ }
+
+ bb8: {
+ StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27
+ StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+ goto -> bb3; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ }
+
+ bb9: {
+ StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:+3:14: +3:15
+ _9 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+3:14: +3:15
+ StorageLive(_10); // scope 3 at $DIR/match_false_edges.rs:+3:24: +3:25
+ _10 = _9; // scope 3 at $DIR/match_false_edges.rs:+3:24: +3:25
+ _1 = (const 2_i32, move _10); // scope 3 at $DIR/match_false_edges.rs:+3:20: +3:26
+ StorageDead(_10); // scope 3 at $DIR/match_false_edges.rs:+3:25: +3:26
+ StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:+3:25: +3:26
+ goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+3:25: +3:26
+ }
+
+ bb10: {
+ StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7
+ StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7
+ _0 = const (); // scope 0 at $DIR/match_false_edges.rs:+0:28: +6:2
+ return; // scope 0 at $DIR/match_false_edges.rs:+6:2: +6:2
+ }
+
+ bb11 (cleanup): {
+ resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +6:2
+ }
+}
diff --git a/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir b/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir
new file mode 100644
index 000000000..145ed878f
--- /dev/null
+++ b/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir
@@ -0,0 +1,108 @@
+// MIR for `full_tested_match2` before PromoteTemps
+
+fn full_tested_match2() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:+0:29: +0:29
+ let mut _1: (i32, i32); // in scope 0 at $DIR/match_false_edges.rs:+1:13: +5:6
+ let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ let mut _3: isize; // in scope 0 at $DIR/match_false_edges.rs:+2:9: +2:16
+ let mut _4: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ let _5: i32; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ let _6: &i32; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ let mut _7: bool; // in scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ let mut _8: i32; // in scope 0 at $DIR/match_false_edges.rs:+2:35: +2:36
+ let _9: i32; // in scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
+ let mut _10: i32; // in scope 0 at $DIR/match_false_edges.rs:+4:24: +4:25
+ scope 1 {
+ }
+ scope 2 {
+ debug x => _5; // in scope 2 at $DIR/match_false_edges.rs:+2:14: +2:15
+ debug x => _6; // in scope 2 at $DIR/match_false_edges.rs:+2:14: +2:15
+ }
+ scope 3 {
+ debug y => _9; // in scope 3 at $DIR/match_false_edges.rs:+4:14: +4:15
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:+1:13: +5:6
+ StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ _2 = Option::<i32>::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ _3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ switchInt(move _3) -> [0_isize: bb1, 1_isize: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:27
+ }
+
+ bb1: {
+ falseEdge -> [real: bb9, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:13
+ }
+
+ bb2: {
+ falseEdge -> [real: bb5, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:9: +2:16
+ }
+
+ bb3: {
+ StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
+ _9 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
+ StorageLive(_10); // scope 3 at $DIR/match_false_edges.rs:+4:24: +4:25
+ _10 = _9; // scope 3 at $DIR/match_false_edges.rs:+4:24: +4:25
+ _1 = (const 2_i32, move _10); // scope 3 at $DIR/match_false_edges.rs:+4:20: +4:26
+ StorageDead(_10); // scope 3 at $DIR/match_false_edges.rs:+4:25: +4:26
+ StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:+4:25: +4:26
+ goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+4:25: +4:26
+ }
+
+ bb4: {
+ unreachable; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ }
+
+ bb5: {
+ StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ _6 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ _4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
+ StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ _7 = guard() -> [return: bb6, unwind: bb11]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ // mir::Constant
+ // + span: $DIR/match_false_edges.rs:25:20: 25:25
+ // + literal: Const { ty: fn() -> bool {guard}, val: Value(<ZST>) }
+ }
+
+ bb6: {
+ switchInt(move _7) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ }
+
+ bb7: {
+ StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27
+ FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27
+ FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27
+ StorageLive(_5); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ _5 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ StorageLive(_8); // scope 2 at $DIR/match_false_edges.rs:+2:35: +2:36
+ _8 = _5; // scope 2 at $DIR/match_false_edges.rs:+2:35: +2:36
+ _1 = (const 1_i32, move _8); // scope 2 at $DIR/match_false_edges.rs:+2:31: +2:37
+ StorageDead(_8); // scope 2 at $DIR/match_false_edges.rs:+2:36: +2:37
+ StorageDead(_5); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+ StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+ goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+ }
+
+ bb8: {
+ StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27
+ StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+ falseEdge -> [real: bb3, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ }
+
+ bb9: {
+ _1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23
+ goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23
+ }
+
+ bb10: {
+ StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7
+ StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7
+ _0 = const (); // scope 0 at $DIR/match_false_edges.rs:+0:29: +6:2
+ return; // scope 0 at $DIR/match_false_edges.rs:+6:2: +6:2
+ }
+
+ bb11 (cleanup): {
+ resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +6:2
+ }
+}
diff --git a/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir b/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir
new file mode 100644
index 000000000..8f40e8a88
--- /dev/null
+++ b/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir
@@ -0,0 +1,153 @@
+// MIR for `main` before PromoteTemps
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/match_false_edges.rs:+1:13: +6:6
+ let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
+ let mut _3: isize; // in scope 0 at $DIR/match_false_edges.rs:+4:9: +4:16
+ let mut _4: isize; // in scope 0 at $DIR/match_false_edges.rs:+2:9: +2:17
+ let mut _5: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
+ let _6: i32; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16
+ let _7: &i32; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16
+ let mut _8: bool; // in scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+ let _9: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
+ let _10: i32; // in scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
+ let _11: &i32; // in scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
+ let mut _12: bool; // in scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+ let mut _13: i32; // in scope 0 at $DIR/match_false_edges.rs:+4:27: +4:28
+ let _14: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+5:9: +5:11
+ scope 1 {
+ }
+ scope 2 {
+ debug _w => _6; // in scope 2 at $DIR/match_false_edges.rs:+2:14: +2:16
+ debug _w => _7; // in scope 2 at $DIR/match_false_edges.rs:+2:14: +2:16
+ }
+ scope 3 {
+ debug _x => _9; // in scope 3 at $DIR/match_false_edges.rs:+3:9: +3:11
+ }
+ scope 4 {
+ debug y => _10; // in scope 4 at $DIR/match_false_edges.rs:+4:14: +4:15
+ debug y => _11; // in scope 4 at $DIR/match_false_edges.rs:+4:14: +4:15
+ }
+ scope 5 {
+ debug _z => _14; // in scope 5 at $DIR/match_false_edges.rs:+5:9: +5:11
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:+1:13: +6:6
+ StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
+ _2 = Option::<i32>::Some(const 1_i32); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
+ FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
+ _4 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
+ switchInt(move _4) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26
+ }
+
+ bb1: {
+ falseEdge -> [real: bb9, imaginary: bb4]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
+ }
+
+ bb2: {
+ falseEdge -> [real: bb5, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:9: +2:17
+ }
+
+ bb3: {
+ StorageLive(_14); // scope 0 at $DIR/match_false_edges.rs:+5:9: +5:11
+ _14 = _2; // scope 0 at $DIR/match_false_edges.rs:+5:9: +5:11
+ _1 = const 4_i32; // scope 5 at $DIR/match_false_edges.rs:+5:15: +5:16
+ StorageDead(_14); // scope 0 at $DIR/match_false_edges.rs:+5:15: +5:16
+ goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:+5:15: +5:16
+ }
+
+ bb4: {
+ falseEdge -> [real: bb10, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+4:9: +4:16
+ }
+
+ bb5: {
+ StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16
+ _7 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16
+ _5 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
+ StorageLive(_8); // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+ _8 = guard() -> [return: bb6, unwind: bb15]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+ // mir::Constant
+ // + span: $DIR/match_false_edges.rs:34:21: 34:26
+ // + literal: Const { ty: fn() -> bool {guard}, val: Value(<ZST>) }
+ }
+
+ bb6: {
+ switchInt(move _8) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+ }
+
+ bb7: {
+ StorageDead(_8); // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28
+ FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28
+ FakeRead(ForGuardBinding, _7); // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28
+ StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16
+ _6 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16
+ _1 = const 1_i32; // scope 2 at $DIR/match_false_edges.rs:+2:32: +2:33
+ StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
+ StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
+ goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
+ }
+
+ bb8: {
+ StorageDead(_8); // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28
+ StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
+ falseEdge -> [real: bb1, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+ }
+
+ bb9: {
+ StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
+ _9 = _2; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
+ _1 = const 2_i32; // scope 3 at $DIR/match_false_edges.rs:+3:15: +3:16
+ StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:+3:15: +3:16
+ goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:+3:15: +3:16
+ }
+
+ bb10: {
+ StorageLive(_11); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
+ _11 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
+ _5 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
+ StorageLive(_12); // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+ StorageLive(_13); // scope 0 at $DIR/match_false_edges.rs:+4:27: +4:28
+ _13 = (*_11); // scope 0 at $DIR/match_false_edges.rs:+4:27: +4:28
+ _12 = guard2(move _13) -> [return: bb11, unwind: bb15]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+ // mir::Constant
+ // + span: $DIR/match_false_edges.rs:36:20: 36:26
+ // + literal: Const { ty: fn(i32) -> bool {guard2}, val: Value(<ZST>) }
+ }
+
+ bb11: {
+ switchInt(move _12) -> [false: bb13, otherwise: bb12]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+ }
+
+ bb12: {
+ StorageDead(_13); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
+ StorageDead(_12); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
+ FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
+ FakeRead(ForGuardBinding, _11); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
+ StorageLive(_10); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
+ _10 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
+ _1 = const 3_i32; // scope 4 at $DIR/match_false_edges.rs:+4:33: +4:34
+ StorageDead(_10); // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
+ StorageDead(_11); // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
+ goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
+ }
+
+ bb13: {
+ StorageDead(_13); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
+ StorageDead(_12); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
+ StorageDead(_11); // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
+ falseEdge -> [real: bb3, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+ }
+
+ bb14: {
+ StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:+6:6: +6:7
+ StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:+6:6: +6:7
+ _0 = const (); // scope 0 at $DIR/match_false_edges.rs:+0:11: +7:2
+ return; // scope 0 at $DIR/match_false_edges.rs:+7:2: +7:2
+ }
+
+ bb15 (cleanup): {
+ resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +7:2
+ }
+}
diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs
new file mode 100644
index 000000000..3603253da
--- /dev/null
+++ b/src/test/mir-opt/match_false_edges.rs
@@ -0,0 +1,39 @@
+fn guard() -> bool {
+ false
+}
+
+fn guard2(_: i32) -> bool {
+ true
+}
+
+// no_mangle to make sure this gets instantiated even in an executable.
+#[no_mangle]
+// EMIT_MIR match_false_edges.full_tested_match.PromoteTemps.after.mir
+pub fn full_tested_match() {
+ let _ = match Some(42) {
+ Some(x) if guard() => (1, x),
+ Some(y) => (2, y),
+ None => (3, 3),
+ };
+}
+
+// no_mangle to make sure this gets instantiated even in an executable.
+#[no_mangle]
+// EMIT_MIR match_false_edges.full_tested_match2.PromoteTemps.before.mir
+pub fn full_tested_match2() {
+ let _ = match Some(42) {
+ Some(x) if guard() => (1, x),
+ None => (3, 3),
+ Some(y) => (2, y),
+ };
+}
+
+// EMIT_MIR match_false_edges.main.PromoteTemps.before.mir
+fn main() {
+ let _ = match Some(1) {
+ Some(_w) if guard() => 1,
+ _x => 2,
+ Some(y) if guard2(y) => 3,
+ _z => 4,
+ };
+}
diff --git a/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir
new file mode 100644
index 000000000..b184ffc40
--- /dev/null
+++ b/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir
@@ -0,0 +1,106 @@
+// MIR for `main` after SimplifyCfg-initial
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/match_test.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/match_test.rs:+1:9: +1:10
+ let _3: i32; // in scope 0 at $DIR/match_test.rs:+6:5: +11:6
+ let mut _4: bool; // in scope 0 at $DIR/match_test.rs:+8:9: +8:16
+ let mut _5: bool; // in scope 0 at $DIR/match_test.rs:+8:9: +8:16
+ let mut _6: bool; // in scope 0 at $DIR/match_test.rs:+7:9: +7:14
+ let mut _7: bool; // in scope 0 at $DIR/match_test.rs:+7:9: +7:14
+ let mut _8: &i32; // in scope 0 at $DIR/match_test.rs:+6:11: +6:12
+ let mut _9: bool; // in scope 0 at $DIR/match_test.rs:+7:18: +7:19
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/match_test.rs:+1:9: +1:10
+ let _2: bool; // in scope 1 at $DIR/match_test.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _2; // in scope 2 at $DIR/match_test.rs:+2:9: +2:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/match_test.rs:+1:9: +1:10
+ _1 = const 3_i32; // scope 0 at $DIR/match_test.rs:+1:13: +1:14
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/match_test.rs:+1:9: +1:10
+ StorageLive(_2); // scope 1 at $DIR/match_test.rs:+2:9: +2:10
+ _2 = const true; // scope 1 at $DIR/match_test.rs:+2:13: +2:17
+ FakeRead(ForLet(None), _2); // scope 1 at $DIR/match_test.rs:+2:9: +2:10
+ StorageLive(_3); // scope 2 at $DIR/match_test.rs:+6:5: +11:6
+ FakeRead(ForMatchedPlace(None), _1); // scope 2 at $DIR/match_test.rs:+6:11: +6:12
+ _6 = Le(const 0_i32, _1); // scope 2 at $DIR/match_test.rs:+7:9: +7:14
+ switchInt(move _6) -> [false: bb4, otherwise: bb1]; // scope 2 at $DIR/match_test.rs:+7:9: +7:14
+ }
+
+ bb1: {
+ _7 = Lt(_1, const 10_i32); // scope 2 at $DIR/match_test.rs:+7:9: +7:14
+ switchInt(move _7) -> [false: bb4, otherwise: bb2]; // scope 2 at $DIR/match_test.rs:+7:9: +7:14
+ }
+
+ bb2: {
+ falseEdge -> [real: bb9, imaginary: bb6]; // scope 2 at $DIR/match_test.rs:+7:9: +7:14
+ }
+
+ bb3: {
+ _3 = const 3_i32; // scope 2 at $DIR/match_test.rs:+10:14: +10:15
+ goto -> bb14; // scope 2 at $DIR/match_test.rs:+10:14: +10:15
+ }
+
+ bb4: {
+ _4 = Le(const 10_i32, _1); // scope 2 at $DIR/match_test.rs:+8:9: +8:16
+ switchInt(move _4) -> [false: bb7, otherwise: bb5]; // scope 2 at $DIR/match_test.rs:+8:9: +8:16
+ }
+
+ bb5: {
+ _5 = Le(_1, const 20_i32); // scope 2 at $DIR/match_test.rs:+8:9: +8:16
+ switchInt(move _5) -> [false: bb7, otherwise: bb6]; // scope 2 at $DIR/match_test.rs:+8:9: +8:16
+ }
+
+ bb6: {
+ falseEdge -> [real: bb12, imaginary: bb8]; // scope 2 at $DIR/match_test.rs:+8:9: +8:16
+ }
+
+ bb7: {
+ switchInt(_1) -> [-1_i32: bb8, otherwise: bb3]; // scope 2 at $DIR/match_test.rs:+6:5: +6:12
+ }
+
+ bb8: {
+ falseEdge -> [real: bb13, imaginary: bb3]; // scope 2 at $DIR/match_test.rs:+9:9: +9:11
+ }
+
+ bb9: {
+ _8 = &shallow _1; // scope 2 at $DIR/match_test.rs:+6:11: +6:12
+ StorageLive(_9); // scope 2 at $DIR/match_test.rs:+7:18: +7:19
+ _9 = _2; // scope 2 at $DIR/match_test.rs:+7:18: +7:19
+ switchInt(move _9) -> [false: bb11, otherwise: bb10]; // scope 2 at $DIR/match_test.rs:+7:18: +7:19
+ }
+
+ bb10: {
+ StorageDead(_9); // scope 2 at $DIR/match_test.rs:+7:18: +7:19
+ FakeRead(ForMatchGuard, _8); // scope 2 at $DIR/match_test.rs:+7:18: +7:19
+ _3 = const 0_i32; // scope 2 at $DIR/match_test.rs:+7:23: +7:24
+ goto -> bb14; // scope 2 at $DIR/match_test.rs:+7:23: +7:24
+ }
+
+ bb11: {
+ StorageDead(_9); // scope 2 at $DIR/match_test.rs:+7:18: +7:19
+ falseEdge -> [real: bb3, imaginary: bb6]; // scope 2 at $DIR/match_test.rs:+7:18: +7:19
+ }
+
+ bb12: {
+ _3 = const 1_i32; // scope 2 at $DIR/match_test.rs:+8:20: +8:21
+ goto -> bb14; // scope 2 at $DIR/match_test.rs:+8:20: +8:21
+ }
+
+ bb13: {
+ _3 = const 2_i32; // scope 2 at $DIR/match_test.rs:+9:15: +9:16
+ goto -> bb14; // scope 2 at $DIR/match_test.rs:+9:15: +9:16
+ }
+
+ bb14: {
+ StorageDead(_3); // scope 2 at $DIR/match_test.rs:+11:6: +11:7
+ _0 = const (); // scope 0 at $DIR/match_test.rs:+0:11: +12:2
+ StorageDead(_2); // scope 1 at $DIR/match_test.rs:+12:1: +12:2
+ StorageDead(_1); // scope 0 at $DIR/match_test.rs:+12:1: +12:2
+ return; // scope 0 at $DIR/match_test.rs:+12:2: +12:2
+ }
+}
diff --git a/src/test/mir-opt/match_test.rs b/src/test/mir-opt/match_test.rs
new file mode 100644
index 000000000..3a2107790
--- /dev/null
+++ b/src/test/mir-opt/match_test.rs
@@ -0,0 +1,18 @@
+// Make sure redundant testing paths in `match` expressions are sorted out.
+
+#![feature(exclusive_range_pattern)]
+
+// EMIT_MIR match_test.main.SimplifyCfg-initial.after.mir
+fn main() {
+ let x = 3;
+ let b = true;
+
+ // When `(0..=10).contains(x) && !b`, we should jump to the last arm
+ // without testing two other candidates.
+ match x {
+ 0..10 if b => 0,
+ 10..=20 => 1,
+ -1 => 2,
+ _ => 3,
+ };
+}
diff --git a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff
new file mode 100644
index 000000000..2005c10ef
--- /dev/null
+++ b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff
@@ -0,0 +1,88 @@
+- // MIR for `bar` before MatchBranchSimplification
++ // MIR for `bar` after MatchBranchSimplification
+
+ fn bar(_1: i32) -> (bool, bool, bool, bool) {
+ debug i => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:9
+ let mut _0: (bool, bool, bool, bool); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:19: +0:43
+ let _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
+ let _6: (); // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +21:6
+ let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:6: +23:7
+ let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:9: +23:10
+ let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:12: +23:13
+ let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:15: +23:16
++ let mut _11: i32; // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
+ scope 1 {
+ debug a => _2; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
+ let _3: bool; // in scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _3; // in scope 2 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
+ let _4: bool; // in scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
+ scope 3 {
+ debug c => _4; // in scope 3 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
+ let _5: bool; // in scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
+ scope 4 {
+ debug d => _5; // in scope 4 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
+ StorageLive(_3); // scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
+ StorageLive(_4); // scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
+ StorageLive(_5); // scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
+ StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +21:6
+- switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
+- }
+-
+- bb1: {
+- _2 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+15:13: +15:21
+- _3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+16:13: +16:22
+- _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+17:13: +17:22
+- _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+18:13: +18:21
+- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
+- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
+- }
+-
+- bb2: {
+- _2 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+8:13: +8:22
+- _3 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21
++ StorageLive(_11); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
++ _11 = _1; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
++ _2 = Ne(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+8:13: +8:22
++ _3 = Eq(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21
+ _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+10:13: +10:22
+ _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+11:13: +11:21
+- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
+- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
+- }
+-
+- bb3: {
++ StorageDead(_11); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
+ StorageDead(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+21:6: +21:7
+ StorageLive(_7); // scope 4 at $DIR/matches_reduce_branches.rs:+23:6: +23:7
+ _7 = _2; // scope 4 at $DIR/matches_reduce_branches.rs:+23:6: +23:7
+ StorageLive(_8); // scope 4 at $DIR/matches_reduce_branches.rs:+23:9: +23:10
+ _8 = _3; // scope 4 at $DIR/matches_reduce_branches.rs:+23:9: +23:10
+ StorageLive(_9); // scope 4 at $DIR/matches_reduce_branches.rs:+23:12: +23:13
+ _9 = _4; // scope 4 at $DIR/matches_reduce_branches.rs:+23:12: +23:13
+ StorageLive(_10); // scope 4 at $DIR/matches_reduce_branches.rs:+23:15: +23:16
+ _10 = _5; // scope 4 at $DIR/matches_reduce_branches.rs:+23:15: +23:16
+ Deinit(_0); // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
+ (_0.0: bool) = move _7; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
+ (_0.1: bool) = move _8; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
+ (_0.2: bool) = move _9; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
+ (_0.3: bool) = move _10; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
+ StorageDead(_10); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17
+ StorageDead(_9); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17
+ StorageDead(_8); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17
+ StorageDead(_7); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17
+ StorageDead(_5); // scope 3 at $DIR/matches_reduce_branches.rs:+24:1: +24:2
+ StorageDead(_4); // scope 2 at $DIR/matches_reduce_branches.rs:+24:1: +24:2
+ StorageDead(_3); // scope 1 at $DIR/matches_reduce_branches.rs:+24:1: +24:2
+ StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+24:1: +24:2
+ return; // scope 0 at $DIR/matches_reduce_branches.rs:+24:2: +24:2
+ }
+ }
+
diff --git a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff
new file mode 100644
index 000000000..2005c10ef
--- /dev/null
+++ b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff
@@ -0,0 +1,88 @@
+- // MIR for `bar` before MatchBranchSimplification
++ // MIR for `bar` after MatchBranchSimplification
+
+ fn bar(_1: i32) -> (bool, bool, bool, bool) {
+ debug i => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:9
+ let mut _0: (bool, bool, bool, bool); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:19: +0:43
+ let _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
+ let _6: (); // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +21:6
+ let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:6: +23:7
+ let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:9: +23:10
+ let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:12: +23:13
+ let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:15: +23:16
++ let mut _11: i32; // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
+ scope 1 {
+ debug a => _2; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
+ let _3: bool; // in scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _3; // in scope 2 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
+ let _4: bool; // in scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
+ scope 3 {
+ debug c => _4; // in scope 3 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
+ let _5: bool; // in scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
+ scope 4 {
+ debug d => _5; // in scope 4 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
+ StorageLive(_3); // scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
+ StorageLive(_4); // scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
+ StorageLive(_5); // scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
+ StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +21:6
+- switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
+- }
+-
+- bb1: {
+- _2 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+15:13: +15:21
+- _3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+16:13: +16:22
+- _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+17:13: +17:22
+- _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+18:13: +18:21
+- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
+- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
+- }
+-
+- bb2: {
+- _2 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+8:13: +8:22
+- _3 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21
++ StorageLive(_11); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
++ _11 = _1; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
++ _2 = Ne(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+8:13: +8:22
++ _3 = Eq(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21
+ _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+10:13: +10:22
+ _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+11:13: +11:21
+- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
+- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
+- }
+-
+- bb3: {
++ StorageDead(_11); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
+ StorageDead(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+21:6: +21:7
+ StorageLive(_7); // scope 4 at $DIR/matches_reduce_branches.rs:+23:6: +23:7
+ _7 = _2; // scope 4 at $DIR/matches_reduce_branches.rs:+23:6: +23:7
+ StorageLive(_8); // scope 4 at $DIR/matches_reduce_branches.rs:+23:9: +23:10
+ _8 = _3; // scope 4 at $DIR/matches_reduce_branches.rs:+23:9: +23:10
+ StorageLive(_9); // scope 4 at $DIR/matches_reduce_branches.rs:+23:12: +23:13
+ _9 = _4; // scope 4 at $DIR/matches_reduce_branches.rs:+23:12: +23:13
+ StorageLive(_10); // scope 4 at $DIR/matches_reduce_branches.rs:+23:15: +23:16
+ _10 = _5; // scope 4 at $DIR/matches_reduce_branches.rs:+23:15: +23:16
+ Deinit(_0); // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
+ (_0.0: bool) = move _7; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
+ (_0.1: bool) = move _8; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
+ (_0.2: bool) = move _9; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
+ (_0.3: bool) = move _10; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
+ StorageDead(_10); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17
+ StorageDead(_9); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17
+ StorageDead(_8); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17
+ StorageDead(_7); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17
+ StorageDead(_5); // scope 3 at $DIR/matches_reduce_branches.rs:+24:1: +24:2
+ StorageDead(_4); // scope 2 at $DIR/matches_reduce_branches.rs:+24:1: +24:2
+ StorageDead(_3); // scope 1 at $DIR/matches_reduce_branches.rs:+24:1: +24:2
+ StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+24:1: +24:2
+ return; // scope 0 at $DIR/matches_reduce_branches.rs:+24:2: +24:2
+ }
+ }
+
diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff
new file mode 100644
index 000000000..b7862e567
--- /dev/null
+++ b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff
@@ -0,0 +1,30 @@
+- // MIR for `foo` before MatchBranchSimplification
++ // MIR for `foo` after MatchBranchSimplification
+
+ fn foo(_1: Option<()>) -> () {
+ debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
+ let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
+ let mut _2: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
++ let mut _3: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
+- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb1: {
+- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb2: {
+- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb3: {
++ StorageLive(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ _3 = move _2; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ StorageDead(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff
new file mode 100644
index 000000000..b7862e567
--- /dev/null
+++ b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff
@@ -0,0 +1,30 @@
+- // MIR for `foo` before MatchBranchSimplification
++ // MIR for `foo` after MatchBranchSimplification
+
+ fn foo(_1: Option<()>) -> () {
+ debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
+ let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
+ let mut _2: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
++ let mut _3: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
+- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb1: {
+- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb2: {
+- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb3: {
++ StorageLive(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ _3 = move _2; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ StorageDead(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.32bit.mir b/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.32bit.mir
new file mode 100644
index 000000000..a36ec8de4
--- /dev/null
+++ b/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.32bit.mir
@@ -0,0 +1,10 @@
+// MIR for `foo` before PreCodegen
+
+fn foo(_1: Option<()>) -> () {
+ debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
+ let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
+
+ bb0: {
+ return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
+ }
+}
diff --git a/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.64bit.mir b/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.64bit.mir
new file mode 100644
index 000000000..a36ec8de4
--- /dev/null
+++ b/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.64bit.mir
@@ -0,0 +1,10 @@
+// MIR for `foo` before PreCodegen
+
+fn foo(_1: Option<()>) -> () {
+ debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
+ let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
+
+ bb0: {
+ return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
+ }
+}
diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff
new file mode 100644
index 000000000..672c6b34e
--- /dev/null
+++ b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff
@@ -0,0 +1,42 @@
+- // MIR for `match_nested_if` before MatchBranchSimplification
++ // MIR for `match_nested_if` after MatchBranchSimplification
+
+ fn match_nested_if() -> bool {
+ let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29
+ let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+ let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ scope 1 {
+ debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+ StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ _2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+- }
+-
+- bb1: {
++ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++ _3 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
+- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
+- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
+- }
+-
+- bb2: {
+- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
+- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+- }
+-
+- bb3: {
++ _1 = Ne(_3, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
++ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ _0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8
+ StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2
+ return; // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2
+ }
+ }
+
diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff
new file mode 100644
index 000000000..672c6b34e
--- /dev/null
+++ b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff
@@ -0,0 +1,42 @@
+- // MIR for `match_nested_if` before MatchBranchSimplification
++ // MIR for `match_nested_if` after MatchBranchSimplification
+
+ fn match_nested_if() -> bool {
+ let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29
+ let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+ let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ scope 1 {
+ debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+ StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ _2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+- }
+-
+- bb1: {
++ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++ _3 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
+- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
+- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
+- }
+-
+- bb2: {
+- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
+- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+- }
+-
+- bb3: {
++ _1 = Ne(_3, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
++ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ _0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8
+ StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2
+ return; // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2
+ }
+ }
+
diff --git a/src/test/mir-opt/matches_reduce_branches.rs b/src/test/mir-opt/matches_reduce_branches.rs
new file mode 100644
index 000000000..51be3884d
--- /dev/null
+++ b/src/test/mir-opt/matches_reduce_branches.rs
@@ -0,0 +1,59 @@
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR matches_reduce_branches.foo.MatchBranchSimplification.diff
+// EMIT_MIR matches_reduce_branches.foo.PreCodegen.before.mir
+// EMIT_MIR matches_reduce_branches.bar.MatchBranchSimplification.diff
+// EMIT_MIR matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff
+
+fn foo(bar: Option<()>) {
+ if matches!(bar, None) {
+ ()
+ }
+}
+
+fn bar(i: i32) -> (bool, bool, bool, bool) {
+ let a;
+ let b;
+ let c;
+ let d;
+
+ match i {
+ 7 => {
+ a = false;
+ b = true;
+ c = false;
+ d = true;
+ ()
+ }
+ _ => {
+ a = true;
+ b = false;
+ c = false;
+ d = true;
+ ()
+ }
+ };
+
+ (a, b, c, d)
+}
+
+fn match_nested_if() -> bool {
+ let val = match () {
+ () if if if if true { true } else { false } { true } else { false } {
+ true
+ } else {
+ false
+ } =>
+ {
+ true
+ }
+ _ => false,
+ };
+ val
+}
+
+fn main() {
+ let _ = foo(None);
+ let _ = foo(Some(()));
+ let _ = bar(0);
+ let _ = match_nested_if();
+}
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff
new file mode 100644
index 000000000..c42657b38
--- /dev/null
+++ b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff
@@ -0,0 +1,28 @@
+- // MIR for `exhaustive_match` before MatchBranchSimplification
++ // MIR for `exhaustive_match` after MatchBranchSimplification
+
+ fn exhaustive_match(_1: E) -> u8 {
+ debug e => _1; // in scope 0 at $DIR/matches_u8.rs:+0:25: +0:26
+ let mut _0: u8; // return place in scope 0 at $DIR/matches_u8.rs:+0:34: +0:36
+ let mut _2: isize; // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
+ switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = const 1_u8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ }
+
+ bb2: {
+ _0 = const 0_u8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ }
+
+ bb3: {
+ return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff
new file mode 100644
index 000000000..c42657b38
--- /dev/null
+++ b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff
@@ -0,0 +1,28 @@
+- // MIR for `exhaustive_match` before MatchBranchSimplification
++ // MIR for `exhaustive_match` after MatchBranchSimplification
+
+ fn exhaustive_match(_1: E) -> u8 {
+ debug e => _1; // in scope 0 at $DIR/matches_u8.rs:+0:25: +0:26
+ let mut _0: u8; // return place in scope 0 at $DIR/matches_u8.rs:+0:34: +0:36
+ let mut _2: isize; // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
+ switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = const 1_u8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ }
+
+ bb2: {
+ _0 = const 0_u8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ }
+
+ bb3: {
+ return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff
new file mode 100644
index 000000000..a4ff2e437
--- /dev/null
+++ b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff
@@ -0,0 +1,28 @@
+- // MIR for `exhaustive_match_i8` before MatchBranchSimplification
++ // MIR for `exhaustive_match_i8` after MatchBranchSimplification
+
+ fn exhaustive_match_i8(_1: E) -> i8 {
+ debug e => _1; // in scope 0 at $DIR/matches_u8.rs:+0:28: +0:29
+ let mut _0: i8; // return place in scope 0 at $DIR/matches_u8.rs:+0:37: +0:39
+ let mut _2: isize; // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
+ switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = const 1_i8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ }
+
+ bb2: {
+ _0 = const 0_i8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ }
+
+ bb3: {
+ return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff
new file mode 100644
index 000000000..a4ff2e437
--- /dev/null
+++ b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff
@@ -0,0 +1,28 @@
+- // MIR for `exhaustive_match_i8` before MatchBranchSimplification
++ // MIR for `exhaustive_match_i8` after MatchBranchSimplification
+
+ fn exhaustive_match_i8(_1: E) -> i8 {
+ debug e => _1; // in scope 0 at $DIR/matches_u8.rs:+0:28: +0:29
+ let mut _0: i8; // return place in scope 0 at $DIR/matches_u8.rs:+0:37: +0:39
+ let mut _2: isize; // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
+ switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = const 1_i8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ }
+
+ bb2: {
+ _0 = const 0_i8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ }
+
+ bb3: {
+ return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/matches_u8.rs b/src/test/mir-opt/matches_u8.rs
new file mode 100644
index 000000000..78373be48
--- /dev/null
+++ b/src/test/mir-opt/matches_u8.rs
@@ -0,0 +1,32 @@
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR matches_u8.exhaustive_match.MatchBranchSimplification.diff
+// EMIT_MIR matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff
+
+pub enum E {
+ A,
+ B,
+}
+
+#[no_mangle]
+pub fn exhaustive_match(e: E) -> u8 {
+ match e {
+ E::A => 0,
+ E::B => 1,
+ }
+}
+
+#[no_mangle]
+pub fn exhaustive_match_i8(e: E) -> i8 {
+ match e {
+ E::A => 0,
+ E::B => 1,
+ }
+}
+
+fn main() {
+ assert_eq!(exhaustive_match(E::A), 0);
+ assert_eq!(exhaustive_match(E::B), 1);
+
+ assert_eq!(exhaustive_match_i8(E::A), 0);
+ assert_eq!(exhaustive_match_i8(E::B), 1);
+}
diff --git a/src/test/mir-opt/multiple_return_terminators.rs b/src/test/mir-opt/multiple_return_terminators.rs
new file mode 100644
index 000000000..a2b902d14
--- /dev/null
+++ b/src/test/mir-opt/multiple_return_terminators.rs
@@ -0,0 +1,14 @@
+// compile-flags: -Z mir-opt-level=4
+// EMIT_MIR multiple_return_terminators.test.MultipleReturnTerminators.diff
+
+fn test(x: bool) {
+ if x {
+ // test
+ } else {
+ // test
+ }
+}
+
+fn main() {
+ test(true)
+}
diff --git a/src/test/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff b/src/test/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff
new file mode 100644
index 000000000..48a11c950
--- /dev/null
+++ b/src/test/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff
@@ -0,0 +1,12 @@
+- // MIR for `test` before MultipleReturnTerminators
++ // MIR for `test` after MultipleReturnTerminators
+
+ fn test(_1: bool) -> () {
+ debug x => _1; // in scope 0 at $DIR/multiple_return_terminators.rs:+0:9: +0:10
+ let mut _0: (); // return place in scope 0 at $DIR/multiple_return_terminators.rs:+0:18: +0:18
+
+ bb0: {
+ return; // scope 0 at $DIR/multiple_return_terminators.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/nll/named-lifetimes-basic.rs b/src/test/mir-opt/nll/named-lifetimes-basic.rs
new file mode 100644
index 000000000..843716033
--- /dev/null
+++ b/src/test/mir-opt/nll/named-lifetimes-basic.rs
@@ -0,0 +1,15 @@
+// Basic test for named lifetime translation. Check that we
+// instantiate the types that appear in function arguments with
+// suitable variables and that we setup the outlives relationship
+// between R0 and R1 properly.
+
+// compile-flags: -Zverbose
+// ^^^^^^^^^ force compiler to dump more region information
+
+#![allow(warnings)]
+
+// EMIT_MIR named_lifetimes_basic.use_x.nll.0.mir
+fn use_x<'a, 'b: 'a, 'c>(w: &'a mut i32, x: &'b u32, y: &'a u32, z: &'c u32) -> bool { true }
+
+fn main() {
+}
diff --git a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir
new file mode 100644
index 000000000..cbfdf8c5d
--- /dev/null
+++ b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir
@@ -0,0 +1,48 @@
+// MIR for `use_x` 0 nll
+
+| Free Region Mapping
+| '_#0r | Global | ['_#2r, '_#1r, '_#0r, '_#4r, '_#3r]
+| '_#1r | Local | ['_#1r, '_#4r]
+| '_#2r | Local | ['_#2r, '_#1r, '_#4r]
+| '_#3r | Local | ['_#4r, '_#3r]
+| '_#4r | Local | ['_#4r]
+|
+| Inferred Region Values
+| '_#0r | U0 | {bb0[0..=1], '_#0r, '_#1r, '_#2r, '_#3r, '_#4r}
+| '_#1r | U0 | {bb0[0..=1], '_#1r}
+| '_#2r | U0 | {bb0[0..=1], '_#2r}
+| '_#3r | U0 | {bb0[0..=1], '_#3r}
+| '_#4r | U0 | {bb0[0..=1], '_#4r}
+| '_#5r | U0 | {}
+| '_#6r | U0 | {bb0[0..=1], '_#1r}
+| '_#7r | U0 | {bb0[0..=1], '_#2r}
+| '_#8r | U0 | {bb0[0..=1], '_#1r}
+| '_#9r | U0 | {bb0[0..=1], '_#3r}
+|
+| Inference Constraints
+| '_#0r live at {bb0[0..=1]}
+| '_#1r live at {bb0[0..=1]}
+| '_#2r live at {bb0[0..=1]}
+| '_#3r live at {bb0[0..=1]}
+| '_#4r live at {bb0[0..=1]}
+| '_#1r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0)
+| '_#1r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0)
+| '_#2r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0)
+| '_#3r: '_#9r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0)
+| '_#6r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0)
+| '_#7r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0)
+| '_#8r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0)
+| '_#9r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0)
+|
+fn use_x(_1: &'_#6r mut i32, _2: &'_#7r u32, _3: &'_#8r u32, _4: &'_#9r u32) -> bool {
+ debug w => _1; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:26: +0:27
+ debug x => _2; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:42: +0:43
+ debug y => _3; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:54: +0:55
+ debug z => _4; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:66: +0:67
+ let mut _0: bool; // return place in scope 0 at $DIR/named-lifetimes-basic.rs:+0:81: +0:85
+
+ bb0: {
+ _0 = const ConstValue(Scalar(0x01): bool); // bb0[0]: scope 0 at $DIR/named-lifetimes-basic.rs:+0:88: +0:92
+ return; // bb0[1]: scope 0 at $DIR/named-lifetimes-basic.rs:+0:94: +0:94
+ }
+}
diff --git a/src/test/mir-opt/nll/region-subtyping-basic.rs b/src/test/mir-opt/nll/region-subtyping-basic.rs
new file mode 100644
index 000000000..64332f302
--- /dev/null
+++ b/src/test/mir-opt/nll/region-subtyping-basic.rs
@@ -0,0 +1,25 @@
+// Basic test for liveness constraints: the region (`R1`) that appears
+// in the type of `p` includes the points after `&v[0]` up to (but not
+// including) the call to `use_x`. The `else` branch is not included.
+
+// compile-flags:-Zverbose
+// ^^^^^^^^^ force compiler to dump more region information
+
+#![allow(warnings)]
+
+fn use_x(_: usize) -> bool {
+ true
+}
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR region_subtyping_basic.main.nll.0.mir
+fn main() {
+ let mut v = [1, 2, 3];
+ let p = &v[0];
+ let q = p;
+ if true {
+ use_x(*q);
+ } else {
+ use_x(22);
+ }
+}
diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
new file mode 100644
index 000000000..55e7faf9e
--- /dev/null
+++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
@@ -0,0 +1,112 @@
+// MIR for `main` 0 nll
+
+| Free Region Mapping
+| '_#0r | Global | ['_#0r, '_#1r]
+| '_#1r | Local | ['_#1r]
+|
+| Inferred Region Values
+| '_#0r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#0r, '_#1r}
+| '_#1r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#1r}
+| '_#2r | U0 | {}
+| '_#3r | U0 | {bb1[0..=7], bb2[0..=2]}
+| '_#4r | U0 | {bb1[1..=7], bb2[0..=2]}
+| '_#5r | U0 | {bb1[4..=7], bb2[0..=2]}
+|
+| Inference Constraints
+| '_#0r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]}
+| '_#1r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]}
+| '_#3r live at {bb1[0]}
+| '_#4r live at {bb1[1..=3]}
+| '_#5r live at {bb1[4..=7], bb2[0..=2]}
+| '_#3r: '_#4r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0)
+| '_#4r: '_#5r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0)
+|
+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 { ty: usize, kind: Value(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
+ let mut _7: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
+ let _8: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:9: +5:18
+ let mut _9: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:15: +5:17
+ let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
+ scope 1 {
+ debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
+ let _2: &'_#4r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
+ scope 2 {
+ debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
+ let _6: &'_#5r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ scope 3 {
+ debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
+ _1 = [const ConstValue(Scalar(0x00000001): usize), const ConstValue(Scalar(0x00000002): usize), const ConstValue(Scalar(0x00000003): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:+1:17: +1:26
+ FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
+ StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
+ StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17
+ _3 = const ConstValue(Scalar(0x00000000): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17
+ _4 = Len(_1); // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
+ _5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
+ }
+
+ bb1: {
+ _2 = &'_#3r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18
+ FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
+ StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ _6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14
+ FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ StorageLive(_7); // bb1[5]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
+ _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
+ switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
+ }
+
+ bb2: {
+ StorageLive(_8); // bb2[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18
+ StorageLive(_9); // bb2[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17
+ _9 = (*_6); // bb2[2]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17
+ _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18
+ // mir::Constant
+ // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14
+ // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_9); // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:17: +5:18
+ StorageDead(_8); // bb3[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:18: +5:19
+ _0 = const ConstValue(ZeroSized: ()); // bb3[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:13: +6:6
+ goto -> bb6; // bb3[3]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6
+ }
+
+ bb4: {
+ StorageLive(_10); // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
+ _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
+ // mir::Constant
+ // + span: $DIR/region-subtyping-basic.rs:23:9: 23:14
+ // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ StorageDead(_10); // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:18: +7:19
+ _0 = const ConstValue(ZeroSized: ()); // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:+6:12: +8:6
+ goto -> bb6; // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6
+ }
+
+ bb6: {
+ StorageDead(_7); // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:+8:5: +8:6
+ StorageDead(_6); // bb6[1]: scope 2 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
+ StorageDead(_3); // bb6[2]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
+ StorageDead(_2); // bb6[3]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
+ StorageDead(_1); // bb6[4]: scope 0 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
+ return; // bb6[5]: scope 0 at $DIR/region-subtyping-basic.rs:+9:2: +9:2
+ }
+
+ bb7 (cleanup): {
+ resume; // bb7[0]: scope 0 at $DIR/region-subtyping-basic.rs:+0:1: +9:2
+ }
+}
diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
new file mode 100644
index 000000000..2647c9433
--- /dev/null
+++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
@@ -0,0 +1,112 @@
+// MIR for `main` 0 nll
+
+| Free Region Mapping
+| '_#0r | Global | ['_#0r, '_#1r]
+| '_#1r | Local | ['_#1r]
+|
+| Inferred Region Values
+| '_#0r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#0r, '_#1r}
+| '_#1r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#1r}
+| '_#2r | U0 | {}
+| '_#3r | U0 | {bb1[0..=7], bb2[0..=2]}
+| '_#4r | U0 | {bb1[1..=7], bb2[0..=2]}
+| '_#5r | U0 | {bb1[4..=7], bb2[0..=2]}
+|
+| Inference Constraints
+| '_#0r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]}
+| '_#1r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]}
+| '_#3r live at {bb1[0]}
+| '_#4r live at {bb1[1..=3]}
+| '_#5r live at {bb1[4..=7], bb2[0..=2]}
+| '_#3r: '_#4r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0)
+| '_#4r: '_#5r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0)
+|
+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 { ty: usize, kind: Value(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
+ let mut _7: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
+ let _8: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:9: +5:18
+ let mut _9: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:15: +5:17
+ let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
+ scope 1 {
+ debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
+ let _2: &'_#4r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
+ scope 2 {
+ debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
+ let _6: &'_#5r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ scope 3 {
+ debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
+ _1 = [const ConstValue(Scalar(0x0000000000000001): usize), const ConstValue(Scalar(0x0000000000000002): usize), const ConstValue(Scalar(0x0000000000000003): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:+1:17: +1:26
+ FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
+ StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
+ StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17
+ _3 = const ConstValue(Scalar(0x0000000000000000): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17
+ _4 = Len(_1); // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
+ _5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
+ }
+
+ bb1: {
+ _2 = &'_#3r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18
+ FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
+ StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ _6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14
+ FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ StorageLive(_7); // bb1[5]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
+ _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
+ switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
+ }
+
+ bb2: {
+ StorageLive(_8); // bb2[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18
+ StorageLive(_9); // bb2[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17
+ _9 = (*_6); // bb2[2]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17
+ _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18
+ // mir::Constant
+ // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14
+ // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_9); // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:17: +5:18
+ StorageDead(_8); // bb3[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:18: +5:19
+ _0 = const ConstValue(ZeroSized: ()); // bb3[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:13: +6:6
+ goto -> bb6; // bb3[3]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6
+ }
+
+ bb4: {
+ StorageLive(_10); // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
+ _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
+ // mir::Constant
+ // + span: $DIR/region-subtyping-basic.rs:23:9: 23:14
+ // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ StorageDead(_10); // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:18: +7:19
+ _0 = const ConstValue(ZeroSized: ()); // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:+6:12: +8:6
+ goto -> bb6; // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6
+ }
+
+ bb6: {
+ StorageDead(_7); // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:+8:5: +8:6
+ StorageDead(_6); // bb6[1]: scope 2 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
+ StorageDead(_3); // bb6[2]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
+ StorageDead(_2); // bb6[3]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
+ StorageDead(_1); // bb6[4]: scope 0 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
+ return; // bb6[5]: scope 0 at $DIR/region-subtyping-basic.rs:+9:2: +9:2
+ }
+
+ bb7 (cleanup): {
+ resume; // bb7[0]: scope 0 at $DIR/region-subtyping-basic.rs:+0:1: +9:2
+ }
+}
diff --git a/src/test/mir-opt/no-drop-for-inactive-variant.rs b/src/test/mir-opt/no-drop-for-inactive-variant.rs
new file mode 100644
index 000000000..34e2b1a13
--- /dev/null
+++ b/src/test/mir-opt/no-drop-for-inactive-variant.rs
@@ -0,0 +1,16 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+
+// Ensure that there are no drop terminators in `unwrap<T>` (except the one along the cleanup
+// path).
+
+// EMIT_MIR no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir
+fn unwrap<T>(opt: Option<T>) -> T {
+ match opt {
+ Some(x) => x,
+ None => panic!(),
+ }
+}
+
+fn main() {
+ let _ = unwrap(Some(1i32));
+}
diff --git a/src/test/mir-opt/no-spurious-drop-after-call.rs b/src/test/mir-opt/no-spurious-drop-after-call.rs
new file mode 100644
index 000000000..bb5bb9aa4
--- /dev/null
+++ b/src/test/mir-opt/no-spurious-drop-after-call.rs
@@ -0,0 +1,10 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+
+// Test that after the call to `std::mem::drop` we do not generate a
+// MIR drop of the argument. (We used to have a `DROP(_2)` in the code
+// below, as part of bb3.)
+
+// EMIT_MIR no_spurious_drop_after_call.main.ElaborateDrops.before.mir
+fn main() {
+ std::mem::drop("".to_string());
+}
diff --git a/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..50fd98ff1
--- /dev/null
+++ b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,49 @@
+// MIR for `unwrap` after SimplifyCfg-elaborate-drops
+
+fn unwrap(_1: Option<T>) -> T {
+ debug opt => _1; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+0:14: +0:17
+ let mut _0: T; // return place in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+0:33: +0:34
+ let mut _2: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:9: +2:16
+ let _3: T; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15
+ let mut _4: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+ let mut _5: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2
+ let mut _6: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2
+ let mut _7: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2
+ scope 1 {
+ debug x => _3; // in scope 1 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15
+ }
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+1:11: +1:14
+ switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+1:5: +1:14
+ }
+
+ bb1: {
+ StorageLive(_4); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+ _4 = begin_panic::<&str>(const "explicit panic") -> bb4; // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
+ // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+1:11: +1:14
+ }
+
+ bb3: {
+ StorageLive(_3); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15
+ _3 = move ((_1 as Some).0: T); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15
+ _0 = move _3; // scope 1 at $DIR/no-drop-for-inactive-variant.rs:+2:20: +2:21
+ StorageDead(_3); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:20: +2:21
+ _5 = discriminant(_1); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:2: +5:2
+ }
+
+ bb4 (cleanup): {
+ _7 = discriminant(_1); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2
+ resume; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+0:1: +5:2
+ }
+}
diff --git a/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir b/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir
new file mode 100644
index 000000000..25c6e3060
--- /dev/null
+++ b/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir
@@ -0,0 +1,49 @@
+// MIR for `main` before ElaborateDrops
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/no-spurious-drop-after-call.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:5: +1:35
+ let mut _2: std::string::String; // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34
+ let mut _3: &str; // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34
+ let _4: &str; // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:22
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:5: +1:35
+ StorageLive(_2); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34
+ StorageLive(_3); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34
+ StorageLive(_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:22
+ _4 = const ""; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:22
+ // mir::Constant
+ // + span: $DIR/no-spurious-drop-after-call.rs:9:20: 9:22
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _3 = &(*_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34
+ _2 = <str as ToString>::to_string(move _3) -> bb1; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34
+ // mir::Constant
+ // + span: $DIR/no-spurious-drop-after-call.rs:9:23: 9:32
+ // + literal: Const { ty: for<'r> fn(&'r str) -> String {<str as ToString>::to_string}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:33: +1:34
+ _1 = std::mem::drop::<String>(move _2) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:5: +1:35
+ // mir::Constant
+ // + span: $DIR/no-spurious-drop-after-call.rs:9:5: 9:19
+ // + literal: Const { ty: fn(String) {std::mem::drop::<String>}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_2); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:34: +1:35
+ StorageDead(_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:35: +1:36
+ StorageDead(_1); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:35: +1:36
+ _0 = const (); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+2:2: +2:2
+ }
+
+ bb3 (cleanup): {
+ drop(_2) -> bb4; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:34: +1:35
+ }
+
+ bb4 (cleanup): {
+ resume; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+0:1: +2:2
+ }
+}
diff --git a/src/test/mir-opt/not_equal_false.opt.InstCombine.diff b/src/test/mir-opt/not_equal_false.opt.InstCombine.diff
new file mode 100644
index 000000000..5009d0906
--- /dev/null
+++ b/src/test/mir-opt/not_equal_false.opt.InstCombine.diff
@@ -0,0 +1,35 @@
+- // MIR for `opt` before InstCombine
++ // MIR for `opt` after InstCombine
+
+ fn opt(_1: bool) -> u32 {
+ debug x => _1; // in scope 0 at $DIR/not_equal_false.rs:+0:8: +0:9
+ let mut _0: u32; // return place in scope 0 at $DIR/not_equal_false.rs:+0:20: +0:23
+ let mut _2: bool; // in scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18
+ let mut _3: bool; // in scope 0 at $DIR/not_equal_false.rs:+1:8: +1:9
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18
+ StorageLive(_3); // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:9
+- _2 = Ne(move _3, const false); // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18
++ _2 = move _3; // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18
+ StorageDead(_3); // scope 0 at $DIR/not_equal_false.rs:+1:17: +1:18
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18
+ }
+
+ bb1: {
+ _0 = const 0_u32; // scope 0 at $DIR/not_equal_false.rs:+1:21: +1:22
+ goto -> bb3; // scope 0 at $DIR/not_equal_false.rs:+1:5: +1:35
+ }
+
+ bb2: {
+ _0 = const 1_u32; // scope 0 at $DIR/not_equal_false.rs:+1:32: +1:33
+ goto -> bb3; // scope 0 at $DIR/not_equal_false.rs:+1:5: +1:35
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/not_equal_false.rs:+1:34: +1:35
+ return; // scope 0 at $DIR/not_equal_false.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/not_equal_false.rs b/src/test/mir-opt/not_equal_false.rs
new file mode 100644
index 000000000..5fbb848dc
--- /dev/null
+++ b/src/test/mir-opt/not_equal_false.rs
@@ -0,0 +1,9 @@
+// EMIT_MIR not_equal_false.opt.InstCombine.diff
+
+fn opt(x: bool) -> u32 {
+ if x != false { 0 } else { 1 }
+}
+
+fn main() {
+ opt(false);
+}
diff --git a/src/test/mir-opt/nrvo-simple.rs b/src/test/mir-opt/nrvo-simple.rs
new file mode 100644
index 000000000..5786ae621
--- /dev/null
+++ b/src/test/mir-opt/nrvo-simple.rs
@@ -0,0 +1,12 @@
+// unit-test: RenameReturnPlace
+
+// EMIT_MIR nrvo_simple.nrvo.RenameReturnPlace.diff
+fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] {
+ let mut buf = [0; 1024];
+ init(&mut buf);
+ buf
+}
+
+fn main() {
+ let _ = nrvo(|buf| { buf[4] = 4; });
+}
diff --git a/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff b/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff
new file mode 100644
index 000000000..9e89bd9fb
--- /dev/null
+++ b/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff
@@ -0,0 +1,43 @@
+- // MIR for `nrvo` before RenameReturnPlace
++ // MIR for `nrvo` after RenameReturnPlace
+
+ fn nrvo(_1: for<'r> fn(&'r mut [u8; 1024])) -> [u8; 1024] {
+ debug init => _1; // in scope 0 at $DIR/nrvo-simple.rs:+0:9: +0:13
+- let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo-simple.rs:+0:39: +0:49
++ let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo-simple.rs:+1:9: +1:16
+ let mut _2: [u8; 1024]; // in scope 0 at $DIR/nrvo-simple.rs:+1:9: +1:16
+ let _3: (); // in scope 0 at $DIR/nrvo-simple.rs:+2:5: +2:19
+ let mut _4: for<'r> fn(&'r mut [u8; 1024]); // in scope 0 at $DIR/nrvo-simple.rs:+2:5: +2:9
+ let mut _5: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo-simple.rs:+2:10: +2:18
+ let mut _6: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo-simple.rs:+2:10: +2:18
+ scope 1 {
+- debug buf => _2; // in scope 1 at $DIR/nrvo-simple.rs:+1:9: +1:16
++ debug buf => _0; // in scope 1 at $DIR/nrvo-simple.rs:+1:9: +1:16
+ }
+
+ bb0: {
+- StorageLive(_2); // scope 0 at $DIR/nrvo-simple.rs:+1:9: +1:16
+- _2 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo-simple.rs:+1:19: +1:28
++ _0 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo-simple.rs:+1:19: +1:28
+ StorageLive(_3); // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:19
+ StorageLive(_4); // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:9
+ _4 = _1; // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:9
+ StorageLive(_5); // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18
+ StorageLive(_6); // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18
+- _6 = &mut _2; // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18
++ _6 = &mut _0; // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18
+ _5 = &mut (*_6); // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18
+ _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:19
+ }
+
+ bb1: {
+ StorageDead(_5); // scope 1 at $DIR/nrvo-simple.rs:+2:18: +2:19
+ StorageDead(_4); // scope 1 at $DIR/nrvo-simple.rs:+2:18: +2:19
+ StorageDead(_6); // scope 1 at $DIR/nrvo-simple.rs:+2:19: +2:20
+ StorageDead(_3); // scope 1 at $DIR/nrvo-simple.rs:+2:19: +2:20
+- _0 = _2; // scope 1 at $DIR/nrvo-simple.rs:+3:5: +3:8
+- StorageDead(_2); // scope 0 at $DIR/nrvo-simple.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/nrvo-simple.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/packed-struct-drop-aligned.rs b/src/test/mir-opt/packed-struct-drop-aligned.rs
new file mode 100644
index 000000000..6c2e265d5
--- /dev/null
+++ b/src/test/mir-opt/packed-struct-drop-aligned.rs
@@ -0,0 +1,17 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir
+fn main() {
+ let mut x = Packed(Aligned(Droppy(0)));
+ x.0 = Aligned(Droppy(0));
+}
+
+struct Aligned(Droppy);
+#[repr(packed)]
+struct Packed(Aligned);
+
+struct Droppy(usize);
+impl Drop for Droppy {
+ fn drop(&mut self) {}
+}
diff --git a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir
new file mode 100644
index 000000000..c3874d3b3
--- /dev/null
+++ b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir
@@ -0,0 +1,55 @@
+// MIR for `main` after SimplifyCfg-elaborate-drops
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +0:11
+ let mut _1: Packed; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
+ let mut _2: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
+ let mut _3: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
+ let mut _4: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
+ let mut _5: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
+ let mut _6: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
+ StorageLive(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
+ StorageLive(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
+ _3 = Droppy(const 0_usize); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
+ _2 = Aligned(move _3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
+ StorageDead(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:41: +1:42
+ _1 = Packed(move _2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:17: +1:43
+ StorageDead(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:42: +1:43
+ StorageLive(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
+ StorageLive(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
+ _5 = Droppy(const 0_usize); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
+ _4 = Aligned(move _5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
+ StorageDead(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29
+ StorageLive(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ _6 = move (_1.0: Aligned); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ drop(_6) -> [return: bb4, unwind: bb3]; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:2: +3:2
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:1: +3:2
+ }
+
+ bb3 (cleanup): {
+ (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ drop(_1) -> bb2; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2
+ }
+
+ bb4: {
+ StorageDead(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ StorageDead(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29
+ _0 = const (); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +3:2
+ drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2
+ }
+}
diff --git a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir
new file mode 100644
index 000000000..c3874d3b3
--- /dev/null
+++ b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir
@@ -0,0 +1,55 @@
+// MIR for `main` after SimplifyCfg-elaborate-drops
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +0:11
+ let mut _1: Packed; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
+ let mut _2: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
+ let mut _3: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
+ let mut _4: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
+ let mut _5: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
+ let mut _6: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
+ StorageLive(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
+ StorageLive(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
+ _3 = Droppy(const 0_usize); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
+ _2 = Aligned(move _3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
+ StorageDead(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:41: +1:42
+ _1 = Packed(move _2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:17: +1:43
+ StorageDead(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:42: +1:43
+ StorageLive(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
+ StorageLive(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
+ _5 = Droppy(const 0_usize); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
+ _4 = Aligned(move _5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
+ StorageDead(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29
+ StorageLive(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ _6 = move (_1.0: Aligned); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ drop(_6) -> [return: bb4, unwind: bb3]; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:2: +3:2
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:1: +3:2
+ }
+
+ bb3 (cleanup): {
+ (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ drop(_1) -> bb2; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2
+ }
+
+ bb4: {
+ StorageDead(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ StorageDead(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29
+ _0 = const (); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +3:2
+ drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2
+ }
+}
diff --git a/src/test/mir-opt/receiver-ptr-mutability.rs b/src/test/mir-opt/receiver-ptr-mutability.rs
new file mode 100644
index 000000000..8e2ff0451
--- /dev/null
+++ b/src/test/mir-opt/receiver-ptr-mutability.rs
@@ -0,0 +1,20 @@
+// EMIT_MIR receiver_ptr_mutability.main.mir_map.0.mir
+
+#![feature(arbitrary_self_types)]
+
+struct Test {}
+
+impl Test {
+ fn x(self: *const Self) {
+ println!("x called");
+ }
+}
+
+fn main() {
+ let ptr: *mut Test = std::ptr::null_mut();
+ ptr.x();
+
+ // Test autoderefs
+ let ptr_ref: &&&&*mut Test = &&&&ptr;
+ ptr_ref.x();
+}
diff --git a/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir b/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir
new file mode 100644
index 000000000..45797ec06
--- /dev/null
+++ b/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir
@@ -0,0 +1,96 @@
+// MIR for `main` 0 mir_map
+
+| User Type Annotations
+| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:14:14: 14:23, inferred_ty: *mut Test
+| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:14:14: 14:23, inferred_ty: *mut Test
+| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test
+| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test
+|
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/receiver-ptr-mutability.rs:+0:11: +0:11
+ let _1: *mut Test as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12
+ let _2: (); // in scope 0 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12
+ let mut _3: *const Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12
+ let mut _4: *mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:8
+ let _6: &&&&*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41
+ let _7: &&&*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:35: +5:41
+ let _8: &&*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:36: +5:41
+ let _9: &*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:37: +5:41
+ let _10: (); // in scope 0 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
+ let mut _11: *const Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
+ let mut _12: *mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
+ scope 1 {
+ debug ptr => _1; // in scope 1 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12
+ let _5: &&&&*mut Test as UserTypeProjection { base: UserType(2), projs: [] }; // in scope 1 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16
+ scope 2 {
+ debug ptr_ref => _5; // in scope 2 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12
+ _1 = null_mut::<Test>() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:26: +1:46
+ // mir::Constant
+ // + span: $DIR/receiver-ptr-mutability.rs:14:26: 14:44
+ // + literal: Const { ty: fn() -> *mut Test {null_mut::<Test>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12
+ AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:14: +1:23
+ StorageLive(_2); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12
+ StorageLive(_3); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12
+ StorageLive(_4); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:8
+ _4 = _1; // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:8
+ _3 = move _4 as *const Test (Pointer(MutToConstPointer)); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12
+ StorageDead(_4); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:7: +2:8
+ _2 = Test::x(move _3) -> [return: bb2, unwind: bb4]; // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12
+ // mir::Constant
+ // + span: $DIR/receiver-ptr-mutability.rs:15:9: 15:10
+ // + literal: Const { ty: fn(*const Test) {Test::x}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_3); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:11: +2:12
+ StorageDead(_2); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:12: +2:13
+ StorageLive(_5); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16
+ StorageLive(_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41
+ StorageLive(_7); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:35: +5:41
+ StorageLive(_8); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:36: +5:41
+ StorageLive(_9); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:37: +5:41
+ _9 = &_1; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:37: +5:41
+ _8 = &_9; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:36: +5:41
+ _7 = &_8; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:35: +5:41
+ _6 = &_7; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41
+ _5 = &(*_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41
+ FakeRead(ForLet(None), _5); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16
+ AscribeUserType(_5, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:18: +5:31
+ StorageDead(_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:41: +5:42
+ StorageLive(_10); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
+ StorageLive(_11); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
+ StorageLive(_12); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
+ _12 = (*(*(*(*_5)))); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
+ _11 = move _12 as *const Test (Pointer(MutToConstPointer)); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
+ StorageDead(_12); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:11: +6:12
+ _10 = Test::x(move _11) -> [return: bb3, unwind: bb4]; // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
+ // mir::Constant
+ // + span: $DIR/receiver-ptr-mutability.rs:19:13: 19:14
+ // + literal: Const { ty: fn(*const Test) {Test::x}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_11); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:15: +6:16
+ StorageDead(_10); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:16: +6:17
+ _0 = const (); // scope 0 at $DIR/receiver-ptr-mutability.rs:+0:11: +7:2
+ StorageDead(_9); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2
+ StorageDead(_8); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2
+ StorageDead(_7); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2
+ StorageDead(_5); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/receiver-ptr-mutability.rs:+7:2: +7:2
+ }
+
+ bb4 (cleanup): {
+ resume; // scope 0 at $DIR/receiver-ptr-mutability.rs:+0:1: +7:2
+ }
+}
diff --git a/src/test/mir-opt/remove-never-const.rs b/src/test/mir-opt/remove-never-const.rs
new file mode 100644
index 000000000..017746647
--- /dev/null
+++ b/src/test/mir-opt/remove-never-const.rs
@@ -0,0 +1,22 @@
+// This was originally a regression test for #66975 - ensure that we do not generate never typed
+// consts in codegen. We also have tests for this that catches the error, see
+// src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs.
+
+// Force generation of optimized mir for functions that do not reach codegen.
+// compile-flags: --emit mir,link
+
+#![feature(never_type)]
+#![warn(const_err)]
+
+struct PrintName<T>(T);
+
+impl<T> PrintName<T> {
+ const VOID: ! = panic!();
+}
+
+// EMIT_MIR remove_never_const.no_codegen.PreCodegen.after.mir
+fn no_codegen<T>() {
+ let _ = PrintName::<T>::VOID;
+}
+
+fn main() {}
diff --git a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff
new file mode 100644
index 000000000..243a54b6a
--- /dev/null
+++ b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff
@@ -0,0 +1,76 @@
+- // MIR for `match_guard` before CleanupNonCodegenStatements
++ // MIR for `match_guard` after CleanupNonCodegenStatements
+
+ fn match_guard(_1: Option<&&i32>, _2: bool) -> i32 {
+ debug x => _1; // in scope 0 at $DIR/remove_fake_borrows.rs:+0:16: +0:17
+ debug c => _2; // in scope 0 at $DIR/remove_fake_borrows.rs:+0:34: +0:35
+ let mut _0: i32; // return place in scope 0 at $DIR/remove_fake_borrows.rs:+0:46: +0:49
+ let mut _3: isize; // in scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16
+ let mut _4: &std::option::Option<&&i32>; // in scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
+ let mut _5: &&i32; // in scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
+ let mut _6: &&&i32; // in scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
+ let mut _7: &i32; // in scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
+ let mut _8: bool; // in scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+
+ bb0: {
+- FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
+ _3 = discriminant(_1); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
+ switchInt(move _3) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = const 1_i32; // scope 0 at $DIR/remove_fake_borrows.rs:+3:14: +3:15
+ goto -> bb7; // scope 0 at $DIR/remove_fake_borrows.rs:+3:14: +3:15
+ }
+
+ bb2: {
+ switchInt((*(*((_1 as Some).0: &&i32)))) -> [0_i32: bb3, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+1:5: +1:12
+ }
+
+ bb3: {
+ goto -> bb4; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16
+ }
+
+ bb4: {
+- _4 = &shallow _1; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
+- _5 = &shallow (*((_1 as Some).0: &&i32)); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
+- _6 = &shallow ((_1 as Some).0: &&i32); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
+- _7 = &shallow (*(*((_1 as Some).0: &&i32))); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12
+ StorageLive(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+ _8 = _2; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+ switchInt(move _8) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+ }
+
+ bb5: {
+ StorageDead(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+- FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+- FakeRead(ForMatchGuard, _6); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+- FakeRead(ForMatchGuard, _7); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+ _0 = const 0_i32; // scope 0 at $DIR/remove_fake_borrows.rs:+2:25: +2:26
+ goto -> bb7; // scope 0 at $DIR/remove_fake_borrows.rs:+2:25: +2:26
+ }
+
+ bb6: {
+ StorageDead(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+ goto -> bb1; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+ }
+
+ bb7: {
+ return; // scope 0 at $DIR/remove_fake_borrows.rs:+5:2: +5:2
+ }
+
+ bb8 (cleanup): {
+ resume; // scope 0 at $DIR/remove_fake_borrows.rs:+0:1: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/remove_fake_borrows.rs b/src/test/mir-opt/remove_fake_borrows.rs
new file mode 100644
index 000000000..a980f386b
--- /dev/null
+++ b/src/test/mir-opt/remove_fake_borrows.rs
@@ -0,0 +1,15 @@
+// Test that the fake borrows for matches are removed after borrow checking.
+
+// ignore-wasm32-bare compiled with panic=abort by default
+
+// EMIT_MIR remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff
+fn match_guard(x: Option<&&i32>, c: bool) -> i32 {
+ match x {
+ Some(0) if c => 0,
+ _ => 1,
+ }
+}
+
+fn main() {
+ match_guard(None, true);
+}
diff --git a/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir b/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir
new file mode 100644
index 000000000..76bdd23be
--- /dev/null
+++ b/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir
@@ -0,0 +1,11 @@
+// MIR for `no_codegen` after PreCodegen
+
+fn no_codegen() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/remove-never-const.rs:+0:20: +0:20
+ scope 1 {
+ }
+
+ bb0: {
+ unreachable; // scope 0 at $DIR/remove-never-const.rs:+1:13: +1:33
+ }
+}
diff --git a/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff
new file mode 100644
index 000000000..750aaa88b
--- /dev/null
+++ b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff
@@ -0,0 +1,100 @@
+- // MIR for `main` before RemoveStorageMarkers
++ // MIR for `main` after RemoveStorageMarkers
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/remove_storage_markers.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/remove_storage_markers.rs:+1:9: +1:16
+ let mut _2: std::ops::Range<i32>; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ let mut _3: std::ops::Range<i32>; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ let mut _5: (); // in scope 0 at $DIR/remove_storage_markers.rs:+0:1: +5:2
+ let _6: (); // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ let mut _7: std::option::Option<i32>; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ let mut _8: &mut std::ops::Range<i32>; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ let mut _9: &mut std::ops::Range<i32>; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ let mut _10: isize; // in scope 0 at $DIR/remove_storage_markers.rs:+2:5: +4:6
+ let mut _11: !; // in scope 0 at $DIR/remove_storage_markers.rs:+2:5: +4:6
+ let mut _13: i32; // in scope 0 at $DIR/remove_storage_markers.rs:+3:16: +3:17
+ scope 1 {
+ debug sum => _1; // in scope 1 at $DIR/remove_storage_markers.rs:+1:9: +1:16
+ let mut _4: std::ops::Range<i32>; // in scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ scope 2 {
+ debug iter => _4; // in scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ let _12: i32; // in scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10
+ scope 3 {
+ debug i => _12; // in scope 3 at $DIR/remove_storage_markers.rs:+2:9: +2:10
+ }
+ scope 5 (inlined iter::range::<impl Iterator for std::ops::Range<i32>>::next) { // at $DIR/remove_storage_markers.rs:8:14: 8:19
+ debug self => _8; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+ let mut _14: &mut std::ops::Range<i32>; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+ }
+ }
+ scope 4 (inlined <std::ops::Range<i32> as IntoIterator>::into_iter) { // at $DIR/remove_storage_markers.rs:8:14: 8:19
+ debug self => _3; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ }
+ }
+
+ bb0: {
+- StorageLive(_1); // scope 0 at $DIR/remove_storage_markers.rs:+1:9: +1:16
+ _1 = const 0_i32; // scope 0 at $DIR/remove_storage_markers.rs:+1:19: +1:20
+- StorageLive(_2); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+- StorageLive(_3); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ Deinit(_3); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ (_3.0: i32) = const 0_i32; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ (_3.1: i32) = const 10_i32; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ _2 = move _3; // scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+- StorageDead(_3); // scope 1 at $DIR/remove_storage_markers.rs:+2:18: +2:19
+- StorageLive(_4); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ _4 = move _2; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ goto -> bb1; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
+ }
+
+ bb1: {
+- StorageLive(_6); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+- StorageLive(_7); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+- StorageLive(_8); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+- StorageLive(_9); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ _9 = &mut _4; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ _8 = &mut (*_9); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+- StorageLive(_14); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+ _14 = &mut (*_8); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+ _7 = <std::ops::Range<i32> as iter::range::RangeIteratorImpl>::spec_next(move _14) -> bb4; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL
+ // + literal: Const { ty: for<'r> fn(&'r mut std::ops::Range<i32>) -> Option<<std::ops::Range<i32> as iter::range::RangeIteratorImpl>::Item> {<std::ops::Range<i32> as iter::range::RangeIteratorImpl>::spec_next}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+- StorageLive(_12); // scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10
+ _12 = ((_7 as Some).0: i32); // scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10
+- StorageLive(_13); // scope 3 at $DIR/remove_storage_markers.rs:+3:16: +3:17
+ _13 = _12; // scope 3 at $DIR/remove_storage_markers.rs:+3:16: +3:17
+ _1 = Add(_1, move _13); // scope 3 at $DIR/remove_storage_markers.rs:+3:9: +3:17
+- StorageDead(_13); // scope 3 at $DIR/remove_storage_markers.rs:+3:16: +3:17
+ _6 = const (); // scope 3 at $DIR/remove_storage_markers.rs:+2:20: +4:6
+- StorageDead(_12); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
+- StorageDead(_9); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
+- StorageDead(_7); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
+- StorageDead(_6); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
+ _5 = const (); // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
+ goto -> bb1; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
+ }
+
+ bb3: {
+ _0 = const (); // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
+- StorageDead(_9); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
+- StorageDead(_7); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
+- StorageDead(_6); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
+- StorageDead(_4); // scope 1 at $DIR/remove_storage_markers.rs:+4:5: +4:6
+- StorageDead(_2); // scope 1 at $DIR/remove_storage_markers.rs:+4:5: +4:6
+- StorageDead(_1); // scope 0 at $DIR/remove_storage_markers.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/remove_storage_markers.rs:+5:2: +5:2
+ }
+
+ bb4: {
+- StorageDead(_14); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+- StorageDead(_8); // scope 2 at $DIR/remove_storage_markers.rs:+2:18: +2:19
+ _10 = discriminant(_7); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ switchInt(move _10) -> [0_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ }
+ }
+
diff --git a/src/test/mir-opt/remove_storage_markers.rs b/src/test/mir-opt/remove_storage_markers.rs
new file mode 100644
index 000000000..c144d3ff7
--- /dev/null
+++ b/src/test/mir-opt/remove_storage_markers.rs
@@ -0,0 +1,11 @@
+// Checks that storage markers are removed at opt-level=0.
+//
+// compile-flags: -C opt-level=0 -Coverflow-checks=off
+
+// EMIT_MIR remove_storage_markers.main.RemoveStorageMarkers.diff
+fn main() {
+ let mut sum = 0;
+ for i in 0..10 {
+ sum += i;
+ }
+}
diff --git a/src/test/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff b/src/test/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff
new file mode 100644
index 000000000..07e4dd418
--- /dev/null
+++ b/src/test/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff
@@ -0,0 +1,31 @@
+- // MIR for `cannot_opt_generic` before RemoveUnneededDrops
++ // MIR for `cannot_opt_generic` after RemoveUnneededDrops
+
+ fn cannot_opt_generic(_1: T) -> () {
+ debug x => _1; // in scope 0 at $DIR/remove_unneeded_drops.rs:+0:26: +0:27
+ let mut _0: (); // return place in scope 0 at $DIR/remove_unneeded_drops.rs:+0:32: +0:32
+ let _2: (); // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12
+ let mut _3: T; // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11
+ scope 1 (inlined std::mem::drop::<T>) { // at $DIR/remove_unneeded_drops.rs:21:5: 21:12
+ debug _x => _3; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12
+ StorageLive(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11
+ _3 = move _1; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11
+ drop(_3) -> [return: bb2, unwind: bb1]; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ }
+
+ bb1 (cleanup): {
+ resume; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:1: +2:2
+ }
+
+ bb2: {
+ StorageDead(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:11: +1:12
+ StorageDead(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:12: +1:13
+ nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:32: +2:2
+ return; // scope 0 at $DIR/remove_unneeded_drops.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff b/src/test/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff
new file mode 100644
index 000000000..e809ca4e9
--- /dev/null
+++ b/src/test/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff
@@ -0,0 +1,31 @@
+- // MIR for `dont_opt` before RemoveUnneededDrops
++ // MIR for `dont_opt` after RemoveUnneededDrops
+
+ fn dont_opt(_1: Vec<bool>) -> () {
+ debug x => _1; // in scope 0 at $DIR/remove_unneeded_drops.rs:+0:13: +0:14
+ let mut _0: (); // return place in scope 0 at $DIR/remove_unneeded_drops.rs:+0:27: +0:27
+ let _2: (); // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12
+ let mut _3: std::vec::Vec<bool>; // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11
+ scope 1 (inlined std::mem::drop::<Vec<bool>>) { // at $DIR/remove_unneeded_drops.rs:9:5: 9:12
+ debug _x => _3; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12
+ StorageLive(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11
+ _3 = move _1; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11
+ drop(_3) -> [return: bb2, unwind: bb1]; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ }
+
+ bb1 (cleanup): {
+ resume; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:1: +2:2
+ }
+
+ bb2: {
+ StorageDead(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:11: +1:12
+ StorageDead(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:12: +1:13
+ nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:27: +2:2
+ return; // scope 0 at $DIR/remove_unneeded_drops.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff b/src/test/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff
new file mode 100644
index 000000000..087f76dbd
--- /dev/null
+++ b/src/test/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff
@@ -0,0 +1,27 @@
+- // MIR for `opt` before RemoveUnneededDrops
++ // MIR for `opt` after RemoveUnneededDrops
+
+ fn opt(_1: bool) -> () {
+ debug x => _1; // in scope 0 at $DIR/remove_unneeded_drops.rs:+0:8: +0:9
+ let mut _0: (); // return place in scope 0 at $DIR/remove_unneeded_drops.rs:+0:17: +0:17
+ let _2: (); // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12
+ let mut _3: bool; // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11
+ scope 1 (inlined std::mem::drop::<bool>) { // at $DIR/remove_unneeded_drops.rs:4:5: 4:12
+ debug _x => _3; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12
+ StorageLive(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11
+ _3 = _1; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11
+- drop(_3) -> bb1; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+- }
+-
+- bb1: {
+ StorageDead(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:11: +1:12
+ StorageDead(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:12: +1:13
+- nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:17: +2:2
+ return; // scope 0 at $DIR/remove_unneeded_drops.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff b/src/test/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff
new file mode 100644
index 000000000..933d6895f
--- /dev/null
+++ b/src/test/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff
@@ -0,0 +1,27 @@
+- // MIR for `opt_generic_copy` before RemoveUnneededDrops
++ // MIR for `opt_generic_copy` after RemoveUnneededDrops
+
+ fn opt_generic_copy(_1: T) -> () {
+ debug x => _1; // in scope 0 at $DIR/remove_unneeded_drops.rs:+0:30: +0:31
+ let mut _0: (); // return place in scope 0 at $DIR/remove_unneeded_drops.rs:+0:36: +0:36
+ let _2: (); // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12
+ let mut _3: T; // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11
+ scope 1 (inlined std::mem::drop::<T>) { // at $DIR/remove_unneeded_drops.rs:14:5: 14:12
+ debug _x => _3; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12
+ StorageLive(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11
+ _3 = _1; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11
+- drop(_3) -> bb1; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+- }
+-
+- bb1: {
+ StorageDead(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:11: +1:12
+ StorageDead(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:12: +1:13
+- nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:36: +2:2
+ return; // scope 0 at $DIR/remove_unneeded_drops.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/remove_unneeded_drops.rs b/src/test/mir-opt/remove_unneeded_drops.rs
new file mode 100644
index 000000000..1052f2886
--- /dev/null
+++ b/src/test/mir-opt/remove_unneeded_drops.rs
@@ -0,0 +1,29 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+// EMIT_MIR remove_unneeded_drops.opt.RemoveUnneededDrops.diff
+fn opt(x: bool) {
+ drop(x);
+}
+
+// EMIT_MIR remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff
+fn dont_opt(x: Vec<bool>) {
+ drop(x);
+}
+
+// EMIT_MIR remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff
+fn opt_generic_copy<T: Copy>(x: T) {
+ drop(x);
+}
+
+// EMIT_MIR remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff
+// since the pass is not running on monomorphisized code,
+// we can't (but probably should) optimize this
+fn cannot_opt_generic<T>(x: T) {
+ drop(x);
+}
+
+fn main() {
+ opt(true);
+ opt_generic_copy(42);
+ cannot_opt_generic(42);
+ dont_opt(vec![true]);
+}
diff --git a/src/test/mir-opt/remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir b/src/test/mir-opt/remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir
new file mode 100644
index 000000000..7d9e60462
--- /dev/null
+++ b/src/test/mir-opt/remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir
@@ -0,0 +1,15 @@
+// MIR for `get_union` after RemoveZsts
+
+fn get_union() -> Foo {
+ let mut _0: Foo; // return place in scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+0:19: +0:22
+ let mut _1: (); // in scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:14: +1:16
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:14: +1:16
+ nop; // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:14: +1:16
+ Deinit(_0); // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:5: +1:18
+ (_0.0: ()) = move _1; // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:5: +1:18
+ StorageDead(_1); // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:17: +1:18
+ return; // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/remove_zsts_dont_touch_unions.rs b/src/test/mir-opt/remove_zsts_dont_touch_unions.rs
new file mode 100644
index 000000000..7a6f86b80
--- /dev/null
+++ b/src/test/mir-opt/remove_zsts_dont_touch_unions.rs
@@ -0,0 +1,19 @@
+// compile-flags: -Zmir-opt-level=3
+
+// Ensure RemoveZsts doesn't remove ZST assignments to union fields,
+// which causes problems in Miri.
+
+union Foo {
+ x: (),
+ y: u64,
+}
+
+// EMIT_MIR remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir
+fn get_union() -> Foo {
+ Foo { x: () }
+}
+
+
+fn main() {
+ get_union();
+}
diff --git a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..451d0fe4c
--- /dev/null
+++ b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,198 @@
+// MIR for `array_casts` after SimplifyCfg-elaborate-drops
+
+fn array_casts() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/retag.rs:+0:18: +0:18
+ let mut _1: [usize; 2]; // in scope 0 at $DIR/retag.rs:+1:9: +1:14
+ let mut _3: *mut [usize; 2]; // in scope 0 at $DIR/retag.rs:+2:13: +2:19
+ let mut _4: &mut [usize; 2]; // in scope 0 at $DIR/retag.rs:+2:13: +2:19
+ let _5: (); // in scope 0 at $DIR/retag.rs:+3:5: +3:30
+ let mut _6: *mut usize; // in scope 0 at $DIR/retag.rs:+3:15: +3:23
+ let mut _7: *mut usize; // in scope 0 at $DIR/retag.rs:+3:15: +3:16
+ let mut _10: *const [usize; 2]; // in scope 0 at $DIR/retag.rs:+6:13: +6:15
+ let _11: &[usize; 2]; // in scope 0 at $DIR/retag.rs:+6:13: +6:15
+ let _12: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _13: (&usize, &usize); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _14: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _15: usize; // in scope 0 at $DIR/retag.rs:+7:16: +7:36
+ let mut _16: *const usize; // in scope 0 at $DIR/retag.rs:+7:26: +7:34
+ let mut _17: *const usize; // in scope 0 at $DIR/retag.rs:+7:26: +7:27
+ let mut _18: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _19: usize; // in scope 0 at $DIR/retag.rs:+7:38: +7:39
+ let mut _22: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _23: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _24: usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _25: usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _26: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _28: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _29: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _30: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _31: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _32: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _33: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _34: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/retag.rs:+1:9: +1:14
+ let _2: *mut usize; // in scope 1 at $DIR/retag.rs:+2:9: +2:10
+ scope 2 {
+ debug p => _2; // in scope 2 at $DIR/retag.rs:+2:9: +2:10
+ let _8: [usize; 2]; // in scope 2 at $DIR/retag.rs:+5:9: +5:10
+ scope 3 {
+ }
+ scope 4 {
+ debug x => _8; // in scope 4 at $DIR/retag.rs:+5:9: +5:10
+ let _9: *const usize; // in scope 4 at $DIR/retag.rs:+6:9: +6:10
+ scope 5 {
+ debug p => _9; // in scope 5 at $DIR/retag.rs:+6:9: +6:10
+ let _20: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _21: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _35: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 6 {
+ }
+ scope 7 {
+ debug left_val => _20; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ debug right_val => _21; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _27: core::panicking::AssertKind; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 8 {
+ debug kind => _27; // in scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/retag.rs:+1:9: +1:14
+ _1 = [const 0_usize, const 0_usize]; // scope 0 at $DIR/retag.rs:+1:29: +1:35
+ StorageLive(_2); // scope 1 at $DIR/retag.rs:+2:9: +2:10
+ StorageLive(_3); // scope 1 at $DIR/retag.rs:+2:13: +2:19
+ StorageLive(_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19
+ _4 = &mut _1; // scope 1 at $DIR/retag.rs:+2:13: +2:19
+ Retag(_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19
+ _3 = &raw mut (*_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19
+ Retag([raw] _3); // scope 1 at $DIR/retag.rs:+2:13: +2:19
+ _2 = move _3 as *mut usize (Pointer(ArrayToPointer)); // scope 1 at $DIR/retag.rs:+2:13: +2:33
+ StorageDead(_3); // scope 1 at $DIR/retag.rs:+2:32: +2:33
+ StorageDead(_4); // scope 1 at $DIR/retag.rs:+2:33: +2:34
+ StorageLive(_5); // scope 2 at $DIR/retag.rs:+3:5: +3:30
+ StorageLive(_6); // scope 3 at $DIR/retag.rs:+3:15: +3:23
+ StorageLive(_7); // scope 3 at $DIR/retag.rs:+3:15: +3:16
+ _7 = _2; // scope 3 at $DIR/retag.rs:+3:15: +3:16
+ _6 = ptr::mut_ptr::<impl *mut usize>::add(move _7, const 1_usize) -> bb1; // scope 3 at $DIR/retag.rs:+3:15: +3:23
+ // mir::Constant
+ // + span: $DIR/retag.rs:60:17: 60:20
+ // + literal: Const { ty: unsafe fn(*mut usize, usize) -> *mut usize {ptr::mut_ptr::<impl *mut usize>::add}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_7); // scope 3 at $DIR/retag.rs:+3:22: +3:23
+ (*_6) = const 1_usize; // scope 3 at $DIR/retag.rs:+3:14: +3:27
+ StorageDead(_6); // scope 3 at $DIR/retag.rs:+3:27: +3:28
+ _5 = const (); // scope 3 at $DIR/retag.rs:+3:5: +3:30
+ StorageDead(_5); // scope 2 at $DIR/retag.rs:+3:29: +3:30
+ StorageLive(_8); // scope 2 at $DIR/retag.rs:+5:9: +5:10
+ _8 = [const 0_usize, const 1_usize]; // scope 2 at $DIR/retag.rs:+5:25: +5:31
+ StorageLive(_9); // scope 4 at $DIR/retag.rs:+6:9: +6:10
+ StorageLive(_10); // scope 4 at $DIR/retag.rs:+6:13: +6:15
+ StorageLive(_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15
+ _11 = &_8; // scope 4 at $DIR/retag.rs:+6:13: +6:15
+ Retag(_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15
+ _10 = &raw const (*_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15
+ Retag([raw] _10); // scope 4 at $DIR/retag.rs:+6:13: +6:15
+ _9 = move _10 as *const usize (Pointer(ArrayToPointer)); // scope 4 at $DIR/retag.rs:+6:13: +6:31
+ StorageDead(_10); // scope 4 at $DIR/retag.rs:+6:30: +6:31
+ StorageDead(_11); // scope 4 at $DIR/retag.rs:+6:31: +6:32
+ StorageLive(_12); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_15); // scope 5 at $DIR/retag.rs:+7:16: +7:36
+ StorageLive(_16); // scope 6 at $DIR/retag.rs:+7:26: +7:34
+ StorageLive(_17); // scope 6 at $DIR/retag.rs:+7:26: +7:27
+ _17 = _9; // scope 6 at $DIR/retag.rs:+7:26: +7:27
+ _16 = ptr::const_ptr::<impl *const usize>::add(move _17, const 1_usize) -> bb2; // scope 6 at $DIR/retag.rs:+7:26: +7:34
+ // mir::Constant
+ // + span: $DIR/retag.rs:64:28: 64:31
+ // + literal: Const { ty: unsafe fn(*const usize, usize) -> *const usize {ptr::const_ptr::<impl *const usize>::add}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_17); // scope 6 at $DIR/retag.rs:+7:33: +7:34
+ _15 = (*_16); // scope 6 at $DIR/retag.rs:+7:25: +7:34
+ _14 = &_15; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _35 = const array_casts::promoted[0]; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: &usize, val: Unevaluated(array_casts, [], Some(promoted[0])) }
+ Retag(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _13 = (move _14, move _18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _20 = (_13.0: &usize); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _21 = (_13.1: &usize); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_22); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_24); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _24 = (*_20); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_25); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _25 = (*_21); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _23 = Eq(move _24, move _25); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_25); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_24); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _22 = Not(move _23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ switchInt(move _22) -> [false: bb4, otherwise: bb3]; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb3: {
+ StorageLive(_27); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _27 = core::panicking::AssertKind::Eq; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_28); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_29); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _29 = move _27; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _31 = &(*_20); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _30 = &(*_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _33 = &(*_21); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _32 = &(*_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _34 = Option::<Arguments>::None; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r usize, &'s usize, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<usize, usize>}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ _12 = const (); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_22); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_12); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _0 = const (); // scope 0 at $DIR/retag.rs:+0:18: +8:2
+ StorageDead(_9); // scope 4 at $DIR/retag.rs:+8:1: +8:2
+ StorageDead(_8); // scope 2 at $DIR/retag.rs:+8:1: +8:2
+ StorageDead(_2); // scope 1 at $DIR/retag.rs:+8:1: +8:2
+ StorageDead(_1); // scope 0 at $DIR/retag.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/retag.rs:+8:2: +8:2
+ }
+}
diff --git a/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir b/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir
new file mode 100644
index 000000000..84f674db2
--- /dev/null
+++ b/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir
@@ -0,0 +1,20 @@
+// MIR for `std::ptr::drop_in_place` after SimplifyCfg-make_shim
+
+fn std::ptr::drop_in_place(_1: *mut Test) -> () {
+ let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _2: &mut Test; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+
+ bb0: {
+ Retag([raw] _1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _3 = <Test as Drop>::drop(move _2) -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r> fn(&'r mut Test) {<Test as Drop>::drop}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+}
diff --git a/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..60c0f336e
--- /dev/null
+++ b/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,22 @@
+// MIR for `main::{closure#0}` after SimplifyCfg-elaborate-drops
+
+fn main::{closure#0}(_1: &[closure@main::{closure#0}], _2: &i32) -> &i32 {
+ debug x => _2; // in scope 0 at $DIR/retag.rs:+0:32: +0:33
+ let mut _0: &i32; // return place in scope 0 at $DIR/retag.rs:+0:44: +0:48
+ let _3: &i32; // in scope 0 at $DIR/retag.rs:+1:13: +1:15
+ scope 1 {
+ debug _y => _3; // in scope 1 at $DIR/retag.rs:+1:13: +1:15
+ }
+
+ bb0: {
+ Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:31: +0:48
+ Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:31: +0:48
+ StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:13: +1:15
+ _3 = _2; // scope 0 at $DIR/retag.rs:+1:18: +1:19
+ Retag(_3); // scope 0 at $DIR/retag.rs:+1:18: +1:19
+ _0 = _2; // scope 1 at $DIR/retag.rs:+2:9: +2:10
+ Retag(_0); // scope 1 at $DIR/retag.rs:+2:9: +2:10
+ StorageDead(_3); // scope 0 at $DIR/retag.rs:+3:5: +3:6
+ return; // scope 0 at $DIR/retag.rs:+0:48: +0:48
+ }
+}
diff --git a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..ae6b5cfe2
--- /dev/null
+++ b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,210 @@
+// MIR for `main` after SimplifyCfg-elaborate-drops
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/retag.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/retag.rs:+1:9: +1:14
+ let _2: (); // in scope 0 at $DIR/retag.rs:+2:5: +8:6
+ let mut _4: &Test; // in scope 0 at $DIR/retag.rs:+3:17: +3:36
+ let _5: Test; // in scope 0 at $DIR/retag.rs:+3:17: +3:24
+ let mut _6: &mut i32; // in scope 0 at $DIR/retag.rs:+3:29: +3:35
+ let mut _7: &mut i32; // in scope 0 at $DIR/retag.rs:+3:29: +3:35
+ let mut _9: &mut i32; // in scope 0 at $DIR/retag.rs:+4:19: +4:20
+ let mut _12: *mut i32; // in scope 0 at $DIR/retag.rs:+7:18: +7:29
+ let mut _14: [closure@main::{closure#0}]; // in scope 0 at $DIR/retag.rs:+11:31: +14:6
+ let mut _16: for<'r> fn(&'r i32) -> &'r i32; // in scope 0 at $DIR/retag.rs:+15:14: +15:15
+ let mut _17: &i32; // in scope 0 at $DIR/retag.rs:+15:16: +15:18
+ let _18: &i32; // in scope 0 at $DIR/retag.rs:+15:16: +15:18
+ let _19: &i32; // in scope 0 at $DIR/retag.rs:+18:5: +18:24
+ let mut _20: &Test; // in scope 0 at $DIR/retag.rs:+18:5: +18:24
+ let _21: Test; // in scope 0 at $DIR/retag.rs:+18:5: +18:12
+ let mut _22: &i32; // in scope 0 at $DIR/retag.rs:+18:21: +18:23
+ let _23: &i32; // in scope 0 at $DIR/retag.rs:+18:21: +18:23
+ let _24: i32; // in scope 0 at $DIR/retag.rs:+18:22: +18:23
+ let mut _26: *const i32; // in scope 0 at $DIR/retag.rs:+21:14: +21:28
+ let _27: (); // in scope 0 at $DIR/retag.rs:+23:5: +23:18
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/retag.rs:+1:9: +1:14
+ let _3: &mut i32; // in scope 1 at $DIR/retag.rs:+3:13: +3:14
+ let _13: for<'r> fn(&'r i32) -> &'r i32; // in scope 1 at $DIR/retag.rs:+11:9: +11:10
+ scope 2 {
+ debug v => _3; // in scope 2 at $DIR/retag.rs:+3:13: +3:14
+ let _8: &mut i32; // in scope 2 at $DIR/retag.rs:+4:13: +4:14
+ scope 3 {
+ debug w => _8; // in scope 3 at $DIR/retag.rs:+4:13: +4:14
+ let _10: &mut i32; // in scope 3 at $DIR/retag.rs:+5:13: +5:14
+ scope 4 {
+ debug w => _10; // in scope 4 at $DIR/retag.rs:+5:13: +5:14
+ let _11: *mut i32; // in scope 4 at $DIR/retag.rs:+7:13: +7:15
+ scope 5 {
+ debug _w => _11; // in scope 5 at $DIR/retag.rs:+7:13: +7:15
+ }
+ }
+ }
+ }
+ scope 6 {
+ debug c => _13; // in scope 6 at $DIR/retag.rs:+11:9: +11:10
+ let _15: &i32; // in scope 6 at $DIR/retag.rs:+15:9: +15:11
+ scope 7 {
+ debug _w => _15; // in scope 7 at $DIR/retag.rs:+15:9: +15:11
+ let _25: *const i32; // in scope 7 at $DIR/retag.rs:+21:9: +21:11
+ let mut _28: &i32; // in scope 7 at $DIR/retag.rs:+18:21: +18:23
+ scope 8 {
+ debug _w => _25; // in scope 8 at $DIR/retag.rs:+21:9: +21:11
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/retag.rs:+1:9: +1:14
+ _1 = const 0_i32; // scope 0 at $DIR/retag.rs:+1:17: +1:18
+ StorageLive(_2); // scope 1 at $DIR/retag.rs:+2:5: +8:6
+ StorageLive(_3); // scope 1 at $DIR/retag.rs:+3:13: +3:14
+ StorageLive(_4); // scope 1 at $DIR/retag.rs:+3:17: +3:36
+ StorageLive(_5); // scope 1 at $DIR/retag.rs:+3:17: +3:24
+ _5 = Test(const 0_i32); // scope 1 at $DIR/retag.rs:+3:17: +3:24
+ _4 = &_5; // scope 1 at $DIR/retag.rs:+3:17: +3:36
+ Retag(_4); // scope 1 at $DIR/retag.rs:+3:17: +3:36
+ StorageLive(_6); // scope 1 at $DIR/retag.rs:+3:29: +3:35
+ StorageLive(_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35
+ _7 = &mut _1; // scope 1 at $DIR/retag.rs:+3:29: +3:35
+ Retag(_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35
+ _6 = &mut (*_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35
+ Retag([2phase] _6); // scope 1 at $DIR/retag.rs:+3:29: +3:35
+ _3 = Test::foo(move _4, move _6) -> [return: bb1, unwind: bb8]; // scope 1 at $DIR/retag.rs:+3:17: +3:36
+ // mir::Constant
+ // + span: $DIR/retag.rs:32:25: 32:28
+ // + literal: Const { ty: for<'r, 'x> fn(&'r Test, &'x mut i32) -> &'x mut i32 {Test::foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ Retag(_3); // scope 1 at $DIR/retag.rs:+3:17: +3:36
+ StorageDead(_6); // scope 1 at $DIR/retag.rs:+3:35: +3:36
+ StorageDead(_4); // scope 1 at $DIR/retag.rs:+3:35: +3:36
+ StorageDead(_7); // scope 1 at $DIR/retag.rs:+3:36: +3:37
+ drop(_5) -> [return: bb2, unwind: bb9]; // scope 1 at $DIR/retag.rs:+3:36: +3:37
+ }
+
+ bb2: {
+ StorageDead(_5); // scope 1 at $DIR/retag.rs:+3:36: +3:37
+ StorageLive(_8); // scope 2 at $DIR/retag.rs:+4:13: +4:14
+ StorageLive(_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20
+ _9 = move _3; // scope 2 at $DIR/retag.rs:+4:19: +4:20
+ Retag(_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20
+ _8 = &mut (*_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20
+ Retag(_8); // scope 2 at $DIR/retag.rs:+4:19: +4:20
+ StorageDead(_9); // scope 2 at $DIR/retag.rs:+4:22: +4:23
+ StorageLive(_10); // scope 3 at $DIR/retag.rs:+5:13: +5:14
+ _10 = move _8; // scope 3 at $DIR/retag.rs:+5:17: +5:18
+ Retag(_10); // scope 3 at $DIR/retag.rs:+5:17: +5:18
+ StorageLive(_11); // scope 4 at $DIR/retag.rs:+7:13: +7:15
+ StorageLive(_12); // scope 4 at $DIR/retag.rs:+7:18: +7:29
+ _12 = &raw mut (*_10); // scope 4 at $DIR/retag.rs:+7:18: +7:19
+ Retag([raw] _12); // scope 4 at $DIR/retag.rs:+7:18: +7:19
+ _11 = _12; // scope 4 at $DIR/retag.rs:+7:18: +7:29
+ StorageDead(_12); // scope 4 at $DIR/retag.rs:+7:29: +7:30
+ _2 = const (); // scope 1 at $DIR/retag.rs:+2:5: +8:6
+ StorageDead(_11); // scope 4 at $DIR/retag.rs:+8:5: +8:6
+ StorageDead(_10); // scope 3 at $DIR/retag.rs:+8:5: +8:6
+ StorageDead(_8); // scope 2 at $DIR/retag.rs:+8:5: +8:6
+ StorageDead(_3); // scope 1 at $DIR/retag.rs:+8:5: +8:6
+ StorageDead(_2); // scope 1 at $DIR/retag.rs:+8:5: +8:6
+ StorageLive(_13); // scope 1 at $DIR/retag.rs:+11:9: +11:10
+ StorageLive(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6
+ _14 = [closure@main::{closure#0}]; // scope 1 at $DIR/retag.rs:+11:31: +14:6
+ // closure
+ // + def_id: DefId(0:14 ~ retag[4622]::main::{closure#0})
+ // + substs: [
+ // i8,
+ // for<'r> extern "rust-call" fn((&'r i32,)) -> &'r i32,
+ // (),
+ // ]
+ Retag(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6
+ _13 = move _14 as for<'r> fn(&'r i32) -> &'r i32 (Pointer(ClosureFnPointer(Normal))); // scope 1 at $DIR/retag.rs:+11:31: +14:6
+ StorageDead(_14); // scope 1 at $DIR/retag.rs:+11:47: +11:48
+ StorageLive(_15); // scope 6 at $DIR/retag.rs:+15:9: +15:11
+ StorageLive(_16); // scope 6 at $DIR/retag.rs:+15:14: +15:15
+ _16 = _13; // scope 6 at $DIR/retag.rs:+15:14: +15:15
+ StorageLive(_17); // scope 6 at $DIR/retag.rs:+15:16: +15:18
+ StorageLive(_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18
+ _18 = &_1; // scope 6 at $DIR/retag.rs:+15:16: +15:18
+ Retag(_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18
+ _17 = &(*_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18
+ Retag(_17); // scope 6 at $DIR/retag.rs:+15:16: +15:18
+ _15 = move _16(move _17) -> bb3; // scope 6 at $DIR/retag.rs:+15:14: +15:19
+ }
+
+ bb3: {
+ Retag(_15); // scope 6 at $DIR/retag.rs:+15:14: +15:19
+ StorageDead(_17); // scope 6 at $DIR/retag.rs:+15:18: +15:19
+ StorageDead(_16); // scope 6 at $DIR/retag.rs:+15:18: +15:19
+ StorageDead(_18); // scope 6 at $DIR/retag.rs:+15:19: +15:20
+ StorageLive(_19); // scope 7 at $DIR/retag.rs:+18:5: +18:24
+ StorageLive(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24
+ StorageLive(_21); // scope 7 at $DIR/retag.rs:+18:5: +18:12
+ _21 = Test(const 0_i32); // scope 7 at $DIR/retag.rs:+18:5: +18:12
+ _20 = &_21; // scope 7 at $DIR/retag.rs:+18:5: +18:24
+ Retag(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24
+ StorageLive(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23
+ StorageLive(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23
+ _28 = const main::promoted[0]; // scope 7 at $DIR/retag.rs:+18:21: +18:23
+ // mir::Constant
+ // + span: $DIR/retag.rs:47:21: 47:23
+ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
+ Retag(_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23
+ _23 = &(*_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23
+ Retag(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23
+ _22 = &(*_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23
+ Retag(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23
+ _19 = Test::foo_shr(move _20, move _22) -> [return: bb4, unwind: bb7]; // scope 7 at $DIR/retag.rs:+18:5: +18:24
+ // mir::Constant
+ // + span: $DIR/retag.rs:47:13: 47:20
+ // + literal: Const { ty: for<'r, 'x> fn(&'r Test, &'x i32) -> &'x i32 {Test::foo_shr}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ Retag(_19); // scope 7 at $DIR/retag.rs:+18:5: +18:24
+ StorageDead(_22); // scope 7 at $DIR/retag.rs:+18:23: +18:24
+ StorageDead(_20); // scope 7 at $DIR/retag.rs:+18:23: +18:24
+ StorageDead(_23); // scope 7 at $DIR/retag.rs:+18:24: +18:25
+ drop(_21) -> [return: bb5, unwind: bb9]; // scope 7 at $DIR/retag.rs:+18:24: +18:25
+ }
+
+ bb5: {
+ StorageDead(_21); // scope 7 at $DIR/retag.rs:+18:24: +18:25
+ StorageDead(_19); // scope 7 at $DIR/retag.rs:+18:24: +18:25
+ StorageLive(_25); // scope 7 at $DIR/retag.rs:+21:9: +21:11
+ StorageLive(_26); // scope 7 at $DIR/retag.rs:+21:14: +21:28
+ _26 = &raw const (*_15); // scope 7 at $DIR/retag.rs:+21:14: +21:16
+ Retag([raw] _26); // scope 7 at $DIR/retag.rs:+21:14: +21:16
+ _25 = _26; // scope 7 at $DIR/retag.rs:+21:14: +21:28
+ StorageDead(_26); // scope 7 at $DIR/retag.rs:+21:28: +21:29
+ StorageLive(_27); // scope 8 at $DIR/retag.rs:+23:5: +23:18
+ _27 = array_casts() -> bb6; // scope 8 at $DIR/retag.rs:+23:5: +23:18
+ // mir::Constant
+ // + span: $DIR/retag.rs:52:5: 52:16
+ // + literal: Const { ty: fn() {array_casts}, val: Value(<ZST>) }
+ }
+
+ bb6: {
+ StorageDead(_27); // scope 8 at $DIR/retag.rs:+23:18: +23:19
+ _0 = const (); // scope 0 at $DIR/retag.rs:+0:11: +24:2
+ StorageDead(_25); // scope 7 at $DIR/retag.rs:+24:1: +24:2
+ StorageDead(_15); // scope 6 at $DIR/retag.rs:+24:1: +24:2
+ StorageDead(_13); // scope 1 at $DIR/retag.rs:+24:1: +24:2
+ StorageDead(_1); // scope 0 at $DIR/retag.rs:+24:1: +24:2
+ return; // scope 0 at $DIR/retag.rs:+24:2: +24:2
+ }
+
+ bb7 (cleanup): {
+ drop(_21) -> bb9; // scope 7 at $DIR/retag.rs:+18:24: +18:25
+ }
+
+ bb8 (cleanup): {
+ drop(_5) -> bb9; // scope 1 at $DIR/retag.rs:+3:36: +3:37
+ }
+
+ bb9 (cleanup): {
+ resume; // scope 0 at $DIR/retag.rs:+0:1: +24:2
+ }
+}
diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs
new file mode 100644
index 000000000..13568b822
--- /dev/null
+++ b/src/test/mir-opt/retag.rs
@@ -0,0 +1,65 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+// ignore-tidy-linelength
+// compile-flags: -Z mir-emit-retag -Z mir-opt-level=0 -Z span_free_formats
+
+#![allow(unused)]
+
+struct Test(i32);
+
+// EMIT_MIR retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir
+// EMIT_MIR retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir
+impl Test {
+ // Make sure we run the pass on a method, not just on bare functions.
+ fn foo<'x>(&self, x: &'x mut i32) -> &'x mut i32 {
+ x
+ }
+ fn foo_shr<'x>(&self, x: &'x i32) -> &'x i32 {
+ x
+ }
+}
+
+// EMIT_MIR core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir
+
+impl Drop for Test {
+ fn drop(&mut self) {}
+}
+
+// EMIT_MIR retag.main.SimplifyCfg-elaborate-drops.after.mir
+// EMIT_MIR retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir
+fn main() {
+ let mut x = 0;
+ {
+ let v = Test(0).foo(&mut x); // just making sure we do not panic when there is a tuple struct ctor
+ let w = { v }; // assignment
+ let w = w; // reborrow
+ // escape-to-raw (mut)
+ let _w = w as *mut _;
+ }
+
+ // Also test closures
+ let c: fn(&i32) -> &i32 = |x: &i32| -> &i32 {
+ let _y = x;
+ x
+ };
+ let _w = c(&x);
+
+ // need to call `foo_shr` or it doesn't even get generated
+ Test(0).foo_shr(&0);
+
+ // escape-to-raw (shr)
+ let _w = _w as *const _;
+
+ array_casts();
+}
+
+/// Casting directly to an array should also go through `&raw` and thus add appropriate retags.
+// EMIT_MIR retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
+fn array_casts() {
+ let mut x: [usize; 2] = [0, 0];
+ let p = &mut x as *mut usize;
+ unsafe { *p.add(1) = 1; }
+
+ let x: [usize; 2] = [0, 1];
+ let p = &x as *const usize;
+ assert_eq!(unsafe { *p.add(1) }, 1);
+}
diff --git a/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..e395fdb27
--- /dev/null
+++ b/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,20 @@
+// MIR for `<impl at $DIR/retag.rs:11:1: 11:10>::foo` after SimplifyCfg-elaborate-drops
+
+fn <impl at $DIR/retag.rs:11:1: 11:10>::foo(_1: &Test, _2: &mut i32) -> &mut i32 {
+ debug self => _1; // in scope 0 at $DIR/retag.rs:+0:16: +0:21
+ debug x => _2; // in scope 0 at $DIR/retag.rs:+0:23: +0:24
+ let mut _0: &mut i32; // return place in scope 0 at $DIR/retag.rs:+0:42: +0:53
+ let mut _3: &mut i32; // in scope 0 at $DIR/retag.rs:+1:9: +1:10
+
+ bb0: {
+ Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:5: +2:6
+ Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:5: +2:6
+ StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10
+ _3 = &mut (*_2); // scope 0 at $DIR/retag.rs:+1:9: +1:10
+ Retag(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10
+ _0 = &mut (*_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10
+ Retag(_0); // scope 0 at $DIR/retag.rs:+1:9: +1:10
+ StorageDead(_3); // scope 0 at $DIR/retag.rs:+2:5: +2:6
+ return; // scope 0 at $DIR/retag.rs:+2:6: +2:6
+ }
+}
diff --git a/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..e609166de
--- /dev/null
+++ b/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,15 @@
+// MIR for `<impl at $DIR/retag.rs:11:1: 11:10>::foo_shr` after SimplifyCfg-elaborate-drops
+
+fn <impl at $DIR/retag.rs:11:1: 11:10>::foo_shr(_1: &Test, _2: &i32) -> &i32 {
+ debug self => _1; // in scope 0 at $DIR/retag.rs:+0:20: +0:25
+ debug x => _2; // in scope 0 at $DIR/retag.rs:+0:27: +0:28
+ let mut _0: &i32; // return place in scope 0 at $DIR/retag.rs:+0:42: +0:49
+
+ bb0: {
+ Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:5: +2:6
+ Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:5: +2:6
+ _0 = _2; // scope 0 at $DIR/retag.rs:+1:9: +1:10
+ Retag(_0); // scope 0 at $DIR/retag.rs:+1:9: +1:10
+ return; // scope 0 at $DIR/retag.rs:+2:6: +2:6
+ }
+}
diff --git a/src/test/mir-opt/return_an_array.rs b/src/test/mir-opt/return_an_array.rs
new file mode 100644
index 000000000..bea3c317c
--- /dev/null
+++ b/src/test/mir-opt/return_an_array.rs
@@ -0,0 +1,8 @@
+// this tests move up progration, which is not yet implemented
+
+fn foo() -> [u8; 1024] {
+ let x = [0; 1024];
+ return x;
+}
+
+fn main() { }
diff --git a/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff b/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff
new file mode 100644
index 000000000..c3e503bf2
--- /dev/null
+++ b/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff
@@ -0,0 +1,72 @@
+- // MIR for `try_identity` before DestinationPropagation
++ // MIR for `try_identity` after DestinationPropagation
+
+ fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
+ debug x => _1; // in scope 0 at $DIR/simplify_try.rs:6:17: 6:18
+ let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:6:41: 6:57
+ let _2: u32; // in scope 0 at $DIR/simplify_try.rs:7:9: 7:10
+ let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15
+ let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:14
+ let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
+ let _6: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
+ let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
+ let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
+ let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
+ let _10: u32; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15
+ let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:8:8: 8:9
+ scope 1 {
+ debug y => _2; // in scope 1 at $DIR/simplify_try.rs:7:9: 7:10
+ }
+ scope 2 {
+ debug err => _6; // in scope 2 at $DIR/simplify_try.rs:7:14: 7:15
+ scope 3 {
+ scope 7 {
+ debug t => _9; // in scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
+ }
+ scope 8 {
+ debug v => _8; // in scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
+ let mut _12: i32; // in scope 8 at $DIR/simplify_try.rs:7:14: 7:15
+ }
+ }
+ }
+ scope 4 {
+ debug val => _10; // in scope 4 at $DIR/simplify_try.rs:7:13: 7:15
+ scope 5 {
+ }
+ }
+ scope 6 {
+- debug self => _4; // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
++ debug self => _0; // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:7:9: 7:10
+- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:7:13: 7:15
+- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
+- _4 = _1; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
+- _3 = move _4; // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
+- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
+- _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
++ nop; // scope 0 at $DIR/simplify_try.rs:7:13: 7:15
++ nop; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
++ _0 = _1; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
++ nop; // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
++ nop; // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
++ _5 = discriminant(_0); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
+ goto -> bb1; // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
+ }
+
+ bb1: {
+- _0 = move _3; // scope 1 at $DIR/simplify_try.rs:8:5: 8:10
+- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:7:15: 7:16
++ nop; // scope 1 at $DIR/simplify_try.rs:8:5: 8:10
++ nop; // scope 0 at $DIR/simplify_try.rs:7:15: 7:16
+ StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:9:1: 9:2
+ goto -> bb2; // scope 0 at $DIR/simplify_try.rs:9:2: 9:2
+ }
+
+ bb2: {
+ return; // scope 0 at $DIR/simplify_try.rs:9:2: 9:2
+ }
+ }
+
diff --git a/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff b/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff
new file mode 100644
index 000000000..3a11e45ca
--- /dev/null
+++ b/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff
@@ -0,0 +1,145 @@
+- // MIR for `identity` before ConstProp
++ // MIR for `identity` after ConstProp
+
+ fn identity(_1: Result<i32, i32>) -> Result<i32, i32> {
+ debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14
+ let mut _0: std::result::Result<i32, i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53
+ let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ let mut _4: std::result::Result<i32, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
+ let mut _5: isize; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ let _6: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ let mut _7: !; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ let mut _8: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ scope 1 {
+ debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ scope 2 {
+ scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10
+ debug residual => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _17: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _18: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ scope 9 {
+ debug e => _16; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL
+ debug t => _18; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+ }
+ }
+ }
+ }
+ scope 3 {
+ debug val => _9; // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ scope 4 {
+ }
+ }
+ scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10
+ debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _10: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _12: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _14: std::result::Result<std::convert::Infallible, i32>; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _15: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ scope 6 {
+ debug v => _11; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+ scope 7 {
+ debug e => _13; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
+ _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
+ StorageLive(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ _10 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ switchInt(move _10) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+
+ bb1: {
+ StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ _9 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ _2 = _9; // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ Deinit(_0); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
+ ((_0 as Ok).0: i32) = move _2; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
+ discriminant(_0) = 0; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
+ StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
+ StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
+ }
+
+ bb2: {
+ StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageLive(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ _8 = _6; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageLive(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ _16 = move ((_8 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ _18 = move _16; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ _17 = move _18; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ StorageDead(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_0 as Err).0: i32) = move _17; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
+ StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
+ }
+
+ bb3: {
+ StorageLive(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ _13 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ _15 = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_14 as Err).0: i32) = move _15; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_14) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_3); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>) = move _14; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+- switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
++ _5 = const 1_isize; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
++ switchInt(const 1_isize) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ }
+
+ bb4: {
+ unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+
+ bb5: {
+ StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ _11 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ _12 = move _11; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_3); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_3 as Continue).0: i32) = move _12; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+- switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
++ _5 = const 0_isize; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
++ switchInt(const 0_isize) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ }
+ }
+
diff --git a/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir b/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir
new file mode 100644
index 000000000..952ef22d4
--- /dev/null
+++ b/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir
@@ -0,0 +1,127 @@
+// MIR for `identity` after PreCodegen
+
+fn identity(_1: Result<i32, i32>) -> Result<i32, i32> {
+ debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14
+ let mut _0: std::result::Result<i32, i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53
+ let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ let mut _4: std::result::Result<i32, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
+ let _5: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ let mut _6: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ let _7: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ scope 1 {
+ debug residual => _5; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ scope 2 {
+ scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10
+ debug residual => _6; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let _14: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _15: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ scope 9 {
+ debug e => _14; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL
+ debug t => _16; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+ }
+ }
+ }
+ }
+ scope 3 {
+ debug val => _7; // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ scope 4 {
+ }
+ }
+ scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10
+ debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _8: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let _9: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _10: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _12: std::result::Result<std::convert::Infallible, i32>; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ scope 6 {
+ debug v => _9; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+ scope 7 {
+ debug e => _11; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
+ _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
+ StorageLive(_8); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ _8 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ switchInt(move _8) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+
+ bb1: {
+ StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ _11 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ _13 = move _11; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_12 as Err).0: i32) = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_12) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_3); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>) = move _12; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_8); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageLive(_5); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ _5 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageLive(_6); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ _6 = _5; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageLive(_14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ _14 = move ((_6 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ _16 = move _14; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ _15 = move _16; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ StorageDead(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_0 as Err).0: i32) = move _15; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_6); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageDead(_5); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
+ StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
+ }
+
+ bb2: {
+ unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+
+ bb3: {
+ StorageLive(_9); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ _9 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ _10 = move _9; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_3); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_3 as Continue).0: i32) = move _10; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_9); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_8); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageLive(_7); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ _7 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ _2 = _7; // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageDead(_7); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ Deinit(_0); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
+ ((_0 as Ok).0: i32) = move _2; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
+ discriminant(_0) = 0; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
+ StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
+ StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
new file mode 100644
index 000000000..8453d5341
--- /dev/null
+++ b/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
@@ -0,0 +1,155 @@
+- // MIR for `identity` before SeparateConstSwitch
++ // MIR for `identity` after SeparateConstSwitch
+
+ fn identity(_1: Result<i32, i32>) -> Result<i32, i32> {
+ debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14
+ let mut _0: std::result::Result<i32, i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53
+ let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ let mut _4: std::result::Result<i32, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
+ let mut _5: isize; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ let _6: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ let mut _7: !; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ let mut _8: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ scope 1 {
+ debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ scope 2 {
+ scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10
+ debug residual => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _17: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _18: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ scope 9 {
+ debug e => _16; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL
+ debug t => _18; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+ }
+ }
+ }
+ }
+ scope 3 {
+ debug val => _9; // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ scope 4 {
+ }
+ }
+ scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10
+ debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _10: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _12: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _14: std::result::Result<std::convert::Infallible, i32>; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _15: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ scope 6 {
+ debug v => _11; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+ scope 7 {
+ debug e => _13; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
+ _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
+ StorageLive(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ _10 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+- switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
++ switchInt(move _10) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+
+ bb1: {
+- StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+- StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+- switchInt(move _5) -> [0_isize: bb2, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+- }
+-
+- bb2: {
+ StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ _9 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ _2 = _9; // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ Deinit(_0); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
+ ((_0 as Ok).0: i32) = move _2; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
+ discriminant(_0) = 0; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
+ StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
+ StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
+ }
+
+- bb3: {
++ bb2: {
+ StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageLive(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ _8 = _6; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageLive(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ _16 = move ((_8 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ _18 = move _16; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ _17 = move _18; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ StorageDead(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_0 as Err).0: i32) = move _17; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
+ StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
+ }
+
+- bb4: {
++ bb3: {
+ StorageLive(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ _13 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ _15 = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_14 as Err).0: i32) = move _15; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_14) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_3); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>) = move _14; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+- goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
++ StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
++ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
++ _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
++ switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ }
+
+- bb5: {
++ bb4: {
+ unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+
+- bb6: {
++ bb5: {
+ StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ _11 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ _12 = move _11; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_3); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_3 as Continue).0: i32) = move _12; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+- goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
++ StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
++ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
++ _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
++ switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ }
+ }
+
diff --git a/src/test/mir-opt/separate_const_switch.rs b/src/test/mir-opt/separate_const_switch.rs
new file mode 100644
index 000000000..5d82acf4d
--- /dev/null
+++ b/src/test/mir-opt/separate_const_switch.rs
@@ -0,0 +1,35 @@
+#![feature(control_flow_enum)]
+#![feature(try_trait_v2)]
+
+use std::ops::ControlFlow;
+
+// EMIT_MIR separate_const_switch.too_complex.SeparateConstSwitch.diff
+// EMIT_MIR separate_const_switch.too_complex.ConstProp.diff
+// EMIT_MIR separate_const_switch.too_complex.PreCodegen.after.mir
+fn too_complex(x: Result<i32, usize>) -> Option<i32> {
+ // The pass should break the outer match into
+ // two blocks that only have one parent each.
+ // Parents are one of the two branches of the first
+ // match, so a later pass can propagate constants.
+ match {
+ match x {
+ Ok(v) => ControlFlow::Continue(v),
+ Err(r) => ControlFlow::Break(r),
+ }
+ } {
+ ControlFlow::Continue(v) => Some(v),
+ ControlFlow::Break(r) => None,
+ }
+}
+
+// EMIT_MIR separate_const_switch.identity.SeparateConstSwitch.diff
+// EMIT_MIR separate_const_switch.identity.ConstProp.diff
+// EMIT_MIR separate_const_switch.identity.PreCodegen.after.mir
+fn identity(x: Result<i32, i32>) -> Result<i32, i32> {
+ Ok(x?)
+}
+
+fn main() {
+ too_complex(Ok(0));
+ identity(Ok(0));
+}
diff --git a/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff b/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff
new file mode 100644
index 000000000..de9f45c3d
--- /dev/null
+++ b/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff
@@ -0,0 +1,95 @@
+- // MIR for `too_complex` before ConstProp
++ // MIR for `too_complex` after ConstProp
+
+ fn too_complex(_1: Result<i32, usize>) -> Option<i32> {
+ debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17
+ let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53
+ let mut _2: std::ops::ControlFlow<usize, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
+ let mut _3: isize; // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18
+ let _4: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ let mut _5: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45
+ let _6: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
+ let mut _7: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:42: +8:43
+ let mut _8: isize; // in scope 0 at $DIR/separate_const_switch.rs:+11:9: +11:33
+ let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ let mut _10: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43
+ let _11: usize; // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ scope 1 {
+ debug v => _4; // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ }
+ scope 2 {
+ debug r => _6; // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18
+ }
+ scope 3 {
+ debug v => _9; // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ }
+ scope 4 {
+ debug r => _11; // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
+ _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16
+ switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16
+ }
+
+ bb1: {
+ StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
+ _6 = ((_1 as Err).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
+ StorageLive(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43
+ _7 = _6; // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43
+ Deinit(_2); // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44
+ ((_2 as Break).0: usize) = move _7; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44
+ discriminant(_2) = 1; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44
+ StorageDead(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:43: +8:44
+ StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
+- _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
+- switchInt(move _8) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
++ _8 = const 1_isize; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
++ switchInt(const 1_isize) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
+ }
+
+ bb2: {
+ StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
+ _5 = _4; // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
+ Deinit(_2); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
+ ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
+ discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
+ StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46
+ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
+- _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
+- switchInt(move _8) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
++ _8 = const 0_isize; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
++ switchInt(const 0_isize) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
+ }
+
+ bb3: {
+ StorageLive(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ _11 = ((_2 as Break).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
+ discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
+ StorageDead(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
+ goto -> bb5; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
+ }
+
+ bb4: {
+ StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ _9 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ StorageLive(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
+ _10 = _9; // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
+ Deinit(_0); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
+ ((_0 as Some).0: i32) = move _10; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
+ discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
+ StorageDead(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44
+ StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
+ goto -> bb5; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
+ }
+
+ bb5: {
+ StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2
+ return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2
+ }
+ }
+
diff --git a/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir b/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir
new file mode 100644
index 000000000..1009225b7
--- /dev/null
+++ b/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir
@@ -0,0 +1,69 @@
+// MIR for `too_complex` after PreCodegen
+
+fn too_complex(_1: Result<i32, usize>) -> Option<i32> {
+ debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17
+ let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53
+ let mut _2: std::ops::ControlFlow<usize, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
+ let mut _3: isize; // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18
+ let _4: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ let mut _5: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45
+ let _6: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
+ let _7: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ let mut _8: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43
+ let _9: usize; // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ scope 1 {
+ debug v => _4; // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ }
+ scope 2 {
+ debug r => _6; // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18
+ }
+ scope 3 {
+ debug v => _7; // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ }
+ scope 4 {
+ debug r => _9; // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
+ _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16
+ switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16
+ }
+
+ bb1: {
+ StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
+ StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
+ StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
+ discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
+ StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
+ goto -> bb3; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
+ }
+
+ bb2: {
+ StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
+ _5 = _4; // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
+ Deinit(_2); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
+ ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
+ discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
+ StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46
+ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
+ StorageLive(_7); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ _7 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ StorageLive(_8); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
+ _8 = _7; // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
+ Deinit(_0); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
+ ((_0 as Some).0: i32) = move _8; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
+ discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
+ StorageDead(_8); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44
+ StorageDead(_7); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
+ goto -> bb3; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2
+ return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2
+ }
+}
diff --git a/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff b/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff
new file mode 100644
index 000000000..3ab1c572a
--- /dev/null
+++ b/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff
@@ -0,0 +1,102 @@
+- // MIR for `too_complex` before SeparateConstSwitch
++ // MIR for `too_complex` after SeparateConstSwitch
+
+ fn too_complex(_1: Result<i32, usize>) -> Option<i32> {
+ debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17
+ let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53
+ let mut _2: std::ops::ControlFlow<usize, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
+ let mut _3: isize; // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18
+ let _4: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ let mut _5: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45
+ let _6: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
+ let mut _7: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:42: +8:43
+ let mut _8: isize; // in scope 0 at $DIR/separate_const_switch.rs:+11:9: +11:33
+ let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ let mut _10: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43
+ let _11: usize; // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ scope 1 {
+ debug v => _4; // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ }
+ scope 2 {
+ debug r => _6; // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18
+ }
+ scope 3 {
+ debug v => _9; // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ }
+ scope 4 {
+ debug r => _11; // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
+ _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16
+ switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16
+ }
+
+ bb1: {
+ StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
+ _6 = ((_1 as Err).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
+ StorageLive(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43
+ _7 = _6; // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43
+ Deinit(_2); // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44
+ ((_2 as Break).0: usize) = move _7; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44
+ discriminant(_2) = 1; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44
+ StorageDead(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:43: +8:44
+ StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
+- goto -> bb3; // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
++ _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
++ switchInt(move _8) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
+ }
+
+ bb2: {
+ StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
+ _5 = _4; // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
+ Deinit(_2); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
+ ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
+ discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
+ StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46
+ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
+- goto -> bb3; // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
+- }
+-
+- bb3: {
+ _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
+- switchInt(move _8) -> [0_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
++ switchInt(move _8) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
+ }
+
+- bb4: {
++ bb3: {
+ StorageLive(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ _11 = ((_2 as Break).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
+ discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
+ StorageDead(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
+- goto -> bb6; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
++ goto -> bb5; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
+ }
+
+- bb5: {
++ bb4: {
+ StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ _9 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ StorageLive(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
+ _10 = _9; // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
+ Deinit(_0); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
+ ((_0 as Some).0: i32) = move _10; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
+ discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
+ StorageDead(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44
+ StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
+- goto -> bb6; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
++ goto -> bb5; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
+ }
+
+- bb6: {
++ bb5: {
+ StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2
+ return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simple-match.rs b/src/test/mir-opt/simple-match.rs
new file mode 100644
index 000000000..44adc55b6
--- /dev/null
+++ b/src/test/mir-opt/simple-match.rs
@@ -0,0 +1,12 @@
+// Test that we don't generate unnecessarily large MIR for very simple matches
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR simple_match.match_bool.mir_map.0.mir
+fn match_bool(x: bool) -> usize {
+ match x {
+ true => 10,
+ _ => 20,
+ }
+}
+
+fn main() {}
diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir
new file mode 100644
index 000000000..3bef6aa05
--- /dev/null
+++ b/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir
@@ -0,0 +1,29 @@
+// MIR for `match_bool` 0 mir_map
+
+fn match_bool(_1: bool) -> usize {
+ debug x => _1; // in scope 0 at $DIR/simple-match.rs:+0:15: +0:16
+ let mut _0: usize; // return place in scope 0 at $DIR/simple-match.rs:+0:27: +0:32
+
+ bb0: {
+ FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple-match.rs:+1:11: +1:12
+ switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple-match.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ falseEdge -> [real: bb3, imaginary: bb2]; // scope 0 at $DIR/simple-match.rs:+2:9: +2:13
+ }
+
+ bb2: {
+ _0 = const 20_usize; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
+ goto -> bb4; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
+ }
+
+ bb3: {
+ _0 = const 10_usize; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
+ goto -> bb4; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/simple-match.rs:+5:2: +5:2
+ }
+}
diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir
new file mode 100644
index 000000000..3bef6aa05
--- /dev/null
+++ b/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir
@@ -0,0 +1,29 @@
+// MIR for `match_bool` 0 mir_map
+
+fn match_bool(_1: bool) -> usize {
+ debug x => _1; // in scope 0 at $DIR/simple-match.rs:+0:15: +0:16
+ let mut _0: usize; // return place in scope 0 at $DIR/simple-match.rs:+0:27: +0:32
+
+ bb0: {
+ FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple-match.rs:+1:11: +1:12
+ switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple-match.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ falseEdge -> [real: bb3, imaginary: bb2]; // scope 0 at $DIR/simple-match.rs:+2:9: +2:13
+ }
+
+ bb2: {
+ _0 = const 20_usize; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
+ goto -> bb4; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
+ }
+
+ bb3: {
+ _0 = const 10_usize; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
+ goto -> bb4; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/simple-match.rs:+5:2: +5:2
+ }
+}
diff --git a/src/test/mir-opt/simplify-arm-identity.rs b/src/test/mir-opt/simplify-arm-identity.rs
new file mode 100644
index 000000000..bedc86bba
--- /dev/null
+++ b/src/test/mir-opt/simplify-arm-identity.rs
@@ -0,0 +1,23 @@
+// Checks that `SimplifyArmIdentity` is not applied if enums have incompatible layouts.
+// Regression test for issue #66856.
+//
+// compile-flags: -Zmir-opt-level=3
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
+enum Src {
+ Foo(u8),
+ Bar,
+}
+
+enum Dst {
+ Foo(u8),
+}
+
+// EMIT_MIR simplify_arm_identity.main.SimplifyArmIdentity.diff
+fn main() {
+ let e: Src = Src::Foo(0);
+ let _: Dst = match e {
+ Src::Foo(x) => Dst::Foo(x),
+ Src::Bar => Dst::Foo(0),
+ };
+}
diff --git a/src/test/mir-opt/simplify-arm.rs b/src/test/mir-opt/simplify-arm.rs
new file mode 100644
index 000000000..f7dcaa134
--- /dev/null
+++ b/src/test/mir-opt/simplify-arm.rs
@@ -0,0 +1,47 @@
+// compile-flags: -Z mir-opt-level=3 -Zunsound-mir-opts
+// EMIT_MIR simplify_arm.id.SimplifyArmIdentity.diff
+// EMIT_MIR simplify_arm.id.SimplifyBranchSame.diff
+// EMIT_MIR simplify_arm.id_result.SimplifyArmIdentity.diff
+// EMIT_MIR simplify_arm.id_result.SimplifyBranchSame.diff
+// EMIT_MIR simplify_arm.id_try.SimplifyArmIdentity.diff
+// EMIT_MIR simplify_arm.id_try.SimplifyBranchSame.diff
+
+fn id(o: Option<u8>) -> Option<u8> {
+ match o {
+ Some(v) => Some(v),
+ None => None,
+ }
+}
+
+fn id_result(r: Result<u8, i32>) -> Result<u8, i32> {
+ match r {
+ Ok(x) => Ok(x),
+ Err(y) => Err(y),
+ }
+}
+
+fn into_result<T, E>(r: Result<T, E>) -> Result<T, E> {
+ r
+}
+
+fn from_error<T, E>(e: E) -> Result<T, E> {
+ Err(e)
+}
+
+// This was written to the `?` from `try_trait`, but `try_trait_v2` uses a different structure,
+// so the relevant desugar is copied inline in order to keep the test testing the same thing.
+// FIXME(#85133): while this might be useful for `r#try!`, it would be nice to have a MIR
+// optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not.
+fn id_try(r: Result<u8, i32>) -> Result<u8, i32> {
+ let x = match into_result(r) {
+ Err(e) => return from_error(From::from(e)),
+ Ok(v) => v,
+ };
+ Ok(x)
+}
+
+fn main() {
+ id(None);
+ id_result(Ok(4));
+ id_try(Ok(4));
+}
diff --git a/src/test/mir-opt/simplify-locals-fixedpoint.rs b/src/test/mir-opt/simplify-locals-fixedpoint.rs
new file mode 100644
index 000000000..78b1f9f55
--- /dev/null
+++ b/src/test/mir-opt/simplify-locals-fixedpoint.rs
@@ -0,0 +1,15 @@
+// compile-flags: -Zmir-opt-level=1
+
+fn foo<T>() {
+ if let (Some(a), None) = (Option::<u8>::None, Option::<T>::None) {
+ if a > 42u8 {
+
+ }
+ }
+}
+
+fn main() {
+ foo::<()>();
+}
+
+// EMIT_MIR simplify_locals_fixedpoint.foo.SimplifyLocals.diff
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-consts.rs b/src/test/mir-opt/simplify-locals-removes-unused-consts.rs
new file mode 100644
index 000000000..179994544
--- /dev/null
+++ b/src/test/mir-opt/simplify-locals-removes-unused-consts.rs
@@ -0,0 +1,17 @@
+// compile-flags: -C overflow-checks=no
+
+fn use_zst(_: ((), ())) {}
+
+struct Temp {
+ x: u8,
+}
+
+fn use_u8(_: u8) {}
+
+// EMIT_MIR simplify_locals_removes_unused_consts.main.SimplifyLocals.diff
+fn main() {
+ let ((), ()) = ((), ());
+ use_zst(((), ()));
+
+ use_u8((Temp { x: 40 }).x + 2);
+}
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs
new file mode 100644
index 000000000..84f57decc
--- /dev/null
+++ b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs
@@ -0,0 +1,15 @@
+// compile-flags: -Zunsound-mir-opts
+
+fn map(x: Option<Box<()>>) -> Option<Box<()>> {
+ match x {
+ None => None,
+ Some(x) => Some(x),
+ }
+}
+
+fn main() {
+ map(None);
+}
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff
diff --git a/src/test/mir-opt/simplify-locals.rs b/src/test/mir-opt/simplify-locals.rs
new file mode 100644
index 000000000..f6bf396cd
--- /dev/null
+++ b/src/test/mir-opt/simplify-locals.rs
@@ -0,0 +1,81 @@
+// unit-test: SimplifyLocals
+
+#![feature(box_syntax)]
+#![feature(thread_local)]
+
+#[derive(Copy, Clone)]
+enum E {
+ A,
+ B,
+}
+
+// EMIT_MIR simplify_locals.c.SimplifyLocals.diff
+fn c() {
+ let bytes = [0u8; 10];
+ // Unused cast
+ let _: &[u8] = &bytes;
+}
+
+// EMIT_MIR simplify_locals.d1.SimplifyLocals.diff
+fn d1() {
+ // Unused set discriminant
+ let _ = E::A;
+}
+
+// EMIT_MIR simplify_locals.d2.SimplifyLocals.diff
+fn d2() {
+ // Unused set discriminant
+ {(10, E::A)}.1 = E::B;
+}
+
+// EMIT_MIR simplify_locals.r.SimplifyLocals.diff
+fn r() {
+ let mut a = 1;
+ // Unused references
+ let _ = &a;
+ let _ = &mut a;
+}
+
+#[thread_local] static mut X: u32 = 0;
+
+// EMIT_MIR simplify_locals.t1.SimplifyLocals.diff
+fn t1() {
+ // Unused thread local
+ unsafe { X };
+}
+
+// EMIT_MIR simplify_locals.t2.SimplifyLocals.diff
+fn t2() {
+ // Unused thread local
+ unsafe { &mut X };
+}
+
+// EMIT_MIR simplify_locals.t3.SimplifyLocals.diff
+fn t3() {
+ // Unused thread local
+ unsafe { *&mut X };
+}
+
+// EMIT_MIR simplify_locals.t4.SimplifyLocals.diff
+fn t4() -> u32 {
+ // Used thread local
+ unsafe { X + 1 }
+}
+
+// EMIT_MIR simplify_locals.expose_addr.SimplifyLocals.diff
+fn expose_addr(p: *const usize) {
+ // Used pointer to address cast. Has a side effect of exposing the provenance.
+ p as usize;
+}
+
+fn main() {
+ c();
+ d1();
+ d2();
+ r();
+ t1();
+ t2();
+ t3();
+ t4();
+ expose_addr(&0);
+}
diff --git a/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff
new file mode 100644
index 000000000..9c3ad4b4d
--- /dev/null
+++ b/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff
@@ -0,0 +1,46 @@
+- // MIR for `id` before SimplifyArmIdentity
++ // MIR for `id` after SimplifyArmIdentity
+
+ fn id(_1: Option<u8>) -> Option<u8> {
+ debug o => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:7: +0:8
+ let mut _0: std::option::Option<u8>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:25: +0:35
+ let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:16
+ let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
+ let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:25: +2:26
+ scope 1 {
+ debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:14: +2:15
+ }
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
+ switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ Deinit(_0); // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
+ discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
+ }
+
+ bb3: {
+ StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
+ _3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
+ StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26
+ _4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26
+ Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
+ ((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
+ discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
+ StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:26: +2:27
+ StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff
new file mode 100644
index 000000000..7b3a69936
--- /dev/null
+++ b/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff
@@ -0,0 +1,46 @@
+- // MIR for `id` before SimplifyBranchSame
++ // MIR for `id` after SimplifyBranchSame
+
+ fn id(_1: Option<u8>) -> Option<u8> {
+ debug o => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:7: +0:8
+ let mut _0: std::option::Option<u8>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:25: +0:35
+ let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:16
+ let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
+ let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:25: +2:26
+ scope 1 {
+ debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:14: +2:15
+ }
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
+ switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ Deinit(_0); // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
+ discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
+ }
+
+ bb3: {
+ StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
+ _3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
+ StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26
+ _4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26
+ Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
+ ((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
+ discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
+ StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:26: +2:27
+ StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff
new file mode 100644
index 000000000..31d8453ce
--- /dev/null
+++ b/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff
@@ -0,0 +1,58 @@
+- // MIR for `id_result` before SimplifyArmIdentity
++ // MIR for `id_result` after SimplifyArmIdentity
+
+ fn id_result(_1: Result<u8, i32>) -> Result<u8, i32> {
+ debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:14: +0:15
+ let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:37: +0:52
+ let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:14
+ let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
+ let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:21: +2:22
+ let _5: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
+ let mut _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:23: +3:24
+ scope 1 {
+ debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:12: +2:13
+ }
+ scope 2 {
+ debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:+3:13: +3:14
+ }
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
+ switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
+ _5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
+ StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24
+ _6 = _5; // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24
+ Deinit(_0); // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
+ ((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
+ discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
+ StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:+3:24: +3:25
+ StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
+ }
+
+ bb3: {
+ StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
+ _3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
+ StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22
+ _4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22
+ Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
+ ((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
+ discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
+ StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:22: +2:23
+ StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff
new file mode 100644
index 000000000..3692ebf74
--- /dev/null
+++ b/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff
@@ -0,0 +1,58 @@
+- // MIR for `id_result` before SimplifyBranchSame
++ // MIR for `id_result` after SimplifyBranchSame
+
+ fn id_result(_1: Result<u8, i32>) -> Result<u8, i32> {
+ debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:14: +0:15
+ let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:37: +0:52
+ let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:14
+ let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
+ let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:21: +2:22
+ let _5: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
+ let mut _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:23: +3:24
+ scope 1 {
+ debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:12: +2:13
+ }
+ scope 2 {
+ debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:+3:13: +3:14
+ }
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
+ switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
+ _5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
+ StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24
+ _6 = _5; // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24
+ Deinit(_0); // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
+ ((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
+ discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
+ StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:+3:24: +3:25
+ StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
+ }
+
+ bb3: {
+ StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
+ _3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
+ StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22
+ _4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22
+ Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
+ ((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
+ discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
+ StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:22: +2:23
+ StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff
new file mode 100644
index 000000000..452cc8a9c
--- /dev/null
+++ b/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff
@@ -0,0 +1,89 @@
+- // MIR for `id_try` before SimplifyArmIdentity
++ // MIR for `id_try` after SimplifyArmIdentity
+
+ fn id_try(_1: Result<u8, i32>) -> Result<u8, i32> {
+ debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:11: +0:12
+ let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:34: +0:49
+ let _2: u8; // in scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10
+ let mut _3: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
+ let mut _4: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
+ let mut _5: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:15
+ let _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
+ let mut _7: !; // in scope 0 at $DIR/simplify-arm.rs:+2:19: +2:51
+ let mut _8: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:37: +2:50
+ let mut _9: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:48: +2:49
+ let _10: u8; // in scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
+ let mut _11: u8; // in scope 0 at $DIR/simplify-arm.rs:+5:8: +5:9
+ scope 1 {
+ debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:+1:9: +1:10
+ }
+ scope 2 {
+ debug e => _6; // in scope 2 at $DIR/simplify-arm.rs:+2:13: +2:14
+ scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify-arm.rs:37:37: 37:50
+ debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+ scope 6 (inlined from_error::<u8, i32>) { // at $DIR/simplify-arm.rs:37:26: 37:51
+ debug e => _8; // in scope 6 at $DIR/simplify-arm.rs:+0:21: +0:22
+ }
+ }
+ scope 3 {
+ debug v => _10; // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13
+ }
+ scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33
+ debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:+0:22: +0:23
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
+ StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
+ _4 = _1; // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
+ _3 = move _4; // scope 4 at $DIR/simplify-arm.rs:+0:5: +0:6
+ StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33
+ _5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
+ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33
+ }
+
+ bb1: {
+ StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
+ _10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
+ _2 = _10; // scope 3 at $DIR/simplify-arm.rs:+3:18: +3:19
+ StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:+3:18: +3:19
+ StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
+ StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9
+ _11 = _2; // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9
+ Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
+ ((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
+ discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
+ StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:+5:9: +5:10
+ StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
+ }
+
+ bb3: {
+ StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
+ _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
+ StorageLive(_8); // scope 2 at $DIR/simplify-arm.rs:+2:37: +2:50
+ StorageLive(_9); // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
+ _9 = _6; // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
+ _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ StorageDead(_9); // scope 2 at $DIR/simplify-arm.rs:+2:49: +2:50
+ ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify-arm.rs:+0:9: +0:10
+ Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:+0:5: +0:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:+0:5: +0:11
+ StorageDead(_8); // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51
+ StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51
+ StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
+ StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff
new file mode 100644
index 000000000..5d7d4ba7c
--- /dev/null
+++ b/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff
@@ -0,0 +1,89 @@
+- // MIR for `id_try` before SimplifyBranchSame
++ // MIR for `id_try` after SimplifyBranchSame
+
+ fn id_try(_1: Result<u8, i32>) -> Result<u8, i32> {
+ debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:11: +0:12
+ let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:34: +0:49
+ let _2: u8; // in scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10
+ let mut _3: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
+ let mut _4: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
+ let mut _5: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:15
+ let _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
+ let mut _7: !; // in scope 0 at $DIR/simplify-arm.rs:+2:19: +2:51
+ let mut _8: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:37: +2:50
+ let mut _9: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:48: +2:49
+ let _10: u8; // in scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
+ let mut _11: u8; // in scope 0 at $DIR/simplify-arm.rs:+5:8: +5:9
+ scope 1 {
+ debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:+1:9: +1:10
+ }
+ scope 2 {
+ debug e => _6; // in scope 2 at $DIR/simplify-arm.rs:+2:13: +2:14
+ scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify-arm.rs:37:37: 37:50
+ debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+ scope 6 (inlined from_error::<u8, i32>) { // at $DIR/simplify-arm.rs:37:26: 37:51
+ debug e => _8; // in scope 6 at $DIR/simplify-arm.rs:+0:21: +0:22
+ }
+ }
+ scope 3 {
+ debug v => _10; // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13
+ }
+ scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33
+ debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:+0:22: +0:23
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
+ StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
+ _4 = _1; // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
+ _3 = move _4; // scope 4 at $DIR/simplify-arm.rs:+0:5: +0:6
+ StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33
+ _5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
+ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33
+ }
+
+ bb1: {
+ StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
+ _10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
+ _2 = _10; // scope 3 at $DIR/simplify-arm.rs:+3:18: +3:19
+ StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:+3:18: +3:19
+ StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
+ StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9
+ _11 = _2; // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9
+ Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
+ ((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
+ discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
+ StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:+5:9: +5:10
+ StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
+ }
+
+ bb3: {
+ StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
+ _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
+ StorageLive(_8); // scope 2 at $DIR/simplify-arm.rs:+2:37: +2:50
+ StorageLive(_9); // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
+ _9 = _6; // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
+ _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ StorageDead(_9); // scope 2 at $DIR/simplify-arm.rs:+2:49: +2:50
+ ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify-arm.rs:+0:9: +0:10
+ Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:+0:5: +0:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:+0:5: +0:11
+ StorageDead(_8); // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51
+ StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51
+ StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
+ StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.32bit.diff b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.32bit.diff
new file mode 100644
index 000000000..118f5dd0a
--- /dev/null
+++ b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.32bit.diff
@@ -0,0 +1,61 @@
+- // MIR for `main` before SimplifyArmIdentity
++ // MIR for `main` after SimplifyArmIdentity
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +0:11
+ let _1: Src; // in scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
+ let mut _2: Dst; // in scope 0 at $DIR/simplify-arm-identity.rs:+2:18: +5:6
+ let mut _3: isize; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:9: +3:20
+ let mut _5: u8; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
+ scope 1 {
+ debug e => _1; // in scope 1 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
+ let _4: u8; // in scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
+ scope 2 {
+ }
+ scope 3 {
+ debug x => _4; // in scope 3 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
+ Deinit(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
+ ((_1 as Foo).0: u8) = const 0_u8; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
+ discriminant(_1) = 0; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
+ StorageLive(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +5:6
+ _3 = const 0_isize; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25
+ goto -> bb3; // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +2:25
+ }
+
+ bb1: {
+ Deinit(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
+ ((_2 as Foo).0: u8) = const 0_u8; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
+ discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
+ goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
+ }
+
+ bb2: {
+ unreachable; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25
+ }
+
+ bb3: {
+ StorageLive(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
+ _4 = ((_1 as Foo).0: u8); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
+ StorageLive(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
+ _5 = _4; // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
+ Deinit(_2); // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
+ ((_2 as Foo).0: u8) = move _5; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
+ discriminant(_2) = 0; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
+ StorageDead(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
+ StorageDead(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
+ goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
+ }
+
+ bb4: {
+ StorageDead(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+5:6: +5:7
+ nop; // scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +6:2
+ StorageDead(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/simplify-arm-identity.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.64bit.diff b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.64bit.diff
new file mode 100644
index 000000000..118f5dd0a
--- /dev/null
+++ b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.64bit.diff
@@ -0,0 +1,61 @@
+- // MIR for `main` before SimplifyArmIdentity
++ // MIR for `main` after SimplifyArmIdentity
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +0:11
+ let _1: Src; // in scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
+ let mut _2: Dst; // in scope 0 at $DIR/simplify-arm-identity.rs:+2:18: +5:6
+ let mut _3: isize; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:9: +3:20
+ let mut _5: u8; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
+ scope 1 {
+ debug e => _1; // in scope 1 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
+ let _4: u8; // in scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
+ scope 2 {
+ }
+ scope 3 {
+ debug x => _4; // in scope 3 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
+ Deinit(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
+ ((_1 as Foo).0: u8) = const 0_u8; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
+ discriminant(_1) = 0; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
+ StorageLive(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +5:6
+ _3 = const 0_isize; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25
+ goto -> bb3; // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +2:25
+ }
+
+ bb1: {
+ Deinit(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
+ ((_2 as Foo).0: u8) = const 0_u8; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
+ discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
+ goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
+ }
+
+ bb2: {
+ unreachable; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25
+ }
+
+ bb3: {
+ StorageLive(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
+ _4 = ((_1 as Foo).0: u8); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
+ StorageLive(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
+ _5 = _4; // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
+ Deinit(_2); // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
+ ((_2 as Foo).0: u8) = move _5; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
+ discriminant(_2) = 0; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
+ StorageDead(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
+ StorageDead(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
+ goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
+ }
+
+ bb4: {
+ StorageDead(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+5:6: +5:7
+ nop; // scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +6:2
+ StorageDead(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/simplify-arm-identity.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff
new file mode 100644
index 000000000..e068b81bc
--- /dev/null
+++ b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff
@@ -0,0 +1,52 @@
+- // MIR for `main` before SimplifyCfg-early-opt
++ // MIR for `main` after SimplifyCfg-early-opt
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_cfg.rs:+0:11: +0:11
+ let mut _1: (); // in scope 0 at $DIR/simplify_cfg.rs:+0:1: +6:2
+ let mut _2: bool; // in scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
+ let mut _3: !; // in scope 0 at $DIR/simplify_cfg.rs:+2:18: +4:10
+
+ bb0: {
+ goto -> bb1; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6
+ }
+
+ bb1: {
+- goto -> bb2; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6
+- }
+-
+- bb2: {
+ StorageLive(_2); // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
+- _2 = bar() -> [return: bb3, unwind: bb6]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
++ _2 = bar() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
+ // mir::Constant
+ // + span: $DIR/simplify_cfg.rs:9:12: 9:15
+ // + literal: Const { ty: fn() -> bool {bar}, val: Value(<ZST>) }
+ }
+
+- bb3: {
+- switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
++ bb2: {
++ switchInt(move _2) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
+ }
+
+- bb4: {
++ bb3: {
+ _0 = const (); // scope 0 at $DIR/simplify_cfg.rs:+3:13: +3:18
+ StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:+4:9: +4:10
+ return; // scope 0 at $DIR/simplify_cfg.rs:+6:2: +6:2
+ }
+
+- bb5: {
++ bb4: {
+ _1 = const (); // scope 0 at $DIR/simplify_cfg.rs:+4:10: +4:10
+ StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:+4:9: +4:10
+ goto -> bb1; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6
+ }
+
+- bb6 (cleanup): {
++ bb5 (cleanup): {
+ resume; // scope 0 at $DIR/simplify_cfg.rs:+0:1: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff
new file mode 100644
index 000000000..f693798eb
--- /dev/null
+++ b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff
@@ -0,0 +1,71 @@
+- // MIR for `main` before SimplifyCfg-initial
++ // MIR for `main` after SimplifyCfg-initial
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_cfg.rs:+0:11: +0:11
+ let mut _1: (); // in scope 0 at $DIR/simplify_cfg.rs:+0:1: +6:2
+ let mut _2: bool; // in scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
+ let mut _3: !; // in scope 0 at $DIR/simplify_cfg.rs:+2:18: +4:10
+
+ bb0: {
+ goto -> bb1; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6
+ }
+
+ bb1: {
+- falseUnwind -> [real: bb2, cleanup: bb11]; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6
++ falseUnwind -> [real: bb2, cleanup: bb6]; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6
+ }
+
+ bb2: {
+ StorageLive(_2); // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
+- _2 = bar() -> [return: bb3, unwind: bb11]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
++ _2 = bar() -> [return: bb3, unwind: bb6]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
+ // mir::Constant
+ // + span: $DIR/simplify_cfg.rs:9:12: 9:15
+ // + literal: Const { ty: fn() -> bool {bar}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
+ }
+
+ bb4: {
+ _0 = const (); // scope 0 at $DIR/simplify_cfg.rs:+3:13: +3:18
+- goto -> bb10; // scope 0 at $DIR/simplify_cfg.rs:+3:13: +3:18
++ StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:+4:9: +4:10
++ return; // scope 0 at $DIR/simplify_cfg.rs:+6:2: +6:2
+ }
+
+ bb5: {
+- goto -> bb8; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
+- }
+-
+- bb6: {
+- unreachable; // scope 0 at $DIR/simplify_cfg.rs:+2:18: +4:10
+- }
+-
+- bb7: {
+- goto -> bb9; // scope 0 at $DIR/simplify_cfg.rs:+2:9: +4:10
+- }
+-
+- bb8: {
+ _1 = const (); // scope 0 at $DIR/simplify_cfg.rs:+4:10: +4:10
+- goto -> bb9; // scope 0 at $DIR/simplify_cfg.rs:+2:9: +4:10
+- }
+-
+- bb9: {
+ StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:+4:9: +4:10
+ goto -> bb1; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6
+ }
+
+- bb10: {
+- StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:+4:9: +4:10
+- return; // scope 0 at $DIR/simplify_cfg.rs:+6:2: +6:2
+- }
+-
+- bb11 (cleanup): {
++ bb6 (cleanup): {
+ resume; // scope 0 at $DIR/simplify_cfg.rs:+0:1: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_cfg.rs b/src/test/mir-opt/simplify_cfg.rs
new file mode 100644
index 000000000..cf7eac440
--- /dev/null
+++ b/src/test/mir-opt/simplify_cfg.rs
@@ -0,0 +1,18 @@
+// Test that the goto chain starting from bb0 is collapsed.
+// compile-flags: -Cpanic=abort
+// no-prefer-dynamic
+
+// EMIT_MIR simplify_cfg.main.SimplifyCfg-initial.diff
+// EMIT_MIR simplify_cfg.main.SimplifyCfg-early-opt.diff
+fn main() {
+ loop {
+ if bar() {
+ break;
+ }
+ }
+}
+
+#[inline(never)]
+fn bar() -> bool {
+ true
+}
diff --git a/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff b/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff
new file mode 100644
index 000000000..9b1bea270
--- /dev/null
+++ b/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff
@@ -0,0 +1,40 @@
+- // MIR for `main` before SimplifyConstCondition-after-const-prop
++ // MIR for `main` after SimplifyConstCondition-after-const-prop
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_if.rs:+0:11: +0:11
+ let mut _1: bool; // in scope 0 at $DIR/simplify_if.rs:+1:8: +1:13
+ let _2: (); // in scope 0 at $DIR/simplify_if.rs:+2:9: +2:15
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13
+ _1 = const false; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13
+- switchInt(const false) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13
++ goto -> bb3; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13
+ }
+
+ bb1: {
+ StorageLive(_2); // scope 0 at $DIR/simplify_if.rs:+2:9: +2:15
+ _2 = noop() -> bb2; // scope 0 at $DIR/simplify_if.rs:+2:9: +2:15
+ // mir::Constant
+ // + span: $DIR/simplify_if.rs:7:9: 7:13
+ // + literal: Const { ty: fn() {noop}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_2); // scope 0 at $DIR/simplify_if.rs:+2:15: +2:16
+ nop; // scope 0 at $DIR/simplify_if.rs:+1:14: +3:6
+ goto -> bb4; // scope 0 at $DIR/simplify_if.rs:+1:5: +3:6
+ }
+
+ bb3: {
+ nop; // scope 0 at $DIR/simplify_if.rs:+3:6: +3:6
+ goto -> bb4; // scope 0 at $DIR/simplify_if.rs:+1:5: +3:6
+ }
+
+ bb4: {
+ StorageDead(_1); // scope 0 at $DIR/simplify_if.rs:+3:5: +3:6
+ return; // scope 0 at $DIR/simplify_if.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_if.rs b/src/test/mir-opt/simplify_if.rs
new file mode 100644
index 000000000..2d093d926
--- /dev/null
+++ b/src/test/mir-opt/simplify_if.rs
@@ -0,0 +1,9 @@
+#[inline(never)]
+fn noop() {}
+
+// EMIT_MIR simplify_if.main.SimplifyConstCondition-after-const-prop.diff
+fn main() {
+ if false {
+ noop();
+ }
+}
diff --git a/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff
new file mode 100644
index 000000000..5d7517e4e
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff
@@ -0,0 +1,33 @@
+- // MIR for `c` before SimplifyLocals
++ // MIR for `c` after SimplifyLocals
+
+ fn c() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:8: +0:8
+ let _1: [u8; 10]; // in scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14
+- let mut _2: &[u8]; // in scope 0 at $DIR/simplify-locals.rs:+3:20: +3:26
+- let mut _3: &[u8; 10]; // in scope 0 at $DIR/simplify-locals.rs:+3:20: +3:26
+- let _4: &[u8; 10]; // in scope 0 at $DIR/simplify-locals.rs:+3:20: +3:26
+ scope 1 {
+ debug bytes => _1; // in scope 1 at $DIR/simplify-locals.rs:+1:9: +1:14
+ scope 2 {
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14
+ _1 = [const 0_u8; 10]; // scope 0 at $DIR/simplify-locals.rs:+1:17: +1:26
+- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26
+- StorageLive(_3); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26
+- StorageLive(_4); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26
+- _4 = &_1; // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26
+- _3 = &(*_4); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26
+- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26
+- StorageDead(_3); // scope 1 at $DIR/simplify-locals.rs:+3:25: +3:26
+- StorageDead(_4); // scope 1 at $DIR/simplify-locals.rs:+3:26: +3:27
+- StorageDead(_2); // scope 1 at $DIR/simplify-locals.rs:+3:26: +3:27
+ _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:8: +4:2
+ StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/simplify-locals.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff
new file mode 100644
index 000000000..a9ea8869a
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff
@@ -0,0 +1,19 @@
+- // MIR for `d1` before SimplifyLocals
++ // MIR for `d1` after SimplifyLocals
+
+ fn d1() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9
+- let mut _1: E; // in scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17
+ scope 1 {
+ }
+
+ bb0: {
+- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17
+- Deinit(_1); // scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17
+- discriminant(_1) = 0; // scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17
+- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:17: +2:18
+ _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2
+ return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff
new file mode 100644
index 000000000..6a89e4584
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff
@@ -0,0 +1,29 @@
+- // MIR for `d2` before SimplifyLocals
++ // MIR for `d2` after SimplifyLocals
+
+ fn d2() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9
+- let mut _1: E; // in scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26
+- let mut _2: (i32, E); // in scope 0 at $DIR/simplify-locals.rs:+2:5: +2:17
+- let mut _3: E; // in scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15
+
+ bb0: {
+- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26
+- Deinit(_1); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26
+- discriminant(_1) = 1; // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26
+- StorageLive(_2); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:17
+- StorageLive(_3); // scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15
+- Deinit(_3); // scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15
+- discriminant(_3) = 0; // scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15
+- Deinit(_2); // scope 0 at $DIR/simplify-locals.rs:+2:6: +2:16
+- (_2.0: i32) = const 10_i32; // scope 0 at $DIR/simplify-locals.rs:+2:6: +2:16
+- (_2.1: E) = move _3; // scope 0 at $DIR/simplify-locals.rs:+2:6: +2:16
+- StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:+2:15: +2:16
+- (_2.1: E) = move _1; // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:26
+- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:25: +2:26
+- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:26: +2:27
+ _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2
+ return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff
new file mode 100644
index 000000000..204a1bffc
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff
@@ -0,0 +1,21 @@
+- // MIR for `expose_addr` before SimplifyLocals
++ // MIR for `expose_addr` after SimplifyLocals
+
+ fn expose_addr(_1: *const usize) -> () {
+ debug p => _1; // in scope 0 at $DIR/simplify-locals.rs:+0:16: +0:17
+ let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:33: +0:33
+ let _2: usize; // in scope 0 at $DIR/simplify-locals.rs:+2:5: +2:15
+ let mut _3: *const usize; // in scope 0 at $DIR/simplify-locals.rs:+2:5: +2:6
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:15
+ StorageLive(_3); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:6
+ _3 = _1; // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:6
+ _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:15
+ StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15
+ StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:15: +2:16
+ _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:33: +3:2
+ return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff
new file mode 100644
index 000000000..329e2a65a
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff
@@ -0,0 +1,31 @@
+- // MIR for `r` before SimplifyLocals
++ // MIR for `r` after SimplifyLocals
+
+ fn r() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:8: +0:8
+ let mut _1: i32; // in scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14
+- let mut _2: &i32; // in scope 0 at $DIR/simplify-locals.rs:+3:13: +3:15
+- let mut _3: &mut i32; // in scope 0 at $DIR/simplify-locals.rs:+4:13: +4:19
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/simplify-locals.rs:+1:9: +1:14
+ scope 2 {
+ scope 3 {
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14
+ _1 = const 1_i32; // scope 0 at $DIR/simplify-locals.rs:+1:17: +1:18
+- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+3:13: +3:15
+- _2 = &_1; // scope 1 at $DIR/simplify-locals.rs:+3:13: +3:15
+- StorageDead(_2); // scope 1 at $DIR/simplify-locals.rs:+3:15: +3:16
+- StorageLive(_3); // scope 2 at $DIR/simplify-locals.rs:+4:13: +4:19
+- _3 = &mut _1; // scope 2 at $DIR/simplify-locals.rs:+4:13: +4:19
+- StorageDead(_3); // scope 2 at $DIR/simplify-locals.rs:+4:19: +4:20
+ _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:8: +5:2
+ StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/simplify-locals.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff
new file mode 100644
index 000000000..b31156ad6
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff
@@ -0,0 +1,22 @@
+- // MIR for `t1` before SimplifyLocals
++ // MIR for `t1` after SimplifyLocals
+
+ fn t1() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9
+- let _1: u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15
+- let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15
+ scope 1 {
+ }
+
+ bb0: {
+- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:17
+- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
+- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
+- _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
+- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:17: +2:18
+- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:17: +2:18
+ _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2
+ return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff
new file mode 100644
index 000000000..66b6d8d64
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff
@@ -0,0 +1,22 @@
+- // MIR for `t2` before SimplifyLocals
++ // MIR for `t2` after SimplifyLocals
+
+ fn t2() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9
+- let _1: &mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:20
+- let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:19: +2:20
+ scope 1 {
+ }
+
+ bb0: {
+- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:22
+- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:19: +2:20
+- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:19: +2:20
+- _1 = &mut (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:20
+- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:23
+- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:23
+ _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2
+ return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff
new file mode 100644
index 000000000..f6b6b78cd
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff
@@ -0,0 +1,26 @@
+- // MIR for `t3` before SimplifyLocals
++ // MIR for `t3` after SimplifyLocals
+
+ fn t3() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9
+- let _1: u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:21
+- let mut _2: &mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:15: +2:21
+- let mut _3: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:20: +2:21
+ scope 1 {
+ }
+
+ bb0: {
+- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:23
+- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:15: +2:21
+- StorageLive(_3); // scope 1 at $DIR/simplify-locals.rs:+2:20: +2:21
+- _3 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:20: +2:21
+- _2 = &mut (*_3); // scope 1 at $DIR/simplify-locals.rs:+2:15: +2:21
+- _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:21
+- StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:+2:23: +2:24
+- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:23: +2:24
+- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:23: +2:24
+ _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2
+ return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff
new file mode 100644
index 000000000..1c1da29aa
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff
@@ -0,0 +1,22 @@
+- // MIR for `t4` before SimplifyLocals
++ // MIR for `t4` after SimplifyLocals
+
+ fn t4() -> u32 {
+ let mut _0: u32; // return place in scope 0 at $DIR/simplify-locals.rs:+0:12: +0:15
+ let mut _1: u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15
+ let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
+ StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
+ _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
+ _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
+ _0 = Add(move _1, const 1_u32); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:19
+ StorageDead(_1); // scope 1 at $DIR/simplify-locals.rs:+2:18: +2:19
+ StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff
new file mode 100644
index 000000000..ac7a47ba5
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff
@@ -0,0 +1,62 @@
+- // MIR for `foo` before SimplifyLocals
++ // MIR for `foo` after SimplifyLocals
+
+ fn foo() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+0:13: +0:13
+ let mut _1: (std::option::Option<u8>, std::option::Option<T>); // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69
+ let mut _2: std::option::Option<u8>; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49
+ let mut _3: std::option::Option<T>; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68
+ let mut _4: isize; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:22: +1:26
+ let mut _5: isize; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:13: +1:20
+- let mut _7: bool; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:20
+- let mut _8: u8; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:13
+ scope 1 {
+ debug a => _6; // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19
+ let _6: u8; // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69
+ StorageLive(_2); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49
+ Deinit(_2); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49
+ discriminant(_2) = 0; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49
+ StorageLive(_3); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68
+ Deinit(_3); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68
+ discriminant(_3) = 0; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68
+ Deinit(_1); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69
+ (_1.0: std::option::Option<u8>) = move _2; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69
+ (_1.1: std::option::Option<T>) = move _3; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69
+ StorageDead(_3); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:68: +1:69
+ StorageDead(_2); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:68: +1:69
+ _5 = discriminant((_1.0: std::option::Option<u8>)); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27
+ switchInt(move _5) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27
+ }
+
+ bb1: {
+ _4 = discriminant((_1.1: std::option::Option<T>)); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27
+ switchInt(move _4) -> [0_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27
+ }
+
+ bb2: {
+ StorageLive(_6); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19
+ _6 = (((_1.0: std::option::Option<u8>) as Some).0: u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19
+- StorageLive(_7); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:20
+- StorageLive(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:13
+- _8 = _6; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:13
+- _7 = Gt(move _8, const 42_u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:20
+- StorageDead(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:19: +2:20
+- StorageDead(_7); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+4:9: +4:10
+ StorageDead(_6); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+5:5: +5:6
+ goto -> bb3; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:5: +5:6
+ }
+
+ bb3: {
+ drop(_1) -> bb4; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+6:1: +6:2
+ }
+
+ bb4: {
+ StorageDead(_1); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff
new file mode 100644
index 000000000..da2f6fc44
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff
@@ -0,0 +1,71 @@
+- // MIR for `main` before SimplifyLocals
++ // MIR for `main` after SimplifyLocals
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+0:11: +0:11
+- let mut _1: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28
+- let mut _2: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:21: +1:23
+- let mut _3: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:25: +1:27
+- let _4: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
+- let mut _5: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
+- let mut _6: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
+- let mut _7: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
+- let _8: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
+- let mut _9: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
+- let mut _10: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
+- let mut _11: Temp; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
++ let _1: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
++ let mut _2: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
++ let _3: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
+ scope 1 {
+ }
+
+ bb0: {
+- StorageLive(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28
+- StorageLive(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:21: +1:23
+- StorageLive(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:25: +1:27
+- StorageDead(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:27: +1:28
+- StorageDead(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:27: +1:28
+- StorageDead(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:28: +1:29
+- StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
+- StorageLive(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
+- StorageLive(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
+- StorageLive(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
+- StorageDead(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21
+- StorageDead(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21
+- _4 = use_zst(move _5) -> bb1; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
++ StorageLive(_1); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
++ StorageLive(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
++ _1 = use_zst(move _2) -> bb1; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
+ // mir::Constant
+ // + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:12
+ // + literal: Const { ty: fn(((), ())) {use_zst}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+- StorageDead(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:21: +2:22
+- StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:22: +2:23
+- StorageLive(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
+- StorageLive(_9); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
+- StorageLive(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
+- StorageLive(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
+- StorageDead(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:33: +4:34
+- _8 = use_u8(const 42_u8) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
++ StorageDead(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:21: +2:22
++ StorageDead(_1); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:22: +2:23
++ StorageLive(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
++ _3 = use_u8(const 42_u8) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
+ // mir::Constant
+ // + span: $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:11
+ // + literal: Const { ty: fn(u8) {use_u8}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+- StorageDead(_9); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:34: +4:35
+- StorageDead(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36
+- StorageDead(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36
++ StorageDead(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36
+ return; // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff
new file mode 100644
index 000000000..c6895fa41
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff
@@ -0,0 +1,39 @@
+- // MIR for `map` before SimplifyLocals
++ // MIR for `map` after SimplifyLocals
+
+ fn map(_1: Option<Box<()>>) -> Option<Box<()>> {
+ debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9
+ let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46
+ let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13
+- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
+- let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
+- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
+- let mut _7: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
+ scope 1 {
+ debug x => ((_0 as Some).0: std::boxed::Box<()>); // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+ }
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
+ switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ ((_0 as Some).0: std::boxed::Box<()>) = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+ Deinit(_0); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
+ discriminant(_0) = 1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
+ goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
+ }
+
+ bb2: {
+ Deinit(_0); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
+ discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
+ goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
+ }
+
+ bb3: {
+ return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff
new file mode 100644
index 000000000..c6895fa41
--- /dev/null
+++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff
@@ -0,0 +1,39 @@
+- // MIR for `map` before SimplifyLocals
++ // MIR for `map` after SimplifyLocals
+
+ fn map(_1: Option<Box<()>>) -> Option<Box<()>> {
+ debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9
+ let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46
+ let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13
+- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
+- let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
+- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
+- let mut _7: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
+ scope 1 {
+ debug x => ((_0 as Some).0: std::boxed::Box<()>); // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+ }
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
+ switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ ((_0 as Some).0: std::boxed::Box<()>) = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+ Deinit(_0); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
+ discriminant(_0) = 1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
+ goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
+ }
+
+ bb2: {
+ Deinit(_0); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
+ discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
+ goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
+ }
+
+ bb3: {
+ return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_match.main.ConstProp.diff b/src/test/mir-opt/simplify_match.main.ConstProp.diff
new file mode 100644
index 000000000..e4f9a4c12
--- /dev/null
+++ b/src/test/mir-opt/simplify_match.main.ConstProp.diff
@@ -0,0 +1,40 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_match.rs:+0:11: +0:11
+ let mut _1: bool; // in scope 0 at $DIR/simplify_match.rs:+1:11: +1:31
+ let _2: bool; // in scope 0 at $DIR/simplify_match.rs:+1:17: +1:18
+ scope 1 {
+ debug x => _2; // in scope 1 at $DIR/simplify_match.rs:+1:17: +1:18
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/simplify_match.rs:+1:11: +1:31
+ StorageLive(_2); // scope 0 at $DIR/simplify_match.rs:+1:17: +1:18
+ _2 = const false; // scope 0 at $DIR/simplify_match.rs:+1:21: +1:26
+- _1 = _2; // scope 1 at $DIR/simplify_match.rs:+1:28: +1:29
++ _1 = const false; // scope 1 at $DIR/simplify_match.rs:+1:28: +1:29
+ StorageDead(_2); // scope 0 at $DIR/simplify_match.rs:+1:30: +1:31
+- switchInt(_1) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31
++ switchInt(const false) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31
+ }
+
+ bb1: {
+ nop; // scope 0 at $DIR/simplify_match.rs:+3:18: +3:20
+ goto -> bb3; // scope 0 at $DIR/simplify_match.rs:+3:18: +3:20
+ }
+
+ bb2: {
+ _0 = noop() -> bb3; // scope 0 at $DIR/simplify_match.rs:+2:17: +2:23
+ // mir::Constant
+ // + span: $DIR/simplify_match.rs:7:17: 7:21
+ // + literal: Const { ty: fn() {noop}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_1); // scope 0 at $DIR/simplify_match.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/simplify_match.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_match.rs b/src/test/mir-opt/simplify_match.rs
new file mode 100644
index 000000000..216203f9f
--- /dev/null
+++ b/src/test/mir-opt/simplify_match.rs
@@ -0,0 +1,10 @@
+#[inline(never)]
+fn noop() {}
+
+// EMIT_MIR simplify_match.main.ConstProp.diff
+fn main() {
+ match { let x = false; x } {
+ true => noop(),
+ false => {},
+ }
+}
diff --git a/src/test/mir-opt/simplify_try.rs b/src/test/mir-opt/simplify_try.rs
new file mode 100644
index 000000000..15e351e7d
--- /dev/null
+++ b/src/test/mir-opt/simplify_try.rs
@@ -0,0 +1,30 @@
+// compile-flags: -Zunsound-mir-opts
+// EMIT_MIR simplify_try.try_identity.SimplifyArmIdentity.diff
+// EMIT_MIR simplify_try.try_identity.SimplifyBranchSame.after.mir
+// EMIT_MIR simplify_try.try_identity.SimplifyLocals.after.mir
+// EMIT_MIR simplify_try.try_identity.DestinationPropagation.diff
+
+
+fn into_result<T, E>(r: Result<T, E>) -> Result<T, E> {
+ r
+}
+
+fn from_error<T, E>(e: E) -> Result<T, E> {
+ Err(e)
+}
+
+// This was written to the `?` from `try_trait`, but `try_trait_v2` uses a different structure,
+// so the relevant desugar is copied inline in order to keep the test testing the same thing.
+// FIXME(#85133): while this might be useful for `r#try!`, it would be nice to have a MIR
+// optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not.
+fn try_identity(x: Result<u32, i32>) -> Result<u32, i32> {
+ let y = match into_result(x) {
+ Err(e) => return from_error(From::from(e)),
+ Ok(v) => v,
+ };
+ Ok(y)
+}
+
+fn main() {
+ let _ = try_identity(Ok(0));
+}
diff --git a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff b/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff
new file mode 100644
index 000000000..d81d23c1c
--- /dev/null
+++ b/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff
@@ -0,0 +1,102 @@
+- // MIR for `try_identity` before DestinationPropagation
++ // MIR for `try_identity` after DestinationPropagation
+
+ fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
+ debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
+ let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
+ let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
+ let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
+ let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
+ let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
+ let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
+ let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
+ let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
+ let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
+ let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
+ scope 1 {
+- debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
++ debug y => ((_0 as Ok).0: u32); // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
+ }
+ scope 2 {
+ debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
+ scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
+ debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+ scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
+ debug e => _8; // in scope 6 at $DIR/simplify_try.rs:+0:21: +0:22
+ }
+ }
+ scope 3 {
+- debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
++ debug v => ((_0 as Ok).0: u32); // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
+ }
+ scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
+- debug r => _4; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23
++ debug r => _3; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23
+ }
+
+ bb0: {
+- StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
+- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
+- _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
+- _3 = move _4; // scope 4 at $DIR/simplify_try.rs:+0:5: +0:6
+- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
++ nop; // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
++ nop; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
++ nop; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
++ _3 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
++ nop; // scope 4 at $DIR/simplify_try.rs:+0:5: +0:6
++ nop; // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
+ _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
+ }
+
+ bb1: {
+- StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
+- _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
+- _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
+- StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
+- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
+- StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
+- _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
++ nop; // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
++ ((_0 as Ok).0: u32) = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
++ nop; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
++ nop; // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
++ nop; // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
++ nop; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
++ nop; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
+ Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
+- ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
++ nop; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
+ discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
+- StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
+- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
++ nop; // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
++ nop; // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
+ }
+
+ bb2: {
+ StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
+ nop; // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
+ StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
+ StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
+ nop; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
+ nop; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
+ nop; // scope 6 at $DIR/simplify_try.rs:+0:9: +0:10
+ Deinit(_0); // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
+ StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
+ StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
+- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
+- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
++ nop; // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
++ nop; // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff
new file mode 100644
index 000000000..853b95cc6
--- /dev/null
+++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff
@@ -0,0 +1,81 @@
+- // MIR for `try_identity` before SimplifyArmIdentity
++ // MIR for `try_identity` after SimplifyArmIdentity
+
+ fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
+ debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
+ let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
+ let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
+ let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
+ let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
+ let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
+ let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
+ let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
+ let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
+ let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
+ let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
+ scope 1 {
+ debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
+ }
+ scope 2 {
+ debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
+ scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
+ debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+ scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
+ debug e => _8; // in scope 6 at $DIR/simplify_try.rs:+0:21: +0:22
+ }
+ }
+ scope 3 {
+ debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
+ }
+ scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
+ debug r => _4; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
+ _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
+ _3 = move _4; // scope 4 at $DIR/simplify_try.rs:+0:5: +0:6
+ StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
+ _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
+ }
+
+ bb1: {
+ StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
+ _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
+ _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
+ StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
+ StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
+ StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
+ _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
+ Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
+ ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
+ discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
+ StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
+ StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
+ }
+
+ bb2: {
+ StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
+ _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
+ StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
+ StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
+ _9 = _6; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
+ _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
+ ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:+0:9: +0:10
+ Deinit(_0); // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
+ StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
+ StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
+ StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
+ StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir
new file mode 100644
index 000000000..10799cd92
--- /dev/null
+++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir
@@ -0,0 +1,79 @@
+// MIR for `try_identity` after SimplifyBranchSame
+
+fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
+ debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
+ let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
+ let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
+ let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
+ let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
+ let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
+ let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
+ let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
+ let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
+ let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
+ let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
+ scope 1 {
+ debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
+ }
+ scope 2 {
+ debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
+ scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
+ debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+ scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
+ debug e => _8; // in scope 6 at $DIR/simplify_try.rs:+0:21: +0:22
+ }
+ }
+ scope 3 {
+ debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
+ }
+ scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
+ debug r => _4; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
+ _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
+ _3 = move _4; // scope 4 at $DIR/simplify_try.rs:+0:5: +0:6
+ StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
+ _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
+ }
+
+ bb1: {
+ StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
+ _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
+ _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
+ StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
+ StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
+ StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
+ _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
+ Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
+ ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
+ discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
+ StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
+ StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
+ }
+
+ bb2: {
+ StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
+ _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
+ StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
+ StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
+ _9 = _6; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
+ _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
+ ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:+0:9: +0:10
+ Deinit(_0); // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
+ StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
+ StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
+ StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
+ StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
+ }
+}
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir
new file mode 100644
index 000000000..f8c9034f7
--- /dev/null
+++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir
@@ -0,0 +1,54 @@
+// MIR for `try_identity` after SimplifyLocals
+
+fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
+ debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
+ let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
+ let mut _2: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ let mut _3: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
+ let _4: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
+ let mut _5: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
+ let mut _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
+ scope 1 {
+ debug y => ((_0 as Ok).0: u32); // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
+ }
+ scope 2 {
+ debug e => _4; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
+ scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
+ debug t => _6; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+ scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
+ debug e => _5; // in scope 6 at $DIR/simplify_try.rs:+0:21: +0:22
+ }
+ }
+ scope 3 {
+ debug v => ((_0 as Ok).0: u32); // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
+ }
+ scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
+ debug r => _2; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23
+ }
+
+ bb0: {
+ _2 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
+ _3 = discriminant(_2); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ switchInt(move _3) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
+ }
+
+ bb1: {
+ ((_0 as Ok).0: u32) = ((_2 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
+ Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
+ discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
+ return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
+ }
+
+ bb2: {
+ StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
+ StorageLive(_5); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
+ StorageLive(_6); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
+ StorageDead(_6); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
+ Deinit(_0); // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
+ StorageDead(_5); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
+ StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
+ return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
+ }
+}
diff --git a/src/test/mir-opt/simplify_try_if_let.rs b/src/test/mir-opt/simplify_try_if_let.rs
new file mode 100644
index 000000000..fba67de40
--- /dev/null
+++ b/src/test/mir-opt/simplify_try_if_let.rs
@@ -0,0 +1,43 @@
+// compile-flags: -Zmir-opt-level=1 -Zunsound-mir-opts
+// ignore-test
+// FIXME: the pass is unsound and causes ICEs in the MIR validator
+
+// EMIT_MIR simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff
+
+use std::ptr::NonNull;
+
+pub struct LinkedList {
+ head: Option<NonNull<Node>>,
+ tail: Option<NonNull<Node>>,
+}
+
+pub struct Node {
+ next: Option<NonNull<Node>>,
+}
+
+impl LinkedList {
+ pub fn new() -> Self {
+ Self { head: None, tail: None }
+ }
+
+ pub fn append(&mut self, other: &mut Self) {
+ match self.tail {
+ None => {}
+ Some(mut tail) => {
+ // `as_mut` is okay here because we have exclusive access to the entirety
+ // of both lists.
+ if let Some(other_head) = other.head.take() {
+ unsafe {
+ tail.as_mut().next = Some(other_head);
+ }
+ }
+ }
+ }
+ }
+}
+
+fn main() {
+ let mut one = LinkedList::new();
+ let mut two = LinkedList::new();
+ one.append(&mut two);
+}
diff --git a/src/test/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff
new file mode 100644
index 000000000..11f6b5337
--- /dev/null
+++ b/src/test/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff
@@ -0,0 +1,104 @@
+- // MIR for `<impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append` before SimplifyArmIdentity
++ // MIR for `<impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append` after SimplifyArmIdentity
+
+ fn <impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append(_1: &mut LinkedList, _2: &mut LinkedList) -> () {
+ debug self => _1; // in scope 0 at $DIR/simplify_try_if_let.rs:20:19: 20:28
+ debug other => _2; // in scope 0 at $DIR/simplify_try_if_let.rs:20:30: 20:35
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_try_if_let.rs:20:48: 20:48
+ let mut _3: isize; // in scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17
+ let mut _4: std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26
+ let mut _5: std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:26:43: 26:60
+ let mut _6: &mut std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:26:43: 26:53
+ let mut _7: isize; // in scope 0 at $DIR/simplify_try_if_let.rs:26:24: 26:40
+ let mut _9: std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:46: 28:62
+ let mut _10: std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:51: 28:61
+ let mut _11: &mut Node; // in scope 0 at $DIR/simplify_try_if_let.rs:28:25: 28:38
+ let mut _12: &mut std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:25: 28:29
+ scope 1 {
+ debug tail => _4; // in scope 1 at $DIR/simplify_try_if_let.rs:23:18: 23:26
+ let _8: std::ptr::NonNull<Node>; // in scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39
+ scope 2 {
+- debug other_head => _8; // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39
++ debug other_head => ((_9 as Some).0: std::ptr::NonNull<Node>); // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39
+ scope 3 {
+ }
+ }
+ }
+
+ bb0: {
+ _3 = discriminant(((*_1).1: std::option::Option<std::ptr::NonNull<Node>>)); // scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17
+ switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17
+ }
+
+ bb1: {
+ StorageLive(_4); // scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26
+ _4 = ((((*_1).1: std::option::Option<std::ptr::NonNull<Node>>) as Some).0: std::ptr::NonNull<Node>); // scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26
+ StorageLive(_5); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:60
+ StorageLive(_6); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:53
+ _6 = &mut ((*_2).0: std::option::Option<std::ptr::NonNull<Node>>); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:53
+ _5 = Option::<NonNull<Node>>::take(move _6) -> bb4; // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:60
+ // mir::Constant
+ // + span: $DIR/simplify_try_if_let.rs:26:54: 26:58
+ // + literal: Const { ty: for<'r> fn(&'r mut std::option::Option<std::ptr::NonNull<Node>>) -> std::option::Option<std::ptr::NonNull<Node>> {std::option::Option::<std::ptr::NonNull<Node>>::take}, val: Value(Scalar(<ZST>)) }
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/simplify_try_if_let.rs:21:15: 21:24
+ }
+
+ bb3: {
+ _0 = const (); // scope 0 at $DIR/simplify_try_if_let.rs:22:21: 22:24
+ goto -> bb9; // scope 0 at $DIR/simplify_try_if_let.rs:21:9: 32:10
+ }
+
+ bb4: {
+ StorageDead(_6); // scope 1 at $DIR/simplify_try_if_let.rs:26:59: 26:60
+ _7 = discriminant(_5); // scope 1 at $DIR/simplify_try_if_let.rs:26:24: 26:40
+ switchInt(move _7) -> [1_isize: bb6, otherwise: bb5]; // scope 1 at $DIR/simplify_try_if_let.rs:26:24: 26:40
+ }
+
+ bb5: {
+ _0 = const (); // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18
+ goto -> bb8; // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18
+ }
+
+ bb6: {
+ StorageLive(_8); // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39
+ _8 = ((_5 as Some).0: std::ptr::NonNull<Node>); // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39
+ StorageLive(_9); // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
+- StorageLive(_10); // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61
+- _10 = _8; // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61
+- ((_9 as Some).0: std::ptr::NonNull<Node>) = move _10; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
+- discriminant(_9) = 1; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
+- StorageDead(_10); // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62
++ _9 = move _5; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
+ StorageLive(_11); // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38
+ StorageLive(_12); // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29
+ _12 = &mut _4; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29
+ _11 = NonNull::<Node>::as_mut(move _12) -> bb7; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38
+ // mir::Constant
+ // + span: $DIR/simplify_try_if_let.rs:28:30: 28:36
+ // + literal: Const { ty: for<'r> unsafe fn(&'r mut std::ptr::NonNull<Node>) -> &'r mut Node {std::ptr::NonNull::<Node>::as_mut}, val: Value(Scalar(<ZST>)) }
+ }
+
+ bb7: {
+ StorageDead(_12); // scope 3 at $DIR/simplify_try_if_let.rs:28:37: 28:38
+ ((*_11).0: std::option::Option<std::ptr::NonNull<Node>>) = move _9; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:62
+ StorageDead(_9); // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62
+ StorageDead(_11); // scope 3 at $DIR/simplify_try_if_let.rs:28:62: 28:63
+ _0 = const (); // scope 3 at $DIR/simplify_try_if_let.rs:27:21: 29:22
+ StorageDead(_8); // scope 1 at $DIR/simplify_try_if_let.rs:30:17: 30:18
+ goto -> bb8; // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18
+ }
+
+ bb8: {
+ StorageDead(_5); // scope 1 at $DIR/simplify_try_if_let.rs:31:13: 31:14
+ StorageDead(_4); // scope 0 at $DIR/simplify_try_if_let.rs:31:13: 31:14
+ goto -> bb9; // scope 0 at $DIR/simplify_try_if_let.rs:21:9: 32:10
+ }
+
+ bb9: {
+ return; // scope 0 at $DIR/simplify_try_if_let.rs:33:6: 33:6
+ }
+ }
+
diff --git a/src/test/mir-opt/slice-drop-shim.rs b/src/test/mir-opt/slice-drop-shim.rs
new file mode 100644
index 000000000..0fd32906d
--- /dev/null
+++ b/src/test/mir-opt/slice-drop-shim.rs
@@ -0,0 +1,7 @@
+// compile-flags: -Zmir-opt-level=0
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
+fn main() {
+ let _fn = std::ptr::drop_in_place::<[String]> as unsafe fn(_);
+}
diff --git a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir
new file mode 100644
index 000000000..b4b317e84
--- /dev/null
+++ b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir
@@ -0,0 +1,101 @@
+// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
+
+fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
+ let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _2: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _3: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _4: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _5: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _6: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _7: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _8: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _9: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _10: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _11: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _12: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _13: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _14: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _15: *mut [std::string::String]; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+
+ bb0: {
+ goto -> bb15; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb1: {
+ return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb3 (cleanup): {
+ _5 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ drop((*_5)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb4 (cleanup): {
+ _6 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ switchInt(move _6) -> [false: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb5: {
+ _7 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ drop((*_7)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb6: {
+ _8 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ switchInt(move _8) -> [false: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb7: {
+ _4 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb8: {
+ goto -> bb7; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb9 (cleanup): {
+ _11 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ drop((*_11)) -> bb10; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb10 (cleanup): {
+ _12 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ switchInt(move _12) -> [false: bb9, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb11: {
+ _13 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ drop((*_13)) -> [return: bb12, unwind: bb10]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb12: {
+ _14 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ switchInt(move _14) -> [false: bb11, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb13: {
+ _15 = &raw mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _9 = move _15 as *mut std::string::String (Misc); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _10 = Offset(_9, move _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ goto -> bb12; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb14: {
+ goto -> bb13; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb15: {
+ _2 = SizeOf(std::string::String); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _3 = Len((*_1)); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ switchInt(move _2) -> [0_usize: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+}
diff --git a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir
new file mode 100644
index 000000000..b4b317e84
--- /dev/null
+++ b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir
@@ -0,0 +1,101 @@
+// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
+
+fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
+ let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _2: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _3: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _4: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _5: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _6: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _7: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _8: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _9: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _10: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _11: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _12: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _13: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _14: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _15: *mut [std::string::String]; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+
+ bb0: {
+ goto -> bb15; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb1: {
+ return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb3 (cleanup): {
+ _5 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ drop((*_5)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb4 (cleanup): {
+ _6 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ switchInt(move _6) -> [false: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb5: {
+ _7 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ drop((*_7)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb6: {
+ _8 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ switchInt(move _8) -> [false: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb7: {
+ _4 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb8: {
+ goto -> bb7; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb9 (cleanup): {
+ _11 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ drop((*_11)) -> bb10; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb10 (cleanup): {
+ _12 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ switchInt(move _12) -> [false: bb9, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb11: {
+ _13 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ drop((*_13)) -> [return: bb12, unwind: bb10]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb12: {
+ _14 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ switchInt(move _14) -> [false: bb11, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb13: {
+ _15 = &raw mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _9 = move _15 as *mut std::string::String (Misc); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _10 = Offset(_9, move _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ goto -> bb12; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb14: {
+ goto -> bb13; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb15: {
+ _2 = SizeOf(std::string::String); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _3 = Len((*_1)); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ switchInt(move _2) -> [0_usize: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+}
diff --git a/src/test/mir-opt/spanview-block.rs b/src/test/mir-opt/spanview-block.rs
new file mode 100644
index 000000000..fc1d6e0ed
--- /dev/null
+++ b/src/test/mir-opt/spanview-block.rs
@@ -0,0 +1,5 @@
+// Test spanview block output
+// compile-flags: -Z dump-mir-spanview=block
+
+// EMIT_MIR spanview_block.main.mir_map.0.html
+fn main() {}
diff --git a/src/test/mir-opt/spanview-statement.rs b/src/test/mir-opt/spanview-statement.rs
new file mode 100644
index 000000000..a43ad5e71
--- /dev/null
+++ b/src/test/mir-opt/spanview-statement.rs
@@ -0,0 +1,5 @@
+// Test spanview output (the default value for `-Z dump-mir-spanview` is "statement")
+// compile-flags: -Z dump-mir-spanview
+
+// EMIT_MIR spanview_statement.main.mir_map.0.html
+fn main() {}
diff --git a/src/test/mir-opt/spanview-terminator.rs b/src/test/mir-opt/spanview-terminator.rs
new file mode 100644
index 000000000..92e1411ea
--- /dev/null
+++ b/src/test/mir-opt/spanview-terminator.rs
@@ -0,0 +1,5 @@
+// Test spanview terminator output
+// compile-flags: -Z dump-mir-spanview=terminator
+
+// EMIT_MIR spanview_terminator.main.mir_map.0.html
+fn main() {}
diff --git a/src/test/mir-opt/spanview_block.main.mir_map.0.html b/src/test/mir-opt/spanview_block.main.mir_map.0.html
new file mode 100644
index 000000000..8e5268043
--- /dev/null
+++ b/src/test/mir-opt/spanview_block.main.mir_map.0.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>spanview_block.main.mir_map.0</title>
+<style>
+ .line {
+ counter-increment: line;
+ }
+ .line:before {
+ content: counter(line) ": ";
+ font-family: Menlo, Monaco, monospace;
+ font-style: italic;
+ width: 3.8em;
+ display: inline-block;
+ text-align: right;
+ filter: opacity(50%);
+ -webkit-user-select: none;
+ }
+ .code {
+ color: #dddddd;
+ background-color: #222222;
+ font-family: Menlo, Monaco, monospace;
+ line-height: 1.4em;
+ border-bottom: 2px solid #222222;
+ white-space: pre;
+ display: inline-block;
+ }
+ .odd {
+ background-color: #55bbff;
+ color: #223311;
+ }
+ .even {
+ background-color: #ee7756;
+ color: #551133;
+ }
+ .code {
+ --index: calc(var(--layer) - 1);
+ padding-top: calc(var(--index) * 0.15em);
+ filter:
+ hue-rotate(calc(var(--index) * 25deg))
+ saturate(calc(100% - (var(--index) * 2%)))
+ brightness(calc(100% - (var(--index) * 1.5%)));
+ }
+ .annotation {
+ color: #4444ff;
+ font-family: monospace;
+ font-style: italic;
+ display: none;
+ -webkit-user-select: none;
+ }
+ body:active .annotation {
+ /* requires holding mouse down anywhere on the page */
+ display: inline-block;
+ }
+ span:hover .annotation {
+ /* requires hover over a span ONLY on its first line */
+ display: inline-block;
+ }
+</style>
+</head>
+<body>
+<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="0: $DIR/spanview-block.rs:5:11: 5:13:
+ 5:11-5:13: Assign: _0 = const ()
+ 5:13-5:13: Return: return"><span class="annotation">0⦊</span>{}<span class="annotation">⦉0</span></span></span></span></div>
+</body>
+</html>
diff --git a/src/test/mir-opt/spanview_statement.main.mir_map.0.html b/src/test/mir-opt/spanview_statement.main.mir_map.0.html
new file mode 100644
index 000000000..abbff2270
--- /dev/null
+++ b/src/test/mir-opt/spanview_statement.main.mir_map.0.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>spanview_statement.main.mir_map.0</title>
+<style>
+ .line {
+ counter-increment: line;
+ }
+ .line:before {
+ content: counter(line) ": ";
+ font-family: Menlo, Monaco, monospace;
+ font-style: italic;
+ width: 3.8em;
+ display: inline-block;
+ text-align: right;
+ filter: opacity(50%);
+ -webkit-user-select: none;
+ }
+ .code {
+ color: #dddddd;
+ background-color: #222222;
+ font-family: Menlo, Monaco, monospace;
+ line-height: 1.4em;
+ border-bottom: 2px solid #222222;
+ white-space: pre;
+ display: inline-block;
+ }
+ .odd {
+ background-color: #55bbff;
+ color: #223311;
+ }
+ .even {
+ background-color: #ee7756;
+ color: #551133;
+ }
+ .code {
+ --index: calc(var(--layer) - 1);
+ padding-top: calc(var(--index) * 0.15em);
+ filter:
+ hue-rotate(calc(var(--index) * 25deg))
+ saturate(calc(100% - (var(--index) * 2%)))
+ brightness(calc(100% - (var(--index) * 1.5%)));
+ }
+ .annotation {
+ color: #4444ff;
+ font-family: monospace;
+ font-style: italic;
+ display: none;
+ -webkit-user-select: none;
+ }
+ body:active .annotation {
+ /* requires holding mouse down anywhere on the page */
+ display: inline-block;
+ }
+ span:hover .annotation {
+ /* requires hover over a span ONLY on its first line */
+ display: inline-block;
+ }
+</style>
+</head>
+<body>
+<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="0[0]: $DIR/spanview-statement.rs:5:11: 5:13:
+ 5:11-5:13: Assign: _0 = const ()"><span class="annotation">0[0]⦊</span>{}<span class="annotation">⦉0[0]</span></span></span><span><span class="code odd" style="--layer: 1" title="0:Return: $DIR/spanview-statement.rs:5:13: 5:13:
+ 5:13-5:13: Return: return"><span class="annotation">0:Return⦊</span>‸<span class="annotation">⦉0:Return</span></span></span></span></div>
+</body>
+</html>
diff --git a/src/test/mir-opt/spanview_terminator.main.mir_map.0.html b/src/test/mir-opt/spanview_terminator.main.mir_map.0.html
new file mode 100644
index 000000000..55fafd90b
--- /dev/null
+++ b/src/test/mir-opt/spanview_terminator.main.mir_map.0.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>spanview_terminator.main.mir_map.0</title>
+<style>
+ .line {
+ counter-increment: line;
+ }
+ .line:before {
+ content: counter(line) ": ";
+ font-family: Menlo, Monaco, monospace;
+ font-style: italic;
+ width: 3.8em;
+ display: inline-block;
+ text-align: right;
+ filter: opacity(50%);
+ -webkit-user-select: none;
+ }
+ .code {
+ color: #dddddd;
+ background-color: #222222;
+ font-family: Menlo, Monaco, monospace;
+ line-height: 1.4em;
+ border-bottom: 2px solid #222222;
+ white-space: pre;
+ display: inline-block;
+ }
+ .odd {
+ background-color: #55bbff;
+ color: #223311;
+ }
+ .even {
+ background-color: #ee7756;
+ color: #551133;
+ }
+ .code {
+ --index: calc(var(--layer) - 1);
+ padding-top: calc(var(--index) * 0.15em);
+ filter:
+ hue-rotate(calc(var(--index) * 25deg))
+ saturate(calc(100% - (var(--index) * 2%)))
+ brightness(calc(100% - (var(--index) * 1.5%)));
+ }
+ .annotation {
+ color: #4444ff;
+ font-family: monospace;
+ font-style: italic;
+ display: none;
+ -webkit-user-select: none;
+ }
+ body:active .annotation {
+ /* requires holding mouse down anywhere on the page */
+ display: inline-block;
+ }
+ span:hover .annotation {
+ /* requires hover over a span ONLY on its first line */
+ display: inline-block;
+ }
+</style>
+</head>
+<body>
+<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() {}</span><span><span class="code even" style="--layer: 1" title="0:Return: $DIR/spanview-terminator.rs:5:13: 5:13:
+ 5:13-5:13: Return: return"><span class="annotation">0:Return⦊</span>‸<span class="annotation">⦉0:Return</span></span></span></span></div>
+</body>
+</html>
diff --git a/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir b/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir
new file mode 100644
index 000000000..bc9e91420
--- /dev/null
+++ b/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir
@@ -0,0 +1,203 @@
+// MIR for `XXX` 0 mir_map
+
+static XXX: &Foo = {
+ let mut _0: &Foo; // return place in scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:13: +0:25
+ let _1: &Foo; // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:28: +18:2
+ let _2: Foo; // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:29: +18:2
+ let mut _3: &[(u32, u32)]; // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6
+ let mut _4: &[(u32, u32); 42]; // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6
+ let _5: &[(u32, u32); 42]; // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6
+ let _6: [(u32, u32); 42]; // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:12: +17:6
+ let mut _7: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:9: +3:15
+ let mut _8: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:17: +3:23
+ let mut _9: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:25: +3:31
+ let mut _10: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:9: +4:15
+ let mut _11: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:17: +4:23
+ let mut _12: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:25: +4:31
+ let mut _13: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:9: +5:15
+ let mut _14: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:17: +5:23
+ let mut _15: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:25: +5:31
+ let mut _16: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:9: +6:15
+ let mut _17: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:17: +6:23
+ let mut _18: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:25: +6:31
+ let mut _19: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:9: +7:15
+ let mut _20: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:17: +7:23
+ let mut _21: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:25: +7:31
+ let mut _22: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:9: +8:15
+ let mut _23: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:17: +8:23
+ let mut _24: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:25: +8:31
+ let mut _25: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:9: +9:15
+ let mut _26: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:17: +9:23
+ let mut _27: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:25: +9:31
+ let mut _28: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:9: +10:15
+ let mut _29: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:17: +10:23
+ let mut _30: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:25: +10:31
+ let mut _31: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:9: +11:15
+ let mut _32: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:17: +11:23
+ let mut _33: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:25: +11:31
+ let mut _34: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:9: +12:15
+ let mut _35: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:17: +12:23
+ let mut _36: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:25: +12:31
+ let mut _37: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:9: +13:15
+ let mut _38: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:17: +13:23
+ let mut _39: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:25: +13:31
+ let mut _40: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:9: +14:15
+ let mut _41: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:17: +14:23
+ let mut _42: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:25: +14:31
+ let mut _43: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:9: +15:15
+ let mut _44: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:17: +15:23
+ let mut _45: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:25: +15:31
+ let mut _46: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:9: +16:15
+ let mut _47: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:17: +16:23
+ let mut _48: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:25: +16:31
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:28: +18:2
+ StorageLive(_2); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:29: +18:2
+ StorageLive(_3); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6
+ StorageLive(_4); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6
+ StorageLive(_5); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6
+ StorageLive(_6); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:12: +17:6
+ StorageLive(_7); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:9: +3:15
+ _7 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:9: +3:15
+ StorageLive(_8); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:17: +3:23
+ _8 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:17: +3:23
+ StorageLive(_9); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:25: +3:31
+ _9 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:25: +3:31
+ StorageLive(_10); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:9: +4:15
+ _10 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:9: +4:15
+ StorageLive(_11); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:17: +4:23
+ _11 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:17: +4:23
+ StorageLive(_12); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:25: +4:31
+ _12 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:25: +4:31
+ StorageLive(_13); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:9: +5:15
+ _13 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:9: +5:15
+ StorageLive(_14); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:17: +5:23
+ _14 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:17: +5:23
+ StorageLive(_15); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:25: +5:31
+ _15 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:25: +5:31
+ StorageLive(_16); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:9: +6:15
+ _16 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:9: +6:15
+ StorageLive(_17); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:17: +6:23
+ _17 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:17: +6:23
+ StorageLive(_18); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:25: +6:31
+ _18 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:25: +6:31
+ StorageLive(_19); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:9: +7:15
+ _19 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:9: +7:15
+ StorageLive(_20); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:17: +7:23
+ _20 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:17: +7:23
+ StorageLive(_21); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:25: +7:31
+ _21 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:25: +7:31
+ StorageLive(_22); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:9: +8:15
+ _22 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:9: +8:15
+ StorageLive(_23); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:17: +8:23
+ _23 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:17: +8:23
+ StorageLive(_24); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:25: +8:31
+ _24 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:25: +8:31
+ StorageLive(_25); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:9: +9:15
+ _25 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:9: +9:15
+ StorageLive(_26); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:17: +9:23
+ _26 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:17: +9:23
+ StorageLive(_27); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:25: +9:31
+ _27 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:25: +9:31
+ StorageLive(_28); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:9: +10:15
+ _28 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:9: +10:15
+ StorageLive(_29); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:17: +10:23
+ _29 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:17: +10:23
+ StorageLive(_30); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:25: +10:31
+ _30 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:25: +10:31
+ StorageLive(_31); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:9: +11:15
+ _31 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:9: +11:15
+ StorageLive(_32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:17: +11:23
+ _32 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:17: +11:23
+ StorageLive(_33); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:25: +11:31
+ _33 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:25: +11:31
+ StorageLive(_34); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:9: +12:15
+ _34 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:9: +12:15
+ StorageLive(_35); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:17: +12:23
+ _35 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:17: +12:23
+ StorageLive(_36); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:25: +12:31
+ _36 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:25: +12:31
+ StorageLive(_37); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:9: +13:15
+ _37 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:9: +13:15
+ StorageLive(_38); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:17: +13:23
+ _38 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:17: +13:23
+ StorageLive(_39); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:25: +13:31
+ _39 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:25: +13:31
+ StorageLive(_40); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:9: +14:15
+ _40 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:9: +14:15
+ StorageLive(_41); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:17: +14:23
+ _41 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:17: +14:23
+ StorageLive(_42); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:25: +14:31
+ _42 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:25: +14:31
+ StorageLive(_43); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:9: +15:15
+ _43 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:9: +15:15
+ StorageLive(_44); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:17: +15:23
+ _44 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:17: +15:23
+ StorageLive(_45); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:25: +15:31
+ _45 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:25: +15:31
+ StorageLive(_46); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:9: +16:15
+ _46 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:9: +16:15
+ StorageLive(_47); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:17: +16:23
+ _47 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:17: +16:23
+ StorageLive(_48); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:25: +16:31
+ _48 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:25: +16:31
+ _6 = [move _7, move _8, move _9, move _10, move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20, move _21, move _22, move _23, move _24, move _25, move _26, move _27, move _28, move _29, move _30, move _31, move _32, move _33, move _34, move _35, move _36, move _37, move _38, move _39, move _40, move _41, move _42, move _43, move _44, move _45, move _46, move _47, move _48]; // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:12: +17:6
+ StorageDead(_48); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_47); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_46); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_45); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_44); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_43); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_42); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_41); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_40); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_39); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_38); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_37); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_36); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_35); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_34); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_33); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_31); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_30); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_29); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_28); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_27); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_26); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_25); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_24); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_23); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_22); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_21); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_20); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_19); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_18); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_17); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_16); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_15); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_14); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_13); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_12); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_11); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_10); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_9); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_8); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ StorageDead(_7); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ _5 = &_6; // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6
+ _4 = &(*_5); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6
+ _3 = move _4 as &[(u32, u32)] (Pointer(Unsize)); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6
+ StorageDead(_4); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6
+ _2 = Foo { tup: const "hi", data: move _3 }; // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:29: +18:2
+ // mir::Constant
+ // + span: $DIR/storage_live_dead_in_statics.rs:6:10: 6:14
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ StorageDead(_3); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+18:1: +18:2
+ _1 = &_2; // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:28: +18:2
+ _0 = &(*_1); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:28: +18:2
+ StorageDead(_5); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+18:1: +18:2
+ StorageDead(_1); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+18:1: +18:2
+ return; // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:1: +0:25
+ }
+}
diff --git a/src/test/mir-opt/storage_live_dead_in_statics.rs b/src/test/mir-opt/storage_live_dead_in_statics.rs
new file mode 100644
index 000000000..b03de8612
--- /dev/null
+++ b/src/test/mir-opt/storage_live_dead_in_statics.rs
@@ -0,0 +1,33 @@
+// Check that when we compile the static `XXX` into MIR, we do not
+// generate `StorageStart` or `StorageEnd` statements.
+
+// EMIT_MIR storage_live_dead_in_statics.XXX.mir_map.0.mir
+static XXX: &'static Foo = &Foo {
+ tup: "hi",
+ data: &[
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ (0, 1), (0, 2), (0, 3),
+ ]
+};
+
+#[derive(Debug)]
+struct Foo {
+ tup: &'static str,
+ data: &'static [(u32, u32)]
+}
+
+fn main() {
+ println!("{:?}", XXX);
+}
diff --git a/src/test/mir-opt/storage_ranges.main.nll.0.mir b/src/test/mir-opt/storage_ranges.main.nll.0.mir
new file mode 100644
index 000000000..812eb3b82
--- /dev/null
+++ b/src/test/mir-opt/storage_ranges.main.nll.0.mir
@@ -0,0 +1,64 @@
+// MIR for `main` 0 nll
+
+| Free Region Mapping
+| '_#0r | Global | ['_#0r, '_#1r]
+| '_#1r | Local | ['_#1r]
+|
+| Inferred Region Values
+| '_#0r | U0 | {bb0[0..=22], '_#0r, '_#1r}
+| '_#1r | U0 | {bb0[0..=22], '_#1r}
+| '_#2r | U0 | {}
+| '_#3r | U0 | {bb0[10..=11]}
+| '_#4r | U0 | {bb0[11]}
+|
+| Inference Constraints
+| '_#0r live at {bb0[0..=22]}
+| '_#1r live at {bb0[0..=22]}
+| '_#3r live at {bb0[10]}
+| '_#4r live at {bb0[11]}
+| '_#3r: '_#4r due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0)
+|
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/storage_ranges.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/storage_ranges.rs:+1:9: +1:10
+ let _2: (); // in scope 0 at $DIR/storage_ranges.rs:+2:5: +4:6
+ let _4: std::option::Option<i32>; // in scope 0 at $DIR/storage_ranges.rs:+3:18: +3:25
+ let mut _5: i32; // in scope 0 at $DIR/storage_ranges.rs:+3:23: +3:24
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/storage_ranges.rs:+1:9: +1:10
+ let _3: &std::option::Option<i32>; // in scope 1 at $DIR/storage_ranges.rs:+3:13: +3:14
+ let _6: i32; // in scope 1 at $DIR/storage_ranges.rs:+5:9: +5:10
+ scope 2 {
+ debug b => _3; // in scope 2 at $DIR/storage_ranges.rs:+3:13: +3:14
+ }
+ scope 3 {
+ debug c => _6; // in scope 3 at $DIR/storage_ranges.rs:+5:9: +5:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/storage_ranges.rs:+1:9: +1:10
+ _1 = const 0_i32; // scope 0 at $DIR/storage_ranges.rs:+1:13: +1:14
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/storage_ranges.rs:+1:9: +1:10
+ StorageLive(_2); // scope 1 at $DIR/storage_ranges.rs:+2:5: +4:6
+ StorageLive(_3); // scope 1 at $DIR/storage_ranges.rs:+3:13: +3:14
+ StorageLive(_4); // scope 1 at $DIR/storage_ranges.rs:+3:18: +3:25
+ StorageLive(_5); // scope 1 at $DIR/storage_ranges.rs:+3:23: +3:24
+ _5 = _1; // scope 1 at $DIR/storage_ranges.rs:+3:23: +3:24
+ _4 = Option::<i32>::Some(move _5); // scope 1 at $DIR/storage_ranges.rs:+3:18: +3:25
+ StorageDead(_5); // scope 1 at $DIR/storage_ranges.rs:+3:24: +3:25
+ _3 = &_4; // scope 1 at $DIR/storage_ranges.rs:+3:17: +3:25
+ FakeRead(ForLet(None), _3); // scope 1 at $DIR/storage_ranges.rs:+3:13: +3:14
+ _2 = const (); // scope 1 at $DIR/storage_ranges.rs:+2:5: +4:6
+ StorageDead(_4); // scope 1 at $DIR/storage_ranges.rs:+4:5: +4:6
+ StorageDead(_3); // scope 1 at $DIR/storage_ranges.rs:+4:5: +4:6
+ StorageDead(_2); // scope 1 at $DIR/storage_ranges.rs:+4:5: +4:6
+ StorageLive(_6); // scope 1 at $DIR/storage_ranges.rs:+5:9: +5:10
+ _6 = const 1_i32; // scope 1 at $DIR/storage_ranges.rs:+5:13: +5:14
+ FakeRead(ForLet(None), _6); // scope 1 at $DIR/storage_ranges.rs:+5:9: +5:10
+ _0 = const (); // scope 0 at $DIR/storage_ranges.rs:+0:11: +6:2
+ StorageDead(_6); // scope 1 at $DIR/storage_ranges.rs:+6:1: +6:2
+ StorageDead(_1); // scope 0 at $DIR/storage_ranges.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/storage_ranges.rs:+6:2: +6:2
+ }
+}
diff --git a/src/test/mir-opt/storage_ranges.rs b/src/test/mir-opt/storage_ranges.rs
new file mode 100644
index 000000000..996051a29
--- /dev/null
+++ b/src/test/mir-opt/storage_ranges.rs
@@ -0,0 +1,9 @@
+// EMIT_MIR storage_ranges.main.nll.0.mir
+
+fn main() {
+ let a = 0;
+ {
+ let b = &Some(a);
+ }
+ let c = 1;
+}
diff --git a/src/test/mir-opt/tls-access.rs b/src/test/mir-opt/tls-access.rs
new file mode 100644
index 000000000..19344c868
--- /dev/null
+++ b/src/test/mir-opt/tls-access.rs
@@ -0,0 +1,14 @@
+// EMIT_MIR tls_access.main.PreCodegen.after.mir
+// compile-flags: -Zmir-opt-level=0
+
+#![feature(thread_local)]
+
+#[thread_local]
+static mut FOO: u8 = 3;
+
+fn main() {
+ unsafe {
+ let a = &FOO;
+ FOO = 42;
+ }
+}
diff --git a/src/test/mir-opt/tls_access.main.PreCodegen.after.mir b/src/test/mir-opt/tls_access.main.PreCodegen.after.mir
new file mode 100644
index 000000000..b6c36be2b
--- /dev/null
+++ b/src/test/mir-opt/tls_access.main.PreCodegen.after.mir
@@ -0,0 +1,28 @@
+// MIR for `main` after PreCodegen
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/tls-access.rs:+0:11: +0:11
+ let _2: *mut u8; // in scope 0 at $DIR/tls-access.rs:+2:18: +2:21
+ let mut _3: *mut u8; // in scope 0 at $DIR/tls-access.rs:+3:9: +3:12
+ scope 1 {
+ let _1: &u8; // in scope 1 at $DIR/tls-access.rs:+2:13: +2:14
+ scope 2 {
+ debug a => _1; // in scope 2 at $DIR/tls-access.rs:+2:13: +2:14
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 1 at $DIR/tls-access.rs:+2:13: +2:14
+ StorageLive(_2); // scope 1 at $DIR/tls-access.rs:+2:18: +2:21
+ _2 = &/*tls*/ mut FOO; // scope 1 at $DIR/tls-access.rs:+2:18: +2:21
+ _1 = &(*_2); // scope 1 at $DIR/tls-access.rs:+2:17: +2:21
+ StorageLive(_3); // scope 2 at $DIR/tls-access.rs:+3:9: +3:12
+ _3 = &/*tls*/ mut FOO; // scope 2 at $DIR/tls-access.rs:+3:9: +3:12
+ (*_3) = const 42_u8; // scope 2 at $DIR/tls-access.rs:+3:9: +3:17
+ StorageDead(_3); // scope 2 at $DIR/tls-access.rs:+3:17: +3:18
+ _0 = const (); // scope 1 at $DIR/tls-access.rs:+1:5: +4:6
+ StorageDead(_2); // scope 1 at $DIR/tls-access.rs:+4:5: +4:6
+ StorageDead(_1); // scope 1 at $DIR/tls-access.rs:+4:5: +4:6
+ return; // scope 0 at $DIR/tls-access.rs:+5:2: +5:2
+ }
+}
diff --git a/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir
new file mode 100644
index 000000000..6e9a8b4d9
--- /dev/null
+++ b/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir
@@ -0,0 +1,111 @@
+// MIR for `move_out_by_subslice` 0 mir_map
+
+fn move_out_by_subslice() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/uniform_array_move_out.rs:+0:27: +0:27
+ let _1: [std::boxed::Box<i32>; 2]; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10
+ let mut _2: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ let mut _3: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ let mut _4: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ let mut _5: *mut u8; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ let mut _6: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ let mut _7: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ let mut _8: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ let mut _9: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ let mut _10: *mut u8; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ let mut _11: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/uniform_array_move_out.rs:+1:9: +1:10
+ let _12: [std::boxed::Box<i32>; 2]; // in scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:17
+ scope 4 {
+ debug _y => _12; // in scope 4 at $DIR/uniform_array_move_out.rs:+2:10: +2:17
+ }
+ }
+ scope 2 {
+ }
+ scope 3 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ _3 = SizeOf(i32); // scope 2 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ _4 = AlignOf(i32); // scope 2 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb12]; // scope 2 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ // mir::Constant
+ // + span: $DIR/uniform_array_move_out.rs:11:14: 11:19
+ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_6); // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ _6 = ShallowInitBox(move _5, i32); // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ (*_6) = const 1_i32; // scope 0 at $DIR/uniform_array_move_out.rs:+1:18: +1:19
+ _2 = move _6; // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ drop(_6) -> [return: bb2, unwind: bb11]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:18: +1:19
+ }
+
+ bb2: {
+ StorageDead(_6); // scope 0 at $DIR/uniform_array_move_out.rs:+1:18: +1:19
+ StorageLive(_7); // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ _8 = SizeOf(i32); // scope 3 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ _9 = AlignOf(i32); // scope 3 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb11]; // scope 3 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ // mir::Constant
+ // + span: $DIR/uniform_array_move_out.rs:11:21: 11:26
+ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageLive(_11); // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ _11 = ShallowInitBox(move _10, i32); // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ (*_11) = const 2_i32; // scope 0 at $DIR/uniform_array_move_out.rs:+1:25: +1:26
+ _7 = move _11; // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ drop(_11) -> [return: bb4, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:25: +1:26
+ }
+
+ bb4: {
+ StorageDead(_11); // scope 0 at $DIR/uniform_array_move_out.rs:+1:25: +1:26
+ _1 = [move _2, move _7]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:13: +1:27
+ drop(_7) -> [return: bb5, unwind: bb11]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
+ }
+
+ bb5: {
+ StorageDead(_7); // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
+ drop(_2) -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
+ }
+
+ bb6: {
+ StorageDead(_2); // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10
+ StorageLive(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:17
+ _12 = move _1[0..2]; // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:17
+ _0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:+0:27: +3:2
+ drop(_12) -> [return: bb7, unwind: bb9]; // scope 1 at $DIR/uniform_array_move_out.rs:+3:1: +3:2
+ }
+
+ bb7: {
+ StorageDead(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+3:1: +3:2
+ drop(_1) -> [return: bb8, unwind: bb12]; // scope 0 at $DIR/uniform_array_move_out.rs:+3:1: +3:2
+ }
+
+ bb8: {
+ StorageDead(_1); // scope 0 at $DIR/uniform_array_move_out.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/uniform_array_move_out.rs:+3:2: +3:2
+ }
+
+ bb9 (cleanup): {
+ drop(_1) -> bb12; // scope 0 at $DIR/uniform_array_move_out.rs:+3:1: +3:2
+ }
+
+ bb10 (cleanup): {
+ drop(_7) -> bb11; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
+ }
+
+ bb11 (cleanup): {
+ drop(_2) -> bb12; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
+ }
+
+ bb12 (cleanup): {
+ resume; // scope 0 at $DIR/uniform_array_move_out.rs:+0:1: +3:2
+ }
+}
diff --git a/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir
new file mode 100644
index 000000000..23a50b22a
--- /dev/null
+++ b/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir
@@ -0,0 +1,111 @@
+// MIR for `move_out_from_end` 0 mir_map
+
+fn move_out_from_end() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/uniform_array_move_out.rs:+0:24: +0:24
+ let _1: [std::boxed::Box<i32>; 2]; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10
+ let mut _2: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ let mut _3: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ let mut _4: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ let mut _5: *mut u8; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ let mut _6: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ let mut _7: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ let mut _8: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ let mut _9: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ let mut _10: *mut u8; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ let mut _11: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/uniform_array_move_out.rs:+1:9: +1:10
+ let _12: std::boxed::Box<i32>; // in scope 1 at $DIR/uniform_array_move_out.rs:+2:14: +2:16
+ scope 4 {
+ debug _y => _12; // in scope 4 at $DIR/uniform_array_move_out.rs:+2:14: +2:16
+ }
+ }
+ scope 2 {
+ }
+ scope 3 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ _3 = SizeOf(i32); // scope 2 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ _4 = AlignOf(i32); // scope 2 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb12]; // scope 2 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ // mir::Constant
+ // + span: $DIR/uniform_array_move_out.rs:5:14: 5:19
+ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_6); // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ _6 = ShallowInitBox(move _5, i32); // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ (*_6) = const 1_i32; // scope 0 at $DIR/uniform_array_move_out.rs:+1:18: +1:19
+ _2 = move _6; // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19
+ drop(_6) -> [return: bb2, unwind: bb11]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:18: +1:19
+ }
+
+ bb2: {
+ StorageDead(_6); // scope 0 at $DIR/uniform_array_move_out.rs:+1:18: +1:19
+ StorageLive(_7); // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ _8 = SizeOf(i32); // scope 3 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ _9 = AlignOf(i32); // scope 3 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb11]; // scope 3 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ // mir::Constant
+ // + span: $DIR/uniform_array_move_out.rs:5:21: 5:26
+ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageLive(_11); // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ _11 = ShallowInitBox(move _10, i32); // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ (*_11) = const 2_i32; // scope 0 at $DIR/uniform_array_move_out.rs:+1:25: +1:26
+ _7 = move _11; // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
+ drop(_11) -> [return: bb4, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:25: +1:26
+ }
+
+ bb4: {
+ StorageDead(_11); // scope 0 at $DIR/uniform_array_move_out.rs:+1:25: +1:26
+ _1 = [move _2, move _7]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:13: +1:27
+ drop(_7) -> [return: bb5, unwind: bb11]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
+ }
+
+ bb5: {
+ StorageDead(_7); // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
+ drop(_2) -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
+ }
+
+ bb6: {
+ StorageDead(_2); // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10
+ StorageLive(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+2:14: +2:16
+ _12 = move _1[1 of 2]; // scope 1 at $DIR/uniform_array_move_out.rs:+2:14: +2:16
+ _0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:+0:24: +3:2
+ drop(_12) -> [return: bb7, unwind: bb9]; // scope 1 at $DIR/uniform_array_move_out.rs:+3:1: +3:2
+ }
+
+ bb7: {
+ StorageDead(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+3:1: +3:2
+ drop(_1) -> [return: bb8, unwind: bb12]; // scope 0 at $DIR/uniform_array_move_out.rs:+3:1: +3:2
+ }
+
+ bb8: {
+ StorageDead(_1); // scope 0 at $DIR/uniform_array_move_out.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/uniform_array_move_out.rs:+3:2: +3:2
+ }
+
+ bb9 (cleanup): {
+ drop(_1) -> bb12; // scope 0 at $DIR/uniform_array_move_out.rs:+3:1: +3:2
+ }
+
+ bb10 (cleanup): {
+ drop(_7) -> bb11; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
+ }
+
+ bb11 (cleanup): {
+ drop(_2) -> bb12; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
+ }
+
+ bb12 (cleanup): {
+ resume; // scope 0 at $DIR/uniform_array_move_out.rs:+0:1: +3:2
+ }
+}
diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/uniform_array_move_out.rs
new file mode 100644
index 000000000..35e425528
--- /dev/null
+++ b/src/test/mir-opt/uniform_array_move_out.rs
@@ -0,0 +1,18 @@
+#![feature(box_syntax)]
+
+// EMIT_MIR uniform_array_move_out.move_out_from_end.mir_map.0.mir
+fn move_out_from_end() {
+ let a = [box 1, box 2];
+ let [.., _y] = a;
+}
+
+// EMIT_MIR uniform_array_move_out.move_out_by_subslice.mir_map.0.mir
+fn move_out_by_subslice() {
+ let a = [box 1, box 2];
+ let [_y @ ..] = a;
+}
+
+fn main() {
+ move_out_by_subslice();
+ move_out_from_end();
+}
diff --git a/src/test/mir-opt/uninhabited-enum.rs b/src/test/mir-opt/uninhabited-enum.rs
new file mode 100644
index 000000000..97c6e8cd5
--- /dev/null
+++ b/src/test/mir-opt/uninhabited-enum.rs
@@ -0,0 +1,19 @@
+#![feature(never_type)]
+
+pub enum Void {}
+
+// EMIT_MIR uninhabited_enum.process_never.SimplifyLocals.after.mir
+#[no_mangle]
+pub fn process_never(input: *const !) {
+ let _input = unsafe { &*input };
+}
+
+// EMIT_MIR uninhabited_enum.process_void.SimplifyLocals.after.mir
+#[no_mangle]
+pub fn process_void(input: *const Void) {
+ let _input = unsafe { &*input };
+ // In the future, this should end with `unreachable`, but we currently only do
+ // unreachability analysis for `!`.
+}
+
+fn main() {}
diff --git a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir
new file mode 100644
index 000000000..34c38d24c
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir
@@ -0,0 +1,18 @@
+// MIR for `process_never` after SimplifyLocals
+
+fn process_never(_1: *const !) -> () {
+ debug input => _1; // in scope 0 at $DIR/uninhabited-enum.rs:+0:22: +0:27
+ let mut _0: (); // return place in scope 0 at $DIR/uninhabited-enum.rs:+0:39: +0:39
+ let _2: &!; // 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
+ }
+ 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:+2:1: +2:2
+ unreachable; // scope 0 at $DIR/uninhabited-enum.rs:+0:39: +2:2
+ }
+}
diff --git a/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir
new file mode 100644
index 000000000..bbb81724c
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir
@@ -0,0 +1,18 @@
+// MIR for `process_void` after SimplifyLocals
+
+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
+ }
+ 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/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
new file mode 100644
index 000000000..3d860dac3
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
@@ -0,0 +1,63 @@
+// MIR for `main` after SimplifyCfg-after-uninhabited-enum-branching
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +0:11
+ let _1: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +5:6
+ let mut _2: Test1; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ let mut _3: isize; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+2:9: +2:20
+ let _4: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34
+ let _5: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
+ let _6: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +10:6
+ let mut _7: Test2; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ let mut _8: isize; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+8:9: +8:17
+ let _9: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +5:6
+ StorageLive(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ Deinit(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ discriminant(_2) = 2; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ _3 = discriminant(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ StorageLive(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
+ _5 = const "C"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching.rs:23:21: 23:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _1 = &(*_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
+ StorageDead(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:23: +4:24
+ StorageDead(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+5:6: +5:7
+ StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching.rs:+5:6: +5:7
+ StorageLive(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +10:6
+ StorageLive(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ Deinit(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ discriminant(_7) = 0; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ _8 = discriminant(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ switchInt(move _8) -> [4_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19
+ }
+
+ bb1: {
+ StorageLive(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
+ _9 = const "E"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching.rs:28:21: 28:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _6 = &(*_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
+ StorageDead(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24
+ goto -> bb3; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24
+ }
+
+ bb2: {
+ _6 = const "D"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching.rs:27:21: 27:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ goto -> bb3; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
+ }
+
+ bb3: {
+ StorageDead(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7
+ StorageDead(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7
+ _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +11:2
+ return; // scope 0 at $DIR/uninhabited_enum_branching.rs:+11:2: +11:2
+ }
+}
diff --git a/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff
new file mode 100644
index 000000000..023f6ae32
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff
@@ -0,0 +1,93 @@
+- // MIR for `main` before UninhabitedEnumBranching
++ // MIR for `main` after UninhabitedEnumBranching
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +0:11
+ let _1: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +5:6
+ let mut _2: Test1; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ let mut _3: isize; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+2:9: +2:20
+ let _4: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34
+ let _5: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
+ let _6: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +10:6
+ let mut _7: Test2; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ let mut _8: isize; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+8:9: +8:17
+ let _9: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +5:6
+ StorageLive(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ Deinit(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ discriminant(_2) = 2; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ _3 = discriminant(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+- switchInt(move _3) -> [0_isize: bb2, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19
++ switchInt(move _3) -> bb1; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
+ _5 = const "C"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching.rs:23:21: 23:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _1 = &(*_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
+ StorageDead(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:23: +4:24
+ goto -> bb4; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:23: +4:24
+ }
+
+ bb2: {
+ _1 = const "A(Empty)"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+2:24: +2:34
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching.rs:21:24: 21:34
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ goto -> bb4; // scope 0 at $DIR/uninhabited_enum_branching.rs:+2:24: +2:34
+ }
+
+ bb3: {
+ StorageLive(_4); // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34
+ _4 = const "B(Empty)"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching.rs:22:24: 22:34
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _1 = &(*_4); // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34
+ StorageDead(_4); // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:33: +3:34
+ goto -> bb4; // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:33: +3:34
+ }
+
+ bb4: {
+ StorageDead(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+5:6: +5:7
+ StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching.rs:+5:6: +5:7
+ StorageLive(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +10:6
+ StorageLive(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ Deinit(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ discriminant(_7) = 0; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ _8 = discriminant(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ switchInt(move _8) -> [4_isize: bb6, otherwise: bb5]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19
+ }
+
+ bb5: {
+ StorageLive(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
+ _9 = const "E"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching.rs:28:21: 28:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _6 = &(*_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
+ StorageDead(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24
+ goto -> bb7; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24
+ }
+
+ bb6: {
+ _6 = const "D"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching.rs:27:21: 27:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ goto -> bb7; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
+ }
+
+ bb7: {
+ StorageDead(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7
+ StorageDead(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7
+ _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +11:2
+ return; // scope 0 at $DIR/uninhabited_enum_branching.rs:+11:2: +11:2
+ }
+ }
+
diff --git a/src/test/mir-opt/uninhabited_enum_branching.rs b/src/test/mir-opt/uninhabited_enum_branching.rs
new file mode 100644
index 000000000..0ef604c30
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_enum_branching.rs
@@ -0,0 +1,30 @@
+enum Empty { }
+
+// test matching an enum with uninhabited variants
+enum Test1 {
+ A(Empty),
+ B(Empty),
+ C
+}
+
+// test an enum where the discriminants don't match the variant indexes
+// (the optimization should do nothing here)
+enum Test2 {
+ D = 4,
+ E = 5,
+}
+
+// EMIT_MIR uninhabited_enum_branching.main.UninhabitedEnumBranching.diff
+// EMIT_MIR uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
+fn main() {
+ match Test1::C {
+ Test1::A(_) => "A(Empty)",
+ Test1::B(_) => "B(Empty)",
+ Test1::C => "C",
+ };
+
+ match Test2::D {
+ Test2::D => "D",
+ Test2::E => "E",
+ };
+}
diff --git a/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
new file mode 100644
index 000000000..a5e7f5269
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
@@ -0,0 +1,96 @@
+// MIR for `main` after SimplifyCfg-after-uninhabited-enum-branching
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +0:11
+ let _1: Plop; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:9: +1:13
+ let mut _2: Test1; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46
+ let _3: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+3:5: +8:6
+ let mut _4: &Test1; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
+ let mut _5: isize; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+4:9: +4:20
+ let _6: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34
+ let _7: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
+ let _8: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24
+ let _9: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6
+ let mut _10: isize; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+11:9: +11:20
+ let _11: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34
+ let _12: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
+ let _13: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
+ scope 1 {
+ debug plop => _1; // in scope 1 at $DIR/uninhabited_enum_branching2.rs:+1:9: +1:13
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:9: +1:13
+ StorageLive(_2); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46
+ Deinit(_2); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46
+ discriminant(_2) = 2; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46
+ Deinit(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:16: +1:48
+ (_1.0: u32) = const 51_u32; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:16: +1:48
+ (_1.1: Test1) = move _2; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:16: +1:48
+ StorageDead(_2); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:47: +1:48
+ StorageLive(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +8:6
+ StorageLive(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
+ _4 = &(_1.1: Test1); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
+ _5 = discriminant((*_4)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
+ switchInt(move _5) -> [2_isize: bb2, otherwise: bb1]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22
+ }
+
+ bb1: {
+ StorageLive(_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24
+ _8 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:25:21: 25:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _3 = &(*_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24
+ StorageDead(_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24
+ goto -> bb3; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24
+ }
+
+ bb2: {
+ StorageLive(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
+ _7 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:24:21: 24:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _3 = &(*_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
+ StorageDead(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24
+ goto -> bb3; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24
+ }
+
+ bb3: {
+ StorageDead(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7
+ StorageDead(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7
+ StorageLive(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6
+ _10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21
+ switchInt(move _10) -> [2_isize: bb5, otherwise: bb4]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21
+ }
+
+ bb4: {
+ StorageLive(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
+ _13 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:32:21: 32:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _9 = &(*_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
+ StorageDead(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24
+ goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24
+ }
+
+ bb5: {
+ StorageLive(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
+ _12 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:31:21: 31:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _9 = &(*_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
+ StorageDead(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24
+ goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24
+ }
+
+ bb6: {
+ StorageDead(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+15:6: +15:7
+ _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +16:2
+ StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:1: +16:2
+ return; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:2: +16:2
+ }
+}
diff --git a/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff
new file mode 100644
index 000000000..157518491
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff
@@ -0,0 +1,138 @@
+- // MIR for `main` before UninhabitedEnumBranching
++ // MIR for `main` after UninhabitedEnumBranching
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +0:11
+ let _1: Plop; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:9: +1:13
+ let mut _2: Test1; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46
+ let _3: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+3:5: +8:6
+ let mut _4: &Test1; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
+ let mut _5: isize; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+4:9: +4:20
+ let _6: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34
+ let _7: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
+ let _8: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24
+ let _9: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6
+ let mut _10: isize; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+11:9: +11:20
+ let _11: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34
+ let _12: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
+ let _13: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
+ scope 1 {
+ debug plop => _1; // in scope 1 at $DIR/uninhabited_enum_branching2.rs:+1:9: +1:13
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:9: +1:13
+ StorageLive(_2); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46
+ Deinit(_2); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46
+ discriminant(_2) = 2; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46
+ Deinit(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:16: +1:48
+ (_1.0: u32) = const 51_u32; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:16: +1:48
+ (_1.1: Test1) = move _2; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:16: +1:48
+ StorageDead(_2); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:47: +1:48
+ StorageLive(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +8:6
+ StorageLive(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
+ _4 = &(_1.1: Test1); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
+ _5 = discriminant((*_4)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
+- switchInt(move _5) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, otherwise: bb1]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22
++ switchInt(move _5) -> [2_isize: bb4, otherwise: bb1]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22
+ }
+
+ bb1: {
+ StorageLive(_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24
+ _8 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:25:21: 25:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _3 = &(*_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24
+ StorageDead(_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24
+ goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24
+ }
+
+ bb2: {
+ _3 = const "A(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+4:24: +4:34
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:22:24: 22:34
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+4:24: +4:34
+ }
+
+ bb3: {
+ StorageLive(_6); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34
+ _6 = const "B(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:23:24: 23:34
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _3 = &(*_6); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34
+ StorageDead(_6); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:33: +5:34
+ goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:33: +5:34
+ }
+
+ bb4: {
+ StorageLive(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
+ _7 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:24:21: 24:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _3 = &(*_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
+ StorageDead(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24
+ goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24
+ }
+
+ bb5: {
+ StorageDead(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7
+ StorageDead(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7
+ StorageLive(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6
+ _10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21
+- switchInt(move _10) -> [0_isize: bb7, 1_isize: bb8, 2_isize: bb9, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21
++ switchInt(move _10) -> [2_isize: bb9, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21
+ }
+
+ bb6: {
+ StorageLive(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
+ _13 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:32:21: 32:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _9 = &(*_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
+ StorageDead(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24
+ goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24
+ }
+
+ bb7: {
+ _9 = const "A(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:29:24: 29:34
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34
+ }
+
+ bb8: {
+ StorageLive(_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34
+ _11 = const "B(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:30:24: 30:34
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _9 = &(*_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34
+ StorageDead(_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:33: +12:34
+ goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:33: +12:34
+ }
+
+ bb9: {
+ StorageLive(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
+ _12 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:31:21: 31:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ _9 = &(*_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
+ StorageDead(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24
+ goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24
+ }
+
+ bb10: {
+ StorageDead(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+15:6: +15:7
+ _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +16:2
+ StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:1: +16:2
+ return; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:2: +16:2
+ }
+ }
+
diff --git a/src/test/mir-opt/uninhabited_enum_branching2.rs b/src/test/mir-opt/uninhabited_enum_branching2.rs
new file mode 100644
index 000000000..e22e94314
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_enum_branching2.rs
@@ -0,0 +1,34 @@
+enum Empty { }
+
+// test matching an enum with uninhabited variants
+enum Test1 {
+ A(Empty),
+ B(Empty),
+ C,
+ D,
+}
+
+struct Plop {
+ xx: u32,
+ test1: Test1,
+}
+
+// EMIT_MIR uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff
+// EMIT_MIR uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
+fn main() {
+ let plop = Plop { xx: 51, test1: Test1::C };
+
+ match &plop.test1 {
+ Test1::A(_) => "A(Empty)",
+ Test1::B(_) => "B(Empty)",
+ Test1::C => "C",
+ Test1::D => "D",
+ };
+
+ match plop.test1 {
+ Test1::A(_) => "A(Empty)",
+ Test1::B(_) => "B(Empty)",
+ Test1::C => "C",
+ Test1::D => "D",
+ };
+}
diff --git a/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff
new file mode 100644
index 000000000..11d93fca7
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff
@@ -0,0 +1,38 @@
+- // MIR for `eliminate_fallthrough` before UninhabitedEnumBranching
++ // MIR for `eliminate_fallthrough` after UninhabitedEnumBranching
+
+ fn eliminate_fallthrough(_1: S) -> u32 {
+ debug s => _1; // in scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+0:26: +0:27
+ let mut _0: u32; // return place in scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+0:35: +0:38
+ let mut _2: isize; // in scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+2:9: +2:10
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:11: +1:12
+- switchInt(move _2) -> [1_isize: bb3, 2_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12
++ switchInt(move _2) -> [1_isize: bb3, 2_isize: bb2, otherwise: bb5]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = const 3_u32; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+4:14: +4:15
+ goto -> bb4; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+4:14: +4:15
+ }
+
+ bb2: {
+ _0 = const 1_u32; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+2:14: +2:15
+ goto -> bb4; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+2:14: +2:15
+ }
+
+ bb3: {
+ _0 = const 2_u32; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+3:14: +3:15
+ goto -> bb4; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+3:14: +3:15
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+6:2: +6:2
++ }
++
++ bb5: {
++ unreachable; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+4:14: +4:15
+ }
+ }
+
diff --git a/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff
new file mode 100644
index 000000000..a7f8321ae
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff
@@ -0,0 +1,34 @@
+- // MIR for `keep_fallthrough` before UninhabitedEnumBranching
++ // MIR for `keep_fallthrough` after UninhabitedEnumBranching
+
+ fn keep_fallthrough(_1: S) -> u32 {
+ debug s => _1; // in scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+0:21: +0:22
+ let mut _0: u32; // return place in scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+0:30: +0:33
+ let mut _2: isize; // in scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+2:9: +2:13
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:11: +1:12
+- switchInt(move _2) -> [0_isize: bb2, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12
++ switchInt(move _2) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = const 3_u32; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+4:14: +4:15
+ goto -> bb4; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+4:14: +4:15
+ }
+
+ bb2: {
+ _0 = const 1_u32; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+2:17: +2:18
+ goto -> bb4; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+2:17: +2:18
+ }
+
+ bb3: {
+ _0 = const 2_u32; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+3:14: +3:15
+ goto -> bb4; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+3:14: +3:15
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/uninhabited_fallthrough_elimination.rs b/src/test/mir-opt/uninhabited_fallthrough_elimination.rs
new file mode 100644
index 000000000..0853883f8
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_fallthrough_elimination.rs
@@ -0,0 +1,32 @@
+enum Empty {}
+
+enum S {
+ A(Empty),
+ B,
+ C,
+}
+
+use S::*;
+
+// EMIT_MIR uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff
+fn keep_fallthrough(s: S) -> u32 {
+ match s {
+ A(_) => 1,
+ B => 2,
+ _ => 3,
+ }
+}
+
+// EMIT_MIR uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff
+fn eliminate_fallthrough(s: S) -> u32 {
+ match s {
+ C => 1,
+ B => 2,
+ _ => 3,
+ }
+}
+
+fn main() {
+ keep_fallthrough(B);
+ eliminate_fallthrough(B);
+}
diff --git a/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff
new file mode 100644
index 000000000..52d9543e9
--- /dev/null
+++ b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff
@@ -0,0 +1,69 @@
+- // MIR for `main` before UnreachablePropagation
++ // MIR for `main` after UnreachablePropagation
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/unreachable.rs:+0:11: +0:11
+ let mut _1: std::option::Option<Empty>; // in scope 0 at $DIR/unreachable.rs:+1:23: +1:30
+ let mut _2: isize; // in scope 0 at $DIR/unreachable.rs:+1:12: +1:20
+ let _5: (); // in scope 0 at $DIR/unreachable.rs:+4:9: +8:10
+ let mut _6: bool; // in scope 0 at $DIR/unreachable.rs:+4:12: +4:16
+ let mut _7: !; // in scope 0 at $DIR/unreachable.rs:+10:9: +10:21
+ scope 1 {
+ debug _x => _3; // in scope 1 at $DIR/unreachable.rs:+1:17: +1:19
+ let _3: Empty; // in scope 1 at $DIR/unreachable.rs:+1:17: +1:19
+ let mut _4: i32; // in scope 1 at $DIR/unreachable.rs:+2:13: +2:19
+ scope 2 {
+ debug _y => _4; // in scope 2 at $DIR/unreachable.rs:+2:13: +2:19
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 1 at $DIR/unreachable.rs:+1:23: +1:30
+ _1 = empty() -> bb1; // scope 1 at $DIR/unreachable.rs:+1:23: +1:30
+ // mir::Constant
+ // + span: $DIR/unreachable.rs:9:23: 9:28
+ // + literal: Const { ty: fn() -> Option<Empty> {empty}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ _2 = discriminant(_1); // scope 1 at $DIR/unreachable.rs:+1:12: +1:20
+- switchInt(move _2) -> [1_isize: bb2, otherwise: bb6]; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20
++ goto -> bb2; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20
+ }
+
+ bb2: {
+- StorageLive(_3); // scope 1 at $DIR/unreachable.rs:+1:17: +1:19
+- _3 = move ((_1 as Some).0: Empty); // scope 1 at $DIR/unreachable.rs:+1:17: +1:19
+- StorageLive(_4); // scope 1 at $DIR/unreachable.rs:+2:13: +2:19
+- StorageLive(_5); // scope 2 at $DIR/unreachable.rs:+4:9: +8:10
+- StorageLive(_6); // scope 2 at $DIR/unreachable.rs:+4:12: +4:16
+- _6 = const true; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16
+- switchInt(move _6) -> [false: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16
+- }
+-
+- bb3: {
+- _4 = const 21_i32; // scope 2 at $DIR/unreachable.rs:+5:13: +5:20
+- _5 = const (); // scope 2 at $DIR/unreachable.rs:+4:17: +6:10
+- goto -> bb5; // scope 2 at $DIR/unreachable.rs:+4:9: +8:10
+- }
+-
+- bb4: {
+- _4 = const 42_i32; // scope 2 at $DIR/unreachable.rs:+7:13: +7:20
+- _5 = const (); // scope 2 at $DIR/unreachable.rs:+6:16: +8:10
+- goto -> bb5; // scope 2 at $DIR/unreachable.rs:+4:9: +8:10
+- }
+-
+- bb5: {
+- StorageDead(_6); // scope 2 at $DIR/unreachable.rs:+8:9: +8:10
+- StorageDead(_5); // scope 2 at $DIR/unreachable.rs:+8:9: +8:10
+- StorageLive(_7); // scope 2 at $DIR/unreachable.rs:+10:9: +10:21
+- unreachable; // scope 2 at $DIR/unreachable.rs:+10:15: +10:17
+- }
+-
+- bb6: {
+ _0 = const (); // scope 0 at $DIR/unreachable.rs:+11:6: +11:6
+ StorageDead(_1); // scope 0 at $DIR/unreachable.rs:+12:1: +12:2
+ return; // scope 0 at $DIR/unreachable.rs:+12:2: +12:2
+ }
+ }
+
diff --git a/src/test/mir-opt/unreachable.rs b/src/test/mir-opt/unreachable.rs
new file mode 100644
index 000000000..6098b525b
--- /dev/null
+++ b/src/test/mir-opt/unreachable.rs
@@ -0,0 +1,20 @@
+enum Empty {}
+
+fn empty() -> Option<Empty> {
+ None
+}
+
+// EMIT_MIR unreachable.main.UnreachablePropagation.diff
+fn main() {
+ if let Some(_x) = empty() {
+ let mut _y;
+
+ if true {
+ _y = 21;
+ } else {
+ _y = 42;
+ }
+
+ match _x { }
+ }
+}
diff --git a/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff
new file mode 100644
index 000000000..3d31553c4
--- /dev/null
+++ b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff
@@ -0,0 +1,74 @@
+- // MIR for `main` before UnreachablePropagation
++ // MIR for `main` after UnreachablePropagation
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/unreachable_diverging.rs:+0:11: +0:11
+ let _1: bool; // in scope 0 at $DIR/unreachable_diverging.rs:+1:9: +1:10
+ let mut _2: std::option::Option<Empty>; // in scope 0 at $DIR/unreachable_diverging.rs:+2:25: +2:32
+ let mut _3: isize; // in scope 0 at $DIR/unreachable_diverging.rs:+2:12: +2:22
+ let _5: (); // in scope 0 at $DIR/unreachable_diverging.rs:+3:9: +5:10
+ let mut _6: bool; // in scope 0 at $DIR/unreachable_diverging.rs:+3:12: +3:13
+ let mut _7: !; // in scope 0 at $DIR/unreachable_diverging.rs:+6:9: +6:22
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/unreachable_diverging.rs:+1:9: +1:10
+ scope 2 {
+ debug bomb => _4; // in scope 2 at $DIR/unreachable_diverging.rs:+2:17: +2:21
+ let _4: Empty; // in scope 2 at $DIR/unreachable_diverging.rs:+2:17: +2:21
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/unreachable_diverging.rs:+1:9: +1:10
+ _1 = const true; // scope 0 at $DIR/unreachable_diverging.rs:+1:13: +1:17
+ StorageLive(_2); // scope 2 at $DIR/unreachable_diverging.rs:+2:25: +2:32
+ _2 = empty() -> bb1; // scope 2 at $DIR/unreachable_diverging.rs:+2:25: +2:32
+ // mir::Constant
+ // + span: $DIR/unreachable_diverging.rs:14:25: 14:30
+ // + literal: Const { ty: fn() -> Option<Empty> {empty}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ _3 = discriminant(_2); // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22
+- switchInt(move _3) -> [1_isize: bb2, otherwise: bb6]; // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22
++ switchInt(move _3) -> [1_isize: bb2, otherwise: bb5]; // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22
+ }
+
+ bb2: {
+ StorageLive(_4); // scope 2 at $DIR/unreachable_diverging.rs:+2:17: +2:21
+ _4 = move ((_2 as Some).0: Empty); // scope 2 at $DIR/unreachable_diverging.rs:+2:17: +2:21
+ StorageLive(_5); // scope 2 at $DIR/unreachable_diverging.rs:+3:9: +5:10
+ StorageLive(_6); // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13
+ _6 = _1; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13
+- switchInt(move _6) -> [false: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13
++ goto -> bb3; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13
+ }
+
+ bb3: {
+- _5 = loop_forever() -> bb5; // scope 2 at $DIR/unreachable_diverging.rs:+4:13: +4:27
++ _5 = loop_forever() -> bb4; // scope 2 at $DIR/unreachable_diverging.rs:+4:13: +4:27
+ // mir::Constant
+ // + span: $DIR/unreachable_diverging.rs:16:13: 16:25
+ // + literal: Const { ty: fn() {loop_forever}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+- _5 = const (); // scope 2 at $DIR/unreachable_diverging.rs:+5:10: +5:10
+- goto -> bb5; // scope 2 at $DIR/unreachable_diverging.rs:+3:9: +5:10
+- }
+-
+- bb5: {
+ StorageDead(_6); // scope 2 at $DIR/unreachable_diverging.rs:+5:9: +5:10
+ StorageDead(_5); // scope 2 at $DIR/unreachable_diverging.rs:+5:9: +5:10
+ StorageLive(_7); // scope 2 at $DIR/unreachable_diverging.rs:+6:9: +6:22
+ unreachable; // scope 2 at $DIR/unreachable_diverging.rs:+6:15: +6:19
+ }
+
+- bb6: {
++ bb5: {
+ _0 = const (); // scope 1 at $DIR/unreachable_diverging.rs:+7:6: +7:6
+ StorageDead(_1); // scope 0 at $DIR/unreachable_diverging.rs:+8:1: +8:2
+ StorageDead(_2); // scope 0 at $DIR/unreachable_diverging.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/unreachable_diverging.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/unreachable_diverging.rs b/src/test/mir-opt/unreachable_diverging.rs
new file mode 100644
index 000000000..bbf28efc7
--- /dev/null
+++ b/src/test/mir-opt/unreachable_diverging.rs
@@ -0,0 +1,20 @@
+pub enum Empty {}
+
+fn empty() -> Option<Empty> {
+ None
+}
+
+fn loop_forever() {
+ loop {}
+}
+
+// EMIT_MIR unreachable_diverging.main.UnreachablePropagation.diff
+fn main() {
+ let x = true;
+ if let Some(bomb) = empty() {
+ if x {
+ loop_forever()
+ }
+ match bomb {}
+ }
+}
diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs
new file mode 100644
index 000000000..670f61cd5
--- /dev/null
+++ b/src/test/mir-opt/unusual-item-types.rs
@@ -0,0 +1,29 @@
+// Test that we don't ICE when trying to dump MIR for unusual item types and
+// that we don't create filenames containing `<` and `>`
+// compile-flags: -Zmir-opt-level=0
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
+struct A;
+
+// EMIT_MIR unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir
+impl A {
+ const ASSOCIATED_CONSTANT: i32 = 2;
+}
+
+// See #59021
+// EMIT_MIR unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir
+enum Test {
+ X(usize),
+ Y { a: usize },
+}
+
+// EMIT_MIR unusual_item_types.E-V-{constant#0}.mir_map.0.mir
+enum E {
+ V = 5,
+}
+
+fn main() {
+ let f = Test::X as fn(usize) -> Test;
+// EMIT_MIR core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir
+ let v = Vec::<i32>::new();
+}
diff --git a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir
new file mode 100644
index 000000000..a72e00ecd
--- /dev/null
+++ b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir
@@ -0,0 +1,10 @@
+// MIR for `E::V::{constant#0}` 0 mir_map
+
+E::V::{constant#0}: isize = {
+ let mut _0: isize; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
+
+ bb0: {
+ _0 = const 5_isize; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
+ return; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
+ }
+}
diff --git a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir
new file mode 100644
index 000000000..a72e00ecd
--- /dev/null
+++ b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir
@@ -0,0 +1,10 @@
+// MIR for `E::V::{constant#0}` 0 mir_map
+
+E::V::{constant#0}: isize = {
+ let mut _0: isize; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
+
+ bb0: {
+ _0 = const 5_isize; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
+ return; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
+ }
+}
diff --git a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir
new file mode 100644
index 000000000..0686af46e
--- /dev/null
+++ b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir
@@ -0,0 +1,12 @@
+// MIR for `Test::X` 0 mir_map
+
+fn Test::X(_1: usize) -> Test {
+ let mut _0: Test; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+
+ bb0: {
+ Deinit(_0); // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+ ((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+ discriminant(_0) = 0; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+ return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+ }
+}
diff --git a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir
new file mode 100644
index 000000000..0686af46e
--- /dev/null
+++ b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir
@@ -0,0 +1,12 @@
+// MIR for `Test::X` 0 mir_map
+
+fn Test::X(_1: usize) -> Test {
+ let mut _0: Test; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+
+ bb0: {
+ Deinit(_0); // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+ ((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+ discriminant(_0) = 0; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+ return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+ }
+}
diff --git a/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir
new file mode 100644
index 000000000..7ffd242e0
--- /dev/null
+++ b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir
@@ -0,0 +1,39 @@
+// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
+
+fn std::ptr::drop_in_place(_1: *mut Vec<i32>) -> () {
+ let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _2: &mut std::vec::Vec<i32>; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+
+ bb0: {
+ goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb1: {
+ return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb3: {
+ goto -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb4 (cleanup): {
+ drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> bb2; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb5: {
+ drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> [return: bb3, unwind: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb6: {
+ _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _3 = <Vec<i32> as Drop>::drop(move _2) -> [return: bb5, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r> fn(&'r mut Vec<i32>) {<Vec<i32> as Drop>::drop}, val: Value(<ZST>) }
+ }
+}
diff --git a/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir
new file mode 100644
index 000000000..7ffd242e0
--- /dev/null
+++ b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir
@@ -0,0 +1,39 @@
+// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
+
+fn std::ptr::drop_in_place(_1: *mut Vec<i32>) -> () {
+ let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _2: &mut std::vec::Vec<i32>; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+
+ bb0: {
+ goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb1: {
+ return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb3: {
+ goto -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb4 (cleanup): {
+ drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> bb2; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb5: {
+ drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> [return: bb3, unwind: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+
+ bb6: {
+ _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _3 = <Vec<i32> as Drop>::drop(move _2) -> [return: bb5, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r> fn(&'r mut Vec<i32>) {<Vec<i32> as Drop>::drop}, val: Value(<ZST>) }
+ }
+}
diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir
new file mode 100644
index 000000000..f7bc8d58f
--- /dev/null
+++ b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir
@@ -0,0 +1,10 @@
+// MIR for `<impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` 0 mir_map
+
+const <impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT: i32 = {
+ let mut _0: i32; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:32: +0:35
+
+ bb0: {
+ _0 = const 2_i32; // scope 0 at $DIR/unusual-item-types.rs:+0:38: +0:39
+ return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:35
+ }
+}
diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir
new file mode 100644
index 000000000..f7bc8d58f
--- /dev/null
+++ b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir
@@ -0,0 +1,10 @@
+// MIR for `<impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` 0 mir_map
+
+const <impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT: i32 = {
+ let mut _0: i32; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:32: +0:35
+
+ bb0: {
+ _0 = const 2_i32; // scope 0 at $DIR/unusual-item-types.rs:+0:38: +0:39
+ return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:35
+ }
+}
diff --git a/src/test/mir-opt/while-storage.rs b/src/test/mir-opt/while-storage.rs
new file mode 100644
index 000000000..afd083acb
--- /dev/null
+++ b/src/test/mir-opt/while-storage.rs
@@ -0,0 +1,19 @@
+// Test that we correctly generate StorageDead statements for while loop
+// conditions on all branches
+
+fn get_bool(c: bool) -> bool {
+ c
+}
+
+// EMIT_MIR while_storage.while_loop.PreCodegen.after.mir
+fn while_loop(c: bool) {
+ while get_bool(c) {
+ if get_bool(c) {
+ break;
+ }
+ }
+}
+
+fn main() {
+ while_loop(false);
+}
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff
new file mode 100644
index 000000000..eef701114
--- /dev/null
+++ b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff
@@ -0,0 +1,55 @@
+- // MIR for `change_loop_body` before ConstProp
++ // MIR for `change_loop_body` after ConstProp
+
+ fn change_loop_body() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27
+ let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
+ let mut _2: (); // in scope 0 at $DIR/while_let_loops.rs:+0:1: +6:2
+ let mut _3: std::option::Option<u32>; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32
+ let mut _4: isize; // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25
+ let mut _5: !; // in scope 0 at $DIR/while_let_loops.rs:+2:33: +5:6
+ let mut _6: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
+ let _7: (); // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
+ let mut _8: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
+ scope 1 {
+ debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15
+ scope 2 {
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
+ _1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:+1:18: +1:19
+ StorageLive(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
+ Deinit(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
+ discriminant(_3) = 0; // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
+- _4 = discriminant(_3); // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
+- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
++ _4 = const 0_isize; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
++ switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
+ }
+
+ bb1: {
+ switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
+ }
+
+ bb2: {
+ _1 = const 1_i32; // scope 2 at $DIR/while_let_loops.rs:+3:9: +3:15
+ nop; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
+ goto -> bb4; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
+ }
+
+ bb3: {
+ StorageLive(_7); // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6
+ nop; // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6
+ StorageDead(_7); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6
+ goto -> bb4; // scope 1 at no-location
+ }
+
+ bb4: {
+ StorageDead(_3); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6
+ StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff
new file mode 100644
index 000000000..eef701114
--- /dev/null
+++ b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff
@@ -0,0 +1,55 @@
+- // MIR for `change_loop_body` before ConstProp
++ // MIR for `change_loop_body` after ConstProp
+
+ fn change_loop_body() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27
+ let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
+ let mut _2: (); // in scope 0 at $DIR/while_let_loops.rs:+0:1: +6:2
+ let mut _3: std::option::Option<u32>; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32
+ let mut _4: isize; // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25
+ let mut _5: !; // in scope 0 at $DIR/while_let_loops.rs:+2:33: +5:6
+ let mut _6: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
+ let _7: (); // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
+ let mut _8: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
+ scope 1 {
+ debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15
+ scope 2 {
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
+ _1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:+1:18: +1:19
+ StorageLive(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
+ Deinit(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
+ discriminant(_3) = 0; // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
+- _4 = discriminant(_3); // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
+- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
++ _4 = const 0_isize; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
++ switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
+ }
+
+ bb1: {
+ switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
+ }
+
+ bb2: {
+ _1 = const 1_i32; // scope 2 at $DIR/while_let_loops.rs:+3:9: +3:15
+ nop; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
+ goto -> bb4; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
+ }
+
+ bb3: {
+ StorageLive(_7); // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6
+ nop; // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6
+ StorageDead(_7); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6
+ goto -> bb4; // scope 1 at no-location
+ }
+
+ bb4: {
+ StorageDead(_3); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6
+ StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir
new file mode 100644
index 000000000..15b0aece8
--- /dev/null
+++ b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir
@@ -0,0 +1,17 @@
+// MIR for `change_loop_body` after PreCodegen
+
+fn change_loop_body() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27
+ let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
+ scope 1 {
+ debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15
+ scope 2 {
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
+ StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2
+ }
+}
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir
new file mode 100644
index 000000000..15b0aece8
--- /dev/null
+++ b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir
@@ -0,0 +1,17 @@
+// MIR for `change_loop_body` after PreCodegen
+
+fn change_loop_body() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27
+ let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
+ scope 1 {
+ debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15
+ scope 2 {
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
+ StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2
+ }
+}
diff --git a/src/test/mir-opt/while_let_loops.rs b/src/test/mir-opt/while_let_loops.rs
new file mode 100644
index 000000000..f320a218c
--- /dev/null
+++ b/src/test/mir-opt/while_let_loops.rs
@@ -0,0 +1,15 @@
+// EMIT_MIR while_let_loops.change_loop_body.ConstProp.diff
+// EMIT_MIR while_let_loops.change_loop_body.PreCodegen.after.mir
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
+pub fn change_loop_body() {
+ let mut _x = 0;
+ while let Some(0u32) = None {
+ _x = 1;
+ break;
+ }
+}
+
+fn main() {
+ change_loop_body();
+}
diff --git a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir
new file mode 100644
index 000000000..a5e7d6afd
--- /dev/null
+++ b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir
@@ -0,0 +1,64 @@
+// MIR for `while_loop` after PreCodegen
+
+fn while_loop(_1: bool) -> () {
+ debug c => _1; // in scope 0 at $DIR/while-storage.rs:+0:15: +0:16
+ let mut _0: (); // return place in scope 0 at $DIR/while-storage.rs:+0:24: +0:24
+ let mut _2: bool; // in scope 0 at $DIR/while-storage.rs:+1:11: +1:22
+ let mut _3: bool; // in scope 0 at $DIR/while-storage.rs:+1:20: +1:21
+ let mut _4: bool; // in scope 0 at $DIR/while-storage.rs:+2:12: +2:23
+ let mut _5: bool; // in scope 0 at $DIR/while-storage.rs:+2:21: +2:22
+
+ bb0: {
+ goto -> bb1; // scope 0 at $DIR/while-storage.rs:+1:5: +5:6
+ }
+
+ bb1: {
+ StorageLive(_2); // scope 0 at $DIR/while-storage.rs:+1:11: +1:22
+ StorageLive(_3); // scope 0 at $DIR/while-storage.rs:+1:20: +1:21
+ _3 = _1; // scope 0 at $DIR/while-storage.rs:+1:20: +1:21
+ _2 = get_bool(move _3) -> bb2; // scope 0 at $DIR/while-storage.rs:+1:11: +1:22
+ // mir::Constant
+ // + span: $DIR/while-storage.rs:10:11: 10:19
+ // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_3); // scope 0 at $DIR/while-storage.rs:+1:21: +1:22
+ switchInt(move _2) -> [false: bb7, otherwise: bb3]; // scope 0 at $DIR/while-storage.rs:+1:11: +1:22
+ }
+
+ bb3: {
+ StorageLive(_4); // scope 0 at $DIR/while-storage.rs:+2:12: +2:23
+ StorageLive(_5); // scope 0 at $DIR/while-storage.rs:+2:21: +2:22
+ _5 = _1; // scope 0 at $DIR/while-storage.rs:+2:21: +2:22
+ _4 = get_bool(move _5) -> bb4; // scope 0 at $DIR/while-storage.rs:+2:12: +2:23
+ // mir::Constant
+ // + span: $DIR/while-storage.rs:11:12: 11:20
+ // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ StorageDead(_5); // scope 0 at $DIR/while-storage.rs:+2:22: +2:23
+ switchInt(move _4) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/while-storage.rs:+2:12: +2:23
+ }
+
+ bb5: {
+ StorageDead(_4); // scope 0 at $DIR/while-storage.rs:+4:9: +4:10
+ goto -> bb8; // scope 0 at no-location
+ }
+
+ bb6: {
+ StorageDead(_4); // scope 0 at $DIR/while-storage.rs:+4:9: +4:10
+ StorageDead(_2); // scope 0 at $DIR/while-storage.rs:+5:5: +5:6
+ goto -> bb1; // scope 0 at $DIR/while-storage.rs:+1:5: +5:6
+ }
+
+ bb7: {
+ goto -> bb8; // scope 0 at no-location
+ }
+
+ bb8: {
+ StorageDead(_2); // scope 0 at $DIR/while-storage.rs:+5:5: +5:6
+ return; // scope 0 at $DIR/while-storage.rs:+6:2: +6:2
+ }
+}