summaryrefslogtreecommitdiffstats
path: root/tests/mir-opt
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/mir-opt
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz
rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/mir-opt')
-rw-r--r--tests/mir-opt/76803_regression.encode.SimplifyBranchSame.diff29
-rw-r--r--tests/mir-opt/76803_regression.rs19
-rw-r--r--tests/mir-opt/README.md51
-rw-r--r--tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir308
-rw-r--r--tests/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir47
-rw-r--r--tests/mir-opt/address_of.rs47
-rw-r--r--tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir64
-rw-r--r--tests/mir-opt/array_index_is_temporary.rs17
-rw-r--r--tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir24
-rw-r--r--tests/mir-opt/asm_unwind_panic_abort.rs15
-rw-r--r--tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir84
-rw-r--r--tests/mir-opt/basic_assignment.rs24
-rw-r--r--tests/mir-opt/bool_compare.opt1.InstCombine.diff35
-rw-r--r--tests/mir-opt/bool_compare.opt2.InstCombine.diff35
-rw-r--r--tests/mir-opt/bool_compare.opt3.InstCombine.diff35
-rw-r--r--tests/mir-opt/bool_compare.opt4.InstCombine.diff35
-rw-r--r--tests/mir-opt/bool_compare.rs28
-rw-r--r--tests/mir-opt/box_expr.main.ElaborateDrops.before.mir80
-rw-r--r--tests/mir-opt/box_expr.rs21
-rw-r--r--tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir41
-rw-r--r--tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir337
-rw-r--r--tests/mir-opt/building/async_await.rs17
-rw-r--r--tests/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir22
-rw-r--r--tests/mir-opt/building/custom/arbitrary_let.rs28
-rw-r--r--tests/mir-opt/building/custom/consts.consts.built.after.mir22
-rw-r--r--tests/mir-opt/building/custom/consts.rs36
-rw-r--r--tests/mir-opt/building/custom/consts.statics.built.after.mir27
-rw-r--r--tests/mir-opt/building/custom/enums.rs120
-rw-r--r--tests/mir-opt/building/custom/enums.set_discr.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/enums.set_discr_repr.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/enums.switch_bool.built.after.mir19
-rw-r--r--tests/mir-opt/building/custom/enums.switch_option.built.after.mir21
-rw-r--r--tests/mir-opt/building/custom/enums.switch_option_repr.built.after.mir21
-rw-r--r--tests/mir-opt/building/custom/projections.rs85
-rw-r--r--tests/mir-opt/building/custom/projections.set.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/projections.simple_index.built.after.mir13
-rw-r--r--tests/mir-opt/building/custom/projections.tuples.built.after.mir13
-rw-r--r--tests/mir-opt/building/custom/projections.unions.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/projections.unwrap.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/projections.unwrap_deref.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/references.immut_ref.built.after.mir13
-rw-r--r--tests/mir-opt/building/custom/references.mut_ref.built.after.mir13
-rw-r--r--tests/mir-opt/building/custom/references.raw_pointer.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/references.rs55
-rw-r--r--tests/mir-opt/building/custom/simple_assign.rs39
-rw-r--r--tests/mir-opt/building/custom/simple_assign.simple.built.after.mir20
-rw-r--r--tests/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/terminators.assert_nonzero.built.after.mir17
-rw-r--r--tests/mir-opt/building/custom/terminators.direct_call.built.after.mir16
-rw-r--r--tests/mir-opt/building/custom/terminators.drop_first.built.after.mir13
-rw-r--r--tests/mir-opt/building/custom/terminators.drop_second.built.after.mir13
-rw-r--r--tests/mir-opt/building/custom/terminators.indirect_call.built.after.mir13
-rw-r--r--tests/mir-opt/building/custom/terminators.rs108
-rw-r--r--tests/mir-opt/building/enum_cast.bar.built.after.mir23
-rw-r--r--tests/mir-opt/building/enum_cast.boo.built.after.mir23
-rw-r--r--tests/mir-opt/building/enum_cast.droppy.built.after.mir72
-rw-r--r--tests/mir-opt/building/enum_cast.foo.built.after.mir17
-rw-r--r--tests/mir-opt/building/enum_cast.rs50
-rw-r--r--tests/mir-opt/building/issue_101867.main.built.after.mir75
-rw-r--r--tests/mir-opt/building/issue_101867.rs7
-rw-r--r--tests/mir-opt/building/issue_49232.main.built.after.mir82
-rw-r--r--tests/mir-opt/building/issue_49232.rs15
-rw-r--r--tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir112
-rw-r--r--tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir112
-rw-r--r--tests/mir-opt/building/match_false_edges.main.built.after.mir174
-rw-r--r--tests/mir-opt/building/match_false_edges.rs39
-rw-r--r--tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir96
-rw-r--r--tests/mir-opt/building/receiver_ptr_mutability.rs20
-rw-r--r--tests/mir-opt/building/simple_match.match_bool.built.after.mir29
-rw-r--r--tests/mir-opt/building/simple_match.rs12
-rw-r--r--tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir203
-rw-r--r--tests/mir-opt/building/storage_live_dead_in_statics.rs33
-rw-r--r--tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir111
-rw-r--r--tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir111
-rw-r--r--tests/mir-opt/building/uniform_array_move_out.rs18
-rw-r--r--tests/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir31
-rw-r--r--tests/mir-opt/byte_slice.rs7
-rw-r--r--tests/mir-opt/combine_array_len.norm2.InstCombine.diff77
-rw-r--r--tests/mir-opt/combine_array_len.rs12
-rw-r--r--tests/mir-opt/combine_clone_of_primitives.rs20
-rw-r--r--tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff85
-rw-r--r--tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir62
-rw-r--r--tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir66
-rw-r--r--tests/mir-opt/const_allocation.rs10
-rw-r--r--tests/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir61
-rw-r--r--tests/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir64
-rw-r--r--tests/mir-opt/const_allocation2.rs12
-rw-r--r--tests/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir55
-rw-r--r--tests/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir56
-rw-r--r--tests/mir-opt/const_allocation3.rs30
-rw-r--r--tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff126
-rw-r--r--tests/mir-opt/const_debuginfo.rs24
-rw-r--r--tests/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff52
-rw-r--r--tests/mir-opt/const_goto.rs18
-rw-r--r--tests/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff51
-rw-r--r--tests/mir-opt/const_goto_const_eval_fail.rs16
-rw-r--r--tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff103
-rw-r--r--tests/mir-opt/const_goto_storage.rs21
-rw-r--r--tests/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir23
-rw-r--r--tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff54
-rw-r--r--tests/mir-opt/const_promotion_extern_static.BOP.built.after.mir17
-rw-r--r--tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir21
-rw-r--r--tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff54
-rw-r--r--tests/mir-opt/const_promotion_extern_static.rs18
-rw-r--r--tests/mir-opt/const_prop/aggregate.main.ConstProp.diff32
-rw-r--r--tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.mir28
-rw-r--r--tests/mir-opt/const_prop/aggregate.rs8
-rw-r--r--tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff39
-rw-r--r--tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff39
-rw-r--r--tests/mir-opt/const_prop/array_index.rs7
-rw-r--r--tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff52
-rw-r--r--tests/mir-opt/const_prop/bad_op_div_by_zero.rs7
-rw-r--r--tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff53
-rw-r--r--tests/mir-opt/const_prop/bad_op_mod_by_zero.rs6
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff54
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff54
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs9
-rw-r--r--tests/mir-opt/const_prop/boolean_identities.rs11
-rw-r--r--tests/mir-opt/const_prop/boolean_identities.test.ConstProp.diff33
-rw-r--r--tests/mir-opt/const_prop/boxes.main.ConstProp.diff60
-rw-r--r--tests/mir-opt/const_prop/boxes.rs14
-rw-r--r--tests/mir-opt/const_prop/cast.main.ConstProp.diff28
-rw-r--r--tests/mir-opt/const_prop/cast.rs8
-rw-r--r--tests/mir-opt/const_prop/checked_add.main.ConstProp.diff28
-rw-r--r--tests/mir-opt/const_prop/checked_add.rs7
-rw-r--r--tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff44
-rw-r--r--tests/mir-opt/const_prop/const_prop_fails_gracefully.rs10
-rw-r--r--tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff32
-rw-r--r--tests/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir9
-rw-r--r--tests/mir-opt/const_prop/control_flow_simplification.rs21
-rw-r--r--tests/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff52
-rw-r--r--tests/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff52
-rw-r--r--tests/mir-opt/const_prop/discriminant.rs13
-rw-r--r--tests/mir-opt/const_prop/indirect.main.ConstProp.diff33
-rw-r--r--tests/mir-opt/const_prop/indirect.rs7
-rw-r--r--tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff66
-rw-r--r--tests/mir-opt/const_prop/invalid_constant.rs42
-rw-r--r--tests/mir-opt/const_prop/issue_66971.main.ConstProp.diff27
-rw-r--r--tests/mir-opt/const_prop/issue_66971.rs18
-rw-r--r--tests/mir-opt/const_prop/issue_67019.main.ConstProp.diff33
-rw-r--r--tests/mir-opt/const_prop/issue_67019.rs13
-rw-r--r--tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff36
-rw-r--r--tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff36
-rw-r--r--tests/mir-opt/const_prop/large_array_index.rs7
-rw-r--r--tests/mir-opt/const_prop/mult_by_zero.rs11
-rw-r--r--tests/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff18
-rw-r--r--tests/mir-opt/const_prop/mutable_variable.main.ConstProp.diff27
-rw-r--r--tests/mir-opt/const_prop/mutable_variable.rs9
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff29
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_aggregate.rs9
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff35
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs10
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff34
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs15
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff43
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_no_prop.rs13
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff57
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_unprop_assign.rs16
-rw-r--r--tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff66
-rw-r--r--tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff66
-rw-r--r--tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir27
-rw-r--r--tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir27
-rw-r--r--tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff72
-rw-r--r--tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff72
-rw-r--r--tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir27
-rw-r--r--tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir27
-rw-r--r--tests/mir-opt/const_prop/optimizes_into_variable.rs18
-rw-r--r--tests/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff47
-rw-r--r--tests/mir-opt/const_prop/read_immutable_static.rs9
-rw-r--r--tests/mir-opt/const_prop/ref_deref.main.ConstProp.diff27
-rw-r--r--tests/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff30
-rw-r--r--tests/mir-opt/const_prop/ref_deref.rs7
-rw-r--r--tests/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff26
-rw-r--r--tests/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff30
-rw-r--r--tests/mir-opt/const_prop/ref_deref_project.rs7
-rw-r--r--tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff24
-rw-r--r--tests/mir-opt/const_prop/reify_fn_ptr.rs5
-rw-r--r--tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff42
-rw-r--r--tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff42
-rw-r--r--tests/mir-opt/const_prop/repeat.rs7
-rw-r--r--tests/mir-opt/const_prop/return_place.add.ConstProp.diff21
-rw-r--r--tests/mir-opt/const_prop/return_place.add.PreCodegen.before.mir10
-rw-r--r--tests/mir-opt/const_prop/return_place.rs11
-rw-r--r--tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff34
-rw-r--r--tests/mir-opt/const_prop/scalar_literal_propagation.rs8
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff50
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff50
-rw-r--r--tests/mir-opt/const_prop/slice_len.rs7
-rw-r--r--tests/mir-opt/const_prop/switch_int.main.ConstProp.diff34
-rw-r--r--tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff34
-rw-r--r--tests/mir-opt/const_prop/switch_int.rs11
-rw-r--r--tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff35
-rw-r--r--tests/mir-opt/const_prop/tuple_literal_propagation.rs9
-rw-r--r--tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff37
-rw-r--r--tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff35
-rw-r--r--tests/mir-opt/const_prop_miscompile.rs22
-rw-r--r--tests/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot6
-rw-r--r--tests/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot13
-rw-r--r--tests/mir-opt/coverage_graphviz.rs20
-rw-r--r--tests/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff37
-rw-r--r--tests/mir-opt/dataflow-const-prop/cast.rs7
-rw-r--r--tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff80
-rw-r--r--tests/mir-opt/dataflow-const-prop/checked.rs13
-rw-r--r--tests/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff61
-rw-r--r--tests/mir-opt/dataflow-const-prop/enum.rs13
-rw-r--r--tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff112
-rw-r--r--tests/mir-opt/dataflow-const-prop/if.rs11
-rw-r--r--tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff39
-rw-r--r--tests/mir-opt/dataflow-const-prop/inherit_overflow.rs8
-rw-r--r--tests/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff35
-rw-r--r--tests/mir-opt/dataflow-const-prop/issue_81605.rs10
-rw-r--r--tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff55
-rw-r--r--tests/mir-opt/dataflow-const-prop/ref_without_sb.rs17
-rw-r--r--tests/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff44
-rw-r--r--tests/mir-opt/dataflow-const-prop/repr_transparent.rs12
-rw-r--r--tests/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff46
-rw-r--r--tests/mir-opt/dataflow-const-prop/self_assign.rs12
-rw-r--r--tests/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff23
-rw-r--r--tests/mir-opt/dataflow-const-prop/self_assign_add.rs8
-rw-r--r--tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff56
-rw-r--r--tests/mir-opt/dataflow-const-prop/sibling_ptr.rs11
-rw-r--r--tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff52
-rw-r--r--tests/mir-opt/dataflow-const-prop/struct.rs11
-rw-r--r--tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff40
-rw-r--r--tests/mir-opt/dataflow-const-prop/terminator.rs10
-rw-r--r--tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff75
-rw-r--r--tests/mir-opt/dataflow-const-prop/tuple.rs9
-rw-r--r--tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff76
-rw-r--r--tests/mir-opt/dead-store-elimination/cycle.rs22
-rw-r--r--tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff35
-rw-r--r--tests/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff14
-rw-r--r--tests/mir-opt/dead-store-elimination/provenance_soundness.rs18
-rw-r--r--tests/mir-opt/deaggregator_test.bar.Deaggregator.diff21
-rw-r--r--tests/mir-opt/deaggregator_test.rs17
-rw-r--r--tests/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff20
-rw-r--r--tests/mir-opt/deaggregator_test_enum.rs19
-rw-r--r--tests/mir-opt/deaggregator_test_enum_2.rs21
-rw-r--r--tests/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff45
-rw-r--r--tests/mir-opt/deaggregator_test_multiple.rs17
-rw-r--r--tests/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff35
-rw-r--r--tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff100
-rw-r--r--tests/mir-opt/deduplicate_blocks.rs15
-rw-r--r--tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir74
-rw-r--r--tests/mir-opt/deref-patterns/string.rs12
-rw-r--r--tests/mir-opt/derefer_complex_case.main.Derefer.diff105
-rw-r--r--tests/mir-opt/derefer_complex_case.rs7
-rw-r--r--tests/mir-opt/derefer_inline_test.main.Derefer.diff61
-rw-r--r--tests/mir-opt/derefer_inline_test.rs12
-rw-r--r--tests/mir-opt/derefer_terminator_test.main.Derefer.diff92
-rw-r--r--tests/mir-opt/derefer_terminator_test.rs17
-rw-r--r--tests/mir-opt/derefer_test.main.Derefer.diff50
-rw-r--r--tests/mir-opt/derefer_test.rs8
-rw-r--r--tests/mir-opt/derefer_test_multiple.main.Derefer.diff80
-rw-r--r--tests/mir-opt/derefer_test_multiple.rs10
-rw-r--r--tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff75
-rw-r--r--tests/mir-opt/dest-prop/branch.rs27
-rw-r--r--tests/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff26
-rw-r--r--tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff32
-rw-r--r--tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff22
-rw-r--r--tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff32
-rw-r--r--tests/mir-opt/dest-prop/copy_propagation_arg.rs40
-rw-r--r--tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff77
-rw-r--r--tests/mir-opt/dest-prop/cycle.rs15
-rw-r--r--tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir34
-rw-r--r--tests/mir-opt/dest-prop/dead_stores_79191.rs17
-rw-r--r--tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir33
-rw-r--r--tests/mir-opt/dest-prop/dead_stores_better.rs21
-rw-r--r--tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff43
-rw-r--r--tests/mir-opt/dest-prop/simple.rs14
-rw-r--r--tests/mir-opt/dest-prop/union.main.DestinationPropagation.diff35
-rw-r--r--tests/mir-opt/dest-prop/union.rs16
-rw-r--r--tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff86
-rw-r--r--tests/mir-opt/dest-prop/unreachable.rs18
-rw-r--r--tests/mir-opt/div_overflow.const_dividend.PreCodegen.after.mir17
-rw-r--r--tests/mir-opt/div_overflow.const_divisor.PreCodegen.after.mir11
-rw-r--r--tests/mir-opt/div_overflow.rs18
-rw-r--r--tests/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff78
-rw-r--r--tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff92
-rw-r--r--tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff78
-rw-r--r--tests/mir-opt/early_otherwise_branch.rs32
-rw-r--r--tests/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff100
-rw-r--r--tests/mir-opt/early_otherwise_branch_3_element_tuple.rs13
-rw-r--r--tests/mir-opt/early_otherwise_branch_68867.rs33
-rw-r--r--tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff231
-rw-r--r--tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff95
-rw-r--r--tests/mir-opt/early_otherwise_branch_noopt.rs18
-rw-r--r--tests/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff47
-rw-r--r--tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff38
-rw-r--r--tests/mir-opt/early_otherwise_branch_soundness.rs32
-rw-r--r--tests/mir-opt/equal_true.opt.InstCombine.diff35
-rw-r--r--tests/mir-opt/equal_true.rs11
-rw-r--r--tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir83
-rw-r--r--tests/mir-opt/exponential_or.rs11
-rw-r--r--tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir13
-rw-r--r--tests/mir-opt/fn_ptr_shim.rs15
-rw-r--r--tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff146
-rw-r--r--tests/mir-opt/funky_arms.rs56
-rw-r--r--tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir84
-rw-r--r--tests/mir-opt/generator_drop_cleanup.rs14
-rw-r--r--tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir124
-rw-r--r--tests/mir-opt/generator_storage_dead_unwind.rs29
-rw-r--r--tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir84
-rw-r--r--tests/mir-opt/generator_tiny.rs26
-rw-r--r--tests/mir-opt/graphviz.main.built.after.dot7
-rw-r--r--tests/mir-opt/graphviz.rs5
-rw-r--r--tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff30
-rw-r--r--tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff34
-rw-r--r--tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff58
-rw-r--r--tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff39
-rw-r--r--tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff39
-rw-r--r--tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff65
-rw-r--r--tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff39
-rw-r--r--tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff39
-rw-r--r--tests/mir-opt/if_condition_int.rs65
-rw-r--r--tests/mir-opt/inline/asm_unwind.main.Inline.diff45
-rw-r--r--tests/mir-opt/inline/asm_unwind.rs22
-rw-r--r--tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff33
-rw-r--r--tests/mir-opt/inline/caller_with_trivial_bound.rs26
-rw-r--r--tests/mir-opt/inline/cycle.f.Inline.diff43
-rw-r--r--tests/mir-opt/inline/cycle.g.Inline.diff57
-rw-r--r--tests/mir-opt/inline/cycle.main.Inline.diff57
-rw-r--r--tests/mir-opt/inline/cycle.rs18
-rw-r--r--tests/mir-opt/inline/dyn_trait.get_query.Inline.diff54
-rw-r--r--tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff23
-rw-r--r--tests/mir-opt/inline/dyn_trait.rs35
-rw-r--r--tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff33
-rw-r--r--tests/mir-opt/inline/exponential_runtime.main.Inline.diff75
-rw-r--r--tests/mir-opt/inline/exponential_runtime.rs87
-rw-r--r--tests/mir-opt/inline/inline_any_operand.bar.Inline.after.mir36
-rw-r--r--tests/mir-opt/inline/inline_any_operand.rs18
-rw-r--r--tests/mir-opt/inline/inline_async.rs18
-rw-r--r--tests/mir-opt/inline/inline_closure.foo.Inline.after.mir49
-rw-r--r--tests/mir-opt/inline/inline_closure.rs13
-rw-r--r--tests/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir52
-rw-r--r--tests/mir-opt/inline/inline_closure_borrows_arg.rs17
-rw-r--r--tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir65
-rw-r--r--tests/mir-opt/inline/inline_closure_captures.rs13
-rw-r--r--tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff24
-rw-r--r--tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff24
-rw-r--r--tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff25
-rw-r--r--tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff22
-rw-r--r--tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff22
-rw-r--r--tests/mir-opt/inline/inline_compatibility.rs55
-rw-r--r--tests/mir-opt/inline/inline_cycle.one.Inline.diff30
-rw-r--r--tests/mir-opt/inline/inline_cycle.rs60
-rw-r--r--tests/mir-opt/inline/inline_cycle.two.Inline.diff41
-rw-r--r--tests/mir-opt/inline/inline_cycle_generic.main.Inline.diff32
-rw-r--r--tests/mir-opt/inline/inline_cycle_generic.rs40
-rw-r--r--tests/mir-opt/inline/inline_diverging.f.Inline.diff24
-rw-r--r--tests/mir-opt/inline/inline_diverging.g.Inline.diff49
-rw-r--r--tests/mir-opt/inline/inline_diverging.h.Inline.diff87
-rw-r--r--tests/mir-opt/inline/inline_diverging.rs40
-rw-r--r--tests/mir-opt/inline/inline_generator.main.Inline.diff136
-rw-r--r--tests/mir-opt/inline/inline_generator.rs16
-rw-r--r--tests/mir-opt/inline/inline_instruction_set.default.Inline.diff60
-rw-r--r--tests/mir-opt/inline/inline_instruction_set.rs61
-rw-r--r--tests/mir-opt/inline/inline_instruction_set.t32.Inline.diff58
-rw-r--r--tests/mir-opt/inline/inline_into_box_place.main.Inline.diff86
-rw-r--r--tests/mir-opt/inline/inline_into_box_place.rs9
-rw-r--r--tests/mir-opt/inline/inline_options.main.Inline.after.mir55
-rw-r--r--tests/mir-opt/inline/inline_options.rs19
-rw-r--r--tests/mir-opt/inline/inline_retag.bar.Inline.after.mir68
-rw-r--r--tests/mir-opt/inline/inline_retag.rs18
-rw-r--r--tests/mir-opt/inline/inline_shims.clone.Inline.diff26
-rw-r--r--tests/mir-opt/inline/inline_shims.drop.Inline.diff56
-rw-r--r--tests/mir-opt/inline/inline_shims.rs13
-rw-r--r--tests/mir-opt/inline/inline_specialization.main.Inline.diff28
-rw-r--r--tests/mir-opt/inline/inline_specialization.rs15
-rw-r--r--tests/mir-opt/inline/inline_trait_method.rs22
-rw-r--r--tests/mir-opt/inline/inline_trait_method.test.Inline.after.mir21
-rw-r--r--tests/mir-opt/inline/inline_trait_method_2.rs27
-rw-r--r--tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir28
-rw-r--r--tests/mir-opt/inline/issue_106141.outer.Inline.diff55
-rw-r--r--tests/mir-opt/inline/issue_106141.rs24
-rw-r--r--tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir30
-rw-r--r--tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir38
-rw-r--r--tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir22
-rw-r--r--tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir26
-rw-r--r--tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs27
-rw-r--r--tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir42
-rw-r--r--tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs7
-rw-r--r--tests/mir-opt/inline/issue_78442.bar.Inline.diff68
-rw-r--r--tests/mir-opt/inline/issue_78442.bar.RevealAll.diff57
-rw-r--r--tests/mir-opt/inline/issue_78442.rs20
-rw-r--r--tests/mir-opt/inline/polymorphic_recursion.rs25
-rw-r--r--tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff13
-rw-r--r--tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff51
-rw-r--r--tests/mir-opt/instrument_coverage.rs37
-rw-r--r--tests/mir-opt/issue_101973.inner.ConstProp.diff95
-rw-r--r--tests/mir-opt/issue_101973.rs20
-rw-r--r--tests/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir52
-rw-r--r--tests/mir-opt/issue_38669.rs12
-rw-r--r--tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir70
-rw-r--r--tests/mir-opt/issue_41110.rs30
-rw-r--r--tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir101
-rw-r--r--tests/mir-opt/issue_41697.rs40
-rw-r--r--tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir20
-rw-r--r--tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir152
-rw-r--r--tests/mir-opt/issue_41888.rs24
-rw-r--r--tests/mir-opt/issue_62289.rs14
-rw-r--r--tests/mir-opt/issue_62289.test.ElaborateDrops.before.mir122
-rw-r--r--tests/mir-opt/issue_72181.bar.built.after.mir17
-rw-r--r--tests/mir-opt/issue_72181.foo.built.after.mir27
-rw-r--r--tests/mir-opt/issue_72181.main.built.after.mir62
-rw-r--r--tests/mir-opt/issue_72181.rs28
-rw-r--r--tests/mir-opt/issue_72181_1.f.built.after.mir29
-rw-r--r--tests/mir-opt/issue_72181_1.main.built.after.mir57
-rw-r--r--tests/mir-opt/issue_72181_1.rs21
-rw-r--r--tests/mir-opt/issue_73223.main.SimplifyArmIdentity.diff156
-rw-r--r--tests/mir-opt/issue_73223.rs12
-rw-r--r--tests/mir-opt/issue_76432.rs16
-rw-r--r--tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff84
-rw-r--r--tests/mir-opt/issue_78192.f.InstCombine.diff29
-rw-r--r--tests/mir-opt/issue_78192.rs11
-rw-r--r--tests/mir-opt/issue_91633.bar.built.after.mir39
-rw-r--r--tests/mir-opt/issue_91633.foo.built.after.mir57
-rw-r--r--tests/mir-opt/issue_91633.fun.built.after.mir35
-rw-r--r--tests/mir-opt/issue_91633.hey.built.after.mir35
-rw-r--r--tests/mir-opt/issue_91633.rs31
-rw-r--r--tests/mir-opt/issue_99325.main.built.after.mir295
-rw-r--r--tests/mir-opt/issue_99325.rs12
-rw-r--r--tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir92
-rw-r--r--tests/mir-opt/issues/issue_59352.rs19
-rw-r--r--tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff89
-rw-r--r--tests/mir-opt/issues/issue_75439.rs19
-rw-r--r--tests/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir52
-rw-r--r--tests/mir-opt/loop_test.rs17
-rw-r--r--tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff68
-rw-r--r--tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff81
-rw-r--r--tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff30
-rw-r--r--tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff30
-rw-r--r--tests/mir-opt/lower_array_len.rs40
-rw-r--r--tests/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir45
-rw-r--r--tests/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir58
-rw-r--r--tests/mir-opt/lower_array_len_e2e.array_len.PreCodegen.after.mir11
-rw-r--r--tests/mir-opt/lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir11
-rw-r--r--tests/mir-opt/lower_array_len_e2e.rs39
-rw-r--r--tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff20
-rw-r--r--tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff26
-rw-r--r--tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff119
-rw-r--r--tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff72
-rw-r--r--tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff29
-rw-r--r--tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff31
-rw-r--r--tests/mir-opt/lower_intrinsics.rs74
-rw-r--r--tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff20
-rw-r--r--tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff22
-rw-r--r--tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff83
-rw-r--r--tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir27
-rw-r--r--tests/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir27
-rw-r--r--tests/mir-opt/lower_intrinsics_e2e.rs32
-rw-r--r--tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff63
-rw-r--r--tests/mir-opt/lower_slice_len.rs14
-rw-r--r--tests/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff272
-rw-r--r--tests/mir-opt/match_arm_scopes.rs35
-rw-r--r--tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir106
-rw-r--r--tests/mir-opt/match_test.rs18
-rw-r--r--tests/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff88
-rw-r--r--tests/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff55
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff113
-rw-r--r--tests/mir-opt/matches_reduce_branches.rs60
-rw-r--r--tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff32
-rw-r--r--tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff32
-rw-r--r--tests/mir-opt/matches_u8.rs34
-rw-r--r--tests/mir-opt/multiple_return_terminators.rs14
-rw-r--r--tests/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff12
-rw-r--r--tests/mir-opt/nll/named_lifetimes_basic.rs15
-rw-r--r--tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir47
-rw-r--r--tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir111
-rw-r--r--tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir111
-rw-r--r--tests/mir-opt/nll/region_subtyping_basic.rs25
-rw-r--r--tests/mir-opt/no_drop_for_inactive_variant.rs16
-rw-r--r--tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir49
-rw-r--r--tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir49
-rw-r--r--tests/mir-opt/no_spurious_drop_after_call.rs10
-rw-r--r--tests/mir-opt/not_equal_false.opt.InstCombine.diff35
-rw-r--r--tests/mir-opt/not_equal_false.rs10
-rw-r--r--tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff43
-rw-r--r--tests/mir-opt/nrvo_simple.rs12
-rw-r--r--tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir60
-rw-r--r--tests/mir-opt/packed_struct_drop_aligned.rs17
-rw-r--r--tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff74
-rw-r--r--tests/mir-opt/remove_fake_borrows.rs15
-rw-r--r--tests/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir11
-rw-r--r--tests/mir-opt/remove_never_const.rs21
-rw-r--r--tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff100
-rw-r--r--tests/mir-opt/remove_storage_markers.rs13
-rw-r--r--tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff31
-rw-r--r--tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff31
-rw-r--r--tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff27
-rw-r--r--tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff27
-rw-r--r--tests/mir-opt/remove_unneeded_drops.rs29
-rw-r--r--tests/mir-opt/remove_zsts.get_union.PreCodegen.after.mir10
-rw-r--r--tests/mir-opt/remove_zsts.get_union.RemoveZsts.diff19
-rw-r--r--tests/mir-opt/remove_zsts.rs14
-rw-r--r--tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir192
-rw-r--r--tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir22
-rw-r--r--tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir21
-rw-r--r--tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir194
-rw-r--r--tests/mir-opt/retag.rs66
-rw-r--r--tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir18
-rw-r--r--tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir15
-rw-r--r--tests/mir-opt/return_an_array.rs8
-rw-r--r--tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff156
-rw-r--r--tests/mir-opt/separate_const_switch.rs31
-rw-r--r--tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff111
-rw-r--r--tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir52
-rw-r--r--tests/mir-opt/simple_option_map_e2e.rs19
-rw-r--r--tests/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff89
-rw-r--r--tests/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff89
-rw-r--r--tests/mir-opt/simplify_arm.rs50
-rw-r--r--tests/mir-opt/simplify_arm_identity.rs26
-rw-r--r--tests/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff52
-rw-r--r--tests/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff71
-rw-r--r--tests/mir-opt/simplify_cfg.rs18
-rw-r--r--tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff38
-rw-r--r--tests/mir-opt/simplify_if.rs9
-rw-r--r--tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff33
-rw-r--r--tests/mir-opt/simplify_locals.d1.SimplifyLocals-before-const-prop.diff19
-rw-r--r--tests/mir-opt/simplify_locals.d2.SimplifyLocals-before-const-prop.diff29
-rw-r--r--tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff21
-rw-r--r--tests/mir-opt/simplify_locals.r.SimplifyLocals-before-const-prop.diff31
-rw-r--r--tests/mir-opt/simplify_locals.rs81
-rw-r--r--tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff22
-rw-r--r--tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff22
-rw-r--r--tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff26
-rw-r--r--tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff22
-rw-r--r--tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff62
-rw-r--r--tests/mir-opt/simplify_locals_fixedpoint.rs15
-rw-r--r--tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff109
-rw-r--r--tests/mir-opt/simplify_locals_removes_unused_consts.rs18
-rw-r--r--tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff52
-rw-r--r--tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs14
-rw-r--r--tests/mir-opt/simplify_match.main.ConstProp.diff39
-rw-r--r--tests/mir-opt/simplify_match.rs10
-rw-r--r--tests/mir-opt/simplify_try_if_let.rs43
-rw-r--r--tests/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff104
-rw-r--r--tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir101
-rw-r--r--tests/mir-opt/slice_drop_shim.rs7
-rw-r--r--tests/mir-opt/spanview_block.main.built.after.html66
-rw-r--r--tests/mir-opt/spanview_block.rs5
-rw-r--r--tests/mir-opt/spanview_statement.main.built.after.html66
-rw-r--r--tests/mir-opt/spanview_statement.rs5
-rw-r--r--tests/mir-opt/spanview_terminator.main.built.after.html65
-rw-r--r--tests/mir-opt/spanview_terminator.rs5
-rw-r--r--tests/mir-opt/sroa.dropping.ScalarReplacementOfAggregates.diff50
-rw-r--r--tests/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff45
-rw-r--r--tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff47
-rw-r--r--tests/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff87
-rw-r--r--tests/mir-opt/sroa.rs88
-rw-r--r--tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff34
-rw-r--r--tests/mir-opt/sroa.unions.ScalarReplacementOfAggregates.diff24
-rw-r--r--tests/mir-opt/storage_ranges.main.nll.0.mir63
-rw-r--r--tests/mir-opt/storage_ranges.rs9
-rw-r--r--tests/mir-opt/tls_access.main.PreCodegen.after.mir28
-rw-r--r--tests/mir-opt/tls_access.rs14
-rw-r--r--tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir71
-rw-r--r--tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir40
-rw-r--r--tests/mir-opt/try_identity_e2e.rs34
-rw-r--r--tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir16
-rw-r--r--tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir18
-rw-r--r--tests/mir-opt/uninhabited_enum.rs19
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir75
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff101
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.rs30
-rw-r--r--tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir104
-rw-r--r--tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff146
-rw-r--r--tests/mir-opt/uninhabited_enum_branching2.rs34
-rw-r--r--tests/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff38
-rw-r--r--tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff34
-rw-r--r--tests/mir-opt/uninhabited_fallthrough_elimination.rs32
-rw-r--r--tests/mir-opt/unreachable.main.UnreachablePropagation.diff70
-rw-r--r--tests/mir-opt/unreachable.rs20
-rw-r--r--tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff71
-rw-r--r--tests/mir-opt/unreachable_diverging.rs20
-rw-r--r--tests/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir10
-rw-r--r--tests/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir12
-rw-r--r--tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir39
-rw-r--r--tests/mir-opt/unusual_item_types.rs29
-rw-r--r--tests/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir10
-rw-r--r--tests/mir-opt/while_let_loops.change_loop_body.ConstProp.diff46
-rw-r--r--tests/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir17
-rw-r--r--tests/mir-opt/while_let_loops.rs14
-rw-r--r--tests/mir-opt/while_storage.rs19
-rw-r--r--tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir60
584 files changed, 24216 insertions, 0 deletions
diff --git a/tests/mir-opt/76803_regression.encode.SimplifyBranchSame.diff b/tests/mir-opt/76803_regression.encode.SimplifyBranchSame.diff
new file mode 100644
index 000000000..9780332d8
--- /dev/null
+++ b/tests/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: 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/tests/mir-opt/76803_regression.rs b/tests/mir-opt/76803_regression.rs
new file mode 100644
index 000000000..05dc3c978
--- /dev/null
+++ b/tests/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/tests/mir-opt/README.md b/tests/mir-opt/README.md
new file mode 100644
index 000000000..0721d9f70
--- /dev/null
+++ b/tests/mir-opt/README.md
@@ -0,0 +1,51 @@
+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.
+
+## Unit testing
+
+If you are only testing the behavior of a particular mir-opt pass on some specific input (as is
+usually the case), you should add
+
+```
+// unit-test: PassName
+```
+
+to the top of the file. This makes sure that other passes don't run which means you'll get the input
+you expected and your test won't break when other code changes.
+
+## Emit a diff of the mir for a specific optimization
+
+This is what you want most often when you want to see how an optimization changes the MIR.
+
+```
+// 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/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
new file mode 100644
index 000000000..5f8b2f931
--- /dev/null
+++ b/tests/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/tests/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir b/tests/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir
new file mode 100644
index 000000000..4c67376b5
--- /dev/null
+++ b/tests/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/tests/mir-opt/address_of.rs b/tests/mir-opt/address_of.rs
new file mode 100644
index 000000000..c4bea5613
--- /dev/null
+++ b/tests/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/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..af5178d40
--- /dev/null
+++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.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/tests/mir-opt/array_index_is_temporary.rs b/tests/mir-opt/array_index_is_temporary.rs
new file mode 100644
index 000000000..e7bde81d4
--- /dev/null
+++ b/tests/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 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/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir b/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
new file mode 100644
index 000000000..2487ef5c2
--- /dev/null
+++ b/tests/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/tests/mir-opt/asm_unwind_panic_abort.rs b/tests/mir-opt/asm_unwind_panic_abort.rs
new file mode 100644
index 000000000..ad8f9398e
--- /dev/null
+++ b/tests/mir-opt/asm_unwind_panic_abort.rs
@@ -0,0 +1,15 @@
+//! Tests that unwinding from an asm block is caught and forced to abort
+//! when `-C panic=abort`.
+
+// 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/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir
new file mode 100644
index 000000000..1f099cd5e
--- /dev/null
+++ b/tests/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/tests/mir-opt/basic_assignment.rs b/tests/mir-opt/basic_assignment.rs
new file mode 100644
index 000000000..ac350271e
--- /dev/null
+++ b/tests/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/tests/mir-opt/bool_compare.opt1.InstCombine.diff b/tests/mir-opt/bool_compare.opt1.InstCombine.diff
new file mode 100644
index 000000000..0af5d82d3
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/bool_compare.opt2.InstCombine.diff b/tests/mir-opt/bool_compare.opt2.InstCombine.diff
new file mode 100644
index 000000000..f5d1febd9
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/bool_compare.opt3.InstCombine.diff b/tests/mir-opt/bool_compare.opt3.InstCombine.diff
new file mode 100644
index 000000000..e7432adac
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/bool_compare.opt4.InstCombine.diff b/tests/mir-opt/bool_compare.opt4.InstCombine.diff
new file mode 100644
index 000000000..6b3e27772
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/bool_compare.rs b/tests/mir-opt/bool_compare.rs
new file mode 100644
index 000000000..4435bf5b0
--- /dev/null
+++ b/tests/mir-opt/bool_compare.rs
@@ -0,0 +1,28 @@
+// unit-test: InstCombine
+
+// 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/tests/mir-opt/box_expr.main.ElaborateDrops.before.mir b/tests/mir-opt/box_expr.main.ElaborateDrops.before.mir
new file mode 100644
index 000000000..49133138d
--- /dev/null
+++ b/tests/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/tests/mir-opt/box_expr.rs b/tests/mir-opt/box_expr.rs
new file mode 100644
index 000000000..a214504f6
--- /dev/null
+++ b/tests/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/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir
new file mode 100644
index 000000000..2a7f90fe9
--- /dev/null
+++ b/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir
@@ -0,0 +1,41 @@
+// MIR for `a::{closure#0}` 0 generator_resume
+/* generator_layout = GeneratorLayout {
+ field_tys: {},
+ variant_fields: {
+ Unresumed(0): [],
+ Returned (1): [],
+ Panicked (2): [],
+ },
+ storage_conflicts: BitMatrix(0x0) {},
+} */
+
+fn a::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:11:14: 11:16]>, _2: &mut Context<'_>) -> Poll<()> {
+ debug _task_context => _4; // in scope 0 at $DIR/async_await.rs:+0:14: +0:16
+ let mut _0: std::task::Poll<()>; // return place in scope 0 at $DIR/async_await.rs:+0:14: +0:16
+ let mut _3: (); // in scope 0 at $DIR/async_await.rs:+0:14: +0:16
+ let mut _4: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+0:14: +0:16
+ let mut _5: u32; // in scope 0 at $DIR/async_await.rs:+0:14: +0:16
+
+ bb0: {
+ _5 = discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:11:14: 11:16]))); // scope 0 at $DIR/async_await.rs:+0:14: +0:16
+ switchInt(move _5) -> [0: bb1, 1: bb2, otherwise: bb3]; // scope 0 at $DIR/async_await.rs:+0:14: +0:16
+ }
+
+ bb1: {
+ _4 = move _2; // scope 0 at $DIR/async_await.rs:+0:14: +0:16
+ _3 = const (); // scope 0 at $DIR/async_await.rs:+0:14: +0:16
+ Deinit(_0); // scope 0 at $DIR/async_await.rs:+0:16: +0:16
+ ((_0 as Ready).0: ()) = move _3; // scope 0 at $DIR/async_await.rs:+0:16: +0:16
+ discriminant(_0) = 0; // scope 0 at $DIR/async_await.rs:+0:16: +0:16
+ discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:11:14: 11:16]))) = 1; // scope 0 at $DIR/async_await.rs:+0:16: +0:16
+ return; // scope 0 at $DIR/async_await.rs:+0:16: +0:16
+ }
+
+ bb2: {
+ assert(const false, "`async fn` resumed after completion") -> bb2; // scope 0 at $DIR/async_await.rs:+0:14: +0:16
+ }
+
+ bb3: {
+ unreachable; // scope 0 at $DIR/async_await.rs:+0:14: +0:16
+ }
+}
diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir
new file mode 100644
index 000000000..05edc4797
--- /dev/null
+++ b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir
@@ -0,0 +1,337 @@
+// MIR for `b::{closure#0}` 0 generator_resume
+/* generator_layout = GeneratorLayout {
+ field_tys: {
+ _0: impl std::future::Future<Output = ()>,
+ _1: impl std::future::Future<Output = ()>,
+ },
+ variant_fields: {
+ Unresumed(0): [],
+ Returned (1): [],
+ Panicked (2): [],
+ Suspend0 (3): [_0],
+ Suspend1 (4): [_1],
+ },
+ storage_conflicts: BitMatrix(2x2) {
+ (_0, _0),
+ (_1, _1),
+ },
+} */
+
+fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>, _2: &mut Context<'_>) -> Poll<()> {
+ debug _task_context => _38; // in scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ let mut _0: std::task::Poll<()>; // return place in scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ let _3: (); // in scope 0 at $DIR/async_await.rs:+1:5: +1:14
+ let mut _4: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ let mut _5: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:5: +1:8
+ let mut _6: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ let mut _7: (); // in scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ let _8: (); // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ let mut _9: std::task::Poll<()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ let mut _10: std::pin::Pin<&mut impl std::future::Future<Output = ()>>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ let mut _11: &mut impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ let mut _12: &mut impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ let mut _13: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+1:5: +1:14
+ let mut _14: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+1:5: +1:14
+ let mut _15: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ let mut _16: isize; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ let mut _18: !; // in scope 0 at $DIR/async_await.rs:+1:5: +1:14
+ let mut _19: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ let mut _20: (); // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ let mut _21: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ let mut _22: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:5: +2:8
+ let mut _23: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ let _24: (); // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ let mut _25: std::task::Poll<()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ let mut _26: std::pin::Pin<&mut impl std::future::Future<Output = ()>>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ let mut _27: &mut impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ let mut _28: &mut impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ let mut _29: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+2:5: +2:14
+ let mut _30: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+2:5: +2:14
+ let mut _31: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ let mut _32: isize; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ let mut _34: !; // in scope 0 at $DIR/async_await.rs:+2:5: +2:14
+ let mut _35: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ let mut _36: (); // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ let mut _37: (); // in scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ let mut _38: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ let mut _39: u32; // in scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ scope 1 {
+ debug __awaitee => (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#3).0: impl std::future::Future<Output = ()>); // in scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ let _17: (); // in scope 1 at $DIR/async_await.rs:+1:5: +1:14
+ scope 2 {
+ }
+ scope 3 {
+ debug result => _17; // in scope 3 at $DIR/async_await.rs:+1:5: +1:14
+ }
+ }
+ scope 4 {
+ debug __awaitee => (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#4).0: impl std::future::Future<Output = ()>); // in scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ let _33: (); // in scope 4 at $DIR/async_await.rs:+2:5: +2:14
+ scope 5 {
+ }
+ scope 6 {
+ debug result => _33; // in scope 6 at $DIR/async_await.rs:+2:5: +2:14
+ }
+ }
+
+ bb0: {
+ _39 = discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb30]; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ }
+
+ bb1: {
+ _38 = move _2; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ StorageLive(_3); // scope 0 at $DIR/async_await.rs:+1:5: +1:14
+ StorageLive(_4); // scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ StorageLive(_5); // scope 0 at $DIR/async_await.rs:+1:5: +1:8
+ _5 = a() -> bb2; // scope 0 at $DIR/async_await.rs:+1:5: +1:8
+ // mir::Constant
+ // + span: $DIR/async_await.rs:15:5: 15:6
+ // + literal: Const { ty: fn() -> impl Future<Output = ()> {a}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ _4 = <impl Future<Output = ()> as IntoFuture>::into_future(move _5) -> bb3; // scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ // mir::Constant
+ // + span: $DIR/async_await.rs:15:8: 15:14
+ // + literal: Const { ty: fn(impl Future<Output = ()>) -> <impl Future<Output = ()> as IntoFuture>::IntoFuture {<impl Future<Output = ()> as IntoFuture>::into_future}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_5); // scope 0 at $DIR/async_await.rs:+1:13: +1:14
+ nop; // scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#3).0: impl std::future::Future<Output = ()>) = move _4; // scope 0 at $DIR/async_await.rs:+1:8: +1:14
+ goto -> bb4; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ }
+
+ bb4: {
+ StorageLive(_8); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ StorageLive(_9); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ StorageLive(_10); // scope 2 at $DIR/async_await.rs:+1:8: +1:14
+ StorageLive(_11); // scope 2 at $DIR/async_await.rs:+1:8: +1:14
+ StorageLive(_12); // scope 2 at $DIR/async_await.rs:+1:8: +1:14
+ _12 = &mut (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#3).0: impl std::future::Future<Output = ()>); // scope 2 at $DIR/async_await.rs:+1:8: +1:14
+ _11 = &mut (*_12); // scope 2 at $DIR/async_await.rs:+1:8: +1:14
+ _10 = Pin::<&mut impl Future<Output = ()>>::new_unchecked(move _11) -> bb5; // scope 2 at $DIR/async_await.rs:+1:8: +1:14
+ // mir::Constant
+ // + span: $DIR/async_await.rs:15:8: 15:14
+ // + literal: Const { ty: unsafe fn(&mut impl Future<Output = ()>) -> Pin<&mut impl Future<Output = ()>> {Pin::<&mut impl Future<Output = ()>>::new_unchecked}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ StorageDead(_11); // scope 2 at $DIR/async_await.rs:+1:13: +1:14
+ StorageLive(_13); // scope 2 at $DIR/async_await.rs:+1:5: +1:14
+ StorageLive(_14); // scope 2 at $DIR/async_await.rs:+1:5: +1:14
+ StorageLive(_15); // scope 2 at $DIR/async_await.rs:+1:8: +1:14
+ _15 = _38; // scope 2 at $DIR/async_await.rs:+1:8: +1:14
+ _14 = move _15; // scope 2 at $DIR/async_await.rs:+1:5: +1:14
+ goto -> bb6; // scope 2 at $DIR/async_await.rs:+1:5: +1:14
+ }
+
+ bb6: {
+ _13 = &mut (*_14); // scope 2 at $DIR/async_await.rs:+1:5: +1:14
+ StorageDead(_15); // scope 2 at $DIR/async_await.rs:+1:13: +1:14
+ _9 = <impl Future<Output = ()> as Future>::poll(move _10, move _13) -> bb7; // scope 2 at $DIR/async_await.rs:+1:8: +1:14
+ // mir::Constant
+ // + span: $DIR/async_await.rs:15:8: 15:14
+ // + literal: Const { ty: for<'a, 'b, 'c> fn(Pin<&'a mut impl Future<Output = ()>>, &'b mut Context<'c>) -> Poll<<impl Future<Output = ()> as Future>::Output> {<impl Future<Output = ()> as Future>::poll}, val: Value(<ZST>) }
+ }
+
+ bb7: {
+ StorageDead(_13); // scope 2 at $DIR/async_await.rs:+1:13: +1:14
+ StorageDead(_10); // scope 2 at $DIR/async_await.rs:+1:13: +1:14
+ _16 = discriminant(_9); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ switchInt(move _16) -> [0: bb10, 1: bb8, otherwise: bb9]; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ }
+
+ bb8: {
+ _8 = const (); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ StorageDead(_14); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
+ StorageDead(_12); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
+ StorageDead(_9); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
+ StorageDead(_8); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
+ StorageLive(_19); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ StorageLive(_20); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ _20 = (); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ Deinit(_0); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ discriminant(_0) = 1; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))) = 3; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ return; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ }
+
+ bb9: {
+ unreachable; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ }
+
+ bb10: {
+ StorageLive(_17); // scope 1 at $DIR/async_await.rs:+1:5: +1:14
+ _17 = ((_9 as Ready).0: ()); // scope 1 at $DIR/async_await.rs:+1:5: +1:14
+ _3 = _17; // scope 3 at $DIR/async_await.rs:+1:5: +1:14
+ StorageDead(_17); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
+ StorageDead(_14); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
+ StorageDead(_12); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
+ StorageDead(_9); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
+ StorageDead(_8); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
+ goto -> bb12; // scope 0 at $DIR/async_await.rs:+1:13: +1:14
+ }
+
+ bb11: {
+ StorageDead(_20); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
+ _38 = move _19; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ StorageDead(_19); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
+ _7 = const (); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ goto -> bb4; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
+ }
+
+ bb12: {
+ nop; // scope 0 at $DIR/async_await.rs:+1:13: +1:14
+ goto -> bb13; // scope 0 at $DIR/async_await.rs:+1:14: +1:15
+ }
+
+ bb13: {
+ StorageDead(_4); // scope 0 at $DIR/async_await.rs:+1:14: +1:15
+ StorageDead(_3); // scope 0 at $DIR/async_await.rs:+1:14: +1:15
+ StorageLive(_21); // scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ StorageLive(_22); // scope 0 at $DIR/async_await.rs:+2:5: +2:8
+ _22 = a() -> bb14; // scope 0 at $DIR/async_await.rs:+2:5: +2:8
+ // mir::Constant
+ // + span: $DIR/async_await.rs:16:5: 16:6
+ // + literal: Const { ty: fn() -> impl Future<Output = ()> {a}, val: Value(<ZST>) }
+ }
+
+ bb14: {
+ _21 = <impl Future<Output = ()> as IntoFuture>::into_future(move _22) -> bb15; // scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ // mir::Constant
+ // + span: $DIR/async_await.rs:16:8: 16:14
+ // + literal: Const { ty: fn(impl Future<Output = ()>) -> <impl Future<Output = ()> as IntoFuture>::IntoFuture {<impl Future<Output = ()> as IntoFuture>::into_future}, val: Value(<ZST>) }
+ }
+
+ bb15: {
+ StorageDead(_22); // scope 0 at $DIR/async_await.rs:+2:13: +2:14
+ nop; // scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#4).0: impl std::future::Future<Output = ()>) = move _21; // scope 0 at $DIR/async_await.rs:+2:8: +2:14
+ goto -> bb16; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ }
+
+ bb16: {
+ StorageLive(_24); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ StorageLive(_25); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ StorageLive(_26); // scope 5 at $DIR/async_await.rs:+2:8: +2:14
+ StorageLive(_27); // scope 5 at $DIR/async_await.rs:+2:8: +2:14
+ StorageLive(_28); // scope 5 at $DIR/async_await.rs:+2:8: +2:14
+ _28 = &mut (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#4).0: impl std::future::Future<Output = ()>); // scope 5 at $DIR/async_await.rs:+2:8: +2:14
+ _27 = &mut (*_28); // scope 5 at $DIR/async_await.rs:+2:8: +2:14
+ _26 = Pin::<&mut impl Future<Output = ()>>::new_unchecked(move _27) -> bb17; // scope 5 at $DIR/async_await.rs:+2:8: +2:14
+ // mir::Constant
+ // + span: $DIR/async_await.rs:16:8: 16:14
+ // + literal: Const { ty: unsafe fn(&mut impl Future<Output = ()>) -> Pin<&mut impl Future<Output = ()>> {Pin::<&mut impl Future<Output = ()>>::new_unchecked}, val: Value(<ZST>) }
+ }
+
+ bb17: {
+ StorageDead(_27); // scope 5 at $DIR/async_await.rs:+2:13: +2:14
+ StorageLive(_29); // scope 5 at $DIR/async_await.rs:+2:5: +2:14
+ StorageLive(_30); // scope 5 at $DIR/async_await.rs:+2:5: +2:14
+ StorageLive(_31); // scope 5 at $DIR/async_await.rs:+2:8: +2:14
+ _31 = _38; // scope 5 at $DIR/async_await.rs:+2:8: +2:14
+ _30 = move _31; // scope 5 at $DIR/async_await.rs:+2:5: +2:14
+ goto -> bb18; // scope 5 at $DIR/async_await.rs:+2:5: +2:14
+ }
+
+ bb18: {
+ _29 = &mut (*_30); // scope 5 at $DIR/async_await.rs:+2:5: +2:14
+ StorageDead(_31); // scope 5 at $DIR/async_await.rs:+2:13: +2:14
+ _25 = <impl Future<Output = ()> as Future>::poll(move _26, move _29) -> bb19; // scope 5 at $DIR/async_await.rs:+2:8: +2:14
+ // mir::Constant
+ // + span: $DIR/async_await.rs:16:8: 16:14
+ // + literal: Const { ty: for<'a, 'b, 'c> fn(Pin<&'a mut impl Future<Output = ()>>, &'b mut Context<'c>) -> Poll<<impl Future<Output = ()> as Future>::Output> {<impl Future<Output = ()> as Future>::poll}, val: Value(<ZST>) }
+ }
+
+ bb19: {
+ StorageDead(_29); // scope 5 at $DIR/async_await.rs:+2:13: +2:14
+ StorageDead(_26); // scope 5 at $DIR/async_await.rs:+2:13: +2:14
+ _32 = discriminant(_25); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ switchInt(move _32) -> [0: bb22, 1: bb20, otherwise: bb21]; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ }
+
+ bb20: {
+ _24 = const (); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ StorageDead(_30); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
+ StorageDead(_28); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
+ StorageDead(_25); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
+ StorageDead(_24); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
+ StorageLive(_35); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ StorageLive(_36); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ _36 = (); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ Deinit(_0); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ discriminant(_0) = 1; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))) = 4; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ return; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ }
+
+ bb21: {
+ unreachable; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ }
+
+ bb22: {
+ StorageLive(_33); // scope 4 at $DIR/async_await.rs:+2:5: +2:14
+ _33 = ((_25 as Ready).0: ()); // scope 4 at $DIR/async_await.rs:+2:5: +2:14
+ _37 = _33; // scope 6 at $DIR/async_await.rs:+2:5: +2:14
+ StorageDead(_33); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
+ StorageDead(_30); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
+ StorageDead(_28); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
+ StorageDead(_25); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
+ StorageDead(_24); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
+ goto -> bb24; // scope 0 at $DIR/async_await.rs:+2:13: +2:14
+ }
+
+ bb23: {
+ StorageDead(_36); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
+ _38 = move _35; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ StorageDead(_35); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
+ _7 = const (); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ goto -> bb16; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
+ }
+
+ bb24: {
+ nop; // scope 0 at $DIR/async_await.rs:+2:13: +2:14
+ goto -> bb25; // scope 0 at $DIR/async_await.rs:+3:1: +3:2
+ }
+
+ bb25: {
+ StorageDead(_21); // scope 0 at $DIR/async_await.rs:+3:1: +3:2
+ goto -> bb26; // scope 0 at $DIR/async_await.rs:+3:1: +3:2
+ }
+
+ bb26: {
+ Deinit(_0); // scope 0 at $DIR/async_await.rs:+3:2: +3:2
+ ((_0 as Ready).0: ()) = move _37; // scope 0 at $DIR/async_await.rs:+3:2: +3:2
+ discriminant(_0) = 0; // scope 0 at $DIR/async_await.rs:+3:2: +3:2
+ discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))) = 1; // scope 0 at $DIR/async_await.rs:+3:2: +3:2
+ return; // scope 0 at $DIR/async_await.rs:+3:2: +3:2
+ }
+
+ bb27: {
+ StorageLive(_3); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ StorageLive(_4); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ StorageLive(_19); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ StorageLive(_20); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ _19 = move _2; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ goto -> bb11; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ }
+
+ bb28: {
+ StorageLive(_21); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ StorageLive(_35); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ StorageLive(_36); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ _35 = move _2; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ goto -> bb23; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ }
+
+ bb29: {
+ assert(const false, "`async fn` resumed after completion") -> bb29; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ }
+
+ bb30: {
+ unreachable; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
+ }
+}
diff --git a/tests/mir-opt/building/async_await.rs b/tests/mir-opt/building/async_await.rs
new file mode 100644
index 000000000..0b991e3b8
--- /dev/null
+++ b/tests/mir-opt/building/async_await.rs
@@ -0,0 +1,17 @@
+// This test makes sure that the generator MIR pass eliminates all calls to
+// `get_context`, and that the MIR argument type for an async fn and all locals
+// related to `yield` are `&mut Context`, and its return type is `Poll`.
+
+// edition:2018
+// compile-flags: -C panic=abort
+
+#![crate_type = "lib"]
+
+// EMIT_MIR async_await.a-{closure#0}.generator_resume.0.mir
+async fn a() {}
+
+// EMIT_MIR async_await.b-{closure#0}.generator_resume.0.mir
+pub async fn b() {
+ a().await;
+ a().await
+}
diff --git a/tests/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir b/tests/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir
new file mode 100644
index 000000000..20dd251e7
--- /dev/null
+++ b/tests/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir
@@ -0,0 +1,22 @@
+// MIR for `arbitrary_let` after built
+
+fn arbitrary_let(_1: i32) -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/arbitrary_let.rs:+0:29: +0:32
+ let mut _2: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _2 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ goto -> bb2; // scope 0 at $DIR/arbitrary_let.rs:+4:13: +4:25
+ }
+
+ bb1: {
+ _0 = _3; // scope 0 at $DIR/arbitrary_let.rs:+7:13: +7:20
+ return; // scope 0 at $DIR/arbitrary_let.rs:+8:13: +8:21
+ }
+
+ bb2: {
+ _3 = _2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ goto -> bb1; // scope 0 at $DIR/arbitrary_let.rs:+12:13: +12:24
+ }
+}
diff --git a/tests/mir-opt/building/custom/arbitrary_let.rs b/tests/mir-opt/building/custom/arbitrary_let.rs
new file mode 100644
index 000000000..776df3151
--- /dev/null
+++ b/tests/mir-opt/building/custom/arbitrary_let.rs
@@ -0,0 +1,28 @@
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+use core::ptr::{addr_of, addr_of_mut};
+
+// EMIT_MIR arbitrary_let.arbitrary_let.built.after.mir
+#[custom_mir(dialect = "built")]
+fn arbitrary_let(x: i32) -> i32 {
+ mir!(
+ {
+ let y = x;
+ Goto(second)
+ }
+ third = {
+ RET = z;
+ Return()
+ }
+ second = {
+ let z = y;
+ Goto(third)
+ }
+ )
+}
+
+fn main() {
+ assert_eq!(arbitrary_let(5), 5);
+}
diff --git a/tests/mir-opt/building/custom/consts.consts.built.after.mir b/tests/mir-opt/building/custom/consts.consts.built.after.mir
new file mode 100644
index 000000000..ba753cfc2
--- /dev/null
+++ b/tests/mir-opt/building/custom/consts.consts.built.after.mir
@@ -0,0 +1,22 @@
+// MIR for `consts` after built
+
+fn consts() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/consts.rs:+0:27: +0:27
+ let mut _1: u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _2: i8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _3: u32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _4: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _5: fn() {consts::<10>}; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _1 = const 5_u8; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _2 = const _; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _3 = const C; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _4 = const _; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _5 = consts::<10>; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ // mir::Constant
+ // + span: $DIR/consts.rs:16:18: 16:30
+ // + literal: Const { ty: fn() {consts::<10>}, val: Value(<ZST>) }
+ return; // scope 0 at $DIR/consts.rs:+7:9: +7:17
+ }
+}
diff --git a/tests/mir-opt/building/custom/consts.rs b/tests/mir-opt/building/custom/consts.rs
new file mode 100644
index 000000000..16d10eb59
--- /dev/null
+++ b/tests/mir-opt/building/custom/consts.rs
@@ -0,0 +1,36 @@
+#![feature(custom_mir, core_intrinsics, inline_const)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+
+const D: i32 = 5;
+
+// EMIT_MIR consts.consts.built.after.mir
+#[custom_mir(dialect = "built")]
+fn consts<const C: u32>() {
+ mir!({
+ let _a = 5_u8;
+ let _b = const { 5_i8 };
+ let _c = C;
+ let _d = D;
+ let _e = consts::<10>;
+ Return()
+ })
+}
+
+static S: i32 = 0x05050505;
+static mut T: i32 = 0x0a0a0a0a;
+// EMIT_MIR consts.statics.built.after.mir
+#[custom_mir(dialect = "built")]
+fn statics() {
+ mir!({
+ let _a: &i32 = Static(S);
+ let _b: *mut i32 = StaticMut(T);
+ Return()
+ })
+}
+
+fn main() {
+ consts::<5>();
+ statics();
+}
diff --git a/tests/mir-opt/building/custom/consts.statics.built.after.mir b/tests/mir-opt/building/custom/consts.statics.built.after.mir
new file mode 100644
index 000000000..bfef976aa
--- /dev/null
+++ b/tests/mir-opt/building/custom/consts.statics.built.after.mir
@@ -0,0 +1,27 @@
+// MIR for `statics` after built
+
+fn statics() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/consts.rs:+0:14: +0:14
+ let mut _1: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _2: *mut i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _1 = const {alloc1: &i32}; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ // mir::Constant
+ // + span: $DIR/consts.rs:27:31: 27:32
+ // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
+ _2 = const {alloc2: *mut i32}; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ // mir::Constant
+ // + span: $DIR/consts.rs:28:38: 28:39
+ // + literal: Const { ty: *mut i32, val: Value(Scalar(alloc2)) }
+ return; // scope 0 at $DIR/consts.rs:+4:9: +4:17
+ }
+}
+
+alloc2 (static: T, size: 4, align: 4) {
+ 0a 0a 0a 0a │ ....
+}
+
+alloc1 (static: S, size: 4, align: 4) {
+ 05 05 05 05 │ ....
+}
diff --git a/tests/mir-opt/building/custom/enums.rs b/tests/mir-opt/building/custom/enums.rs
new file mode 100644
index 000000000..e5cd45637
--- /dev/null
+++ b/tests/mir-opt/building/custom/enums.rs
@@ -0,0 +1,120 @@
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+
+// EMIT_MIR enums.switch_bool.built.after.mir
+#[custom_mir(dialect = "built")]
+pub fn switch_bool(b: bool) -> u32 {
+ mir!(
+ {
+ match b {
+ true => t,
+ false => f,
+ _ => f,
+ }
+ }
+
+ t = {
+ RET = 5;
+ Return()
+ }
+
+ f = {
+ RET = 10;
+ Return()
+ }
+ )
+}
+
+// EMIT_MIR enums.switch_option.built.after.mir
+#[custom_mir(dialect = "built")]
+pub fn switch_option(option: Option<()>) -> bool {
+ mir!(
+ {
+ let discr = Discriminant(option);
+ match discr {
+ 0 => n,
+ 1 => s,
+ _ => s,
+ }
+ }
+
+ n = {
+ RET = false;
+ Return()
+ }
+
+ s = {
+ RET = true;
+ Return()
+ }
+ )
+}
+
+#[repr(u8)]
+enum Bool {
+ False = 0,
+ True = 1,
+}
+
+// EMIT_MIR enums.switch_option_repr.built.after.mir
+#[custom_mir(dialect = "built")]
+fn switch_option_repr(option: Bool) -> bool {
+ mir!(
+ {
+ let discr = Discriminant(option);
+ match discr {
+ 0 => f,
+ _ => t,
+ }
+ }
+
+ t = {
+ RET = true;
+ Return()
+ }
+
+ f = {
+ RET = false;
+ Return()
+ }
+ )
+}
+
+// EMIT_MIR enums.set_discr.built.after.mir
+#[custom_mir(dialect = "runtime", phase = "initial")]
+fn set_discr(option: &mut Option<()>) {
+ mir!({
+ SetDiscriminant(*option, 0);
+ Return()
+ })
+}
+
+// EMIT_MIR enums.set_discr_repr.built.after.mir
+#[custom_mir(dialect = "runtime", phase = "initial")]
+fn set_discr_repr(b: &mut Bool) {
+ mir!({
+ SetDiscriminant(*b, 0);
+ Return()
+ })
+}
+
+fn main() {
+ assert_eq!(switch_bool(true), 5);
+ assert_eq!(switch_bool(false), 10);
+
+ assert_eq!(switch_option(Some(())), true);
+ assert_eq!(switch_option(None), false);
+
+ assert_eq!(switch_option_repr(Bool::True), true);
+ assert_eq!(switch_option_repr(Bool::False), false);
+
+ let mut opt = Some(());
+ set_discr(&mut opt);
+ assert_eq!(opt, None);
+
+ let mut b = Bool::True;
+ set_discr_repr(&mut b);
+ assert!(matches!(b, Bool::False));
+}
diff --git a/tests/mir-opt/building/custom/enums.set_discr.built.after.mir b/tests/mir-opt/building/custom/enums.set_discr.built.after.mir
new file mode 100644
index 000000000..7de9ed098
--- /dev/null
+++ b/tests/mir-opt/building/custom/enums.set_discr.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `set_discr` after built
+
+fn set_discr(_1: &mut Option<()>) -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/enums.rs:+0:39: +0:39
+
+ bb0: {
+ discriminant((*_1)) = 0; // scope 0 at $DIR/enums.rs:+2:9: +2:36
+ return; // scope 0 at $DIR/enums.rs:+3:9: +3:17
+ }
+}
diff --git a/tests/mir-opt/building/custom/enums.set_discr_repr.built.after.mir b/tests/mir-opt/building/custom/enums.set_discr_repr.built.after.mir
new file mode 100644
index 000000000..6fdc3d0f4
--- /dev/null
+++ b/tests/mir-opt/building/custom/enums.set_discr_repr.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `set_discr_repr` after built
+
+fn set_discr_repr(_1: &mut Bool) -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/enums.rs:+0:33: +0:33
+
+ bb0: {
+ discriminant((*_1)) = 0; // scope 0 at $DIR/enums.rs:+2:9: +2:31
+ return; // scope 0 at $DIR/enums.rs:+3:9: +3:17
+ }
+}
diff --git a/tests/mir-opt/building/custom/enums.switch_bool.built.after.mir b/tests/mir-opt/building/custom/enums.switch_bool.built.after.mir
new file mode 100644
index 000000000..95c57d2dc
--- /dev/null
+++ b/tests/mir-opt/building/custom/enums.switch_bool.built.after.mir
@@ -0,0 +1,19 @@
+// MIR for `switch_bool` after built
+
+fn switch_bool(_1: bool) -> u32 {
+ let mut _0: u32; // return place in scope 0 at $DIR/enums.rs:+0:32: +0:35
+
+ bb0: {
+ switchInt(_1) -> [1: bb1, 0: bb2, otherwise: bb2]; // scope 0 at $DIR/enums.rs:+3:13: +7:14
+ }
+
+ bb1: {
+ _0 = const 5_u32; // scope 0 at $DIR/enums.rs:+11:13: +11:20
+ return; // scope 0 at $DIR/enums.rs:+12:13: +12:21
+ }
+
+ bb2: {
+ _0 = const 10_u32; // scope 0 at $DIR/enums.rs:+16:13: +16:21
+ return; // scope 0 at $DIR/enums.rs:+17:13: +17:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/enums.switch_option.built.after.mir b/tests/mir-opt/building/custom/enums.switch_option.built.after.mir
new file mode 100644
index 000000000..a659ba7c1
--- /dev/null
+++ b/tests/mir-opt/building/custom/enums.switch_option.built.after.mir
@@ -0,0 +1,21 @@
+// MIR for `switch_option` after built
+
+fn switch_option(_1: Option<()>) -> bool {
+ let mut _0: bool; // return place in scope 0 at $DIR/enums.rs:+0:45: +0:49
+ let mut _2: isize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ switchInt(_2) -> [0: bb1, 1: bb2, otherwise: bb2]; // scope 0 at $DIR/enums.rs:+4:13: +8:14
+ }
+
+ bb1: {
+ _0 = const false; // scope 0 at $DIR/enums.rs:+12:13: +12:24
+ return; // scope 0 at $DIR/enums.rs:+13:13: +13:21
+ }
+
+ bb2: {
+ _0 = const true; // scope 0 at $DIR/enums.rs:+17:13: +17:23
+ return; // scope 0 at $DIR/enums.rs:+18:13: +18:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/enums.switch_option_repr.built.after.mir b/tests/mir-opt/building/custom/enums.switch_option_repr.built.after.mir
new file mode 100644
index 000000000..d60e4b1b7
--- /dev/null
+++ b/tests/mir-opt/building/custom/enums.switch_option_repr.built.after.mir
@@ -0,0 +1,21 @@
+// MIR for `switch_option_repr` after built
+
+fn switch_option_repr(_1: Bool) -> bool {
+ let mut _0: bool; // return place in scope 0 at $DIR/enums.rs:+0:40: +0:44
+ let mut _2: u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ switchInt(_2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/enums.rs:+4:13: +7:14
+ }
+
+ bb1: {
+ _0 = const true; // scope 0 at $DIR/enums.rs:+11:13: +11:23
+ return; // scope 0 at $DIR/enums.rs:+12:13: +12:21
+ }
+
+ bb2: {
+ _0 = const false; // scope 0 at $DIR/enums.rs:+16:13: +16:24
+ return; // scope 0 at $DIR/enums.rs:+17:13: +17:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/projections.rs b/tests/mir-opt/building/custom/projections.rs
new file mode 100644
index 000000000..5e472e531
--- /dev/null
+++ b/tests/mir-opt/building/custom/projections.rs
@@ -0,0 +1,85 @@
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+
+union U {
+ a: i32,
+ b: u32,
+}
+
+// EMIT_MIR projections.unions.built.after.mir
+#[custom_mir(dialect = "built")]
+fn unions(u: U) -> i32 {
+ mir!({
+ RET = u.a;
+ Return()
+ })
+}
+
+// EMIT_MIR projections.tuples.built.after.mir
+#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
+fn tuples(i: (u32, i32)) -> (u32, i32) {
+ mir!(
+ // FIXME(JakobDegen): This is necessary because we can't give type hints for `RET`
+ let temp: (u32, i32);
+ {
+ temp.0 = i.0;
+ temp.1 = i.1;
+
+ RET = temp;
+ Return()
+ }
+ )
+}
+
+// EMIT_MIR projections.unwrap.built.after.mir
+#[custom_mir(dialect = "built")]
+fn unwrap(opt: Option<i32>) -> i32 {
+ mir!({
+ RET = Field(Variant(opt, 1), 0);
+ Return()
+ })
+}
+
+// EMIT_MIR projections.unwrap_deref.built.after.mir
+#[custom_mir(dialect = "built")]
+fn unwrap_deref(opt: Option<&i32>) -> i32 {
+ mir!({
+ RET = *Field::<&i32>(Variant(opt, 1), 0);
+ Return()
+ })
+}
+
+// EMIT_MIR projections.set.built.after.mir
+#[custom_mir(dialect = "built")]
+fn set(opt: &mut Option<i32>) {
+ mir!({
+ place!(Field(Variant(*opt, 1), 0)) = 10;
+ Return()
+ })
+}
+
+// EMIT_MIR projections.simple_index.built.after.mir
+#[custom_mir(dialect = "built")]
+fn simple_index(a: [i32; 10], b: &[i32]) -> i32 {
+ mir!({
+ let temp = 3;
+ RET = a[temp];
+ RET = (*b)[temp];
+ Return()
+ })
+}
+
+fn main() {
+ assert_eq!(unions(U { a: 5 }), 5);
+ assert_eq!(tuples((5, 6)), (5, 6));
+
+ assert_eq!(unwrap(Some(5)), 5);
+ assert_eq!(unwrap_deref(Some(&5)), 5);
+ let mut o = Some(5);
+ set(&mut o);
+ assert_eq!(o, Some(10));
+
+ assert_eq!(simple_index([0; 10], &[0; 10]), 0);
+}
diff --git a/tests/mir-opt/building/custom/projections.set.built.after.mir b/tests/mir-opt/building/custom/projections.set.built.after.mir
new file mode 100644
index 000000000..2f15176a6
--- /dev/null
+++ b/tests/mir-opt/building/custom/projections.set.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `set` after built
+
+fn set(_1: &mut Option<i32>) -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/projections.rs:+0:31: +0:31
+
+ bb0: {
+ (((*_1) as variant#1).0: i32) = const 10_i32; // scope 0 at $DIR/projections.rs:+2:9: +2:48
+ return; // scope 0 at $DIR/projections.rs:+3:9: +3:17
+ }
+}
diff --git a/tests/mir-opt/building/custom/projections.simple_index.built.after.mir b/tests/mir-opt/building/custom/projections.simple_index.built.after.mir
new file mode 100644
index 000000000..fc422e4b3
--- /dev/null
+++ b/tests/mir-opt/building/custom/projections.simple_index.built.after.mir
@@ -0,0 +1,13 @@
+// MIR for `simple_index` after built
+
+fn simple_index(_1: [i32; 10], _2: &[i32]) -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/projections.rs:+0:45: +0:48
+ let mut _3: usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _3 = const 3_usize; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _0 = _1[_3]; // scope 0 at $DIR/projections.rs:+3:9: +3:22
+ _0 = (*_2)[_3]; // scope 0 at $DIR/projections.rs:+4:9: +4:25
+ return; // scope 0 at $DIR/projections.rs:+5:9: +5:17
+ }
+}
diff --git a/tests/mir-opt/building/custom/projections.tuples.built.after.mir b/tests/mir-opt/building/custom/projections.tuples.built.after.mir
new file mode 100644
index 000000000..65487d3c9
--- /dev/null
+++ b/tests/mir-opt/building/custom/projections.tuples.built.after.mir
@@ -0,0 +1,13 @@
+// MIR for `tuples` after built
+
+fn tuples(_1: (u32, i32)) -> (u32, i32) {
+ let mut _0: (u32, i32); // return place in scope 0 at $DIR/projections.rs:+0:29: +0:39
+ let mut _2: (u32, i32); // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ (_2.0: u32) = (_1.0: u32); // scope 0 at $DIR/projections.rs:+5:13: +5:25
+ (_2.1: i32) = (_1.1: i32); // scope 0 at $DIR/projections.rs:+6:13: +6:25
+ _0 = _2; // scope 0 at $DIR/projections.rs:+8:13: +8:23
+ return; // scope 0 at $DIR/projections.rs:+9:13: +9:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/projections.unions.built.after.mir b/tests/mir-opt/building/custom/projections.unions.built.after.mir
new file mode 100644
index 000000000..922538a5f
--- /dev/null
+++ b/tests/mir-opt/building/custom/projections.unions.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `unions` after built
+
+fn unions(_1: U) -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/projections.rs:+0:20: +0:23
+
+ bb0: {
+ _0 = (_1.0: i32); // scope 0 at $DIR/projections.rs:+2:9: +2:18
+ return; // scope 0 at $DIR/projections.rs:+3:9: +3:17
+ }
+}
diff --git a/tests/mir-opt/building/custom/projections.unwrap.built.after.mir b/tests/mir-opt/building/custom/projections.unwrap.built.after.mir
new file mode 100644
index 000000000..75b03a3c3
--- /dev/null
+++ b/tests/mir-opt/building/custom/projections.unwrap.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `unwrap` after built
+
+fn unwrap(_1: Option<i32>) -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/projections.rs:+0:32: +0:35
+
+ bb0: {
+ _0 = ((_1 as variant#1).0: i32); // scope 0 at $DIR/projections.rs:+2:9: +2:40
+ return; // scope 0 at $DIR/projections.rs:+3:9: +3:17
+ }
+}
diff --git a/tests/mir-opt/building/custom/projections.unwrap_deref.built.after.mir b/tests/mir-opt/building/custom/projections.unwrap_deref.built.after.mir
new file mode 100644
index 000000000..c6b0f7efa
--- /dev/null
+++ b/tests/mir-opt/building/custom/projections.unwrap_deref.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `unwrap_deref` after built
+
+fn unwrap_deref(_1: Option<&i32>) -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/projections.rs:+0:39: +0:42
+
+ bb0: {
+ _0 = (*((_1 as variant#1).0: &i32)); // scope 0 at $DIR/projections.rs:+2:9: +2:49
+ return; // scope 0 at $DIR/projections.rs:+3:9: +3:17
+ }
+}
diff --git a/tests/mir-opt/building/custom/references.immut_ref.built.after.mir b/tests/mir-opt/building/custom/references.immut_ref.built.after.mir
new file mode 100644
index 000000000..f5ee11262
--- /dev/null
+++ b/tests/mir-opt/building/custom/references.immut_ref.built.after.mir
@@ -0,0 +1,13 @@
+// MIR for `immut_ref` after built
+
+fn immut_ref(_1: &i32) -> &i32 {
+ let mut _0: &i32; // return place in scope 0 at $DIR/references.rs:+0:30: +0:34
+ let mut _2: *const i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _2 = &raw const (*_1); // scope 0 at $DIR/references.rs:+5:13: +5:29
+ _0 = &(*_2); // scope 0 at $DIR/references.rs:+6:13: +6:23
+ Retag(_0); // scope 0 at $DIR/references.rs:+7:13: +7:23
+ return; // scope 0 at $DIR/references.rs:+8:13: +8:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/references.mut_ref.built.after.mir b/tests/mir-opt/building/custom/references.mut_ref.built.after.mir
new file mode 100644
index 000000000..8e2ffc33b
--- /dev/null
+++ b/tests/mir-opt/building/custom/references.mut_ref.built.after.mir
@@ -0,0 +1,13 @@
+// MIR for `mut_ref` after built
+
+fn mut_ref(_1: &mut i32) -> &mut i32 {
+ let mut _0: &mut i32; // return place in scope 0 at $DIR/references.rs:+0:32: +0:40
+ let mut _2: *mut i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _2 = &raw mut (*_1); // scope 0 at $DIR/references.rs:+5:13: +5:33
+ _0 = &mut (*_2); // scope 0 at $DIR/references.rs:+6:13: +6:26
+ Retag(_0); // scope 0 at $DIR/references.rs:+7:13: +7:23
+ return; // scope 0 at $DIR/references.rs:+8:13: +8:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/references.raw_pointer.built.after.mir b/tests/mir-opt/building/custom/references.raw_pointer.built.after.mir
new file mode 100644
index 000000000..775e5e3ad
--- /dev/null
+++ b/tests/mir-opt/building/custom/references.raw_pointer.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `raw_pointer` after built
+
+fn raw_pointer(_1: *const i32) -> *const i32 {
+ let mut _0: *const i32; // return place in scope 0 at $DIR/references.rs:+0:38: +0:48
+
+ bb0: {
+ _0 = &raw const (*_1); // scope 0 at $DIR/references.rs:+4:9: +4:27
+ return; // scope 0 at $DIR/references.rs:+5:9: +5:17
+ }
+}
diff --git a/tests/mir-opt/building/custom/references.rs b/tests/mir-opt/building/custom/references.rs
new file mode 100644
index 000000000..a1c896de0
--- /dev/null
+++ b/tests/mir-opt/building/custom/references.rs
@@ -0,0 +1,55 @@
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+use core::ptr::{addr_of, addr_of_mut};
+
+// EMIT_MIR references.mut_ref.built.after.mir
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+pub fn mut_ref(x: &mut i32) -> &mut i32 {
+ mir!(
+ let t: *mut i32;
+
+ {
+ t = addr_of_mut!(*x);
+ RET = &mut *t;
+ Retag(RET);
+ Return()
+ }
+ )
+}
+
+// EMIT_MIR references.immut_ref.built.after.mir
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+pub fn immut_ref(x: &i32) -> &i32 {
+ mir!(
+ let t: *const i32;
+
+ {
+ t = addr_of!(*x);
+ RET = & *t;
+ Retag(RET);
+ Return()
+ }
+ )
+}
+
+// EMIT_MIR references.raw_pointer.built.after.mir
+#[custom_mir(dialect = "built")]
+pub fn raw_pointer(x: *const i32) -> *const i32 {
+ // Regression test for a bug in which unsafetyck was not correctly turned off for
+ // `dialect = "built"`
+ mir!({
+ RET = addr_of!(*x);
+ Return()
+ })
+}
+
+fn main() {
+ let mut x = 5;
+ assert_eq!(*mut_ref(&mut x), 5);
+ assert_eq!(*immut_ref(&x), 5);
+ unsafe {
+ assert_eq!(*raw_pointer(addr_of!(x)), 5);
+ }
+}
diff --git a/tests/mir-opt/building/custom/simple_assign.rs b/tests/mir-opt/building/custom/simple_assign.rs
new file mode 100644
index 000000000..db041aab2
--- /dev/null
+++ b/tests/mir-opt/building/custom/simple_assign.rs
@@ -0,0 +1,39 @@
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+
+// EMIT_MIR simple_assign.simple.built.after.mir
+#[custom_mir(dialect = "built")]
+pub fn simple(x: i32) -> i32 {
+ mir!(
+ let temp1: i32;
+ let temp2: _;
+
+ {
+ StorageLive(temp1);
+ temp1 = x;
+ Goto(exit)
+ }
+
+ exit = {
+ temp2 = Move(temp1);
+ StorageDead(temp1);
+ RET = temp2;
+ Return()
+ }
+ )
+}
+
+// EMIT_MIR simple_assign.simple_ref.built.after.mir
+#[custom_mir(dialect = "built")]
+pub fn simple_ref(x: &mut i32) -> &mut i32 {
+ mir!({
+ RET = Move(x);
+ Return()
+ })
+}
+
+fn main() {
+ assert_eq!(5, simple(5));
+}
diff --git a/tests/mir-opt/building/custom/simple_assign.simple.built.after.mir b/tests/mir-opt/building/custom/simple_assign.simple.built.after.mir
new file mode 100644
index 000000000..743016708
--- /dev/null
+++ b/tests/mir-opt/building/custom/simple_assign.simple.built.after.mir
@@ -0,0 +1,20 @@
+// MIR for `simple` after built
+
+fn simple(_1: i32) -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/simple_assign.rs:+0:26: +0:29
+ let mut _2: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/simple_assign.rs:+6:13: +6:31
+ _2 = _1; // scope 0 at $DIR/simple_assign.rs:+7:13: +7:22
+ goto -> bb1; // scope 0 at $DIR/simple_assign.rs:+8:13: +8:23
+ }
+
+ bb1: {
+ _3 = move _2; // scope 0 at $DIR/simple_assign.rs:+12:13: +12:32
+ StorageDead(_2); // scope 0 at $DIR/simple_assign.rs:+13:13: +13:31
+ _0 = _3; // scope 0 at $DIR/simple_assign.rs:+14:13: +14:24
+ return; // scope 0 at $DIR/simple_assign.rs:+15:13: +15:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir b/tests/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir
new file mode 100644
index 000000000..2b0e8f104
--- /dev/null
+++ b/tests/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `simple_ref` after built
+
+fn simple_ref(_1: &mut i32) -> &mut i32 {
+ let mut _0: &mut i32; // return place in scope 0 at $DIR/simple_assign.rs:+0:35: +0:43
+
+ bb0: {
+ _0 = move _1; // scope 0 at $DIR/simple_assign.rs:+2:9: +2:22
+ return; // scope 0 at $DIR/simple_assign.rs:+3:9: +3:17
+ }
+}
diff --git a/tests/mir-opt/building/custom/terminators.assert_nonzero.built.after.mir b/tests/mir-opt/building/custom/terminators.assert_nonzero.built.after.mir
new file mode 100644
index 000000000..a1a27226b
--- /dev/null
+++ b/tests/mir-opt/building/custom/terminators.assert_nonzero.built.after.mir
@@ -0,0 +1,17 @@
+// MIR for `assert_nonzero` after built
+
+fn assert_nonzero(_1: i32) -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/terminators.rs:+0:27: +0:27
+
+ bb0: {
+ switchInt(_1) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/terminators.rs:+3:13: +6:14
+ }
+
+ bb1: {
+ unreachable; // scope 0 at $DIR/terminators.rs:+10:13: +10:26
+ }
+
+ bb2: {
+ return; // scope 0 at $DIR/terminators.rs:+14:13: +14:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/terminators.direct_call.built.after.mir b/tests/mir-opt/building/custom/terminators.direct_call.built.after.mir
new file mode 100644
index 000000000..1b2345a96
--- /dev/null
+++ b/tests/mir-opt/building/custom/terminators.direct_call.built.after.mir
@@ -0,0 +1,16 @@
+// MIR for `direct_call` after built
+
+fn direct_call(_1: i32) -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/terminators.rs:+0:27: +0:30
+
+ bb0: {
+ _0 = ident::<i32>(_1) -> bb1; // scope 0 at $DIR/terminators.rs:+3:13: +3:42
+ // mir::Constant
+ // + span: $DIR/terminators.rs:15:33: 15:38
+ // + literal: Const { ty: fn(i32) -> i32 {ident::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ return; // scope 0 at $DIR/terminators.rs:+7:13: +7:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/terminators.drop_first.built.after.mir b/tests/mir-opt/building/custom/terminators.drop_first.built.after.mir
new file mode 100644
index 000000000..c903e5946
--- /dev/null
+++ b/tests/mir-opt/building/custom/terminators.drop_first.built.after.mir
@@ -0,0 +1,13 @@
+// MIR for `drop_first` after built
+
+fn drop_first(_1: WriteOnDrop<'_>, _2: WriteOnDrop<'_>) -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/terminators.rs:+0:59: +0:59
+
+ bb0: {
+ replace(_1 <- move _2) -> bb1; // scope 0 at $DIR/terminators.rs:+3:13: +3:49
+ }
+
+ bb1: {
+ return; // scope 0 at $DIR/terminators.rs:+7:13: +7:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/terminators.drop_second.built.after.mir b/tests/mir-opt/building/custom/terminators.drop_second.built.after.mir
new file mode 100644
index 000000000..f14246f2d
--- /dev/null
+++ b/tests/mir-opt/building/custom/terminators.drop_second.built.after.mir
@@ -0,0 +1,13 @@
+// MIR for `drop_second` after built
+
+fn drop_second(_1: WriteOnDrop<'_>, _2: WriteOnDrop<'_>) -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/terminators.rs:+0:60: +0:60
+
+ bb0: {
+ drop(_2) -> bb1; // scope 0 at $DIR/terminators.rs:+3:13: +3:30
+ }
+
+ bb1: {
+ return; // scope 0 at $DIR/terminators.rs:+7:13: +7:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/terminators.indirect_call.built.after.mir b/tests/mir-opt/building/custom/terminators.indirect_call.built.after.mir
new file mode 100644
index 000000000..2f1b14069
--- /dev/null
+++ b/tests/mir-opt/building/custom/terminators.indirect_call.built.after.mir
@@ -0,0 +1,13 @@
+// MIR for `indirect_call` after built
+
+fn indirect_call(_1: i32, _2: fn(i32) -> i32) -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/terminators.rs:+0:48: +0:51
+
+ bb0: {
+ _0 = _2(_1) -> bb1; // scope 0 at $DIR/terminators.rs:+3:13: +3:38
+ }
+
+ bb1: {
+ return; // scope 0 at $DIR/terminators.rs:+7:13: +7:21
+ }
+}
diff --git a/tests/mir-opt/building/custom/terminators.rs b/tests/mir-opt/building/custom/terminators.rs
new file mode 100644
index 000000000..c23233fcf
--- /dev/null
+++ b/tests/mir-opt/building/custom/terminators.rs
@@ -0,0 +1,108 @@
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+
+fn ident<T>(t: T) -> T {
+ t
+}
+
+// EMIT_MIR terminators.direct_call.built.after.mir
+#[custom_mir(dialect = "built")]
+fn direct_call(x: i32) -> i32 {
+ mir!(
+ {
+ Call(RET, retblock, ident(x))
+ }
+
+ retblock = {
+ Return()
+ }
+ )
+}
+
+// EMIT_MIR terminators.indirect_call.built.after.mir
+#[custom_mir(dialect = "built")]
+fn indirect_call(x: i32, f: fn(i32) -> i32) -> i32 {
+ mir!(
+ {
+ Call(RET, retblock, f(x))
+ }
+
+ retblock = {
+ Return()
+ }
+ )
+}
+
+struct WriteOnDrop<'a>(&'a mut i32, i32);
+
+impl<'a> Drop for WriteOnDrop<'a> {
+ fn drop(&mut self) {
+ *self.0 = self.1;
+ }
+}
+
+// EMIT_MIR terminators.drop_first.built.after.mir
+#[custom_mir(dialect = "built")]
+fn drop_first<'a>(a: WriteOnDrop<'a>, b: WriteOnDrop<'a>) {
+ mir!(
+ {
+ DropAndReplace(a, Move(b), retblock)
+ }
+
+ retblock = {
+ Return()
+ }
+ )
+}
+
+// EMIT_MIR terminators.drop_second.built.after.mir
+#[custom_mir(dialect = "built")]
+fn drop_second<'a>(a: WriteOnDrop<'a>, b: WriteOnDrop<'a>) {
+ mir!(
+ {
+ Drop(b, retblock)
+ }
+
+ retblock = {
+ Return()
+ }
+ )
+}
+
+// EMIT_MIR terminators.assert_nonzero.built.after.mir
+#[custom_mir(dialect = "built")]
+fn assert_nonzero(a: i32) {
+ mir!(
+ {
+ match a {
+ 0 => unreachable,
+ _ => retblock
+ }
+ }
+
+ unreachable = {
+ Unreachable()
+ }
+
+ retblock = {
+ Return()
+ }
+ )
+}
+
+fn main() {
+ assert_eq!(direct_call(5), 5);
+ assert_eq!(indirect_call(5, ident), 5);
+
+ let mut a = 0;
+ let mut b = 0;
+ drop_first(WriteOnDrop(&mut a, 1), WriteOnDrop(&mut b, 1));
+ assert_eq!((a, b), (1, 0));
+
+ let mut a = 0;
+ let mut b = 0;
+ drop_second(WriteOnDrop(&mut a, 1), WriteOnDrop(&mut b, 1));
+ assert_eq!((a, b), (0, 1));
+}
diff --git a/tests/mir-opt/building/enum_cast.bar.built.after.mir b/tests/mir-opt/building/enum_cast.bar.built.after.mir
new file mode 100644
index 000000000..0746e0b49
--- /dev/null
+++ b/tests/mir-opt/building/enum_cast.bar.built.after.mir
@@ -0,0 +1,23 @@
+// MIR for `bar` after built
+
+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 _2: Bar; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let mut _3: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let mut _4: bool; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ let mut _5: bool; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _4 = Ge(const 1_isize, _3); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ assume(_4); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _5 = Le(const 0_isize, _3); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ assume(_5); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
+ return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
+ }
+}
diff --git a/tests/mir-opt/building/enum_cast.boo.built.after.mir b/tests/mir-opt/building/enum_cast.boo.built.after.mir
new file mode 100644
index 000000000..699c876b0
--- /dev/null
+++ b/tests/mir-opt/building/enum_cast.boo.built.after.mir
@@ -0,0 +1,23 @@
+// MIR for `boo` after built
+
+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 _2: Boo; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let mut _3: u8; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let mut _4: bool; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ let mut _5: bool; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _4 = Ge(const 1_u8, _3); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ assume(_4); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _5 = Le(const 0_u8, _3); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ assume(_5); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
+ return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
+ }
+}
diff --git a/tests/mir-opt/building/enum_cast.droppy.built.after.mir b/tests/mir-opt/building/enum_cast.droppy.built.after.mir
new file mode 100644
index 000000000..5231c2eab
--- /dev/null
+++ b/tests/mir-opt/building/enum_cast.droppy.built.after.mir
@@ -0,0 +1,72 @@
+// MIR for `droppy` after built
+
+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 _4: Droppy; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
+ let mut _5: isize; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
+ let mut _6: bool; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:27
+ let mut _7: bool; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:27
+ let _8: 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 => _8; // 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
+ StorageLive(_4); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18
+ _4 = move _2; // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18
+ _5 = discriminant(_4); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ _6 = Ge(const 2_isize, _5); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ assume(_6); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ _7 = Le(const 0_isize, _5); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ assume(_7); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ _3 = move _5 as usize (IntToInt); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ drop(_4) -> [return: bb1, unwind: bb4]; // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27
+ }
+
+ bb1: {
+ StorageDead(_4); // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27
+ FakeRead(ForLet(None), _3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14
+ _1 = const (); // scope 0 at $DIR/enum_cast.rs:+1:5: +6:6
+ StorageDead(_3); // scope 1 at $DIR/enum_cast.rs:+6:5: +6:6
+ drop(_2) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+ }
+
+ bb2: {
+ StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+ StorageDead(_1); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+ StorageLive(_8); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+ _8 = Droppy::B; // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22
+ FakeRead(ForLet(None), _8); // 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(_8) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
+ }
+
+ bb3: {
+ StorageDead(_8); // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/enum_cast.rs:+8:2: +8:2
+ }
+
+ bb4 (cleanup): {
+ drop(_2) -> bb5; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+ }
+
+ bb5 (cleanup): {
+ resume; // scope 0 at $DIR/enum_cast.rs:+0:1: +8:2
+ }
+}
diff --git a/tests/mir-opt/building/enum_cast.foo.built.after.mir b/tests/mir-opt/building/enum_cast.foo.built.after.mir
new file mode 100644
index 000000000..17e0abf2e
--- /dev/null
+++ b/tests/mir-opt/building/enum_cast.foo.built.after.mir
@@ -0,0 +1,17 @@
+// MIR for `foo` after built
+
+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 _2: Foo; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let mut _3: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
+ return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
+ }
+}
diff --git a/tests/mir-opt/building/enum_cast.rs b/tests/mir-opt/building/enum_cast.rs
new file mode 100644
index 000000000..98fd5acfb
--- /dev/null
+++ b/tests/mir-opt/building/enum_cast.rs
@@ -0,0 +1,50 @@
+// EMIT_MIR enum_cast.foo.built.after.mir
+// EMIT_MIR enum_cast.bar.built.after.mir
+// EMIT_MIR enum_cast.boo.built.after.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.built.after.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/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir
new file mode 100644
index 000000000..628a33f10
--- /dev/null
+++ b/tests/mir-opt/building/issue_101867.main.built.after.mir
@@ -0,0 +1,75 @@
+// MIR for `main` after built
+
+| User Type Annotations
+| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<u8>) }, span: $DIR/issue_101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8>
+| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<u8>) }, span: $DIR/issue_101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8>
+|
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue_101867.rs:+0:11: +0:11
+ let _1: std::option::Option<u8> as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue_101867.rs:+1:9: +1:10
+ let mut _2: !; // in scope 0 at $DIR/issue_101867.rs:+2:26: +4:6
+ let _3: (); // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+ let mut _4: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+ let mut _6: isize; // in scope 0 at $DIR/issue_101867.rs:+2:9: +2:16
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/issue_101867.rs:+1:9: +1:10
+ let _5: u8; // in scope 1 at $DIR/issue_101867.rs:+2:14: +2:15
+ scope 2 {
+ debug y => _5; // in scope 2 at $DIR/issue_101867.rs:+2:14: +2:15
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue_101867.rs:+1:9: +1:10
+ _1 = Option::<u8>::Some(const 1_u8); // scope 0 at $DIR/issue_101867.rs:+1:25: +1:32
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue_101867.rs:+1:9: +1:10
+ AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue_101867.rs:+1:12: +1:22
+ StorageLive(_5); // scope 1 at $DIR/issue_101867.rs:+2:14: +2:15
+ FakeRead(ForMatchedPlace(None), _1); // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20
+ _6 = discriminant(_1); // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20
+ switchInt(move _6) -> [1: bb4, otherwise: bb3]; // scope 1 at $DIR/issue_101867.rs:+2:9: +2:16
+ }
+
+ bb1: {
+ StorageLive(_3); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
+ StorageLive(_4); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
+ _4 = begin_panic::<&str>(const "explicit panic") -> bb7; // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
+ // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ }
+
+ bb2: {
+ StorageDead(_4); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
+ StorageDead(_3); // scope 1 at $DIR/issue_101867.rs:+3:16: +3:17
+ unreachable; // scope 1 at $DIR/issue_101867.rs:+2:26: +4:6
+ }
+
+ bb3: {
+ goto -> bb6; // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20
+ }
+
+ bb4: {
+ falseEdge -> [real: bb5, imaginary: bb3]; // scope 1 at $DIR/issue_101867.rs:+2:9: +2:16
+ }
+
+ bb5: {
+ _5 = ((_1 as Some).0: u8); // scope 1 at $DIR/issue_101867.rs:+2:14: +2:15
+ _0 = const (); // scope 0 at $DIR/issue_101867.rs:+0:11: +5:2
+ StorageDead(_5); // scope 1 at $DIR/issue_101867.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/issue_101867.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/issue_101867.rs:+5:2: +5:2
+ }
+
+ bb6: {
+ StorageDead(_5); // scope 1 at $DIR/issue_101867.rs:+5:1: +5:2
+ goto -> bb1; // scope 0 at $DIR/issue_101867.rs:+0:11: +5:2
+ }
+
+ bb7 (cleanup): {
+ resume; // scope 0 at $DIR/issue_101867.rs:+0:1: +5:2
+ }
+}
diff --git a/tests/mir-opt/building/issue_101867.rs b/tests/mir-opt/building/issue_101867.rs
new file mode 100644
index 000000000..a32d8cb37
--- /dev/null
+++ b/tests/mir-opt/building/issue_101867.rs
@@ -0,0 +1,7 @@
+// EMIT_MIR issue_101867.main.built.after.mir
+fn main() {
+ let x: Option<u8> = Some(1);
+ let Some(y) = x else {
+ panic!();
+ };
+}
diff --git a/tests/mir-opt/building/issue_49232.main.built.after.mir b/tests/mir-opt/building/issue_49232.main.built.after.mir
new file mode 100644
index 000000000..de5e4c0f6
--- /dev/null
+++ b/tests/mir-opt/building/issue_49232.main.built.after.mir
@@ -0,0 +1,82 @@
+// MIR for `main` after built
+
+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) -> [0: 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/tests/mir-opt/building/issue_49232.rs b/tests/mir-opt/building/issue_49232.rs
new file mode 100644
index 000000000..7e9f0de81
--- /dev/null
+++ b/tests/mir-opt/building/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.built.after.mir
+fn main() {
+ loop {
+ let beacon = {
+ match true {
+ false => 4,
+ true => break,
+ }
+ };
+ drop(&beacon);
+ }
+}
diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir b/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir
new file mode 100644
index 000000000..cb36bc64d
--- /dev/null
+++ b/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir
@@ -0,0 +1,112 @@
+// MIR for `full_tested_match` after built
+
+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
+ 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: bb1, 1: 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 -> bb11; // 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: bb10, 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
+ _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: bb12]; // 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) -> [0: 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 -> bb11; // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+ }
+
+ bb8: {
+ goto -> bb9; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ }
+
+ bb9: {
+ 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
+ }
+
+ bb10: {
+ 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 -> bb11; // scope 0 at $DIR/match_false_edges.rs:+3:25: +3:26
+ }
+
+ bb11: {
+ 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
+ }
+
+ bb12 (cleanup): {
+ resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +6:2
+ }
+}
diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir b/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir
new file mode 100644
index 000000000..7f8755faa
--- /dev/null
+++ b/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir
@@ -0,0 +1,112 @@
+// MIR for `full_tested_match2` after built
+
+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: bb1, 1: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:27
+ }
+
+ bb1: {
+ falseEdge -> [real: bb10, 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 -> bb11; // 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: bb12]; // 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) -> [0: 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 -> bb11; // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+ }
+
+ bb8: {
+ goto -> bb9; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ }
+
+ bb9: {
+ 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
+ }
+
+ bb10: {
+ _1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23
+ goto -> bb11; // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23
+ }
+
+ bb11: {
+ 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
+ }
+
+ bb12 (cleanup): {
+ resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +6:2
+ }
+}
diff --git a/tests/mir-opt/building/match_false_edges.main.built.after.mir b/tests/mir-opt/building/match_false_edges.main.built.after.mir
new file mode 100644
index 000000000..e8b93f437
--- /dev/null
+++ b/tests/mir-opt/building/match_false_edges.main.built.after.mir
@@ -0,0 +1,174 @@
+// MIR for `main` after built
+
+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: bb2, otherwise: bb1]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26
+ }
+
+ bb1: {
+ falseEdge -> [real: bb13, imaginary: bb6]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
+ }
+
+ bb2: {
+ falseEdge -> [real: bb8, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:9: +2:17
+ }
+
+ bb3: {
+ goto -> bb1; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26
+ }
+
+ bb4: {
+ _3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
+ switchInt(move _3) -> [1: bb6, otherwise: bb5]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26
+ }
+
+ bb5: {
+ 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 -> bb19; // scope 0 at $DIR/match_false_edges.rs:+5:15: +5:16
+ }
+
+ bb6: {
+ falseEdge -> [real: bb14, imaginary: bb5]; // scope 0 at $DIR/match_false_edges.rs:+4:9: +4:16
+ }
+
+ bb7: {
+ goto -> bb5; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26
+ }
+
+ bb8: {
+ 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: bb9, unwind: bb20]; // 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>) }
+ }
+
+ bb9: {
+ switchInt(move _8) -> [0: bb11, otherwise: bb10]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+ }
+
+ bb10: {
+ 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 -> bb19; // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
+ }
+
+ bb11: {
+ goto -> bb12; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+ }
+
+ bb12: {
+ 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: bb3, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+ }
+
+ bb13: {
+ 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 -> bb19; // scope 0 at $DIR/match_false_edges.rs:+3:15: +3:16
+ }
+
+ bb14: {
+ 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: bb15, unwind: bb20]; // 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>) }
+ }
+
+ bb15: {
+ switchInt(move _12) -> [0: bb17, otherwise: bb16]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+ }
+
+ bb16: {
+ 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 -> bb19; // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
+ }
+
+ bb17: {
+ goto -> bb18; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+ }
+
+ bb18: {
+ 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: bb7, imaginary: bb5]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+ }
+
+ bb19: {
+ 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
+ }
+
+ bb20 (cleanup): {
+ resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +7:2
+ }
+}
diff --git a/tests/mir-opt/building/match_false_edges.rs b/tests/mir-opt/building/match_false_edges.rs
new file mode 100644
index 000000000..ddfcc1493
--- /dev/null
+++ b/tests/mir-opt/building/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.built.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.built.after.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.built.after.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/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir
new file mode 100644
index 000000000..41eb00363
--- /dev/null
+++ b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir
@@ -0,0 +1,96 @@
+// MIR for `main` after built
+
+| 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/tests/mir-opt/building/receiver_ptr_mutability.rs b/tests/mir-opt/building/receiver_ptr_mutability.rs
new file mode 100644
index 000000000..668530968
--- /dev/null
+++ b/tests/mir-opt/building/receiver_ptr_mutability.rs
@@ -0,0 +1,20 @@
+// EMIT_MIR receiver_ptr_mutability.main.built.after.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/tests/mir-opt/building/simple_match.match_bool.built.after.mir b/tests/mir-opt/building/simple_match.match_bool.built.after.mir
new file mode 100644
index 000000000..aa2fd4632
--- /dev/null
+++ b/tests/mir-opt/building/simple_match.match_bool.built.after.mir
@@ -0,0 +1,29 @@
+// MIR for `match_bool` after built
+
+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) -> [0: 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/tests/mir-opt/building/simple_match.rs b/tests/mir-opt/building/simple_match.rs
new file mode 100644
index 000000000..0ef97dde6
--- /dev/null
+++ b/tests/mir-opt/building/simple_match.rs
@@ -0,0 +1,12 @@
+// Test that we don't generate unnecessarily large MIR for very simple matches
+
+
+// EMIT_MIR simple_match.match_bool.built.after.mir
+fn match_bool(x: bool) -> usize {
+ match x {
+ true => 10,
+ _ => 20,
+ }
+}
+
+fn main() {}
diff --git a/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir b/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir
new file mode 100644
index 000000000..1d3f77e07
--- /dev/null
+++ b/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir
@@ -0,0 +1,203 @@
+// MIR for `XXX` after built
+
+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: +18:3
+ }
+}
diff --git a/tests/mir-opt/building/storage_live_dead_in_statics.rs b/tests/mir-opt/building/storage_live_dead_in_statics.rs
new file mode 100644
index 000000000..79f709148
--- /dev/null
+++ b/tests/mir-opt/building/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.built.after.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/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
new file mode 100644
index 000000000..234cd0839
--- /dev/null
+++ b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
@@ -0,0 +1,111 @@
+// MIR for `move_out_by_subslice` after built
+
+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:12
+ scope 4 {
+ debug _y => _12; // in scope 4 at $DIR/uniform_array_move_out.rs:+2:10: +2:12
+ }
+ }
+ 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:12
+ _12 = move _1[0..2]; // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:12
+ _0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:+0:27: +3:2
+ drop(_12) -> [return: bb7, unwind: bb9]; // scope 1 at $DIR/uniform_array_move_out.rs:+3:1: +3:2
+ }
+
+ 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/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
new file mode 100644
index 000000000..24a189498
--- /dev/null
+++ b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
@@ -0,0 +1,111 @@
+// MIR for `move_out_from_end` after built
+
+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/tests/mir-opt/building/uniform_array_move_out.rs b/tests/mir-opt/building/uniform_array_move_out.rs
new file mode 100644
index 000000000..e925036ec
--- /dev/null
+++ b/tests/mir-opt/building/uniform_array_move_out.rs
@@ -0,0 +1,18 @@
+#![feature(box_syntax)]
+
+// EMIT_MIR uniform_array_move_out.move_out_from_end.built.after.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.built.after.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/tests/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..73f5655a1
--- /dev/null
+++ b/tests/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/tests/mir-opt/byte_slice.rs b/tests/mir-opt/byte_slice.rs
new file mode 100644
index 000000000..48e9c48c1
--- /dev/null
+++ b/tests/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/tests/mir-opt/combine_array_len.norm2.InstCombine.diff b/tests/mir-opt/combine_array_len.norm2.InstCombine.diff
new file mode 100644
index 000000000..c73150f94
--- /dev/null
+++ b/tests/mir-opt/combine_array_len.norm2.InstCombine.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/tests/mir-opt/combine_array_len.rs b/tests/mir-opt/combine_array_len.rs
new file mode 100644
index 000000000..3ef3bd09a
--- /dev/null
+++ b/tests/mir-opt/combine_array_len.rs
@@ -0,0 +1,12 @@
+// unit-test: InstCombine
+// 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/tests/mir-opt/combine_clone_of_primitives.rs b/tests/mir-opt/combine_clone_of_primitives.rs
new file mode 100644
index 000000000..7cc50a86e
--- /dev/null
+++ b/tests/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/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff b/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff
new file mode 100644
index 000000000..6f01553ee
--- /dev/null
+++ b/tests/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:8:5: 8:9
+ let mut _3: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ let _4: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ let mut _5: u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ let mut _6: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ let _7: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ let mut _8: [f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+ let mut _9: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+ let _10: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ StorageLive(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ StorageLive(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ _4 = &((*_1).0: T); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+- _3 = &(*_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
++ _3 = _4; // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ _2 = <T as Clone>::clone(move _3) -> bb1; // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ // mir::Constant
+ // + span: $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ // + literal: Const { ty: for<'a> fn(&'a T) -> T {<T as Clone>::clone}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:8: 8:9
+ StorageLive(_5); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ StorageLive(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ StorageLive(_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ _7 = &((*_1).1: u64); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+- _6 = &(*_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+- _5 = <u64 as Clone>::clone(move _6) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+- // mir::Constant
+- // + span: $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+- // + literal: Const { ty: for<'a> fn(&'a u64) -> u64 {<u64 as Clone>::clone}, val: Value(<ZST>) }
++ _6 = _7; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
++ _5 = (*_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
++ goto -> bb2; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ }
+
+ bb2: {
+ StorageDead(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:10: 9:11
+ StorageLive(_8); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+ StorageLive(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+ StorageLive(_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+ _10 = &((*_1).2: [f32; 3]); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+- _9 = &(*_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+- _8 = <[f32; 3] as Clone>::clone(move _9) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+- // mir::Constant
+- // + span: $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+- // + literal: Const { ty: for<'a> fn(&'a [f32; 3]) -> [f32; 3] {<[f32; 3] as Clone>::clone}, val: Value(<ZST>) }
++ _9 = _10; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
++ _8 = (*_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
++ goto -> bb3; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+ }
+
+ bb3: {
+ StorageDead(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:15: 10:16
+ Deinit(_0); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
+ (_0.0: T) = move _2; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
+ (_0.1: u64) = move _5; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
+ (_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/tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir b/tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir
new file mode 100644
index 000000000..6140fc52f
--- /dev/null
+++ b/tests/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:9:5: 9: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
+ _0 = const (); // 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/tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir b/tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir
new file mode 100644
index 000000000..b2ed23c68
--- /dev/null
+++ b/tests/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:9:5: 9: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
+ _0 = const (); // 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/tests/mir-opt/const_allocation.rs b/tests/mir-opt/const_allocation.rs
new file mode 100644
index 000000000..91a2455eb
--- /dev/null
+++ b/tests/mir-opt/const_allocation.rs
@@ -0,0 +1,10 @@
+// unit-test: ConstProp
+// 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/tests/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir b/tests/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir
new file mode 100644
index 000000000..aab005c52
--- /dev/null
+++ b/tests/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:6:5: 6: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
+ _0 = const (); // 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/tests/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir b/tests/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir
new file mode 100644
index 000000000..0eff9474c
--- /dev/null
+++ b/tests/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:6:5: 6: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
+ _0 = const (); // 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/tests/mir-opt/const_allocation2.rs b/tests/mir-opt/const_allocation2.rs
new file mode 100644
index 000000000..f2870aa47
--- /dev/null
+++ b/tests/mir-opt/const_allocation2.rs
@@ -0,0 +1,12 @@
+// unit-test: ConstProp
+// 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/tests/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir b/tests/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir
new file mode 100644
index 000000000..55c6db5d0
--- /dev/null
+++ b/tests/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:6:5: 6: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
+ _0 = const (); // 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/tests/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir b/tests/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir
new file mode 100644
index 000000000..27492a7fd
--- /dev/null
+++ b/tests/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:6:5: 6: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
+ _0 = const (); // 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/tests/mir-opt/const_allocation3.rs b/tests/mir-opt/const_allocation3.rs
new file mode 100644
index 000000000..da3fd089b
--- /dev/null
+++ b/tests/mir-opt/const_allocation3.rs
@@ -0,0 +1,30 @@
+// unit-test: ConstProp
+// 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/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
new file mode 100644
index 000000000..dd548adde
--- /dev/null
+++ b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
@@ -0,0 +1,126 @@
+- // 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 _12: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16
+ let mut _13: 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 _14: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ let _15: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ let _16: u32; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ scope 6 {
+ debug f => (bool, bool, u32){ .0 => _14, .1 => _15, .2 => _16, }; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ let _10: std::option::Option<u16>; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10
+ scope 7 {
+ debug o => _10; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10
+ let _17: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ let _18: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ scope 8 {
+ debug p => Point{ .0 => _17, .1 => _18, }; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ let _11: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10
+ scope 9 {
+- debug a => _11; // 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(_14); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ StorageLive(_15); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ StorageLive(_16); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ Deinit(_14); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ Deinit(_15); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ Deinit(_16); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ _14 = const true; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ _15 = const false; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ _16 = const 123_u32; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ StorageLive(_10); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10
+ Deinit(_10); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
+ ((_10 as Some).0: u16) = const 99_u16; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
+ discriminant(_10) = 1; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
+ StorageLive(_17); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ StorageLive(_18); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ Deinit(_17); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+ Deinit(_18); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+ _17 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+ _18 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+ StorageLive(_11); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10
+ StorageLive(_12); // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16
+ _12 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16
+ StorageLive(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22
+ _13 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22
+ _11 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22
+ StorageDead(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22
+ StorageDead(_12); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22
+ StorageDead(_11); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_17); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_18); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_10); // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_14); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_15); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_16); // 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/tests/mir-opt/const_debuginfo.rs b/tests/mir-opt/const_debuginfo.rs
new file mode 100644
index 000000000..a188da385
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff b/tests/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff
new file mode 100644
index 000000000..a717d1bbd
--- /dev/null
+++ b/tests/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: bb2, 2: 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: bb2, 2: 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) -> [0: 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/tests/mir-opt/const_goto.rs b/tests/mir-opt/const_goto.rs
new file mode 100644
index 000000000..6f84f186b
--- /dev/null
+++ b/tests/mir-opt/const_goto.rs
@@ -0,0 +1,18 @@
+// unit-test: ConstGoto
+
+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/tests/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff b/tests/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff
new file mode 100644
index 000000000..24be8c9b8
--- /dev/null
+++ b/tests/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: bb2, 2: bb2, 3: 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) -> [0: bb4, otherwise: bb3]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:5: +6:6
+ }
+
+ bb3: {
+- switchInt(_1) -> [0: 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/tests/mir-opt/const_goto_const_eval_fail.rs b/tests/mir-opt/const_goto_const_eval_fail.rs
new file mode 100644
index 000000000..3b85fe6ab
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff b/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff
new file mode 100644
index 000000000..f54577259
--- /dev/null
+++ b/tests/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
+- Deinit(_2); // scope 0 at $DIR/const_goto_storage.rs:+1:21: +1:23
+- StorageLive(_3); // scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10
+- StorageLive(_4); // scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76
+- StorageLive(_5); // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52
+- 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) -> [0: 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) -> [0: 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) -> [0: 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) -> [0: 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) -> [0: 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/tests/mir-opt/const_goto_storage.rs b/tests/mir-opt/const_goto_storage.rs
new file mode 100644
index 000000000..459599c73
--- /dev/null
+++ b/tests/mir-opt/const_goto_storage.rs
@@ -0,0 +1,21 @@
+// unit-test: ConstGoto
+
+// 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/tests/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..028480bdc
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
new file mode 100644
index 000000000..2ef437811
--- /dev/null
+++ b/tests/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 _; // 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<'a> fn(&'a [&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:45
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:45
+ }
+- }
+-
+- alloc1 (static: Y, size: 4, align: 4) {
+- 2a 00 00 00 │ *...
+ }
+
diff --git a/tests/mir-opt/const_promotion_extern_static.BOP.built.after.mir b/tests/mir-opt/const_promotion_extern_static.BOP.built.after.mir
new file mode 100644
index 000000000..476fc49a1
--- /dev/null
+++ b/tests/mir-opt/const_promotion_extern_static.BOP.built.after.mir
@@ -0,0 +1,17 @@
+// MIR for `BOP` after built
+
+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:24
+ }
+}
diff --git a/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..41657b53f
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
new file mode 100644
index 000000000..25ba0face
--- /dev/null
+++ b/tests/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 _; // 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<'a> fn(&'a [&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:56
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:56
+ }
+ }
+-
+- alloc3 (extern static: X)
+
diff --git a/tests/mir-opt/const_promotion_extern_static.rs b/tests/mir-opt/const_promotion_extern_static.rs
new file mode 100644
index 000000000..e4261cfe5
--- /dev/null
+++ b/tests/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.built.after.mir
+static BOP: &i32 = &13;
+
+fn main() {}
diff --git a/tests/mir-opt/const_prop/aggregate.main.ConstProp.diff b/tests/mir-opt/const_prop/aggregate.main.ConstProp.diff
new file mode 100644
index 000000000..04378dbf3
--- /dev/null
+++ b/tests/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
+ _0 = const (); // scope 0 at $DIR/aggregate.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/aggregate.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/aggregate.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.mir b/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.mir
new file mode 100644
index 000000000..cfc9a72e3
--- /dev/null
+++ b/tests/mir-opt/const_prop/aggregate.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/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 = 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
+ _0 = const (); // scope 0 at $DIR/aggregate.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/aggregate.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/aggregate.rs:+2:2: +2:2
+ }
+}
diff --git a/tests/mir-opt/const_prop/aggregate.rs b/tests/mir-opt/const_prop/aggregate.rs
new file mode 100644
index 000000000..6a3080384
--- /dev/null
+++ b/tests/mir-opt/const_prop/aggregate.rs
@@ -0,0 +1,8 @@
+// unit-test: ConstProp
+// compile-flags: -O
+
+// EMIT_MIR aggregate.main.ConstProp.diff
+// EMIT_MIR aggregate.main.PreCodegen.after.mir
+fn main() {
+ let x = (0, 1, 2).1 + 0;
+}
diff --git a/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..439b2a3e1
--- /dev/null
+++ b/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff
@@ -0,0 +1,39 @@
+- // 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 = Len(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _5 = const true; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> 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
+ _0 = const (); // scope 0 at $DIR/array_index.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/array_index.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/array_index.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..439b2a3e1
--- /dev/null
+++ b/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff
@@ -0,0 +1,39 @@
+- // 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 = Len(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _5 = const true; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> 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
+ _0 = const (); // scope 0 at $DIR/array_index.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/array_index.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/array_index.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/array_index.rs b/tests/mir-opt/const_prop/array_index.rs
new file mode 100644
index 000000000..d31c2827b
--- /dev/null
+++ b/tests/mir-opt/const_prop/array_index.rs
@@ -0,0 +1,7 @@
+// unit-test: ConstProp
+// 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/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff b/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff
new file mode 100644
index 000000000..bea32a67e
--- /dev/null
+++ b/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.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/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
++ _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(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ }
+
+ bb1: {
+- _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, _3) -> bb2; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ }
+
+ bb2: {
+ _2 = Div(const 1_i32, move _3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ StorageDead(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
+ _0 = const (); // scope 0 at $DIR/bad_op_div_by_zero.rs:+0:11: +3:2
+ StorageDead(_2); // scope 1 at $DIR/bad_op_div_by_zero.rs:+3:1: +3:2
+ StorageDead(_1); // scope 0 at $DIR/bad_op_div_by_zero.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/bad_op_div_by_zero.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/bad_op_div_by_zero.rs b/tests/mir-opt/const_prop/bad_op_div_by_zero.rs
new file mode 100644
index 000000000..a6fd325ec
--- /dev/null
+++ b/tests/mir-opt/const_prop/bad_op_div_by_zero.rs
@@ -0,0 +1,7 @@
+// unit-test: ConstProp
+// 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/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff b/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff
new file mode 100644
index 000000000..8485703e3
--- /dev/null
+++ b/tests/mir-opt/const_prop/bad_op_mod_by_zero.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/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
+ 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/tests/mir-opt/const_prop/bad_op_mod_by_zero.rs b/tests/mir-opt/const_prop/bad_op_mod_by_zero.rs
new file mode 100644
index 000000000..cc16a4a5a
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..27e41d486
--- /dev/null
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.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_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 _5: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ let mut _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ let mut _7: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ let mut _8: &[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 _4: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ scope 3 {
+ debug _b => _4; // 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
+ _8 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ // mir::Constant
+ // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
+ // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
+ _3 = _8; // 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(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ _5 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ _6 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- _7 = Lt(_5, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ _7 = Lt(const 3_usize, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ }
+
+ bb1: {
+ _4 = (*_1)[_5]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26
+ StorageDead(_4); // 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/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..27e41d486
--- /dev/null
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.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_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 _5: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ let mut _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ let mut _7: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ let mut _8: &[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 _4: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ scope 3 {
+ debug _b => _4; // 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
+ _8 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ // mir::Constant
+ // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
+ // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
+ _3 = _8; // 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(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ _5 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ _6 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- _7 = Lt(_5, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ _7 = Lt(const 3_usize, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ }
+
+ bb1: {
+ _4 = (*_1)[_5]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26
+ StorageDead(_4); // 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/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs
new file mode 100644
index 000000000..cf22b06d5
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/boolean_identities.rs b/tests/mir-opt/const_prop/boolean_identities.rs
new file mode 100644
index 000000000..c7b609949
--- /dev/null
+++ b/tests/mir-opt/const_prop/boolean_identities.rs
@@ -0,0 +1,11 @@
+// unit-test: ConstProp
+// 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/tests/mir-opt/const_prop/boolean_identities.test.ConstProp.diff b/tests/mir-opt/const_prop/boolean_identities.test.ConstProp.diff
new file mode 100644
index 000000000..0de800917
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/boxes.main.ConstProp.diff b/tests/mir-opt/const_prop/boxes.main.ConstProp.diff
new file mode 100644
index 000000000..5ec421eb2
--- /dev/null
+++ b/tests/mir-opt/const_prop/boxes.main.ConstProp.diff
@@ -0,0 +1,60 @@
+- // 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
+ 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
++ _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(move _4, move _5) -> bb1; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
+ // mir::Constant
+ // + span: $DIR/boxes.rs:13:14: 13:22
+ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_7); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ _7 = ShallowInitBox(move _6, i32); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ _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
+ _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
+ _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
+ _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
+ _0 = const (); // scope 0 at $DIR/boxes.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/boxes.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/boxes.rs:+2:2: +2:2
+ }
+
+ bb3 (cleanup): {
+ resume; // scope 0 at $DIR/boxes.rs:+0:1: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/boxes.rs b/tests/mir-opt/const_prop/boxes.rs
new file mode 100644
index 000000000..d287830db
--- /dev/null
+++ b/tests/mir-opt/const_prop/boxes.rs
@@ -0,0 +1,14 @@
+// unit-test: ConstProp
+// 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/tests/mir-opt/const_prop/cast.main.ConstProp.diff b/tests/mir-opt/const_prop/cast.main.ConstProp.diff
new file mode 100644
index 000000000..1d4dfc29f
--- /dev/null
+++ b/tests/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 (IntToInt); // 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 (IntToInt); // scope 1 at $DIR/cast.rs:+3:13: +3:24
++ _2 = const 42_u8; // scope 1 at $DIR/cast.rs:+3:13: +3:24
+ _0 = const (); // scope 0 at $DIR/cast.rs:+0:11: +4:2
+ StorageDead(_2); // scope 1 at $DIR/cast.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/cast.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/cast.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/cast.rs b/tests/mir-opt/const_prop/cast.rs
new file mode 100644
index 000000000..984086eda
--- /dev/null
+++ b/tests/mir-opt/const_prop/cast.rs
@@ -0,0 +1,8 @@
+// unit-test: ConstProp
+// EMIT_MIR cast.main.ConstProp.diff
+
+fn main() {
+ let x = 42u8 as u32;
+
+ let y = 42u32 as u8;
+}
diff --git a/tests/mir-opt/const_prop/checked_add.main.ConstProp.diff b/tests/mir-opt/const_prop/checked_add.main.ConstProp.diff
new file mode 100644
index 000000000..96d0d2566
--- /dev/null
+++ b/tests/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
+ _0 = const (); // scope 0 at $DIR/checked_add.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/checked_add.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/checked_add.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/checked_add.rs b/tests/mir-opt/const_prop/checked_add.rs
new file mode 100644
index 000000000..b9860da4c
--- /dev/null
+++ b/tests/mir-opt/const_prop/checked_add.rs
@@ -0,0 +1,7 @@
+// unit-test: ConstProp
+// compile-flags: -C overflow-checks=on
+
+// EMIT_MIR checked_add.main.ConstProp.diff
+fn main() {
+ let x: u32 = 1 + 1;
+}
diff --git a/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff b/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
new file mode 100644
index 000000000..bea7114c7
--- /dev/null
+++ b/tests/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 _; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
+ // mir::Constant
+ // + span: $DIR/const_prop_fails_gracefully.rs:8:13: 8:16
+ // + literal: Const { ty: &i32, val: Unevaluated(FOO, [], None) }
+ _2 = &raw const (*_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
+ _1 = move _2 as usize (PointerExposeAddress); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:39
+ 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:9:5: 9:9
+ // + literal: Const { ty: fn(usize) {read}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_5); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:11: +3:12
+ StorageDead(_4); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:12: +3:13
+ _0 = const (); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+0:11: +4:2
+ StorageDead(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/const_prop_fails_gracefully.rs b/tests/mir-opt/const_prop/const_prop_fails_gracefully.rs
new file mode 100644
index 000000000..0a3dcbd38
--- /dev/null
+++ b/tests/mir-opt/const_prop/const_prop_fails_gracefully.rs
@@ -0,0 +1,10 @@
+// unit-test: ConstProp
+#[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/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff
new file mode 100644
index 000000000..f270ab8b6
--- /dev/null
+++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff
@@ -0,0 +1,32 @@
+- // 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 _; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21
+- switchInt(move _1) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21
++ switchInt(const false) -> [0: 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: {
+ 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/tests/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir b/tests/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir
new file mode 100644
index 000000000..9f7528f0c
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/control_flow_simplification.rs b/tests/mir-opt/const_prop/control_flow_simplification.rs
new file mode 100644
index 000000000..7dbe8e734
--- /dev/null
+++ b/tests/mir-opt/const_prop/control_flow_simplification.rs
@@ -0,0 +1,21 @@
+// unit-test: ConstProp
+// 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/tests/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..b4dccecc6
--- /dev/null
+++ b/tests/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: 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: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+ }
+
+ bb1: {
+ switchInt(((_3 as Some).0: bool)) -> [0: 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
+ _0 = const (); // scope 0 at $DIR/discriminant.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/discriminant.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/discriminant.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..b4dccecc6
--- /dev/null
+++ b/tests/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: 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: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+ }
+
+ bb1: {
+ switchInt(((_3 as Some).0: bool)) -> [0: 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
+ _0 = const (); // scope 0 at $DIR/discriminant.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/discriminant.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/discriminant.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/discriminant.rs b/tests/mir-opt/const_prop/discriminant.rs
new file mode 100644
index 000000000..fdd67ca8a
--- /dev/null
+++ b/tests/mir-opt/const_prop/discriminant.rs
@@ -0,0 +1,13 @@
+// unit-test: ConstProp
+// 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/tests/mir-opt/const_prop/indirect.main.ConstProp.diff b/tests/mir-opt/const_prop/indirect.main.ConstProp.diff
new file mode 100644
index 000000000..f4c0c5c5e
--- /dev/null
+++ b/tests/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 (IntToInt); // 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", move _2, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
+ }
+
+ bb1: {
+- _1 = move (_3.0: u8); // scope 0 at $DIR/indirect.rs:+1:13: +1:29
++ _1 = const 3_u8; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
+ StorageDead(_2); // scope 0 at $DIR/indirect.rs:+1:28: +1:29
+ _0 = const (); // scope 0 at $DIR/indirect.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/indirect.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/indirect.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/indirect.rs b/tests/mir-opt/const_prop/indirect.rs
new file mode 100644
index 000000000..44916cbfe
--- /dev/null
+++ b/tests/mir-opt/const_prop/indirect.rs
@@ -0,0 +1,7 @@
+// unit-test: ConstProp
+// compile-flags: -C overflow-checks=on
+
+// EMIT_MIR indirect.main.ConstProp.diff
+fn main() {
+ let x = (2u32 as u8) + 1;
+}
diff --git a/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff b/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff
new file mode 100644
index 000000000..6c4757c1a
--- /dev/null
+++ b/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff
@@ -0,0 +1,66 @@
+- // 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
+ 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 _7: main::Str<"���">; // in scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22
+ scope 7 {
+ debug _non_utf8_str => _7; // 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 5 at $DIR/invalid_constant.rs:+24:9: +24:22
+ StorageDead(_7); // 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/tests/mir-opt/const_prop/invalid_constant.rs b/tests/mir-opt/const_prop/invalid_constant.rs
new file mode 100644
index 000000000..0337a7ca8
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/issue_66971.main.ConstProp.diff b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.diff
new file mode 100644
index 000000000..488e772d0
--- /dev/null
+++ b/tests/mir-opt/const_prop/issue_66971.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/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
+
+ 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
+ Deinit(_2); // 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
+ _1 = encode(move _2) -> bb1; // scope 0 at $DIR/issue_66971.rs:+1:5: +1:23
+ // mir::Constant
+ // + span: $DIR/issue_66971.rs:17:5: 17: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
+ return; // scope 0 at $DIR/issue_66971.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/issue_66971.rs b/tests/mir-opt/const_prop/issue_66971.rs
new file mode 100644
index 000000000..6ca03438e
--- /dev/null
+++ b/tests/mir-opt/const_prop/issue_66971.rs
@@ -0,0 +1,18 @@
+// unit-test: ConstProp
+// compile-flags: -Z mir-opt-level=3
+
+// Due to a bug in propagating scalar pairs the assertion below used to fail. In the expected
+// 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/tests/mir-opt/const_prop/issue_67019.main.ConstProp.diff b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.diff
new file mode 100644
index 000000000..cd5304859
--- /dev/null
+++ b/tests/mir-opt/const_prop/issue_67019.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_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:12:5: 12: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
+ return; // scope 0 at $DIR/issue_67019.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/issue_67019.rs b/tests/mir-opt/const_prop/issue_67019.rs
new file mode 100644
index 000000000..ffc6fa1f2
--- /dev/null
+++ b/tests/mir-opt/const_prop/issue_67019.rs
@@ -0,0 +1,13 @@
+// unit-test: ConstProp
+// 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/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..5331e5b82
--- /dev/null
+++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.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/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
+ 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/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..5331e5b82
--- /dev/null
+++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.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/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
+ 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/tests/mir-opt/const_prop/large_array_index.rs b/tests/mir-opt/const_prop/large_array_index.rs
new file mode 100644
index 000000000..48d134376
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/mult_by_zero.rs b/tests/mir-opt/const_prop/mult_by_zero.rs
new file mode 100644
index 000000000..c839f92f2
--- /dev/null
+++ b/tests/mir-opt/const_prop/mult_by_zero.rs
@@ -0,0 +1,11 @@
+// unit-test
+// 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/tests/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff b/tests/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff
new file mode 100644
index 000000000..629c8e601
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/mutable_variable.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable.main.ConstProp.diff
new file mode 100644
index 000000000..a672c457a
--- /dev/null
+++ b/tests/mir-opt/const_prop/mutable_variable.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/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
+ 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/tests/mir-opt/const_prop/mutable_variable.rs b/tests/mir-opt/const_prop/mutable_variable.rs
new file mode 100644
index 000000000..cb01719dd
--- /dev/null
+++ b/tests/mir-opt/const_prop/mutable_variable.rs
@@ -0,0 +1,9 @@
+// unit-test
+// compile-flags: -O
+
+// EMIT_MIR mutable_variable.main.ConstProp.diff
+fn main() {
+ let mut x = 42;
+ x = 99;
+ let y = x;
+}
diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff
new file mode 100644
index 000000000..f6bf52206
--- /dev/null
+++ b/tests/mir-opt/const_prop/mutable_variable_aggregate.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/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
+ 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/tests/mir-opt/const_prop/mutable_variable_aggregate.rs b/tests/mir-opt/const_prop/mutable_variable_aggregate.rs
new file mode 100644
index 000000000..d4ff8d890
--- /dev/null
+++ b/tests/mir-opt/const_prop/mutable_variable_aggregate.rs
@@ -0,0 +1,9 @@
+// unit-test
+// 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/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff
new file mode 100644
index 000000000..213a70227
--- /dev/null
+++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.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_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
+ 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/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs
new file mode 100644
index 000000000..9060f7e9b
--- /dev/null
+++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs
@@ -0,0 +1,10 @@
+// unit-test
+// 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/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff
new file mode 100644
index 000000000..149aa6290
--- /dev/null
+++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.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/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:6:29: 6: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
+ 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/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs
new file mode 100644
index 000000000..cb59509ff
--- /dev/null
+++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs
@@ -0,0 +1,15 @@
+// unit-test
+// 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/tests/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff
new file mode 100644
index 000000000..7fa29cccd
--- /dev/null
+++ b/tests/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.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/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 mut _2: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ let mut _3: *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 _4: u32; // in scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10
+ scope 2 {
+ }
+ scope 3 {
+ debug y => _4; // 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 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ StorageLive(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ _3 = 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:10:13: 10:19
+ // + literal: Const { ty: *mut u32, val: Value(Scalar(alloc1)) }
+ _2 = (*_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ _1 = move _2; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:9: +3:19
+ StorageDead(_2); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:18: +3:19
+ StorageDead(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:19: +3:20
+ StorageLive(_4); // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10
+ _4 = _1; // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:13: +5:14
+ StorageDead(_4); // 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) {
+ 42 42 42 42 │ BBBB
+ }
+
diff --git a/tests/mir-opt/const_prop/mutable_variable_no_prop.rs b/tests/mir-opt/const_prop/mutable_variable_no_prop.rs
new file mode 100644
index 000000000..b69ec931a
--- /dev/null
+++ b/tests/mir-opt/const_prop/mutable_variable_no_prop.rs
@@ -0,0 +1,13 @@
+// unit-test
+// compile-flags: -O
+
+static mut STATIC: u32 = 0x42424242;
+
+// EMIT_MIR mutable_variable_no_prop.main.ConstProp.diff
+fn main() {
+ let mut x = 42;
+ unsafe {
+ x = STATIC;
+ }
+ let y = x;
+}
diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
new file mode 100644
index 000000000..c3f77b960
--- /dev/null
+++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
@@ -0,0 +1,57 @@
+- // 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 _2: 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 _5: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ let mut _6: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ scope 2 {
+ debug x => (i32, i32){ .0 => _5, .1 => _6, }; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ let _3: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
+ scope 3 {
+ debug y => _3; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
+ let _4: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
+ scope 4 {
+ debug z => _4; // 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:6:13: 6:16
+ // + literal: Const { ty: fn() -> i32 {foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ StorageLive(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ Deinit(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ Deinit(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ _5 = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ _6 = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ StorageLive(_2); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
+ _2 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
+ _6 = move _2; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12
+ StorageDead(_2); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
+ StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
+ _3 = _6; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16
+ StorageLive(_4); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
+- _4 = _5; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16
++ _4 = const 1_i32; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16
+ StorageDead(_4); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ StorageDead(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ StorageDead(_6); // 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/tests/mir-opt/const_prop/mutable_variable_unprop_assign.rs b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.rs
new file mode 100644
index 000000000..b077cfd3e
--- /dev/null
+++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.rs
@@ -0,0 +1,16 @@
+// unit-test
+// 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/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..7c7aeac4c
--- /dev/null
+++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff
@@ -0,0 +1,66 @@
+- // 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: u32; // 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 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- _8 = _9; // 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
+ 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/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..7c7aeac4c
--- /dev/null
+++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff
@@ -0,0 +1,66 @@
+- // 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: u32; // 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 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- _8 = _9; // 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
+ 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/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir
new file mode 100644
index 000000000..9db87cfc8
--- /dev/null
+++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir
@@ -0,0 +1,27 @@
+// MIR for `main` after PreCodegen
+
+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/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir
new file mode 100644
index 000000000..9db87cfc8
--- /dev/null
+++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir
@@ -0,0 +1,27 @@
+// MIR for `main` after PreCodegen
+
+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/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff
new file mode 100644
index 000000000..3f9f3b2ea
--- /dev/null
+++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff
@@ -0,0 +1,72 @@
+- // MIR for `main` before ScalarReplacementOfAggregates
++ // MIR for `main` after ScalarReplacementOfAggregates
+
+ 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
++ let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ let mut _11: u32; // 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
+ }
+
+ bb1: {
+ _1 = move (_2.0: 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 = Len(_4); // 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
+ }
+
+ bb2: {
+ _3 = _4[_5]; // 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
+- StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
++ StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ Deinit(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ Deinit(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
++ StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
++ StorageDead(_11); // 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/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff
new file mode 100644
index 000000000..3f9f3b2ea
--- /dev/null
+++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff
@@ -0,0 +1,72 @@
+- // MIR for `main` before ScalarReplacementOfAggregates
++ // MIR for `main` after ScalarReplacementOfAggregates
+
+ 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
++ let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ let mut _11: u32; // 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
+ }
+
+ bb1: {
+ _1 = move (_2.0: 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 = Len(_4); // 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
+ }
+
+ bb2: {
+ _3 = _4[_5]; // 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
+- StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
++ StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ Deinit(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ Deinit(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
++ StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
++ StorageDead(_11); // 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/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir
new file mode 100644
index 000000000..d926b9df7
--- /dev/null
+++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir
@@ -0,0 +1,27 @@
+// MIR for `main` after SimplifyLocals-final
+
+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/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir
new file mode 100644
index 000000000..d926b9df7
--- /dev/null
+++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir
@@ -0,0 +1,27 @@
+// MIR for `main` after SimplifyLocals-final
+
+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/tests/mir-opt/const_prop/optimizes_into_variable.rs b/tests/mir-opt/const_prop/optimizes_into_variable.rs
new file mode 100644
index 000000000..abea07e20
--- /dev/null
+++ b/tests/mir-opt/const_prop/optimizes_into_variable.rs
@@ -0,0 +1,18 @@
+// unit-test
+// compile-flags: -C overflow-checks=on
+
+struct Point {
+ x: u32,
+ y: u32,
+}
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR optimizes_into_variable.main.ScalarReplacementOfAggregates.diff
+// EMIT_MIR optimizes_into_variable.main.ConstProp.diff
+// EMIT_MIR optimizes_into_variable.main.SimplifyLocals-final.after.mir
+// EMIT_MIR optimizes_into_variable.main.PreCodegen.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/tests/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff b/tests/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff
new file mode 100644
index 000000000..388c6ca81
--- /dev/null
+++ b/tests/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff
@@ -0,0 +1,47 @@
+- // 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:8:13: 8:16
+ // + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }
+- _2 = (*_3); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
++ _2 = const 2_u8; // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ 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:8:19: 8:22
+ // + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }
+- _4 = (*_5); // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+- _1 = Add(move _2, move _4); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:22
++ _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
+ 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/tests/mir-opt/const_prop/read_immutable_static.rs b/tests/mir-opt/const_prop/read_immutable_static.rs
new file mode 100644
index 000000000..4f7afe6ca
--- /dev/null
+++ b/tests/mir-opt/const_prop/read_immutable_static.rs
@@ -0,0 +1,9 @@
+// unit-test
+// compile-flags: -O
+
+static FOO: u8 = 2;
+
+// EMIT_MIR read_immutable_static.main.ConstProp.diff
+fn main() {
+ let x = FOO + FOO;
+}
diff --git a/tests/mir-opt/const_prop/ref_deref.main.ConstProp.diff b/tests/mir-opt/const_prop/ref_deref.main.ConstProp.diff
new file mode 100644
index 000000000..8a73f0390
--- /dev/null
+++ b/tests/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 _; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ // mir::Constant
+ // + span: $DIR/ref_deref.rs:6:6: 6: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/tests/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff b/tests/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
new file mode 100644
index 000000000..015ec4d07
--- /dev/null
+++ b/tests/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 _; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
++ // mir::Constant
++ // + span: $DIR/ref_deref.rs:6:6: 6: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/tests/mir-opt/const_prop/ref_deref.rs b/tests/mir-opt/const_prop/ref_deref.rs
new file mode 100644
index 000000000..d2549c8b6
--- /dev/null
+++ b/tests/mir-opt/const_prop/ref_deref.rs
@@ -0,0 +1,7 @@
+// compile-flags: -Zmir-enable-passes=-SimplifyLocals-before-const-prop
+// EMIT_MIR ref_deref.main.PromoteTemps.diff
+// EMIT_MIR ref_deref.main.ConstProp.diff
+
+fn main() {
+ *(&4);
+}
diff --git a/tests/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff b/tests/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
new file mode 100644
index 000000000..ec3d90433
--- /dev/null
+++ b/tests/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 _; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ // mir::Constant
+ // + span: $DIR/ref_deref_project.rs:6:6: 6:17
+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
+ _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+ 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/tests/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff b/tests/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
new file mode 100644
index 000000000..cd0616e65
--- /dev/null
+++ b/tests/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 _; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
++ // mir::Constant
++ // + span: $DIR/ref_deref_project.rs:6:6: 6:17
++ // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
++ _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+- 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/tests/mir-opt/const_prop/ref_deref_project.rs b/tests/mir-opt/const_prop/ref_deref_project.rs
new file mode 100644
index 000000000..2fdd4e153
--- /dev/null
+++ b/tests/mir-opt/const_prop/ref_deref_project.rs
@@ -0,0 +1,7 @@
+// compile-flags: -Zmir-enable-passes=-SimplifyLocals-before-const-prop
+// 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/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff b/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
new file mode 100644
index 000000000..15c93f270
--- /dev/null
+++ b/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
@@ -0,0 +1,24 @@
+- // 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: usize; // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26
+ let mut _2: 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:26
+ StorageLive(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17
+ _2 = 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>) }
+ _1 = move _2 as usize (PointerExposeAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26
+ StorageDead(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:25: +1:26
+ StorageDead(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:40: +1:41
+ return; // scope 0 at $DIR/reify_fn_ptr.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.rs b/tests/mir-opt/const_prop/reify_fn_ptr.rs
new file mode 100644
index 000000000..bfe2563ad
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..636032adb
--- /dev/null
+++ b/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff
@@ -0,0 +1,42 @@
+- // 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
+ 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/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..636032adb
--- /dev/null
+++ b/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff
@@ -0,0 +1,42 @@
+- // 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
+ 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/tests/mir-opt/const_prop/repeat.rs b/tests/mir-opt/const_prop/repeat.rs
new file mode 100644
index 000000000..36d9b9fc6
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/return_place.add.ConstProp.diff b/tests/mir-opt/const_prop/return_place.add.ConstProp.diff
new file mode 100644
index 000000000..5ebd8a520
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.mir b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.mir
new file mode 100644
index 000000000..ececd9942
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/return_place.rs b/tests/mir-opt/const_prop/return_place.rs
new file mode 100644
index 000000000..06a853696
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff b/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff
new file mode 100644
index 000000000..d518eff04
--- /dev/null
+++ b/tests/mir-opt/const_prop/scalar_literal_propagation.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/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
+ 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/tests/mir-opt/const_prop/scalar_literal_propagation.rs b/tests/mir-opt/const_prop/scalar_literal_propagation.rs
new file mode 100644
index 000000000..8724e4d57
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..9017fd18e
--- /dev/null
+++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
@@ -0,0 +1,50 @@
+- // 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
+
+ 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 _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ // mir::Constant
+ // + span: $DIR/slice_len.rs:6:6: 6: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
+ _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 = Len((*_2)); // 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
++ _7 = const 3_usize; // 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/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..9017fd18e
--- /dev/null
+++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
@@ -0,0 +1,50 @@
+- // 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
+
+ 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 _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ // mir::Constant
+ // + span: $DIR/slice_len.rs:6:6: 6: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
+ _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 = Len((*_2)); // 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
++ _7 = const 3_usize; // 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/tests/mir-opt/const_prop/slice_len.rs b/tests/mir-opt/const_prop/slice_len.rs
new file mode 100644
index 000000000..eaaf34b96
--- /dev/null
+++ b/tests/mir-opt/const_prop/slice_len.rs
@@ -0,0 +1,7 @@
+// compile-flags: -Zmir-enable-passes=-SimplifyLocals-before-const-prop
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
+// EMIT_MIR slice_len.main.ConstProp.diff
+fn main() {
+ (&[1u32, 2, 3] as &[u32])[1];
+}
diff --git a/tests/mir-opt/const_prop/switch_int.main.ConstProp.diff b/tests/mir-opt/const_prop/switch_int.main.ConstProp.diff
new file mode 100644
index 000000000..ddc1a4493
--- /dev/null
+++ b/tests/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: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12
++ switchInt(const 1_i32) -> [1: 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/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff b/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff
new file mode 100644
index 000000000..09c47ee6e
--- /dev/null
+++ b/tests/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: 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/tests/mir-opt/const_prop/switch_int.rs b/tests/mir-opt/const_prop/switch_int.rs
new file mode 100644
index 000000000..d7319eca1
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff
new file mode 100644
index 000000000..e4c92b617
--- /dev/null
+++ b/tests/mir-opt/const_prop/tuple_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/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
+ 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/tests/mir-opt/const_prop/tuple_literal_propagation.rs b/tests/mir-opt/const_prop/tuple_literal_propagation.rs
new file mode 100644
index 000000000..e644baec4
--- /dev/null
+++ b/tests/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/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff b/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff
new file mode 100644
index 000000000..ea9fec0aa
--- /dev/null
+++ b/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff
@@ -0,0 +1,37 @@
+- // 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 mut _2: *mut i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
+ let mut _4: 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 _3: bool; // in scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10
+ scope 2 {
+ }
+ scope 3 {
+ debug y => _3; // 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 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
+ _2 = &raw mut (_1.0: i32); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
+ (*_2) = const 5_i32; // scope 2 at $DIR/const_prop_miscompile.rs:+3:9: +3:26
+ StorageDead(_2); // scope 2 at $DIR/const_prop_miscompile.rs:+3:26: +3:27
+ StorageLive(_3); // scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10
+ StorageLive(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:20
+ _4 = (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:15: +5:18
+ _3 = Eq(move _4, const 5_i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:25
+ StorageDead(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+5:24: +5:25
+ StorageDead(_3); // 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/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff b/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff
new file mode 100644
index 000000000..043f40474
--- /dev/null
+++ b/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff
@@ -0,0 +1,35 @@
+- // 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
+ 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/tests/mir-opt/const_prop_miscompile.rs b/tests/mir-opt/const_prop_miscompile.rs
new file mode 100644
index 000000000..bc54556b3
--- /dev/null
+++ b/tests/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/tests/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot b/tests/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot
new file mode 100644
index 000000000..03df5c950
--- /dev/null
+++ b/tests/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 align="left"/> 19:5-19:9: @0[0]: Coverage::Counter(1) for $DIR/coverage_graphviz.rs:18:1 - 20:2<br align="left"/> 20:2-20:2: @0.Return: return</td></tr><tr><td align="left" balign="left">bb0: Return</td></tr></table>>];
+}
diff --git a/tests/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot b/tests/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot
new file mode 100644
index 000000000..c4d389b2d
--- /dev/null
+++ b/tests/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 align="left"/> 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 align="left"/> 12:13-12:18: @4[0]: Coverage::Expression(4294967293) = 4294967294 + 0 for $DIR/coverage_graphviz.rs:15:1 - 15:2<br align="left"/>Expression(bcb2:(bcb1:(bcb0 + bcb3) - bcb3) + 0) at 15:2-15:2<br align="left"/> 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 align="left"/> 11:12-11:17: @2.Call: _2 = bar() -&gt; [return: bb3, unwind: bb6]</td></tr><tr><td align="left" balign="left">bb1: FalseUnwind<br align="left"/>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 align="left"/> </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=<0>];
+ bcb1__Cov_0_3 -> bcb2__Cov_0_3 [label=<otherwise>];
+ bcb0__Cov_0_3 -> bcb1__Cov_0_3 [label=<>];
+}
diff --git a/tests/mir-opt/coverage_graphviz.rs b/tests/mir-opt/coverage_graphviz.rs
new file mode 100644
index 000000000..09403bb3a
--- /dev/null
+++ b/tests/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/tests/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff
new file mode 100644
index 000000000..bf9ab8669
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff
@@ -0,0 +1,37 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/cast.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/cast.rs:+1:9: +1:10
+ let mut _3: u8; // in scope 0 at $DIR/cast.rs:+2:13: +2:20
+ let mut _4: i32; // in scope 0 at $DIR/cast.rs:+2:13: +2:14
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/cast.rs:+1:9: +1:10
+ let _2: u8; // in scope 1 at $DIR/cast.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _2; // in scope 2 at $DIR/cast.rs:+2:9: +2:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/cast.rs:+1:9: +1:10
+ _1 = const 257_i32; // scope 0 at $DIR/cast.rs:+1:13: +1:16
+ StorageLive(_2); // scope 1 at $DIR/cast.rs:+2:9: +2:10
+ StorageLive(_3); // scope 1 at $DIR/cast.rs:+2:13: +2:20
+ StorageLive(_4); // scope 1 at $DIR/cast.rs:+2:13: +2:14
+- _4 = _1; // scope 1 at $DIR/cast.rs:+2:13: +2:14
+- _3 = move _4 as u8 (IntToInt); // scope 1 at $DIR/cast.rs:+2:13: +2:20
++ _4 = const 257_i32; // scope 1 at $DIR/cast.rs:+2:13: +2:14
++ _3 = const 1_u8; // scope 1 at $DIR/cast.rs:+2:13: +2:20
+ StorageDead(_4); // scope 1 at $DIR/cast.rs:+2:19: +2:20
+- _2 = Add(move _3, const 1_u8); // scope 1 at $DIR/cast.rs:+2:13: +2:24
++ _2 = const 2_u8; // scope 1 at $DIR/cast.rs:+2:13: +2:24
+ StorageDead(_3); // scope 1 at $DIR/cast.rs:+2:23: +2:24
+ _0 = const (); // scope 0 at $DIR/cast.rs:+0:11: +3:2
+ StorageDead(_2); // scope 1 at $DIR/cast.rs:+3:1: +3:2
+ StorageDead(_1); // scope 0 at $DIR/cast.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/cast.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/cast.rs b/tests/mir-opt/dataflow-const-prop/cast.rs
new file mode 100644
index 000000000..484403f7f
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/cast.rs
@@ -0,0 +1,7 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR cast.main.DataflowConstProp.diff
+fn main() {
+ let a = 257;
+ let b = a as u8 + 1;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff
new file mode 100644
index 000000000..a4ebd0c8c
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff
@@ -0,0 +1,80 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/checked.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/checked.rs:+1:9: +1:10
+ let mut _4: i32; // in scope 0 at $DIR/checked.rs:+3:13: +3:14
+ let mut _5: i32; // in scope 0 at $DIR/checked.rs:+3:17: +3:18
+ let mut _6: (i32, bool); // in scope 0 at $DIR/checked.rs:+3:13: +3:18
+ let mut _9: i32; // in scope 0 at $DIR/checked.rs:+6:13: +6:14
+ let mut _10: (i32, bool); // in scope 0 at $DIR/checked.rs:+6:13: +6:18
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/checked.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/checked.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _2; // in scope 2 at $DIR/checked.rs:+2:9: +2:10
+ let _3: i32; // in scope 2 at $DIR/checked.rs:+3:9: +3:10
+ scope 3 {
+ debug c => _3; // in scope 3 at $DIR/checked.rs:+3:9: +3:10
+ let _7: i32; // in scope 3 at $DIR/checked.rs:+5:9: +5:10
+ scope 4 {
+ debug d => _7; // in scope 4 at $DIR/checked.rs:+5:9: +5:10
+ let _8: i32; // in scope 4 at $DIR/checked.rs:+6:9: +6:10
+ scope 5 {
+ debug e => _8; // in scope 5 at $DIR/checked.rs:+6:9: +6:10
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/checked.rs:+1:9: +1:10
+ _1 = const 1_i32; // scope 0 at $DIR/checked.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/checked.rs:+2:9: +2:10
+ _2 = const 2_i32; // scope 1 at $DIR/checked.rs:+2:13: +2:14
+ StorageLive(_3); // scope 2 at $DIR/checked.rs:+3:9: +3:10
+ StorageLive(_4); // scope 2 at $DIR/checked.rs:+3:13: +3:14
+- _4 = _1; // scope 2 at $DIR/checked.rs:+3:13: +3:14
++ _4 = const 1_i32; // scope 2 at $DIR/checked.rs:+3:13: +3:14
+ StorageLive(_5); // scope 2 at $DIR/checked.rs:+3:17: +3:18
+- _5 = _2; // scope 2 at $DIR/checked.rs:+3:17: +3:18
+- _6 = CheckedAdd(_4, _5); // scope 2 at $DIR/checked.rs:+3:13: +3:18
+- assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> bb1; // scope 2 at $DIR/checked.rs:+3:13: +3:18
++ _5 = const 2_i32; // scope 2 at $DIR/checked.rs:+3:17: +3:18
++ _6 = CheckedAdd(const 1_i32, const 2_i32); // scope 2 at $DIR/checked.rs:+3:13: +3:18
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_i32, const 2_i32) -> bb1; // scope 2 at $DIR/checked.rs:+3:13: +3:18
+ }
+
+ bb1: {
+- _3 = move (_6.0: i32); // scope 2 at $DIR/checked.rs:+3:13: +3:18
++ _3 = const 3_i32; // scope 2 at $DIR/checked.rs:+3:13: +3:18
+ StorageDead(_5); // scope 2 at $DIR/checked.rs:+3:17: +3:18
+ StorageDead(_4); // scope 2 at $DIR/checked.rs:+3:17: +3:18
+ StorageLive(_7); // scope 3 at $DIR/checked.rs:+5:9: +5:10
+ _7 = const _; // scope 3 at $DIR/checked.rs:+5:13: +5:21
+ StorageLive(_8); // scope 4 at $DIR/checked.rs:+6:9: +6:10
+ StorageLive(_9); // scope 4 at $DIR/checked.rs:+6:13: +6:14
+- _9 = _7; // scope 4 at $DIR/checked.rs:+6:13: +6:14
+- _10 = CheckedAdd(_9, const 1_i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18
+- assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18
++ _9 = const i32::MAX; // scope 4 at $DIR/checked.rs:+6:13: +6:14
++ _10 = CheckedAdd(const i32::MAX, const 1_i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18
++ assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18
+ }
+
+ bb2: {
+- _8 = move (_10.0: i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18
++ _8 = const i32::MIN; // scope 4 at $DIR/checked.rs:+6:13: +6:18
+ StorageDead(_9); // scope 4 at $DIR/checked.rs:+6:17: +6:18
+ _0 = const (); // scope 0 at $DIR/checked.rs:+0:11: +7:2
+ StorageDead(_8); // scope 4 at $DIR/checked.rs:+7:1: +7:2
+ StorageDead(_7); // scope 3 at $DIR/checked.rs:+7:1: +7:2
+ StorageDead(_3); // scope 2 at $DIR/checked.rs:+7:1: +7:2
+ StorageDead(_2); // scope 1 at $DIR/checked.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/checked.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/checked.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/checked.rs b/tests/mir-opt/dataflow-const-prop/checked.rs
new file mode 100644
index 000000000..0738a4ee5
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/checked.rs
@@ -0,0 +1,13 @@
+// unit-test: DataflowConstProp
+// compile-flags: -Coverflow-checks=on
+
+// EMIT_MIR checked.main.DataflowConstProp.diff
+#[allow(arithmetic_overflow)]
+fn main() {
+ let a = 1;
+ let b = 2;
+ let c = a + b;
+
+ let d = i32::MAX;
+ let e = d + 1;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff
new file mode 100644
index 000000000..fce18fae4
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff
@@ -0,0 +1,61 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/enum.rs:+0:11: +0:11
+ let _1: E; // in scope 0 at $DIR/enum.rs:+1:9: +1:10
+ let mut _3: isize; // in scope 0 at $DIR/enum.rs:+2:23: +2:31
+ scope 1 {
+ debug e => _1; // in scope 1 at $DIR/enum.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/enum.rs:+2:9: +2:10
+ let _4: i32; // in scope 1 at $DIR/enum.rs:+2:29: +2:30
+ let _5: i32; // in scope 1 at $DIR/enum.rs:+2:44: +2:45
+ scope 2 {
+ debug x => _2; // in scope 2 at $DIR/enum.rs:+2:9: +2:10
+ }
+ scope 3 {
+ debug x => _4; // in scope 3 at $DIR/enum.rs:+2:29: +2:30
+ }
+ scope 4 {
+ debug x => _5; // in scope 4 at $DIR/enum.rs:+2:44: +2:45
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/enum.rs:+1:9: +1:10
+ Deinit(_1); // scope 0 at $DIR/enum.rs:+1:13: +1:21
+ ((_1 as V1).0: i32) = const 0_i32; // scope 0 at $DIR/enum.rs:+1:13: +1:21
+ discriminant(_1) = 0; // scope 0 at $DIR/enum.rs:+1:13: +1:21
+ StorageLive(_2); // scope 1 at $DIR/enum.rs:+2:9: +2:10
+ _3 = discriminant(_1); // scope 1 at $DIR/enum.rs:+2:19: +2:20
+ switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 1 at $DIR/enum.rs:+2:13: +2:20
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 1 at $DIR/enum.rs:+2:44: +2:45
+ _5 = ((_1 as V2).0: i32); // scope 1 at $DIR/enum.rs:+2:44: +2:45
+ _2 = _5; // scope 4 at $DIR/enum.rs:+2:50: +2:51
+ StorageDead(_5); // scope 1 at $DIR/enum.rs:+2:50: +2:51
+ goto -> bb4; // scope 1 at $DIR/enum.rs:+2:50: +2:51
+ }
+
+ bb2: {
+ unreachable; // scope 1 at $DIR/enum.rs:+2:19: +2:20
+ }
+
+ bb3: {
+ StorageLive(_4); // scope 1 at $DIR/enum.rs:+2:29: +2:30
+ _4 = ((_1 as V1).0: i32); // scope 1 at $DIR/enum.rs:+2:29: +2:30
+ _2 = _4; // scope 3 at $DIR/enum.rs:+2:35: +2:36
+ StorageDead(_4); // scope 1 at $DIR/enum.rs:+2:35: +2:36
+ goto -> bb4; // scope 1 at $DIR/enum.rs:+2:35: +2:36
+ }
+
+ bb4: {
+ _0 = const (); // scope 0 at $DIR/enum.rs:+0:11: +3:2
+ StorageDead(_2); // scope 1 at $DIR/enum.rs:+3:1: +3:2
+ StorageDead(_1); // scope 0 at $DIR/enum.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/enum.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs
new file mode 100644
index 000000000..13288577d
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/enum.rs
@@ -0,0 +1,13 @@
+// unit-test: DataflowConstProp
+
+// Not trackable, because variants could be aliased.
+enum E {
+ V1(i32),
+ V2(i32)
+}
+
+// EMIT_MIR enum.main.DataflowConstProp.diff
+fn main() {
+ let e = E::V1(0);
+ let x = match e { E::V1(x) => x, E::V2(x) => x };
+}
diff --git a/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff
new file mode 100644
index 000000000..32489b4bd
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff
@@ -0,0 +1,112 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/if.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/if.rs:+1:9: +1:10
+ let mut _3: bool; // in scope 0 at $DIR/if.rs:+2:16: +2:22
+ let mut _4: i32; // in scope 0 at $DIR/if.rs:+2:16: +2:17
+ let mut _6: i32; // in scope 0 at $DIR/if.rs:+3:13: +3:14
+ let mut _8: bool; // in scope 0 at $DIR/if.rs:+5:16: +5:22
+ let mut _9: i32; // in scope 0 at $DIR/if.rs:+5:16: +5:17
+ let mut _10: i32; // in scope 0 at $DIR/if.rs:+5:36: +5:37
+ let mut _12: i32; // in scope 0 at $DIR/if.rs:+6:13: +6:14
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/if.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/if.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _2; // in scope 2 at $DIR/if.rs:+2:9: +2:10
+ let _5: i32; // in scope 2 at $DIR/if.rs:+3:9: +3:10
+ scope 3 {
+ debug c => _5; // in scope 3 at $DIR/if.rs:+3:9: +3:10
+ let _7: i32; // in scope 3 at $DIR/if.rs:+5:9: +5:10
+ scope 4 {
+ debug d => _7; // in scope 4 at $DIR/if.rs:+5:9: +5:10
+ let _11: i32; // in scope 4 at $DIR/if.rs:+6:9: +6:10
+ scope 5 {
+ debug e => _11; // in scope 5 at $DIR/if.rs:+6:9: +6:10
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/if.rs:+1:9: +1:10
+ _1 = const 1_i32; // scope 0 at $DIR/if.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/if.rs:+2:9: +2:10
+ StorageLive(_3); // scope 1 at $DIR/if.rs:+2:16: +2:22
+ StorageLive(_4); // scope 1 at $DIR/if.rs:+2:16: +2:17
+- _4 = _1; // scope 1 at $DIR/if.rs:+2:16: +2:17
+- _3 = Eq(move _4, const 1_i32); // scope 1 at $DIR/if.rs:+2:16: +2:22
++ _4 = const 1_i32; // scope 1 at $DIR/if.rs:+2:16: +2:17
++ _3 = const true; // scope 1 at $DIR/if.rs:+2:16: +2:22
+ StorageDead(_4); // scope 1 at $DIR/if.rs:+2:21: +2:22
+- switchInt(move _3) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22
++ switchInt(const true) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22
+ }
+
+ bb1: {
+ _2 = const 2_i32; // scope 1 at $DIR/if.rs:+2:25: +2:26
+ goto -> bb3; // scope 1 at $DIR/if.rs:+2:13: +2:39
+ }
+
+ bb2: {
+ _2 = const 3_i32; // scope 1 at $DIR/if.rs:+2:36: +2:37
+ goto -> bb3; // scope 1 at $DIR/if.rs:+2:13: +2:39
+ }
+
+ bb3: {
+ StorageDead(_3); // scope 1 at $DIR/if.rs:+2:38: +2:39
+ StorageLive(_5); // scope 2 at $DIR/if.rs:+3:9: +3:10
+ StorageLive(_6); // scope 2 at $DIR/if.rs:+3:13: +3:14
+- _6 = _2; // scope 2 at $DIR/if.rs:+3:13: +3:14
+- _5 = Add(move _6, const 1_i32); // scope 2 at $DIR/if.rs:+3:13: +3:18
++ _6 = const 2_i32; // scope 2 at $DIR/if.rs:+3:13: +3:14
++ _5 = const 3_i32; // scope 2 at $DIR/if.rs:+3:13: +3:18
+ StorageDead(_6); // scope 2 at $DIR/if.rs:+3:17: +3:18
+ StorageLive(_7); // scope 3 at $DIR/if.rs:+5:9: +5:10
+ StorageLive(_8); // scope 3 at $DIR/if.rs:+5:16: +5:22
+ StorageLive(_9); // scope 3 at $DIR/if.rs:+5:16: +5:17
+- _9 = _1; // scope 3 at $DIR/if.rs:+5:16: +5:17
+- _8 = Eq(move _9, const 1_i32); // scope 3 at $DIR/if.rs:+5:16: +5:22
++ _9 = const 1_i32; // scope 3 at $DIR/if.rs:+5:16: +5:17
++ _8 = const true; // scope 3 at $DIR/if.rs:+5:16: +5:22
+ StorageDead(_9); // scope 3 at $DIR/if.rs:+5:21: +5:22
+- switchInt(move _8) -> [0: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22
++ switchInt(const true) -> [0: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22
+ }
+
+ bb4: {
+- _7 = _1; // scope 3 at $DIR/if.rs:+5:25: +5:26
++ _7 = const 1_i32; // scope 3 at $DIR/if.rs:+5:25: +5:26
+ goto -> bb6; // scope 3 at $DIR/if.rs:+5:13: +5:43
+ }
+
+ bb5: {
+ StorageLive(_10); // scope 3 at $DIR/if.rs:+5:36: +5:37
+ _10 = _1; // scope 3 at $DIR/if.rs:+5:36: +5:37
+ _7 = Add(move _10, const 1_i32); // scope 3 at $DIR/if.rs:+5:36: +5:41
+ StorageDead(_10); // scope 3 at $DIR/if.rs:+5:40: +5:41
+ goto -> bb6; // scope 3 at $DIR/if.rs:+5:13: +5:43
+ }
+
+ bb6: {
+ StorageDead(_8); // scope 3 at $DIR/if.rs:+5:42: +5:43
+ StorageLive(_11); // scope 4 at $DIR/if.rs:+6:9: +6:10
+ StorageLive(_12); // scope 4 at $DIR/if.rs:+6:13: +6:14
+- _12 = _7; // scope 4 at $DIR/if.rs:+6:13: +6:14
+- _11 = Add(move _12, const 1_i32); // scope 4 at $DIR/if.rs:+6:13: +6:18
++ _12 = const 1_i32; // scope 4 at $DIR/if.rs:+6:13: +6:14
++ _11 = const 2_i32; // scope 4 at $DIR/if.rs:+6:13: +6:18
+ StorageDead(_12); // scope 4 at $DIR/if.rs:+6:17: +6:18
+ _0 = const (); // scope 0 at $DIR/if.rs:+0:11: +7:2
+ StorageDead(_11); // scope 4 at $DIR/if.rs:+7:1: +7:2
+ StorageDead(_7); // scope 3 at $DIR/if.rs:+7:1: +7:2
+ StorageDead(_5); // scope 2 at $DIR/if.rs:+7:1: +7:2
+ StorageDead(_2); // scope 1 at $DIR/if.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/if.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/if.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/if.rs b/tests/mir-opt/dataflow-const-prop/if.rs
new file mode 100644
index 000000000..34fc35790
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/if.rs
@@ -0,0 +1,11 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR if.main.DataflowConstProp.diff
+fn main() {
+ let a = 1;
+ let b = if a == 1 { 2 } else { 3 };
+ let c = b + 1;
+
+ let d = if a == 1 { a } else { a + 1 };
+ let e = d + 1;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff
new file mode 100644
index 000000000..02aafd7ac
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff
@@ -0,0 +1,39 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inherit_overflow.rs:+0:11: +0:11
+ let mut _1: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ let mut _2: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ scope 1 {
+ }
+ scope 2 (inlined <u8 as Add>::add) { // at $DIR/inherit_overflow.rs:7:13: 7:47
+ debug self => _1; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ debug other => _2; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ let mut _3: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ let mut _4: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ let mut _5: (u8, bool); // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ _1 = const u8::MAX; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ StorageLive(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ _2 = const 1_u8; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ StorageLive(_3); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ _3 = const u8::MAX; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ StorageLive(_4); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ _4 = const 1_u8; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ _5 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ }
+
+ bb1: {
+ StorageDead(_4); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ StorageDead(_3); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ StorageDead(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ StorageDead(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ return; // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs
new file mode 100644
index 000000000..2f2d9d010
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs
@@ -0,0 +1,8 @@
+// compile-flags: -Zunsound-mir-opts
+
+// EMIT_MIR inherit_overflow.main.DataflowConstProp.diff
+fn main() {
+ // After inlining, this will contain a `CheckedBinaryOp`. The overflow
+ // must be ignored by the constant propagation to avoid triggering a panic.
+ let _ = <u8 as std::ops::Add>::add(255, 1);
+}
diff --git a/tests/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff
new file mode 100644
index 000000000..5a8788497
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff
@@ -0,0 +1,35 @@
+- // MIR for `f` before DataflowConstProp
++ // MIR for `f` after DataflowConstProp
+
+ fn f() -> usize {
+ let mut _0: usize; // return place in scope 0 at $DIR/issue_81605.rs:+0:11: +0:16
+ let mut _1: usize; // in scope 0 at $DIR/issue_81605.rs:+1:9: +1:33
+ let mut _2: bool; // in scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33
+ StorageLive(_2); // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
+ _2 = const true; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
+- switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
++ switchInt(const true) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
+ }
+
+ bb1: {
+ _1 = const 1_usize; // scope 0 at $DIR/issue_81605.rs:+1:19: +1:20
+ goto -> bb3; // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33
+ }
+
+ bb2: {
+ _1 = const 2_usize; // scope 0 at $DIR/issue_81605.rs:+1:30: +1:31
+ goto -> bb3; // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/issue_81605.rs:+1:32: +1:33
+- _0 = Add(const 1_usize, move _1); // scope 0 at $DIR/issue_81605.rs:+1:5: +1:33
++ _0 = const 2_usize; // scope 0 at $DIR/issue_81605.rs:+1:5: +1:33
+ StorageDead(_1); // scope 0 at $DIR/issue_81605.rs:+1:32: +1:33
+ return; // scope 0 at $DIR/issue_81605.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/issue_81605.rs b/tests/mir-opt/dataflow-const-prop/issue_81605.rs
new file mode 100644
index 000000000..d75e2a28b
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/issue_81605.rs
@@ -0,0 +1,10 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR issue_81605.f.DataflowConstProp.diff
+fn f() -> usize {
+ 1 + if true { 1 } else { 2 }
+}
+
+fn main() {
+ f();
+}
diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff
new file mode 100644
index 000000000..158f187f1
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff
@@ -0,0 +1,55 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/ref_without_sb.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/ref_without_sb.rs:+1:9: +1:14
+ let _2: (); // in scope 0 at $DIR/ref_without_sb.rs:+2:5: +2:15
+ let mut _3: &i32; // in scope 0 at $DIR/ref_without_sb.rs:+2:12: +2:14
+ let _4: &i32; // in scope 0 at $DIR/ref_without_sb.rs:+2:12: +2:14
+ let _5: (); // in scope 0 at $DIR/ref_without_sb.rs:+4:5: +4:20
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/ref_without_sb.rs:+1:9: +1:14
+ let _6: i32; // in scope 1 at $DIR/ref_without_sb.rs:+6:9: +6:10
+ scope 2 {
+ debug b => _6; // in scope 2 at $DIR/ref_without_sb.rs:+6:9: +6:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/ref_without_sb.rs:+1:9: +1:14
+ _1 = const 0_i32; // scope 0 at $DIR/ref_without_sb.rs:+1:17: +1:18
+ StorageLive(_2); // scope 1 at $DIR/ref_without_sb.rs:+2:5: +2:15
+ StorageLive(_3); // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14
+ StorageLive(_4); // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14
+ _4 = &_1; // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14
+ _3 = &(*_4); // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14
+ _2 = escape::<i32>(move _3) -> bb1; // scope 1 at $DIR/ref_without_sb.rs:+2:5: +2:15
+ // mir::Constant
+ // + span: $DIR/ref_without_sb.rs:12:5: 12:11
+ // + literal: Const { ty: for<'a> fn(&'a i32) {escape::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 1 at $DIR/ref_without_sb.rs:+2:14: +2:15
+ StorageDead(_4); // scope 1 at $DIR/ref_without_sb.rs:+2:15: +2:16
+ StorageDead(_2); // scope 1 at $DIR/ref_without_sb.rs:+2:15: +2:16
+ _1 = const 1_i32; // scope 1 at $DIR/ref_without_sb.rs:+3:5: +3:10
+ StorageLive(_5); // scope 1 at $DIR/ref_without_sb.rs:+4:5: +4:20
+ _5 = some_function() -> bb2; // scope 1 at $DIR/ref_without_sb.rs:+4:5: +4:20
+ // mir::Constant
+ // + span: $DIR/ref_without_sb.rs:14:5: 14:18
+ // + literal: Const { ty: fn() {some_function}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_5); // scope 1 at $DIR/ref_without_sb.rs:+4:20: +4:21
+ StorageLive(_6); // scope 1 at $DIR/ref_without_sb.rs:+6:9: +6:10
+ _6 = _1; // scope 1 at $DIR/ref_without_sb.rs:+6:13: +6:14
+ _0 = const (); // scope 0 at $DIR/ref_without_sb.rs:+0:11: +7:2
+ StorageDead(_6); // scope 1 at $DIR/ref_without_sb.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/ref_without_sb.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/ref_without_sb.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs
new file mode 100644
index 000000000..2fd480b09
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs
@@ -0,0 +1,17 @@
+// unit-test: DataflowConstProp
+
+#[inline(never)]
+fn escape<T>(x: &T) {}
+
+#[inline(never)]
+fn some_function() {}
+
+// EMIT_MIR ref_without_sb.main.DataflowConstProp.diff
+fn main() {
+ let mut a = 0;
+ escape(&a);
+ a = 1;
+ some_function();
+ // This should currently not be propagated.
+ let b = a;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff
new file mode 100644
index 000000000..f66b00a9a
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff
@@ -0,0 +1,44 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/repr_transparent.rs:+0:11: +0:11
+ let _1: I32; // in scope 0 at $DIR/repr_transparent.rs:+1:9: +1:10
+ let mut _3: i32; // in scope 0 at $DIR/repr_transparent.rs:+2:17: +2:26
+ let mut _4: i32; // in scope 0 at $DIR/repr_transparent.rs:+2:17: +2:20
+ let mut _5: i32; // in scope 0 at $DIR/repr_transparent.rs:+2:23: +2:26
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/repr_transparent.rs:+1:9: +1:10
+ let _2: I32; // in scope 1 at $DIR/repr_transparent.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/repr_transparent.rs:+2:9: +2:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/repr_transparent.rs:+1:9: +1:10
+ Deinit(_1); // scope 0 at $DIR/repr_transparent.rs:+1:13: +1:19
+ (_1.0: i32) = const 0_i32; // scope 0 at $DIR/repr_transparent.rs:+1:13: +1:19
+ StorageLive(_2); // scope 1 at $DIR/repr_transparent.rs:+2:9: +2:10
+ StorageLive(_3); // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:26
+ StorageLive(_4); // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:20
+- _4 = (_1.0: i32); // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:20
++ _4 = const 0_i32; // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:20
+ StorageLive(_5); // scope 1 at $DIR/repr_transparent.rs:+2:23: +2:26
+- _5 = (_1.0: i32); // scope 1 at $DIR/repr_transparent.rs:+2:23: +2:26
+- _3 = Add(move _4, move _5); // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:26
++ _5 = const 0_i32; // scope 1 at $DIR/repr_transparent.rs:+2:23: +2:26
++ _3 = const 0_i32; // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:26
+ StorageDead(_5); // scope 1 at $DIR/repr_transparent.rs:+2:25: +2:26
+ StorageDead(_4); // scope 1 at $DIR/repr_transparent.rs:+2:25: +2:26
+ Deinit(_2); // scope 1 at $DIR/repr_transparent.rs:+2:13: +2:27
+- (_2.0: i32) = move _3; // scope 1 at $DIR/repr_transparent.rs:+2:13: +2:27
++ (_2.0: i32) = const 0_i32; // scope 1 at $DIR/repr_transparent.rs:+2:13: +2:27
+ StorageDead(_3); // scope 1 at $DIR/repr_transparent.rs:+2:26: +2:27
+ _0 = const (); // scope 0 at $DIR/repr_transparent.rs:+0:11: +3:2
+ StorageDead(_2); // scope 1 at $DIR/repr_transparent.rs:+3:1: +3:2
+ StorageDead(_1); // scope 0 at $DIR/repr_transparent.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/repr_transparent.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/repr_transparent.rs b/tests/mir-opt/dataflow-const-prop/repr_transparent.rs
new file mode 100644
index 000000000..4ce0ca4df
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/repr_transparent.rs
@@ -0,0 +1,12 @@
+// unit-test: DataflowConstProp
+
+// The struct has scalar ABI, but is not a scalar type.
+// Make sure that we handle this correctly.
+#[repr(transparent)]
+struct I32(i32);
+
+// EMIT_MIR repr_transparent.main.DataflowConstProp.diff
+fn main() {
+ let x = I32(0);
+ let y = I32(x.0 + x.0);
+}
diff --git a/tests/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff
new file mode 100644
index 000000000..df08eff94
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff
@@ -0,0 +1,46 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/self_assign.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/self_assign.rs:+1:9: +1:14
+ let mut _2: i32; // in scope 0 at $DIR/self_assign.rs:+2:9: +2:10
+ let mut _3: i32; // in scope 0 at $DIR/self_assign.rs:+3:9: +3:10
+ let mut _5: &i32; // in scope 0 at $DIR/self_assign.rs:+6:9: +6:10
+ let mut _6: i32; // in scope 0 at $DIR/self_assign.rs:+7:9: +7:11
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/self_assign.rs:+1:9: +1:14
+ let mut _4: &i32; // in scope 1 at $DIR/self_assign.rs:+5:9: +5:14
+ scope 2 {
+ debug b => _4; // in scope 2 at $DIR/self_assign.rs:+5:9: +5:14
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/self_assign.rs:+1:9: +1:14
+ _1 = const 0_i32; // scope 0 at $DIR/self_assign.rs:+1:17: +1:18
+ StorageLive(_2); // scope 1 at $DIR/self_assign.rs:+2:9: +2:10
+ _2 = _1; // scope 1 at $DIR/self_assign.rs:+2:9: +2:10
+ _1 = Add(move _2, const 1_i32); // scope 1 at $DIR/self_assign.rs:+2:5: +2:14
+ StorageDead(_2); // scope 1 at $DIR/self_assign.rs:+2:13: +2:14
+ StorageLive(_3); // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
+ _3 = _1; // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
+ _1 = move _3; // scope 1 at $DIR/self_assign.rs:+3:5: +3:10
+ StorageDead(_3); // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
+ StorageLive(_4); // scope 1 at $DIR/self_assign.rs:+5:9: +5:14
+ _4 = &_1; // scope 1 at $DIR/self_assign.rs:+5:17: +5:19
+ StorageLive(_5); // scope 2 at $DIR/self_assign.rs:+6:9: +6:10
+ _5 = _4; // scope 2 at $DIR/self_assign.rs:+6:9: +6:10
+ _4 = move _5; // scope 2 at $DIR/self_assign.rs:+6:5: +6:10
+ StorageDead(_5); // scope 2 at $DIR/self_assign.rs:+6:9: +6:10
+ StorageLive(_6); // scope 2 at $DIR/self_assign.rs:+7:9: +7:11
+ _6 = (*_4); // scope 2 at $DIR/self_assign.rs:+7:9: +7:11
+ _1 = move _6; // scope 2 at $DIR/self_assign.rs:+7:5: +7:11
+ StorageDead(_6); // scope 2 at $DIR/self_assign.rs:+7:10: +7:11
+ _0 = const (); // scope 0 at $DIR/self_assign.rs:+0:11: +8:2
+ StorageDead(_4); // scope 1 at $DIR/self_assign.rs:+8:1: +8:2
+ StorageDead(_1); // scope 0 at $DIR/self_assign.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/self_assign.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/self_assign.rs b/tests/mir-opt/dataflow-const-prop/self_assign.rs
new file mode 100644
index 000000000..8de2195f9
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/self_assign.rs
@@ -0,0 +1,12 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR self_assign.main.DataflowConstProp.diff
+fn main() {
+ let mut a = 0;
+ a = a + 1;
+ a = a;
+
+ let mut b = &a;
+ b = b;
+ a = *b;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff
new file mode 100644
index 000000000..c09e4061e
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff
@@ -0,0 +1,23 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/self_assign_add.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/self_assign_add.rs:+1:9: +1:14
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/self_assign_add.rs:+1:9: +1:14
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/self_assign_add.rs:+1:9: +1:14
+ _1 = const 0_i32; // scope 0 at $DIR/self_assign_add.rs:+1:17: +1:18
+- _1 = Add(_1, const 1_i32); // scope 1 at $DIR/self_assign_add.rs:+2:5: +2:11
+- _1 = Add(_1, const 1_i32); // scope 1 at $DIR/self_assign_add.rs:+3:5: +3:11
++ _1 = const 1_i32; // scope 1 at $DIR/self_assign_add.rs:+2:5: +2:11
++ _1 = const 2_i32; // scope 1 at $DIR/self_assign_add.rs:+3:5: +3:11
+ _0 = const (); // scope 0 at $DIR/self_assign_add.rs:+0:11: +4:2
+ StorageDead(_1); // scope 0 at $DIR/self_assign_add.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/self_assign_add.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/self_assign_add.rs b/tests/mir-opt/dataflow-const-prop/self_assign_add.rs
new file mode 100644
index 000000000..e32827624
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/self_assign_add.rs
@@ -0,0 +1,8 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR self_assign_add.main.DataflowConstProp.diff
+fn main() {
+ let mut a = 0;
+ a += 1;
+ a += 1;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff
new file mode 100644
index 000000000..8126d4b85
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff
@@ -0,0 +1,56 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/sibling_ptr.rs:+0:11: +0:11
+ let mut _1: (u8, u8); // in scope 0 at $DIR/sibling_ptr.rs:+1:9: +1:14
+ let _2: (); // in scope 0 at $DIR/sibling_ptr.rs:+2:5: +5:6
+ let mut _4: *mut u8; // in scope 0 at $DIR/sibling_ptr.rs:+4:10: +4:18
+ let mut _5: *mut u8; // in scope 0 at $DIR/sibling_ptr.rs:+4:10: +4:11
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/sibling_ptr.rs:+1:9: +1:14
+ let _6: u8; // in scope 1 at $DIR/sibling_ptr.rs:+6:9: +6:11
+ scope 2 {
+ let _3: *mut u8; // in scope 2 at $DIR/sibling_ptr.rs:+3:13: +3:14
+ scope 3 {
+ debug p => _3; // in scope 3 at $DIR/sibling_ptr.rs:+3:13: +3:14
+ }
+ }
+ scope 4 {
+ debug x1 => _6; // in scope 4 at $DIR/sibling_ptr.rs:+6:9: +6:11
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/sibling_ptr.rs:+1:9: +1:14
+ Deinit(_1); // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33
+ (_1.0: u8) = const 0_u8; // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33
+ (_1.1: u8) = const 0_u8; // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33
+ StorageLive(_2); // scope 1 at $DIR/sibling_ptr.rs:+2:5: +5:6
+ StorageLive(_3); // scope 2 at $DIR/sibling_ptr.rs:+3:13: +3:14
+ _3 = &raw mut (_1.0: u8); // scope 2 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ StorageLive(_4); // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:18
+ StorageLive(_5); // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:11
+ _5 = _3; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:11
+ _4 = ptr::mut_ptr::<impl *mut u8>::add(move _5, const 1_usize) -> bb1; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:18
+ // mir::Constant
+ // + span: $DIR/sibling_ptr.rs:8:12: 8:15
+ // + literal: Const { ty: unsafe fn(*mut u8, usize) -> *mut u8 {ptr::mut_ptr::<impl *mut u8>::add}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_5); // scope 3 at $DIR/sibling_ptr.rs:+4:17: +4:18
+ (*_4) = const 1_u8; // scope 3 at $DIR/sibling_ptr.rs:+4:9: +4:22
+ StorageDead(_4); // scope 3 at $DIR/sibling_ptr.rs:+4:22: +4:23
+ _2 = const (); // scope 2 at $DIR/sibling_ptr.rs:+2:5: +5:6
+ StorageDead(_3); // scope 2 at $DIR/sibling_ptr.rs:+5:5: +5:6
+ StorageDead(_2); // scope 1 at $DIR/sibling_ptr.rs:+5:5: +5:6
+ StorageLive(_6); // scope 1 at $DIR/sibling_ptr.rs:+6:9: +6:11
+ _6 = (_1.1: u8); // scope 1 at $DIR/sibling_ptr.rs:+6:14: +6:17
+ _0 = const (); // scope 0 at $DIR/sibling_ptr.rs:+0:11: +7:2
+ StorageDead(_6); // scope 1 at $DIR/sibling_ptr.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/sibling_ptr.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/sibling_ptr.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs
new file mode 100644
index 000000000..87ef00d18
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs
@@ -0,0 +1,11 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR sibling_ptr.main.DataflowConstProp.diff
+fn main() {
+ let mut x: (u8, u8) = (0, 0);
+ unsafe {
+ let p = std::ptr::addr_of_mut!(x.0);
+ *p.add(1) = 1;
+ }
+ let x1 = x.1; // should not be propagated
+}
diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff
new file mode 100644
index 000000000..cfb2706c1
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff
@@ -0,0 +1,52 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/struct.rs:+0:11: +0:11
+ let mut _1: S; // in scope 0 at $DIR/struct.rs:+1:9: +1:14
+ let mut _3: i32; // in scope 0 at $DIR/struct.rs:+2:13: +2:16
+ let mut _5: i32; // in scope 0 at $DIR/struct.rs:+4:13: +4:14
+ let mut _6: i32; // in scope 0 at $DIR/struct.rs:+4:17: +4:20
+ scope 1 {
+ debug s => _1; // in scope 1 at $DIR/struct.rs:+1:9: +1:14
+ let _2: i32; // in scope 1 at $DIR/struct.rs:+2:9: +2:10
+ scope 2 {
+ debug a => _2; // in scope 2 at $DIR/struct.rs:+2:9: +2:10
+ let _4: i32; // in scope 2 at $DIR/struct.rs:+4:9: +4:10
+ scope 3 {
+ debug b => _4; // in scope 3 at $DIR/struct.rs:+4:9: +4:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/struct.rs:+1:9: +1:14
+ Deinit(_1); // scope 0 at $DIR/struct.rs:+1:17: +1:21
+ (_1.0: i32) = const 1_i32; // scope 0 at $DIR/struct.rs:+1:17: +1:21
+ StorageLive(_2); // scope 1 at $DIR/struct.rs:+2:9: +2:10
+ StorageLive(_3); // scope 1 at $DIR/struct.rs:+2:13: +2:16
+- _3 = (_1.0: i32); // scope 1 at $DIR/struct.rs:+2:13: +2:16
+- _2 = Add(move _3, const 2_i32); // scope 1 at $DIR/struct.rs:+2:13: +2:20
++ _3 = const 1_i32; // scope 1 at $DIR/struct.rs:+2:13: +2:16
++ _2 = const 3_i32; // scope 1 at $DIR/struct.rs:+2:13: +2:20
+ StorageDead(_3); // scope 1 at $DIR/struct.rs:+2:19: +2:20
+ (_1.0: i32) = const 3_i32; // scope 2 at $DIR/struct.rs:+3:5: +3:12
+ StorageLive(_4); // scope 2 at $DIR/struct.rs:+4:9: +4:10
+ StorageLive(_5); // scope 2 at $DIR/struct.rs:+4:13: +4:14
+- _5 = _2; // scope 2 at $DIR/struct.rs:+4:13: +4:14
++ _5 = const 3_i32; // scope 2 at $DIR/struct.rs:+4:13: +4:14
+ StorageLive(_6); // scope 2 at $DIR/struct.rs:+4:17: +4:20
+- _6 = (_1.0: i32); // scope 2 at $DIR/struct.rs:+4:17: +4:20
+- _4 = Add(move _5, move _6); // scope 2 at $DIR/struct.rs:+4:13: +4:20
++ _6 = const 3_i32; // scope 2 at $DIR/struct.rs:+4:17: +4:20
++ _4 = const 6_i32; // scope 2 at $DIR/struct.rs:+4:13: +4:20
+ StorageDead(_6); // scope 2 at $DIR/struct.rs:+4:19: +4:20
+ StorageDead(_5); // scope 2 at $DIR/struct.rs:+4:19: +4:20
+ _0 = const (); // scope 0 at $DIR/struct.rs:+0:11: +5:2
+ StorageDead(_4); // scope 2 at $DIR/struct.rs:+5:1: +5:2
+ StorageDead(_2); // scope 1 at $DIR/struct.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/struct.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/struct.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/struct.rs b/tests/mir-opt/dataflow-const-prop/struct.rs
new file mode 100644
index 000000000..841b279e0
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/struct.rs
@@ -0,0 +1,11 @@
+// unit-test: DataflowConstProp
+
+struct S(i32);
+
+// EMIT_MIR struct.main.DataflowConstProp.diff
+fn main() {
+ let mut s = S(1);
+ let a = s.0 + 2;
+ s.0 = 3;
+ let b = a + s.0;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff
new file mode 100644
index 000000000..8018400e7
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff
@@ -0,0 +1,40 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/terminator.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/terminator.rs:+1:9: +1:10
+ let _2: (); // in scope 0 at $DIR/terminator.rs:+3:5: +3:15
+ let mut _3: i32; // in scope 0 at $DIR/terminator.rs:+3:9: +3:14
+ let mut _4: i32; // in scope 0 at $DIR/terminator.rs:+3:9: +3:10
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/terminator.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/terminator.rs:+1:9: +1:10
+ _1 = const 1_i32; // scope 0 at $DIR/terminator.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/terminator.rs:+3:5: +3:15
+ StorageLive(_3); // scope 1 at $DIR/terminator.rs:+3:9: +3:14
+ StorageLive(_4); // scope 1 at $DIR/terminator.rs:+3:9: +3:10
+- _4 = _1; // scope 1 at $DIR/terminator.rs:+3:9: +3:10
+- _3 = Add(move _4, const 1_i32); // scope 1 at $DIR/terminator.rs:+3:9: +3:14
++ _4 = const 1_i32; // scope 1 at $DIR/terminator.rs:+3:9: +3:10
++ _3 = const 2_i32; // scope 1 at $DIR/terminator.rs:+3:9: +3:14
+ StorageDead(_4); // scope 1 at $DIR/terminator.rs:+3:13: +3:14
+- _2 = foo(move _3) -> bb1; // scope 1 at $DIR/terminator.rs:+3:5: +3:15
++ _2 = foo(const 2_i32) -> bb1; // scope 1 at $DIR/terminator.rs:+3:5: +3:15
+ // mir::Constant
+ // + span: $DIR/terminator.rs:9:5: 9:8
+ // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 1 at $DIR/terminator.rs:+3:14: +3:15
+ StorageDead(_2); // scope 1 at $DIR/terminator.rs:+3:15: +3:16
+ _0 = const (); // scope 0 at $DIR/terminator.rs:+0:11: +4:2
+ StorageDead(_1); // scope 0 at $DIR/terminator.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/terminator.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/terminator.rs b/tests/mir-opt/dataflow-const-prop/terminator.rs
new file mode 100644
index 000000000..d151f666a
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/terminator.rs
@@ -0,0 +1,10 @@
+// unit-test: DataflowConstProp
+
+fn foo(n: i32) {}
+
+// EMIT_MIR terminator.main.DataflowConstProp.diff
+fn main() {
+ let a = 1;
+ // Checks that we propagate into terminators.
+ foo(a + 1);
+}
diff --git a/tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff
new file mode 100644
index 000000000..e028def00
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff
@@ -0,0 +1,75 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/tuple.rs:+0:11: +0:11
+ let mut _1: (i32, i32); // in scope 0 at $DIR/tuple.rs:+1:9: +1:14
+ let mut _3: i32; // in scope 0 at $DIR/tuple.rs:+2:13: +2:22
+ let mut _4: i32; // in scope 0 at $DIR/tuple.rs:+2:13: +2:16
+ let mut _5: i32; // in scope 0 at $DIR/tuple.rs:+2:19: +2:22
+ let mut _7: i32; // in scope 0 at $DIR/tuple.rs:+4:13: +4:22
+ let mut _8: i32; // in scope 0 at $DIR/tuple.rs:+4:13: +4:16
+ let mut _9: i32; // in scope 0 at $DIR/tuple.rs:+4:19: +4:22
+ let mut _10: i32; // in scope 0 at $DIR/tuple.rs:+4:25: +4:26
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/tuple.rs:+1:9: +1:14
+ let _2: i32; // in scope 1 at $DIR/tuple.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _2; // in scope 2 at $DIR/tuple.rs:+2:9: +2:10
+ let _6: i32; // in scope 2 at $DIR/tuple.rs:+4:9: +4:10
+ scope 3 {
+ debug c => _6; // in scope 3 at $DIR/tuple.rs:+4:9: +4:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/tuple.rs:+1:9: +1:14
+ Deinit(_1); // scope 0 at $DIR/tuple.rs:+1:17: +1:23
+ (_1.0: i32) = const 1_i32; // scope 0 at $DIR/tuple.rs:+1:17: +1:23
+ (_1.1: i32) = const 2_i32; // scope 0 at $DIR/tuple.rs:+1:17: +1:23
+ StorageLive(_2); // scope 1 at $DIR/tuple.rs:+2:9: +2:10
+ StorageLive(_3); // scope 1 at $DIR/tuple.rs:+2:13: +2:22
+ StorageLive(_4); // scope 1 at $DIR/tuple.rs:+2:13: +2:16
+- _4 = (_1.0: i32); // scope 1 at $DIR/tuple.rs:+2:13: +2:16
++ _4 = const 1_i32; // scope 1 at $DIR/tuple.rs:+2:13: +2:16
+ StorageLive(_5); // scope 1 at $DIR/tuple.rs:+2:19: +2:22
+- _5 = (_1.1: i32); // scope 1 at $DIR/tuple.rs:+2:19: +2:22
+- _3 = Add(move _4, move _5); // scope 1 at $DIR/tuple.rs:+2:13: +2:22
++ _5 = const 2_i32; // scope 1 at $DIR/tuple.rs:+2:19: +2:22
++ _3 = const 3_i32; // scope 1 at $DIR/tuple.rs:+2:13: +2:22
+ StorageDead(_5); // scope 1 at $DIR/tuple.rs:+2:21: +2:22
+ StorageDead(_4); // scope 1 at $DIR/tuple.rs:+2:21: +2:22
+- _2 = Add(move _3, const 3_i32); // scope 1 at $DIR/tuple.rs:+2:13: +2:26
++ _2 = const 6_i32; // scope 1 at $DIR/tuple.rs:+2:13: +2:26
+ StorageDead(_3); // scope 1 at $DIR/tuple.rs:+2:25: +2:26
+ Deinit(_1); // scope 2 at $DIR/tuple.rs:+3:5: +3:15
+ (_1.0: i32) = const 2_i32; // scope 2 at $DIR/tuple.rs:+3:5: +3:15
+ (_1.1: i32) = const 3_i32; // scope 2 at $DIR/tuple.rs:+3:5: +3:15
+ StorageLive(_6); // scope 2 at $DIR/tuple.rs:+4:9: +4:10
+ StorageLive(_7); // scope 2 at $DIR/tuple.rs:+4:13: +4:22
+ StorageLive(_8); // scope 2 at $DIR/tuple.rs:+4:13: +4:16
+- _8 = (_1.0: i32); // scope 2 at $DIR/tuple.rs:+4:13: +4:16
++ _8 = const 2_i32; // scope 2 at $DIR/tuple.rs:+4:13: +4:16
+ StorageLive(_9); // scope 2 at $DIR/tuple.rs:+4:19: +4:22
+- _9 = (_1.1: i32); // scope 2 at $DIR/tuple.rs:+4:19: +4:22
+- _7 = Add(move _8, move _9); // scope 2 at $DIR/tuple.rs:+4:13: +4:22
++ _9 = const 3_i32; // scope 2 at $DIR/tuple.rs:+4:19: +4:22
++ _7 = const 5_i32; // scope 2 at $DIR/tuple.rs:+4:13: +4:22
+ StorageDead(_9); // scope 2 at $DIR/tuple.rs:+4:21: +4:22
+ StorageDead(_8); // scope 2 at $DIR/tuple.rs:+4:21: +4:22
+ StorageLive(_10); // scope 2 at $DIR/tuple.rs:+4:25: +4:26
+- _10 = _2; // scope 2 at $DIR/tuple.rs:+4:25: +4:26
+- _6 = Add(move _7, move _10); // scope 2 at $DIR/tuple.rs:+4:13: +4:26
++ _10 = const 6_i32; // scope 2 at $DIR/tuple.rs:+4:25: +4:26
++ _6 = const 11_i32; // scope 2 at $DIR/tuple.rs:+4:13: +4:26
+ StorageDead(_10); // scope 2 at $DIR/tuple.rs:+4:25: +4:26
+ StorageDead(_7); // scope 2 at $DIR/tuple.rs:+4:25: +4:26
+ _0 = const (); // scope 0 at $DIR/tuple.rs:+0:11: +5:2
+ StorageDead(_6); // scope 2 at $DIR/tuple.rs:+5:1: +5:2
+ StorageDead(_2); // scope 1 at $DIR/tuple.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/tuple.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/tuple.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/tests/mir-opt/dataflow-const-prop/tuple.rs b/tests/mir-opt/dataflow-const-prop/tuple.rs
new file mode 100644
index 000000000..92c70eab0
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/tuple.rs
@@ -0,0 +1,9 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR tuple.main.DataflowConstProp.diff
+fn main() {
+ let mut a = (1, 2);
+ let b = a.0 + a.1 + 3;
+ a = (2, 3);
+ let c = a.0 + a.1 + b;
+}
diff --git a/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff
new file mode 100644
index 000000000..cd3b792fb
--- /dev/null
+++ b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff
@@ -0,0 +1,76 @@
+- // 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
++ let mut _4: bool; // in scope 0 at $DIR/cycle.rs:+3:11: +3:17
++ let _5: i32; // in scope 0 at $DIR/cycle.rs:+4:13: +4:17
+ scope 1 {
+- debug temp => _6; // in scope 1 at $DIR/cycle.rs:+4:13: +4:17
++ debug temp => _5; // 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
++ StorageLive(_4); // scope 0 at $DIR/cycle.rs:+3:11: +3:17
++ _4 = 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) -> [0: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17
++ switchInt(move _4) -> [0: 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
+- 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
+- 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
+- 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
+- StorageDead(_9); // scope 1 at $DIR/cycle.rs:+7:16: +7:17
+- _4 = const (); // scope 0 at $DIR/cycle.rs:+3:18: +8:6
+- StorageDead(_6); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
++ StorageLive(_5); // scope 0 at $DIR/cycle.rs:+4:13: +4:17
+ StorageDead(_5); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
++ StorageDead(_4); // 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
++ StorageDead(_4); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
+ return; // scope 0 at $DIR/cycle.rs:+9:2: +9:2
+ }
+ }
+
diff --git a/tests/mir-opt/dead-store-elimination/cycle.rs b/tests/mir-opt/dead-store-elimination/cycle.rs
new file mode 100644
index 000000000..b35ce0bcb
--- /dev/null
+++ b/tests/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/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff b/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff
new file mode 100644
index 000000000..89f1846b4
--- /dev/null
+++ b/tests/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/tests/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff b/tests/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff
new file mode 100644
index 000000000..b5f98233b
--- /dev/null
+++ b/tests/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:11: +0:13
+ _0 = const (); // scope 0 at $DIR/provenance_soundness.rs:+0:25: +0:27
+ return; // scope 0 at $DIR/provenance_soundness.rs:+0:27: +0:27
+ }
+ }
+
diff --git a/tests/mir-opt/dead-store-elimination/provenance_soundness.rs b/tests/mir-opt/dead-store-elimination/provenance_soundness.rs
new file mode 100644
index 000000000..11314e990
--- /dev/null
+++ b/tests/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/tests/mir-opt/deaggregator_test.bar.Deaggregator.diff b/tests/mir-opt/deaggregator_test.bar.Deaggregator.diff
new file mode 100644
index 000000000..db136485a
--- /dev/null
+++ b/tests/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/tests/mir-opt/deaggregator_test.rs b/tests/mir-opt/deaggregator_test.rs
new file mode 100644
index 000000000..ee59402af
--- /dev/null
+++ b/tests/mir-opt/deaggregator_test.rs
@@ -0,0 +1,17 @@
+// unit-test: Deaggregator
+
+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/tests/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff b/tests/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff
new file mode 100644
index 000000000..f28c2b482
--- /dev/null
+++ b/tests/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/tests/mir-opt/deaggregator_test_enum.rs b/tests/mir-opt/deaggregator_test_enum.rs
new file mode 100644
index 000000000..ea402dafd
--- /dev/null
+++ b/tests/mir-opt/deaggregator_test_enum.rs
@@ -0,0 +1,19 @@
+// unit-test: Deaggregator
+
+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/tests/mir-opt/deaggregator_test_enum_2.rs b/tests/mir-opt/deaggregator_test_enum_2.rs
new file mode 100644
index 000000000..955c31732
--- /dev/null
+++ b/tests/mir-opt/deaggregator_test_enum_2.rs
@@ -0,0 +1,21 @@
+// unit-test: Deaggregator
+// 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/tests/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff b/tests/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff
new file mode 100644
index 000000000..210d3849e
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/deaggregator_test_multiple.rs b/tests/mir-opt/deaggregator_test_multiple.rs
new file mode 100644
index 000000000..46305fe21
--- /dev/null
+++ b/tests/mir-opt/deaggregator_test_multiple.rs
@@ -0,0 +1,17 @@
+// unit-test: Deaggregator
+// 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/tests/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff b/tests/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff
new file mode 100644
index 000000000..cf5da273c
--- /dev/null
+++ b/tests/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/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff
new file mode 100644
index 000000000..3b1f81175
--- /dev/null
+++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff
@@ -0,0 +1,100 @@
+- // 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: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ let mut _6: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ let mut _7: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ let mut _8: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ let mut _9: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
+ StorageLive(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
+ _3 = &(*_1); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
+ _2 = core::str::<impl str>::as_bytes(move _3) -> bb1; // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
+ // mir::Constant
+ // + span: $DIR/deduplicate_blocks.rs:5:13: 5:21
+ // + literal: Const { ty: for<'a> fn(&'a str) -> &'a [u8] {core::str::<impl str>::as_bytes}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:22: +1:23
+ _7 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ _8 = const 4_usize; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ _9 = Ge(move _7, move _8); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ switchInt(move _9) -> [0: bb6, otherwise: bb2]; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ }
+
+ bb2: {
+ switchInt((*_2)[0 of 4]) -> [47: bb3, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb3: {
+ switchInt((*_2)[1 of 4]) -> [47: bb4, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb4: {
+ switchInt((*_2)[2 of 4]) -> [47: bb5, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb5: {
+- switchInt((*_2)[3 of 4]) -> [47: bb11, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
++ switchInt((*_2)[3 of 4]) -> [47: bb10, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb6: {
+ _4 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ _5 = const 3_usize; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ _6 = Ge(move _4, move _5); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ switchInt(move _6) -> [0: bb10, otherwise: bb7]; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ }
+
+ bb7: {
+ switchInt((*_2)[0 of 3]) -> [47: bb8, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb8: {
+ switchInt((*_2)[1 of 3]) -> [47: bb9, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb9: {
+- switchInt((*_2)[2 of 3]) -> [47: bb12, 33: bb13, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
++ switchInt((*_2)[2 of 3]) -> [47: bb11, 33: bb11, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb10: {
+- _0 = const false; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19
+- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19
+- }
+-
+- bb11: {
+ _0 = const false; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46
+- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46
++ goto -> bb12; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46
+ }
+
+- bb12: {
+- _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39
+- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39
+- }
+-
+- bb13: {
++ bb11: {
+ _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39
+- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39
++ goto -> bb12; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39
+ }
+
+- bb14: {
++ bb12: {
+ StorageDead(_2); // scope 0 at $DIR/deduplicate_blocks.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/deduplicate_blocks.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/tests/mir-opt/deduplicate_blocks.rs b/tests/mir-opt/deduplicate_blocks.rs
new file mode 100644
index 000000000..2b9eed99e
--- /dev/null
+++ b/tests/mir-opt/deduplicate_blocks.rs
@@ -0,0 +1,15 @@
+// unit-test: DeduplicateBlocks
+
+// EMIT_MIR deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff
+pub const fn is_line_doc_comment_2(s: &str) -> bool {
+ match s.as_bytes() {
+ [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/tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir b/tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir
new file mode 100644
index 000000000..9597a0c83
--- /dev/null
+++ b/tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir
@@ -0,0 +1,74 @@
+// MIR for `foo` after PreCodegen
+
+fn foo(_1: Option<String>) -> i32 {
+ debug s => _1; // in scope 0 at $DIR/string.rs:+0:12: +0:13
+ let mut _0: i32; // return place in scope 0 at $DIR/string.rs:+0:34: +0:37
+ let mut _2: &std::string::String; // in scope 0 at $DIR/string.rs:+2:14: +2:17
+ let mut _3: &str; // in scope 0 at $DIR/string.rs:+2:14: +2:17
+ let mut _4: bool; // in scope 0 at $DIR/string.rs:+2:14: +2:17
+ let mut _5: isize; // in scope 0 at $DIR/string.rs:+2:9: +2:18
+ let _6: std::option::Option<std::string::String>; // in scope 0 at $DIR/string.rs:+3:9: +3:10
+ let mut _7: bool; // in scope 0 at $DIR/string.rs:+5:1: +5:2
+ scope 1 {
+ debug s => _6; // in scope 1 at $DIR/string.rs:+3:9: +3:10
+ }
+
+ bb0: {
+ _7 = const false; // scope 0 at $DIR/string.rs:+1:11: +1:12
+ _7 = const true; // scope 0 at $DIR/string.rs:+1:11: +1:12
+ _5 = discriminant(_1); // scope 0 at $DIR/string.rs:+1:11: +1:12
+ switchInt(move _5) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/string.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ StorageLive(_6); // scope 0 at $DIR/string.rs:+3:9: +3:10
+ _7 = const false; // scope 0 at $DIR/string.rs:+3:9: +3:10
+ _6 = move _1; // scope 0 at $DIR/string.rs:+3:9: +3:10
+ _0 = const 4321_i32; // scope 1 at $DIR/string.rs:+3:14: +3:18
+ drop(_6) -> bb6; // scope 0 at $DIR/string.rs:+3:17: +3:18
+ }
+
+ bb2: {
+ _2 = &((_1 as Some).0: std::string::String); // scope 0 at $DIR/string.rs:+2:14: +2:17
+ _3 = <String as Deref>::deref(move _2) -> bb3; // scope 0 at $DIR/string.rs:+2:14: +2:17
+ // mir::Constant
+ // + span: $DIR/string.rs:9:14: 9:17
+ // + literal: Const { ty: for<'a> fn(&'a String) -> &'a <String as Deref>::Target {<String as Deref>::deref}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ _4 = <str as PartialEq>::eq(_3, const "a") -> bb4; // scope 0 at $DIR/string.rs:+2:14: +2:17
+ // mir::Constant
+ // + span: $DIR/string.rs:9:14: 9:17
+ // + literal: Const { ty: for<'a, 'b> fn(&'a str, &'b str) -> bool {<str as PartialEq>::eq}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $DIR/string.rs:9:14: 9:17
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ }
+
+ bb4: {
+ switchInt(move _4) -> [0: bb1, otherwise: bb5]; // scope 0 at $DIR/string.rs:+2:14: +2:17
+ }
+
+ bb5: {
+ _0 = const 1234_i32; // scope 0 at $DIR/string.rs:+2:22: +2:26
+ goto -> bb9; // scope 0 at $DIR/string.rs:+2:22: +2:26
+ }
+
+ bb6: {
+ StorageDead(_6); // scope 0 at $DIR/string.rs:+3:17: +3:18
+ goto -> bb9; // scope 0 at $DIR/string.rs:+3:17: +3:18
+ }
+
+ bb7: {
+ return; // scope 0 at $DIR/string.rs:+5:2: +5:2
+ }
+
+ bb8: {
+ drop(_1) -> bb7; // scope 0 at $DIR/string.rs:+5:1: +5:2
+ }
+
+ bb9: {
+ switchInt(_7) -> [0: bb7, otherwise: bb8]; // scope 0 at $DIR/string.rs:+5:1: +5:2
+ }
+}
diff --git a/tests/mir-opt/deref-patterns/string.rs b/tests/mir-opt/deref-patterns/string.rs
new file mode 100644
index 000000000..3a99c44aa
--- /dev/null
+++ b/tests/mir-opt/deref-patterns/string.rs
@@ -0,0 +1,12 @@
+// compile-flags: -Z mir-opt-level=0 -C panic=abort
+
+#![feature(string_deref_patterns)]
+#![crate_type = "lib"]
+
+// EMIT_MIR string.foo.PreCodegen.after.mir
+pub fn foo(s: Option<String>) -> i32 {
+ match s {
+ Some("a") => 1234,
+ s => 4321,
+ }
+}
diff --git a/tests/mir-opt/derefer_complex_case.main.Derefer.diff b/tests/mir-opt/derefer_complex_case.main.Derefer.diff
new file mode 100644
index 000000000..fa3eeedc4
--- /dev/null
+++ b/tests/mir-opt/derefer_complex_case.main.Derefer.diff
@@ -0,0 +1,105 @@
+- // 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 _; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ // mir::Constant
+ // + span: $DIR/derefer_complex_case.rs:6:17: 6:26
+ // + literal: Const { ty: &[i32; 2], val: Unevaluated(main, [], Some(promoted[0])) }
+ _2 = &(*_14); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ _1 = <&[i32; 2] as IntoIterator>::into_iter(move _2) -> bb1; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ // mir::Constant
+ // + span: $DIR/derefer_complex_case.rs:6:17: 6: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:6:17: 6:26
+ // + literal: Const { ty: for<'a> fn(&'a 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: bb6, 1: 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
++ _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
+ 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:6:29: 6: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/tests/mir-opt/derefer_complex_case.rs b/tests/mir-opt/derefer_complex_case.rs
new file mode 100644
index 000000000..dc48cee95
--- /dev/null
+++ b/tests/mir-opt/derefer_complex_case.rs
@@ -0,0 +1,7 @@
+// unit-test: Derefer
+// EMIT_MIR derefer_complex_case.main.Derefer.diff
+// ignore-wasm32
+
+fn main() {
+ for &foo in &[42, 43] { drop(foo) }
+}
diff --git a/tests/mir-opt/derefer_inline_test.main.Derefer.diff b/tests/mir-opt/derefer_inline_test.main.Derefer.diff
new file mode 100644
index 000000000..3540df308
--- /dev/null
+++ b/tests/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:11:5: 11: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:11:9: 11: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/tests/mir-opt/derefer_inline_test.rs b/tests/mir-opt/derefer_inline_test.rs
new file mode 100644
index 000000000..cc06a7dd8
--- /dev/null
+++ b/tests/mir-opt/derefer_inline_test.rs
@@ -0,0 +1,12 @@
+// unit-test: Derefer
+// 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/tests/mir-opt/derefer_terminator_test.main.Derefer.diff b/tests/mir-opt/derefer_terminator_test.main.Derefer.diff
new file mode 100644
index 000000000..ab2388d13
--- /dev/null
+++ b/tests/mir-opt/derefer_terminator_test.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_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:6:13: 6: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:7:13: 7: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))))) -> [0: bb3, otherwise: bb4]; // 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
++ _11 = deref_copy (*_10); // 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
++ switchInt((*_12)) -> [0: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
+ }
+
+ bb3: {
+ _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: {
+ 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/tests/mir-opt/derefer_terminator_test.rs b/tests/mir-opt/derefer_terminator_test.rs
new file mode 100644
index 000000000..d6750c29d
--- /dev/null
+++ b/tests/mir-opt/derefer_terminator_test.rs
@@ -0,0 +1,17 @@
+// unit-test: Derefer
+// 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/tests/mir-opt/derefer_test.main.Derefer.diff b/tests/mir-opt/derefer_test.main.Derefer.diff
new file mode 100644
index 000000000..87306d818
--- /dev/null
+++ b/tests/mir-opt/derefer_test.main.Derefer.diff
@@ -0,0 +1,50 @@
+- // 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
++ _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
+ 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
++ _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
+ _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/tests/mir-opt/derefer_test.rs b/tests/mir-opt/derefer_test.rs
new file mode 100644
index 000000000..fad0fe8eb
--- /dev/null
+++ b/tests/mir-opt/derefer_test.rs
@@ -0,0 +1,8 @@
+// unit-test: Derefer
+// 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/tests/mir-opt/derefer_test_multiple.main.Derefer.diff b/tests/mir-opt/derefer_test_multiple.main.Derefer.diff
new file mode 100644
index 000000000..3e40db118
--- /dev/null
+++ b/tests/mir-opt/derefer_test_multiple.main.Derefer.diff
@@ -0,0 +1,80 @@
+- // 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
++ _10 = deref_copy (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // 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
++ _12 = deref_copy ((*_11).1: &mut (i32, i32)); // 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
+ 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
++ _13 = deref_copy (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // 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
++ _15 = deref_copy ((*_14).1: &mut (i32, i32)); // 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
+ _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/tests/mir-opt/derefer_test_multiple.rs b/tests/mir-opt/derefer_test_multiple.rs
new file mode 100644
index 000000000..0b3888b07
--- /dev/null
+++ b/tests/mir-opt/derefer_test_multiple.rs
@@ -0,0 +1,10 @@
+// unit-test: Derefer
+// 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/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff b/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff
new file mode 100644
index 000000000..9c7296632
--- /dev/null
+++ b/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff
@@ -0,0 +1,75 @@
+- // MIR for `foo` before DestinationPropagation
++ // MIR for `foo` after DestinationPropagation
+
+ fn foo() -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/branch.rs:+0:13: +0:16
+ 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
++ debug x => _0; // 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
++ debug y => _0; // 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
++ nop; // scope 0 at $DIR/branch.rs:+1:9: +1:10
++ _0 = 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
++ nop; // 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) -> [0: bb4, otherwise: bb3]; // scope 1 at $DIR/branch.rs:+3:16: +3:22
+ }
+
+ bb3: {
+- _2 = _1; // scope 1 at $DIR/branch.rs:+4:9: +4:10
++ 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
+- _2 = _1; // scope 1 at $DIR/branch.rs:+7:9: +7:10
++ 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
+- _0 = _2; // scope 2 at $DIR/branch.rs:+10:5: +10:6
+- StorageDead(_2); // scope 1 at $DIR/branch.rs:+11:1: +11:2
+- StorageDead(_1); // scope 0 at $DIR/branch.rs:+11:1: +11:2
++ nop; // scope 2 at $DIR/branch.rs:+10:5: +10:6
++ nop; // scope 1 at $DIR/branch.rs:+11:1: +11:2
++ nop; // scope 0 at $DIR/branch.rs:+11:1: +11:2
+ return; // scope 0 at $DIR/branch.rs:+11:2: +11:2
+ }
+ }
+
diff --git a/tests/mir-opt/dest-prop/branch.rs b/tests/mir-opt/dest-prop/branch.rs
new file mode 100644
index 000000000..898c908b1
--- /dev/null
+++ b/tests/mir-opt/dest-prop/branch.rs
@@ -0,0 +1,27 @@
+//! Tests that assignment in both branches of an `if` are eliminated.
+// unit-test: DestinationPropagation
+fn val() -> i32 {
+ 1
+}
+
+fn cond() -> bool {
+ true
+}
+
+// EMIT_MIR branch.foo.DestinationPropagation.diff
+fn foo() -> i32 {
+ let x = val();
+
+ let y = if cond() {
+ x
+ } else {
+ val();
+ x
+ };
+
+ y
+}
+
+fn main() {
+ foo();
+}
diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff
new file mode 100644
index 000000000..4343a5935
--- /dev/null
+++ b/tests/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 => _1; // 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
+ _1 = const 123_i32; // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12
+- _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
+- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2
++ 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/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff
new file mode 100644
index 000000000..298991b5a
--- /dev/null
+++ b/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff
@@ -0,0 +1,32 @@
+- // MIR for `bar` before DestinationPropagation
++ // MIR for `bar` after DestinationPropagation
+
+ fn bar(_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 _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
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
++ _2 = dummy(move _1) -> 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
++ nop; // 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
+ _1 = const 5_u8; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
+ _0 = const (); // 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/tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff
new file mode 100644
index 000000000..bc88787e6
--- /dev/null
+++ b/tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff
@@ -0,0 +1,22 @@
+- // MIR for `baz` before DestinationPropagation
++ // MIR for `baz` after DestinationPropagation
+
+ fn baz(_1: i32) -> i32 {
+ debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
+ let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:23: +0:26
+ 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
+- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+- _1 = move _2; // 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:+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
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
+ return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff
new file mode 100644
index 000000000..d37a9f71d
--- /dev/null
+++ b/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff
@@ -0,0 +1,32 @@
+- // 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
++ nop; // 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
++ _1 = 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
+- _1 = move _2; // 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:+2:5: +2:17
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
+ _0 = const (); // 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/tests/mir-opt/dest-prop/copy_propagation_arg.rs b/tests/mir-opt/dest-prop/copy_propagation_arg.rs
new file mode 100644
index 000000000..31be6c931
--- /dev/null
+++ b/tests/mir-opt/dest-prop/copy_propagation_arg.rs
@@ -0,0 +1,40 @@
+// Check that DestinationPropagation does not propagate an assignment to a function argument
+// (doing so can break usages of the original argument value)
+// unit-test: DestinationPropagation
+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) -> i32 {
+ // self-assignment to a function argument should be eliminated
+ x = 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/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff b/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff
new file mode 100644
index 000000000..cfc203c5f
--- /dev/null
+++ b/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff
@@ -0,0 +1,77 @@
+- // 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
++ debug x => _6; // 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
++ debug y => _6; // 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
++ debug z => _6; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ 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
++ nop; // scope 0 at $DIR/cycle.rs:+1:9: +1:14
++ _6 = 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
+- _2 = _1; // scope 1 at $DIR/cycle.rs:+2:13: +2:14
+- StorageLive(_3); // scope 2 at $DIR/cycle.rs:+3:9: +3:10
+- _3 = _2; // scope 2 at $DIR/cycle.rs:+3:13: +3:14
+- StorageLive(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+- _4 = _3; // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+- _1 = move _4; // scope 3 at $DIR/cycle.rs:+4:5: +4:10
+- StorageDead(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10
++ nop; // scope 1 at $DIR/cycle.rs:+2:9: +2:10
++ nop; // scope 1 at $DIR/cycle.rs:+2:13: +2:14
++ nop; // scope 2 at $DIR/cycle.rs:+3:9: +3:10
++ nop; // scope 2 at $DIR/cycle.rs:+3:13: +3:14
++ nop; // 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
++ nop; // 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
+- _6 = _1; // scope 3 at $DIR/cycle.rs:+6:10: +6:11
++ nop; // scope 3 at $DIR/cycle.rs:+6:10: +6:11
++ nop; // scope 3 at $DIR/cycle.rs:+6:10: +6:11
+ _5 = std::mem::drop::<i32>(move _6) -> bb2; // scope 3 at $DIR/cycle.rs:+6:5: +6:12
+ // mir::Constant
+ // + span: $DIR/cycle.rs:14:5: 14:9
+ // + literal: Const { ty: fn(i32) {std::mem::drop::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+- StorageDead(_6); // scope 3 at $DIR/cycle.rs:+6:11: +6:12
++ nop; // scope 3 at $DIR/cycle.rs:+6:11: +6:12
+ StorageDead(_5); // scope 3 at $DIR/cycle.rs:+6:12: +6:13
+ _0 = const (); // scope 0 at $DIR/cycle.rs:+0:11: +7:2
+- 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
++ nop; // scope 2 at $DIR/cycle.rs:+7:1: +7:2
++ nop; // scope 1 at $DIR/cycle.rs:+7:1: +7:2
++ nop; // scope 0 at $DIR/cycle.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/cycle.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/tests/mir-opt/dest-prop/cycle.rs b/tests/mir-opt/dest-prop/cycle.rs
new file mode 100644
index 000000000..6182878f3
--- /dev/null
+++ b/tests/mir-opt/dest-prop/cycle.rs
@@ -0,0 +1,15 @@
+//! Tests that cyclic assignments don't hang DestinationPropagation, and result in reasonable code.
+// unit-test: DestinationPropagation
+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/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir b/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir
new file mode 100644
index 000000000..63cac133b
--- /dev/null
+++ b/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir
@@ -0,0 +1,34 @@
+// MIR for `f` after DestinationPropagation
+
+fn f(_1: usize) -> usize {
+ debug a => _1; // in scope 0 at $DIR/dead_stores_79191.rs:+0:6: +0:11
+ let mut _0: usize; // return place in scope 0 at $DIR/dead_stores_79191.rs:+0:23: +0:28
+ let _2: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+1:9: +1:10
+ let mut _3: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+3:9: +3:10
+ let mut _4: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+4:8: +4:9
+ scope 1 {
+ debug b => _3; // in scope 1 at $DIR/dead_stores_79191.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ nop; // scope 0 at $DIR/dead_stores_79191.rs:+1:9: +1:10
+ _3 = _1; // scope 0 at $DIR/dead_stores_79191.rs:+1:13: +1:14
+ _1 = const 5_usize; // scope 1 at $DIR/dead_stores_79191.rs:+2:5: +2:10
+ nop; // scope 1 at $DIR/dead_stores_79191.rs:+3:9: +3:10
+ nop; // scope 1 at $DIR/dead_stores_79191.rs:+3:9: +3:10
+ _1 = move _3; // scope 1 at $DIR/dead_stores_79191.rs:+3:5: +3:10
+ nop; // scope 1 at $DIR/dead_stores_79191.rs:+3:9: +3:10
+ nop; // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9
+ nop; // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9
+ _0 = id::<usize>(move _1) -> bb1; // scope 1 at $DIR/dead_stores_79191.rs:+4:5: +4:10
+ // mir::Constant
+ // + span: $DIR/dead_stores_79191.rs:12:5: 12:7
+ // + literal: Const { ty: fn(usize) -> usize {id::<usize>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ nop; // scope 1 at $DIR/dead_stores_79191.rs:+4:9: +4:10
+ nop; // scope 0 at $DIR/dead_stores_79191.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/dead_stores_79191.rs:+5:2: +5:2
+ }
+}
diff --git a/tests/mir-opt/dest-prop/dead_stores_79191.rs b/tests/mir-opt/dest-prop/dead_stores_79191.rs
new file mode 100644
index 000000000..43e0bf664
--- /dev/null
+++ b/tests/mir-opt/dest-prop/dead_stores_79191.rs
@@ -0,0 +1,17 @@
+// unit-test: DestinationPropagation
+
+fn id<T>(x: T) -> T {
+ x
+}
+
+// EMIT_MIR dead_stores_79191.f.DestinationPropagation.after.mir
+fn f(mut a: usize) -> usize {
+ let b = a;
+ a = 5;
+ a = b;
+ id(a)
+}
+
+fn main() {
+ f(0);
+}
diff --git a/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir b/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir
new file mode 100644
index 000000000..26068931a
--- /dev/null
+++ b/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir
@@ -0,0 +1,33 @@
+// MIR for `f` after DestinationPropagation
+
+fn f(_1: usize) -> usize {
+ debug a => _1; // in scope 0 at $DIR/dead_stores_better.rs:+0:10: +0:15
+ let mut _0: usize; // return place in scope 0 at $DIR/dead_stores_better.rs:+0:27: +0:32
+ let _2: usize; // in scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10
+ let mut _3: usize; // in scope 0 at $DIR/dead_stores_better.rs:+3:9: +3:10
+ let mut _4: usize; // in scope 0 at $DIR/dead_stores_better.rs:+4:8: +4:9
+ scope 1 {
+ debug b => _1; // in scope 1 at $DIR/dead_stores_better.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ nop; // scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10
+ nop; // scope 0 at $DIR/dead_stores_better.rs:+1:13: +1:14
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+3:5: +3:10
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9
+ _0 = id::<usize>(move _1) -> bb1; // scope 1 at $DIR/dead_stores_better.rs:+4:5: +4:10
+ // mir::Constant
+ // + span: $DIR/dead_stores_better.rs:16:5: 16:7
+ // + literal: Const { ty: fn(usize) -> usize {id::<usize>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+4:9: +4:10
+ nop; // scope 0 at $DIR/dead_stores_better.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/dead_stores_better.rs:+5:2: +5:2
+ }
+}
diff --git a/tests/mir-opt/dest-prop/dead_stores_better.rs b/tests/mir-opt/dest-prop/dead_stores_better.rs
new file mode 100644
index 000000000..003ad57d8
--- /dev/null
+++ b/tests/mir-opt/dest-prop/dead_stores_better.rs
@@ -0,0 +1,21 @@
+// This is a copy of the `dead_stores_79191` test, except that we turn on DSE. This demonstrates
+// that that pass enables this one to do more optimizations.
+
+// unit-test: DestinationPropagation
+// compile-flags: -Zmir-enable-passes=+DeadStoreElimination
+
+fn id<T>(x: T) -> T {
+ x
+}
+
+// EMIT_MIR dead_stores_better.f.DestinationPropagation.after.mir
+pub fn f(mut a: usize) -> usize {
+ let b = a;
+ a = 5;
+ a = b;
+ id(a)
+}
+
+fn main() {
+ f(0);
+}
diff --git a/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff
new file mode 100644
index 000000000..c2a3a0025
--- /dev/null
+++ b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff
@@ -0,0 +1,43 @@
+- // MIR for `nrvo` before DestinationPropagation
++ // MIR for `nrvo` after DestinationPropagation
+
+ fn nrvo(_1: for<'a> fn(&'a 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<'a> fn(&'a 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
++ nop; // scope 1 at $DIR/simple.rs:+2:5: +2:9
++ nop; // 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
++ _3 = move _1(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
++ nop; // 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/tests/mir-opt/dest-prop/simple.rs b/tests/mir-opt/dest-prop/simple.rs
new file mode 100644
index 000000000..d4c27228f
--- /dev/null
+++ b/tests/mir-opt/dest-prop/simple.rs
@@ -0,0 +1,14 @@
+//! Copy of `nrvo-simple.rs`, to ensure that full dest-prop handles it too.
+// unit-test: DestinationPropagation
+// 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/tests/mir-opt/dest-prop/union.main.DestinationPropagation.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.diff
new file mode 100644
index 000000000..fbed31788
--- /dev/null
+++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.diff
@@ -0,0 +1,35 @@
+- // 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 mut _3: 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 => _3; // 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: {
+ StorageDead(_2); // scope 0 at $DIR/union.rs:+5:29: +5:30
+ StorageLive(_3); // scope 1 at $DIR/union.rs:+7:10: +7:26
+ StorageDead(_3); // scope 1 at $DIR/union.rs:+7:26: +7:27
+ 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/tests/mir-opt/dest-prop/union.rs b/tests/mir-opt/dest-prop/union.rs
new file mode 100644
index 000000000..eb6cb09fc
--- /dev/null
+++ b/tests/mir-opt/dest-prop/union.rs
@@ -0,0 +1,16 @@
+//! Tests that we can propagate 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/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff b/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff
new file mode 100644
index 000000000..9ea756c27
--- /dev/null
+++ b/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff
@@ -0,0 +1,86 @@
+- // MIR for `f` before DestinationPropagation
++ // MIR for `f` after DestinationPropagation
+
+ fn f(_1: T) -> () {
+ debug a => _1; // in scope 0 at $DIR/unreachable.rs:+0:19: +0:20
+ let mut _0: (); // return place in scope 0 at $DIR/unreachable.rs:+0:25: +0:25
+ let _2: T; // in scope 0 at $DIR/unreachable.rs:+1:9: +1:10
+ let mut _3: bool; // in scope 0 at $DIR/unreachable.rs:+2:8: +2:13
+ let _4: (); // in scope 0 at $DIR/unreachable.rs:+3:9: +3:16
+ let mut _5: T; // in scope 0 at $DIR/unreachable.rs:+3:11: +3:12
+ let mut _6: T; // in scope 0 at $DIR/unreachable.rs:+3:14: +3:15
+ let _7: (); // in scope 0 at $DIR/unreachable.rs:+5:9: +5:16
+ let mut _8: T; // in scope 0 at $DIR/unreachable.rs:+5:11: +5:12
+ let mut _9: T; // in scope 0 at $DIR/unreachable.rs:+5:14: +5:15
+ scope 1 {
+- debug b => _2; // in scope 1 at $DIR/unreachable.rs:+1:9: +1:10
++ debug b => _1; // in scope 1 at $DIR/unreachable.rs:+1:9: +1:10
+ }
+
+ bb0: {
+- StorageLive(_2); // scope 0 at $DIR/unreachable.rs:+1:9: +1:10
+- _2 = _1; // scope 0 at $DIR/unreachable.rs:+1:13: +1:14
++ nop; // scope 0 at $DIR/unreachable.rs:+1:9: +1:10
++ nop; // scope 0 at $DIR/unreachable.rs:+1:13: +1:14
+ StorageLive(_3); // scope 1 at $DIR/unreachable.rs:+2:8: +2:13
+ _3 = const false; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13
+- goto -> bb3; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13
++ goto -> bb1; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13
+ }
+
+ bb1: {
+- StorageLive(_4); // scope 1 at $DIR/unreachable.rs:+3:9: +3:16
+- StorageLive(_5); // scope 1 at $DIR/unreachable.rs:+3:11: +3:12
+- _5 = _1; // scope 1 at $DIR/unreachable.rs:+3:11: +3:12
+- StorageLive(_6); // scope 1 at $DIR/unreachable.rs:+3:14: +3:15
+- _6 = _2; // scope 1 at $DIR/unreachable.rs:+3:14: +3:15
+- _4 = g::<T>(move _5, move _6) -> bb2; // scope 1 at $DIR/unreachable.rs:+3:9: +3:16
+- // mir::Constant
+- // + span: $DIR/unreachable.rs:11:9: 11:10
+- // + literal: Const { ty: fn(T, T) {g::<T>}, val: Value(<ZST>) }
+- }
+-
+- bb2: {
+- StorageDead(_6); // scope 1 at $DIR/unreachable.rs:+3:15: +3:16
+- StorageDead(_5); // scope 1 at $DIR/unreachable.rs:+3:15: +3:16
+- StorageDead(_4); // scope 1 at $DIR/unreachable.rs:+3:16: +3:17
+- _0 = const (); // scope 1 at $DIR/unreachable.rs:+2:14: +4:6
+- goto -> bb5; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6
+- }
+-
+- bb3: {
+ StorageLive(_7); // scope 1 at $DIR/unreachable.rs:+5:9: +5:16
+- StorageLive(_8); // scope 1 at $DIR/unreachable.rs:+5:11: +5:12
+- _8 = _2; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12
++ nop; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12
++ nop; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12
+ StorageLive(_9); // scope 1 at $DIR/unreachable.rs:+5:14: +5:15
+- _9 = _2; // scope 1 at $DIR/unreachable.rs:+5:14: +5:15
+- _7 = g::<T>(move _8, move _9) -> bb4; // scope 1 at $DIR/unreachable.rs:+5:9: +5:16
++ _9 = _1; // scope 1 at $DIR/unreachable.rs:+5:14: +5:15
++ _7 = g::<T>(move _1, move _9) -> bb2; // scope 1 at $DIR/unreachable.rs:+5:9: +5:16
+ // mir::Constant
+ // + span: $DIR/unreachable.rs:13:9: 13:10
+ // + literal: Const { ty: fn(T, T) {g::<T>}, val: Value(<ZST>) }
+ }
+
+- bb4: {
++ bb2: {
+ StorageDead(_9); // scope 1 at $DIR/unreachable.rs:+5:15: +5:16
+- StorageDead(_8); // scope 1 at $DIR/unreachable.rs:+5:15: +5:16
++ nop; // scope 1 at $DIR/unreachable.rs:+5:15: +5:16
+ StorageDead(_7); // scope 1 at $DIR/unreachable.rs:+5:16: +5:17
+ _0 = const (); // scope 1 at $DIR/unreachable.rs:+4:12: +6:6
+- goto -> bb5; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6
++ goto -> bb3; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6
+ }
+
+- bb5: {
++ bb3: {
+ StorageDead(_3); // scope 1 at $DIR/unreachable.rs:+6:5: +6:6
+- StorageDead(_2); // scope 0 at $DIR/unreachable.rs:+7:1: +7:2
++ nop; // scope 0 at $DIR/unreachable.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/unreachable.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/tests/mir-opt/dest-prop/unreachable.rs b/tests/mir-opt/dest-prop/unreachable.rs
new file mode 100644
index 000000000..32b5def98
--- /dev/null
+++ b/tests/mir-opt/dest-prop/unreachable.rs
@@ -0,0 +1,18 @@
+// Check that unreachable code is removed after the destination propagation.
+// Regression test for issue #105428.
+//
+// compile-flags: --crate-type=lib -Zmir-opt-level=0
+// compile-flags: -Zmir-enable-passes=+ConstProp,+SimplifyConstCondition-after-const-prop,+DestinationPropagation
+
+// EMIT_MIR unreachable.f.DestinationPropagation.diff
+pub fn f<T: Copy>(a: T) {
+ let b = a;
+ if false {
+ g(a, b);
+ } else {
+ g(b, b);
+ }
+}
+
+#[inline(never)]
+pub fn g<T: Copy>(_: T, _: T) {}
diff --git a/tests/mir-opt/div_overflow.const_dividend.PreCodegen.after.mir b/tests/mir-opt/div_overflow.const_dividend.PreCodegen.after.mir
new file mode 100644
index 000000000..d7f66a6bf
--- /dev/null
+++ b/tests/mir-opt/div_overflow.const_dividend.PreCodegen.after.mir
@@ -0,0 +1,17 @@
+// MIR for `const_dividend` after PreCodegen
+
+fn const_dividend(_1: i32) -> i32 {
+ debug a => _1; // in scope 0 at $DIR/div_overflow.rs:+0:23: +0:24
+ let mut _0: i32; // return place in scope 0 at $DIR/div_overflow.rs:+0:34: +0:37
+ let mut _2: bool; // in scope 0 at $DIR/div_overflow.rs:+1:5: +1:12
+
+ bb0: {
+ _2 = Eq(_1, const 0_i32); // scope 0 at $DIR/div_overflow.rs:+1:5: +1:12
+ assert(!move _2, "attempt to divide `{}` by zero", const 256_i32) -> bb1; // scope 0 at $DIR/div_overflow.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = Div(const 256_i32, move _1); // scope 0 at $DIR/div_overflow.rs:+1:5: +1:12
+ return; // scope 0 at $DIR/div_overflow.rs:+2:2: +2:2
+ }
+}
diff --git a/tests/mir-opt/div_overflow.const_divisor.PreCodegen.after.mir b/tests/mir-opt/div_overflow.const_divisor.PreCodegen.after.mir
new file mode 100644
index 000000000..7b7ab1978
--- /dev/null
+++ b/tests/mir-opt/div_overflow.const_divisor.PreCodegen.after.mir
@@ -0,0 +1,11 @@
+// MIR for `const_divisor` after PreCodegen
+
+fn const_divisor(_1: i32) -> i32 {
+ debug a => _1; // in scope 0 at $DIR/div_overflow.rs:+0:22: +0:23
+ let mut _0: i32; // return place in scope 0 at $DIR/div_overflow.rs:+0:33: +0:36
+
+ bb0: {
+ _0 = Div(move _1, const 256_i32); // scope 0 at $DIR/div_overflow.rs:+1:5: +1:12
+ return; // scope 0 at $DIR/div_overflow.rs:+2:2: +2:2
+ }
+}
diff --git a/tests/mir-opt/div_overflow.rs b/tests/mir-opt/div_overflow.rs
new file mode 100644
index 000000000..10ce5bc0f
--- /dev/null
+++ b/tests/mir-opt/div_overflow.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Copt-level=0 -Coverflow-checks=yes
+
+// Tests that division with a const does not emit a panicking branch for overflow
+
+// EMIT_MIR div_overflow.const_divisor.PreCodegen.after.mir
+pub fn const_divisor(a: i32) -> i32 {
+ a / 256
+}
+
+// EMIT_MIR div_overflow.const_dividend.PreCodegen.after.mir
+pub fn const_dividend(a: i32) -> i32 {
+ 256 / a
+}
+
+fn main() {
+ const_divisor(123);
+ const_dividend(123);
+}
diff --git a/tests/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..98a02ee38
--- /dev/null
+++ b/tests/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: 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) -> [0: 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: 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: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+ }
+ }
+
diff --git a/tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..aa75c44b8
--- /dev/null
+++ b/tests/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: bb1, 1: 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) -> [0: 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: 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: 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: bb3, 1: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+ }
+ }
+
diff --git a/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..cea6ff7cd
--- /dev/null
+++ b/tests/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: 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) -> [0: 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: 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: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17
+ }
+ }
+
diff --git a/tests/mir-opt/early_otherwise_branch.rs b/tests/mir-opt/early_otherwise_branch.rs
new file mode 100644
index 000000000..7be9fbd03
--- /dev/null
+++ b/tests/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/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..b90d70ce4
--- /dev/null
+++ b/tests/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: 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) -> [0: 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: 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: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
++ switchInt(move _8) -> [1: 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: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20
+ }
+ }
+
diff --git a/tests/mir-opt/early_otherwise_branch_3_element_tuple.rs b/tests/mir-opt/early_otherwise_branch_3_element_tuple.rs
new file mode 100644
index 000000000..76055e133
--- /dev/null
+++ b/tests/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/tests/mir-opt/early_otherwise_branch_68867.rs b/tests/mir-opt/early_otherwise_branch_68867.rs
new file mode 100644
index 000000000..a6a56f3a9
--- /dev/null
+++ b/tests/mir-opt/early_otherwise_branch_68867.rs
@@ -0,0 +1,33 @@
+// unit-test: EarlyOtherwiseBranch
+
+// FIXME: This test was broken by the derefer change.
+
+// 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
+#[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/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..9edd1a39f
--- /dev/null
+++ b/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
@@ -0,0 +1,231 @@
+- // 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
+ _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
+ switchInt(move _11) -> [0: bb1, 1: bb3, 2: bb4, 3: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb1: {
+ _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
+ switchInt(move _7) -> [0: 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
+ Deinit(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
+ Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
+ ((_0 as Err).0: ()) = move _33; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
+ discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
+ StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:27: +10:28
+ StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
+ StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
+ goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
+ }
+
+ bb3: {
+ _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
+ switchInt(move _8) -> [1: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb4: {
+ _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
+ switchInt(move _9) -> [2: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
+ }
+
+ bb5: {
+ _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
+ switchInt(move _10) -> [3: 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
+ _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
+ StorageLive(_13); // 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
+ 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
+ _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
+ StorageLive(_18); // 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
+ 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
+ _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
+ StorageLive(_23); // 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
+ 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
+ _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
+ StorageLive(_28); // 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
+ 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
+ goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
+ }
+
+ bb11: {
+ return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
+ }
+ }
+
diff --git a/tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..82d8b2fc5
--- /dev/null
+++ b/tests/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: bb1, 1: 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: bb2, 1: 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: bb6, 1: 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/tests/mir-opt/early_otherwise_branch_noopt.rs b/tests/mir-opt/early_otherwise_branch_noopt.rs
new file mode 100644
index 000000000..ef766bbd4
--- /dev/null
+++ b/tests/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/tests/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..a3fa2529b
--- /dev/null
+++ b/tests/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: 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: 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/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
new file mode 100644
index 000000000..6d0224b54
--- /dev/null
+++ b/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
@@ -0,0 +1,38 @@
+- // 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: bb1, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
+ }
+
+ bb1: {
+ _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
+ switchInt(move _2) -> [1: 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/tests/mir-opt/early_otherwise_branch_soundness.rs b/tests/mir-opt/early_otherwise_branch_soundness.rs
new file mode 100644
index 000000000..cd4589232
--- /dev/null
+++ b/tests/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/tests/mir-opt/equal_true.opt.InstCombine.diff b/tests/mir-opt/equal_true.opt.InstCombine.diff
new file mode 100644
index 000000000..8b542a7c1
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/equal_true.rs b/tests/mir-opt/equal_true.rs
new file mode 100644
index 000000000..717d10c6d
--- /dev/null
+++ b/tests/mir-opt/equal_true.rs
@@ -0,0 +1,11 @@
+// unit-test InstCombine
+
+// 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/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
new file mode 100644
index 000000000..ab9550499
--- /dev/null
+++ b/tests/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:11
+ let _8: u32; // in scope 0 at $DIR/exponential_or.rs:+2:57: +2:58
+ let mut _9: u32; // in scope 0 at $DIR/exponential_or.rs:+2:83: +2:84
+ let mut _10: u32; // in scope 0 at $DIR/exponential_or.rs:+2:87: +2:88
+ scope 1 {
+ debug y => _7; // in scope 1 at $DIR/exponential_or.rs:+2:10: +2:11
+ debug z => _8; // in scope 1 at $DIR/exponential_or.rs:+2:57: +2:58
+ }
+
+ bb0: {
+ FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/exponential_or.rs:+1:11: +1:12
+ switchInt((_1.0: u32)) -> [1: bb2, 4: 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: bb4, 1: 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: bb4, 8: 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) -> [0: 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) -> [0: 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) -> [0: 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) -> [0: 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:11
+ _7 = (_1.0: u32); // scope 0 at $DIR/exponential_or.rs:+2:10: +2:11
+ StorageLive(_8); // scope 0 at $DIR/exponential_or.rs:+2:57: +2:58
+ _8 = (_1.3: u32); // scope 0 at $DIR/exponential_or.rs:+2:57: +2:58
+ StorageLive(_9); // scope 1 at $DIR/exponential_or.rs:+2:83: +2:84
+ _9 = _7; // scope 1 at $DIR/exponential_or.rs:+2:83: +2:84
+ StorageLive(_10); // scope 1 at $DIR/exponential_or.rs:+2:87: +2:88
+ _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/tests/mir-opt/exponential_or.rs b/tests/mir-opt/exponential_or.rs
new file mode 100644
index 000000000..0b8be8385
--- /dev/null
+++ b/tests/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/tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir b/tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir
new file mode 100644
index 000000000..c63433d36
--- /dev/null
+++ b/tests/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/tests/mir-opt/fn_ptr_shim.rs b/tests/mir-opt/fn_ptr_shim.rs
new file mode 100644
index 000000000..64fbdc9de
--- /dev/null
+++ b/tests/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/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff
new file mode 100644
index 000000000..c1c2cde71
--- /dev/null
+++ b/tests/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<'a> fn(&'a 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) -> [0: 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<'a> fn(&'a 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: 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 (IntToInt); // 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<'a, 'b, 'c> fn(&'a mut Formatter<'b>, &'c 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<'a, 'b, 'c> fn(&'a mut Formatter<'b>, &'c 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/tests/mir-opt/funky_arms.rs b/tests/mir-opt/funky_arms.rs
new file mode 100644
index 000000000..3e70d85e0
--- /dev/null
+++ b/tests/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/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir b/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
new file mode 100644
index 000000000..a8e090020
--- /dev/null
+++ b/tests/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: +3:6
+ let mut _2: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ let _3: std::string::String; // in scope 0 at $DIR/generator_drop_cleanup.rs:+1:13: +1:15
+ let _4: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+2:9: +2:14
+ let mut _5: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+2:9: +2:14
+ let mut _6: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:18: +0:18
+ let mut _7: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ let mut _8: u32; // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ scope 1 {
+ debug _s => (((*_1) as variant#3).0: std::string::String); // in scope 1 at $DIR/generator_drop_cleanup.rs:+1:13: +1:15
+ }
+
+ bb0: {
+ _8 = discriminant((*_1)); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ switchInt(move _8) -> [0: bb7, 3: bb10, otherwise: bb11]; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ }
+
+ 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: +3:6
+ }
+
+ bb4 (cleanup): {
+ resume; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ }
+
+ 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: +3:6
+ }
+
+ bb7: {
+ goto -> bb9; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ }
+
+ 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: +3:6
+ }
+
+ bb10: {
+ StorageLive(_4); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ StorageLive(_5); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ goto -> bb1; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ }
+
+ bb11: {
+ return; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ }
+}
diff --git a/tests/mir-opt/generator_drop_cleanup.rs b/tests/mir-opt/generator_drop_cleanup.rs
new file mode 100644
index 000000000..82c1292cb
--- /dev/null
+++ b/tests/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/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir b/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir
new file mode 100644
index 000000000..cfbe0aaf2
--- /dev/null
+++ b/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir
@@ -0,0 +1,124 @@
+// 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
+ _3 = Foo(const 5_i32); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+1:17: +1:23
+ StorageLive(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+2:13: +2:14
+ _4 = Bar(const 6_i32); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+2:17: +2:23
+ StorageLive(_5); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14
+ StorageLive(_6); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14
+ _6 = (); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14
+ _5 = yield(move _6) -> [resume: bb1, drop: bb6]; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14
+ }
+
+ bb1: {
+ 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: bb10]; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:9: +4:16
+ // mir::Constant
+ // + span: $DIR/generator_storage_dead_unwind.rs:26:9: 26:13
+ // + literal: Const { ty: fn(Foo) {take::<Foo>}, val: Value(<ZST>) }
+ }
+
+ 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: bb9]; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:9: +5:16
+ // mir::Constant
+ // + span: $DIR/generator_storage_dead_unwind.rs:27:9: 27:13
+ // + literal: Const { ty: fn(Bar) {take::<Bar>}, val: Value(<ZST>) }
+ }
+
+ 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
+ goto -> bb4; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ }
+
+ bb4: {
+ StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ drop(_1) -> [return: bb5, unwind: bb14]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ }
+
+ bb5: {
+ return; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:6: +6:6
+ }
+
+ bb6: {
+ StorageDead(_6); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:13: +3:14
+ StorageDead(_5); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:14: +3:15
+ StorageDead(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ drop(_3) -> [return: bb7, unwind: bb15]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ }
+
+ bb7: {
+ StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ drop(_1) -> [return: bb8, unwind: bb14]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ }
+
+ bb8: {
+ generator_drop; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:16: +6:6
+ }
+
+ bb9 (cleanup): {
+ StorageDead(_10); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:15: +5:16
+ StorageDead(_9); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:16: +5:17
+ goto -> bb12; // scope 2 at no-location
+ }
+
+ bb10 (cleanup): {
+ goto -> bb11; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:15: +4:16
+ }
+
+ bb11 (cleanup): {
+ StorageDead(_8); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:15: +4:16
+ StorageDead(_7); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:16: +4:17
+ goto -> bb12; // scope 2 at no-location
+ }
+
+ bb12 (cleanup): {
+ StorageDead(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ goto -> bb13; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ }
+
+ bb13 (cleanup): {
+ StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ drop(_1) -> bb14; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ }
+
+ bb14 (cleanup): {
+ resume; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:16: +6:6
+ }
+
+ bb15 (cleanup): {
+ StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ drop(_1) -> bb14; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ }
+}
diff --git a/tests/mir-opt/generator_storage_dead_unwind.rs b/tests/mir-opt/generator_storage_dead_unwind.rs
new file mode 100644
index 000000000..b72170ade
--- /dev/null
+++ b/tests/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/tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir b/tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir
new file mode 100644
index 000000000..b3d3c768a
--- /dev/null
+++ b/tests/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: +6:6
+ let _3: HasDrop; // in scope 0 at $DIR/generator_tiny.rs:+1:13: +1:15
+ let mut _4: !; // in scope 0 at $DIR/generator_tiny.rs:+2:9: +5:10
+ let mut _5: (); // in scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ let _6: u8; // in scope 0 at $DIR/generator_tiny.rs:+3:13: +3:18
+ let mut _7: (); // in scope 0 at $DIR/generator_tiny.rs:+3:13: +3:18
+ let _8: (); // in scope 0 at $DIR/generator_tiny.rs:+4:13: +4:21
+ let mut _9: (); // in scope 0 at $DIR/generator_tiny.rs:+0:25: +0:25
+ let _10: u8; // in scope 0 at $DIR/generator_tiny.rs:+0:17: +0:19
+ let mut _11: u32; // in scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ scope 1 {
+ debug _d => (((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop); // in scope 1 at $DIR/generator_tiny.rs:+1:13: +1:15
+ }
+
+ bb0: {
+ _11 = discriminant((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24]))); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ switchInt(move _11) -> [0: bb1, 3: bb5, otherwise: bb6]; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ }
+
+ bb1: {
+ _10 = move _2; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ nop; // scope 0 at $DIR/generator_tiny.rs:+1:13: +1:15
+ (((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop) = HasDrop; // scope 0 at $DIR/generator_tiny.rs:+1:18: +1:25
+ StorageLive(_4); // scope 1 at $DIR/generator_tiny.rs:+2:9: +5:10
+ goto -> bb2; // scope 1 at $DIR/generator_tiny.rs:+2:9: +5:10
+ }
+
+ 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
+ _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: +6:6
+ StorageLive(_6); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ StorageLive(_7); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ _6 = move _2; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ goto -> bb3; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ }
+
+ bb6: {
+ unreachable; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ }
+}
diff --git a/tests/mir-opt/generator_tiny.rs b/tests/mir-opt/generator_tiny.rs
new file mode 100644
index 000000000..7dad63a61
--- /dev/null
+++ b/tests/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/tests/mir-opt/graphviz.main.built.after.dot b/tests/mir-opt/graphviz.main.built.after.dot
new file mode 100644
index 000000000..8d1da7f1b
--- /dev/null
+++ b/tests/mir-opt/graphviz.main.built.after.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/tests/mir-opt/graphviz.rs b/tests/mir-opt/graphviz.rs
new file mode 100644
index 000000000..6906b86c2
--- /dev/null
+++ b/tests/mir-opt/graphviz.rs
@@ -0,0 +1,5 @@
+// Test graphviz output
+// compile-flags: -Z dump-mir-graphviz
+
+// EMIT_MIR graphviz.main.built.after.dot
+fn main() {}
diff --git a/tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..de4235c9e
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..754c6579a
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..ff23839e2
--- /dev/null
+++ b/tests/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) -> [0: 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: 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 (IntToInt); // 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 (IntToInt); // 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/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..5964d76a4
--- /dev/null
+++ b/tests/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) -> [0: 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) -> [120: 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/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..98918cc74
--- /dev/null
+++ b/tests/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) -> [0: 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: 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/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..db38140b8
--- /dev/null
+++ b/tests/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) -> [0: 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: 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) -> [0: 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: 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/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..1a1ac4caa
--- /dev/null
+++ b/tests/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) -> [0: 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) -> [4294967254: 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/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..fc3f50227
--- /dev/null
+++ b/tests/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) -> [0: 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: 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/tests/mir-opt/if_condition_int.rs b/tests/mir-opt/if_condition_int.rs
new file mode 100644
index 000000000..398311e6b
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/asm_unwind.main.Inline.diff b/tests/mir-opt/inline/asm_unwind.main.Inline.diff
new file mode 100644
index 000000000..f1b62ac38
--- /dev/null
+++ b/tests/mir-opt/inline/asm_unwind.main.Inline.diff
@@ -0,0 +1,45 @@
+- // MIR for `main` before Inline
++ // MIR for `main` after Inline
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/asm_unwind.rs:+0:15: +0:15
+ let _1: (); // in scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10
++ scope 1 (inlined foo) { // at $DIR/asm_unwind.rs:21:5: 21:10
++ let _2: D; // in scope 1 at $DIR/asm_unwind.rs:15:9: 15:11
++ scope 2 {
++ debug _d => _2; // in scope 2 at $DIR/asm_unwind.rs:15:9: 15:11
++ scope 3 {
++ }
++ }
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10
+- _1 = foo() -> bb1; // scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10
+- // mir::Constant
+- // + span: $DIR/asm_unwind.rs:21:5: 21:8
+- // + literal: Const { ty: fn() {foo}, val: Value(<ZST>) }
++ StorageLive(_2); // scope 1 at $DIR/asm_unwind.rs:15:9: 15:11
++ asm!("", options(MAY_UNWIND)) -> [return: bb1, unwind: bb3]; // scope 3 at $DIR/asm_unwind.rs:16:14: 16:54
+ }
+
+ bb1: {
++ drop(_2) -> bb2; // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2
++ }
++
++ bb2: {
++ StorageDead(_2); // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2
+ StorageDead(_1); // scope 0 at $DIR/asm_unwind.rs:+1:10: +1:11
+ _0 = const (); // scope 0 at $DIR/asm_unwind.rs:+0:15: +2:2
+ return; // scope 0 at $DIR/asm_unwind.rs:+2:2: +2:2
++ }
++
++ bb3 (cleanup): {
++ drop(_2) -> bb4; // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2
++ }
++
++ bb4 (cleanup): {
++ resume; // scope 1 at $DIR/asm_unwind.rs:14:1: 17:2
+ }
+ }
+
diff --git a/tests/mir-opt/inline/asm_unwind.rs b/tests/mir-opt/inline/asm_unwind.rs
new file mode 100644
index 000000000..c03feb433
--- /dev/null
+++ b/tests/mir-opt/inline/asm_unwind.rs
@@ -0,0 +1,22 @@
+// Tests inlining of `may_unwind` inline assembly.
+//
+// ignore-wasm32-bare compiled with panic=abort by default
+// needs-asm-support
+#![feature(asm_unwind)]
+
+struct D;
+
+impl Drop for D {
+ fn drop(&mut self) {}
+}
+
+#[inline(always)]
+fn foo() {
+ let _d = D;
+ unsafe { std::arch::asm!("", options(may_unwind)) };
+}
+
+// EMIT_MIR asm_unwind.main.Inline.diff
+pub fn main() {
+ foo();
+}
diff --git a/tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff b/tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff
new file mode 100644
index 000000000..8b0300678
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/caller_with_trivial_bound.rs b/tests/mir-opt/inline/caller_with_trivial_bound.rs
new file mode 100644
index 000000000..8545db894
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/cycle.f.Inline.diff b/tests/mir-opt/inline/cycle.f.Inline.diff
new file mode 100644
index 000000000..75ea69a42
--- /dev/null
+++ b/tests/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<'a> extern "rust-call" fn(&'a 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/tests/mir-opt/inline/cycle.g.Inline.diff b/tests/mir-opt/inline/cycle.g.Inline.diff
new file mode 100644
index 000000000..5f3ee467c
--- /dev/null
+++ b/tests/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:5:6: 5:7
++ let _3: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8
++ let mut _4: &fn() {main}; // in scope 1 at $DIR/cycle.rs:6:5: 6:6
++ let mut _5: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8
++ scope 2 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) { // at $DIR/cycle.rs:6:5: 6:8
++ }
++ }
+
+ 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:6:5: 6:8
++ StorageLive(_4); // scope 1 at $DIR/cycle.rs:6:5: 6:6
++ _4 = &_2; // scope 1 at $DIR/cycle.rs:6:5: 6:6
++ StorageLive(_5); // scope 1 at $DIR/cycle.rs:6:5: 6:8
++ _3 = move (*_4)() -> [return: bb4, unwind: bb2]; // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL
+ }
+
+ 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:7:1: 7:2
++ }
++
++ bb3 (cleanup): {
++ resume; // scope 1 at $DIR/cycle.rs:5:1: 7:2
++ }
++
++ bb4: {
++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_4); // scope 1 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:6:8: 6:9
++ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:7:1: 7:2
+ }
+ }
+
diff --git a/tests/mir-opt/inline/cycle.main.Inline.diff b/tests/mir-opt/inline/cycle.main.Inline.diff
new file mode 100644
index 000000000..6b4c63bbd
--- /dev/null
+++ b/tests/mir-opt/inline/cycle.main.Inline.diff
@@ -0,0 +1,57 @@
+- // 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:5:6: 5:7
++ let _3: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8
++ let mut _4: &fn() {g}; // in scope 1 at $DIR/cycle.rs:6:5: 6:6
++ let mut _5: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8
++ scope 2 (inlined <fn() {g} as Fn<()>>::call - shim(fn() {g})) { // at $DIR/cycle.rs:6:5: 6:8
++ }
++ }
+
+ 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:6:5: 6:8
++ StorageLive(_4); // scope 1 at $DIR/cycle.rs:6:5: 6:6
++ _4 = &_2; // scope 1 at $DIR/cycle.rs:6:5: 6:6
++ StorageLive(_5); // scope 1 at $DIR/cycle.rs:6:5: 6:8
++ _3 = move (*_4)() -> [return: bb4, unwind: bb2]; // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL
+ }
+
+ 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:7:1: 7:2
++ }
++
++ bb3 (cleanup): {
++ resume; // scope 1 at $DIR/cycle.rs:5:1: 7:2
++ }
++
++ bb4: {
++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_4); // scope 1 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:6:8: 6:9
++ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:7:1: 7:2
+ }
+ }
+
diff --git a/tests/mir-opt/inline/cycle.rs b/tests/mir-opt/inline/cycle.rs
new file mode 100644
index 000000000..9e8950d8a
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/dyn_trait.get_query.Inline.diff b/tests/mir-opt/inline/dyn_trait.get_query.Inline.diff
new file mode 100644
index 000000000..8ea1a0757
--- /dev/null
+++ b/tests/mir-opt/inline/dyn_trait.get_query.Inline.diff
@@ -0,0 +1,54 @@
+- // 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:26:36: 26:37
++ let mut _5: &dyn Cache<V = <Q as Query>::V>; // in scope 2 at $DIR/dyn_trait.rs:27:14: 27:15
++ 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:20:27: 20:28
++ }
++ }
+ }
+
+ 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<'a> fn(&'a T) -> &'a <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:27:14: 27:15
++ _5 = move _4 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn_trait.rs:27:14: 27:15
++ _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(move _5) -> bb2; // scope 3 at $DIR/dyn_trait.rs:21:5: 21:22
+ // mir::Constant
+- // + span: $DIR/dyn_trait.rs:34:5: 34:22
+- // + literal: Const { ty: for<'a> fn(&'a <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<'a> fn(&'a dyn Cache<V = <Q as Query>::V>) {<dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache}, val: Value(<ZST>) }
+ }
+
+ bb2: {
++ StorageDead(_5); // scope 2 at $DIR/dyn_trait.rs:27:15: 27:16
+ StorageDead(_4); // scope 1 at $DIR/dyn_trait.rs:+2:24: +2:25
+ StorageDead(_2); // scope 0 at $DIR/dyn_trait.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/dyn_trait.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff b/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff
new file mode 100644
index 000000000..7653a5ded
--- /dev/null
+++ b/tests/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<'a> fn(&'a 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/tests/mir-opt/inline/dyn_trait.rs b/tests/mir-opt/inline/dyn_trait.rs
new file mode 100644
index 000000000..6a46e1e07
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
new file mode 100644
index 000000000..a71d73b74
--- /dev/null
+++ b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
@@ -0,0 +1,33 @@
+- // 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:20:27: 20:28
++ }
+
+ 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
++ _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(move _2) -> bb1; // scope 1 at $DIR/dyn_trait.rs:21:5: 21:22
+ // mir::Constant
+- // + span: $DIR/dyn_trait.rs:27:5: 27:13
+- // + literal: Const { ty: for<'a> fn(&'a (dyn Cache<V = <C as Cache>::V> + 'a)) {mk_cycle::<<C as Cache>::V>}, val: Value(<ZST>) }
++ // + span: $DIR/dyn_trait.rs:21:7: 21:20
++ // + literal: Const { ty: for<'a> fn(&'a dyn Cache<V = <C as Cache>::V>) {<dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ 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/tests/mir-opt/inline/exponential_runtime.main.Inline.diff b/tests/mir-opt/inline/exponential_runtime.main.Inline.diff
new file mode 100644
index 000000000..7fd62be7a
--- /dev/null
+++ b/tests/mir-opt/inline/exponential_runtime.main.Inline.diff
@@ -0,0 +1,75 @@
+- // MIR for `main` before Inline
++ // MIR for `main` after Inline
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/exponential_runtime.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22
++ scope 1 (inlined <() as G>::call) { // at $DIR/exponential_runtime.rs:86:5: 86:22
++ let _2: (); // in scope 1 at $DIR/exponential_runtime.rs:73:9: 73:25
++ let _3: (); // in scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25
++ let _4: (); // in scope 1 at $DIR/exponential_runtime.rs:75:9: 75:25
++ scope 2 (inlined <() as F>::call) { // at $DIR/exponential_runtime.rs:73:9: 73:25
++ let _5: (); // in scope 2 at $DIR/exponential_runtime.rs:61:9: 61:25
++ let _6: (); // in scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25
++ let _7: (); // in scope 2 at $DIR/exponential_runtime.rs:63:9: 63:25
++ }
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22
+- _1 = <() as G>::call() -> bb1; // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22
++ StorageLive(_2); // scope 1 at $DIR/exponential_runtime.rs:73:9: 73:25
++ StorageLive(_5); // scope 2 at $DIR/exponential_runtime.rs:61:9: 61:25
++ _5 = <() as E>::call() -> bb3; // scope 2 at $DIR/exponential_runtime.rs:61:9: 61:25
+ // mir::Constant
+- // + span: $DIR/exponential_runtime.rs:86:5: 86:20
+- // + literal: Const { ty: fn() {<() as G>::call}, val: Value(<ZST>) }
++ // + span: $DIR/exponential_runtime.rs:61:9: 61:23
++ // + literal: Const { ty: fn() {<() as E>::call}, val: Value(<ZST>) }
+ }
+
+ bb1: {
++ StorageDead(_3); // scope 1 at $DIR/exponential_runtime.rs:74:25: 74:26
++ StorageLive(_4); // scope 1 at $DIR/exponential_runtime.rs:75:9: 75:25
++ _4 = <() as F>::call() -> bb2; // scope 1 at $DIR/exponential_runtime.rs:75:9: 75:25
++ // mir::Constant
++ // + span: $DIR/exponential_runtime.rs:75:9: 75:23
++ // + literal: Const { ty: fn() {<() as F>::call}, val: Value(<ZST>) }
++ }
++
++ bb2: {
++ StorageDead(_4); // scope 1 at $DIR/exponential_runtime.rs:75:25: 75:26
+ StorageDead(_1); // scope 0 at $DIR/exponential_runtime.rs:+1:22: +1:23
+ _0 = const (); // scope 0 at $DIR/exponential_runtime.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/exponential_runtime.rs:+2:2: +2:2
++ }
++
++ bb3: {
++ StorageDead(_5); // scope 2 at $DIR/exponential_runtime.rs:61:25: 61:26
++ StorageLive(_6); // scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25
++ _6 = <() as E>::call() -> bb4; // scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25
++ // mir::Constant
++ // + span: $DIR/exponential_runtime.rs:62:9: 62:23
++ // + literal: Const { ty: fn() {<() as E>::call}, val: Value(<ZST>) }
++ }
++
++ bb4: {
++ StorageDead(_6); // scope 2 at $DIR/exponential_runtime.rs:62:25: 62:26
++ StorageLive(_7); // scope 2 at $DIR/exponential_runtime.rs:63:9: 63:25
++ _7 = <() as E>::call() -> bb5; // scope 2 at $DIR/exponential_runtime.rs:63:9: 63:25
++ // mir::Constant
++ // + span: $DIR/exponential_runtime.rs:63:9: 63:23
++ // + literal: Const { ty: fn() {<() as E>::call}, val: Value(<ZST>) }
++ }
++
++ bb5: {
++ StorageDead(_7); // scope 2 at $DIR/exponential_runtime.rs:63:25: 63:26
++ StorageDead(_2); // scope 1 at $DIR/exponential_runtime.rs:73:25: 73:26
++ StorageLive(_3); // scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25
++ _3 = <() as F>::call() -> bb1; // scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25
++ // mir::Constant
++ // + span: $DIR/exponential_runtime.rs:74:9: 74:23
++ // + literal: Const { ty: fn() {<() as F>::call}, val: Value(<ZST>) }
+ }
+ }
+
diff --git a/tests/mir-opt/inline/exponential_runtime.rs b/tests/mir-opt/inline/exponential_runtime.rs
new file mode 100644
index 000000000..d9219d76a
--- /dev/null
+++ b/tests/mir-opt/inline/exponential_runtime.rs
@@ -0,0 +1,87 @@
+// Checks that code with exponential runtime does not have exponential behavior in inlining.
+
+trait A {
+ fn call();
+}
+
+trait B {
+ fn call();
+}
+impl<T: A> B for T {
+ #[inline]
+ fn call() {
+ <T as A>::call();
+ <T as A>::call();
+ <T as A>::call();
+ }
+}
+
+trait C {
+ fn call();
+}
+impl<T: B> C for T {
+ #[inline]
+ fn call() {
+ <T as B>::call();
+ <T as B>::call();
+ <T as B>::call();
+ }
+}
+
+trait D {
+ fn call();
+}
+impl<T: C> D for T {
+ #[inline]
+ fn call() {
+ <T as C>::call();
+ <T as C>::call();
+ <T as C>::call();
+ }
+}
+
+trait E {
+ fn call();
+}
+impl<T: D> E for T {
+ #[inline]
+ fn call() {
+ <T as D>::call();
+ <T as D>::call();
+ <T as D>::call();
+ }
+}
+
+trait F {
+ fn call();
+}
+impl<T: E> F for T {
+ #[inline]
+ fn call() {
+ <T as E>::call();
+ <T as E>::call();
+ <T as E>::call();
+ }
+}
+
+trait G {
+ fn call();
+}
+impl<T: F> G for T {
+ #[inline]
+ fn call() {
+ <T as F>::call();
+ <T as F>::call();
+ <T as F>::call();
+ }
+}
+
+impl A for () {
+ #[inline(never)]
+ fn call() {}
+}
+
+// EMIT_MIR exponential_runtime.main.Inline.diff
+fn main() {
+ <() as G>::call();
+}
diff --git a/tests/mir-opt/inline/inline_any_operand.bar.Inline.after.mir b/tests/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
new file mode 100644
index 000000000..3502c2586
--- /dev/null
+++ b/tests/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
@@ -0,0 +1,36 @@
+// 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:16:8: 16:9
+ debug y => _4; // in scope 2 at $DIR/inline_any_operand.rs:16:16: 16:17
+ }
+ }
+
+ 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
+ _0 = Eq(move _3, move _4); // scope 2 at $DIR/inline_any_operand.rs:17:5: 17:11
+ StorageDead(_4); // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
+ StorageDead(_3); // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
+ StorageDead(_2); // scope 1 at $DIR/inline_any_operand.rs:+2:12: +2:13
+ 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/tests/mir-opt/inline/inline_any_operand.rs b/tests/mir-opt/inline/inline_any_operand.rs
new file mode 100644
index 000000000..fb0de020f
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_async.rs b/tests/mir-opt/inline/inline_async.rs
new file mode 100644
index 000000000..5c838159b
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_closure.foo.Inline.after.mir b/tests/mir-opt/inline/inline_closure.foo.Inline.after.mir
new file mode 100644
index 000000000..9eb3a01ee
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_closure.rs b/tests/mir-opt/inline/inline_closure.rs
new file mode 100644
index 000000000..715fd0138
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir b/tests/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir
new file mode 100644
index 000000000..dd32eb2d8
--- /dev/null
+++ b/tests/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir
@@ -0,0 +1,52 @@
+// 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
+ scope 3 {
+ debug variable => _8; // 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
+ _0 = (*_8); // scope 3 at $DIR/inline_closure_borrows_arg.rs:+3:9: +3:18
+ 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/tests/mir-opt/inline/inline_closure_borrows_arg.rs b/tests/mir-opt/inline/inline_closure_borrows_arg.rs
new file mode 100644
index 000000000..d76bc33f5
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
new file mode 100644
index 000000000..fd19c2886
--- /dev/null
+++ b/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
@@ -0,0 +1,65 @@
+// 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:24
+ let mut _13: &T; // in scope 2 at $DIR/inline_closure_captures.rs:+1:13: +1:24
+ }
+ }
+
+ 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
+ _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
+ StorageLive(_11); // 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
+ 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/tests/mir-opt/inline/inline_closure_captures.rs b/tests/mir-opt/inline/inline_closure_captures.rs
new file mode 100644
index 000000000..52b6817e4
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff b/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff
new file mode 100644
index 000000000..e30a5e116
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff b/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff
new file mode 100644
index 000000000..c2b3c46a3
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff
new file mode 100644
index 000000000..0ca5a5f70
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff
new file mode 100644
index 000000000..00d405c77
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff
new file mode 100644
index 000000000..8b9c86f55
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_compatibility.rs b/tests/mir-opt/inline/inline_compatibility.rs
new file mode 100644
index 000000000..30aff0a64
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_cycle.one.Inline.diff b/tests/mir-opt/inline/inline_cycle.one.Inline.diff
new file mode 100644
index 000000000..5510cd7bc
--- /dev/null
+++ b/tests/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:36:9: 36: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/tests/mir-opt/inline/inline_cycle.rs b/tests/mir-opt/inline/inline_cycle.rs
new file mode 100644
index 000000000..63ad57de1
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_cycle.two.Inline.diff b/tests/mir-opt/inline/inline_cycle.two.Inline.diff
new file mode 100644
index 000000000..64c0065b5
--- /dev/null
+++ b/tests/mir-opt/inline/inline_cycle.two.Inline.diff
@@ -0,0 +1,41 @@
+- // 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:53:22: 53:23
++ let _3: (); // in scope 1 at $DIR/inline_cycle.rs:54:5: 54:8
++ let mut _4: (); // in scope 1 at $DIR/inline_cycle.rs:54:5: 54:8
++ scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) { // at $DIR/inline_cycle.rs:54:5: 54:8
++ }
++ }
+
+ 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
+- // + literal: Const { ty: fn(fn() {f}) {call::<fn() {f}>}, val: Value(<ZST>) }
+- // mir::Constant
+ // + 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:54:5: 54:8
++ StorageLive(_4); // scope 1 at $DIR/inline_cycle.rs:54:5: 54:8
++ _3 = move _2() -> bb1; // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL
+ }
+
+ bb1: {
++ StorageDead(_4); // scope 1 at $DIR/inline_cycle.rs:54:7: 54:8
++ StorageDead(_3); // scope 1 at $DIR/inline_cycle.rs:54:8: 54:9
++ StorageDead(_2); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12
+ StorageDead(_1); // scope 0 at $DIR/inline_cycle.rs:+1:12: +1:13
+ _0 = const (); // scope 0 at $DIR/inline_cycle.rs:+0:10: +2:2
+ return; // scope 0 at $DIR/inline_cycle.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.diff b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.diff
new file mode 100644
index 000000000..52debab4d
--- /dev/null
+++ b/tests/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:31:9: 31:28
+ // mir::Constant
+- // + span: $DIR/inline_cycle_generic.rs:9:5: 9:22
++ // + span: $DIR/inline_cycle_generic.rs:31:9: 31:26
+ // + 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/tests/mir-opt/inline/inline_cycle_generic.rs b/tests/mir-opt/inline/inline_cycle_generic.rs
new file mode 100644
index 000000000..24b4f3793
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_diverging.f.Inline.diff b/tests/mir-opt/inline/inline_diverging.f.Inline.diff
new file mode 100644
index 000000000..b49191f49
--- /dev/null
+++ b/tests/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:39:5: 39:12
+ }
+ }
+
diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.diff
new file mode 100644
index 000000000..b787a19f4
--- /dev/null
+++ b/tests/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) -> [0: 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 (IntToInt); // 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/tests/mir-opt/inline/inline_diverging.h.Inline.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.diff
new file mode 100644
index 000000000..f82fcf4c8
--- /dev/null
+++ b/tests/mir-opt/inline/inline_diverging.h.Inline.diff
@@ -0,0 +1,87 @@
+- // 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:26:36: 26:37
++ let _3: !; // in scope 1 at $DIR/inline_diverging.rs:27:9: 27:10
++ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline_diverging.rs:27:13: 27:14
++ let mut _5: (); // in scope 1 at $DIR/inline_diverging.rs:27:13: 27:16
++ let mut _6: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline_diverging.rs:28:13: 28:14
++ let mut _7: (); // in scope 1 at $DIR/inline_diverging.rs:28:13: 28:16
++ let mut _8: !; // in scope 1 at $DIR/inline_diverging.rs:29:6: 29:7
++ let mut _9: !; // in scope 1 at $DIR/inline_diverging.rs:29:9: 29:10
++ scope 2 {
++ debug a => _3; // in scope 2 at $DIR/inline_diverging.rs:27:9: 27:10
++ scope 3 {
++ debug b => _9; // in scope 3 at $DIR/inline_diverging.rs:28:9: 28:10
++ }
++ }
++ scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline_diverging.rs:27:13: 27:16
++ }
++ }
+
+ 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(_9); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22
++ StorageLive(_3); // scope 1 at $DIR/inline_diverging.rs:27:9: 27:10
++ StorageLive(_4); // scope 1 at $DIR/inline_diverging.rs:27:13: 27:14
++ _4 = &_2; // scope 1 at $DIR/inline_diverging.rs:27:13: 27:14
++ StorageLive(_5); // scope 1 at $DIR/inline_diverging.rs:27:13: 27:16
++ _3 = move (*_4)() -> [return: bb6, unwind: bb4]; // scope 4 at $SRC_DIR/core/src/ops/function.rs:LL:COL
++ }
++
++ bb1: {
++ StorageDead(_7); // scope 2 at $DIR/inline_diverging.rs:28:15: 28:16
++ StorageDead(_6); // scope 2 at $DIR/inline_diverging.rs:28:15: 28:16
++ StorageLive(_8); // scope 3 at $DIR/inline_diverging.rs:29:6: 29:7
++ _8 = move _3; // scope 3 at $DIR/inline_diverging.rs:29:6: 29:7
++ Deinit(_1); // scope 3 at $DIR/inline_diverging.rs:29:5: 29:11
++ (_1.0: !) = move _8; // scope 3 at $DIR/inline_diverging.rs:29:5: 29:11
++ (_1.1: !) = move _9; // scope 3 at $DIR/inline_diverging.rs:29:5: 29:11
++ StorageDead(_8); // scope 3 at $DIR/inline_diverging.rs:29:10: 29:11
++ StorageDead(_3); // scope 1 at $DIR/inline_diverging.rs:30:1: 30:2
++ drop(_2) -> bb2; // scope 1 at $DIR/inline_diverging.rs:30:1: 30:2
++ }
++
++ bb2: {
++ unreachable; // scope 0 at $DIR/inline_diverging.rs:30:2: 30:2
++ }
++
++ bb3 (cleanup): {
++ drop(_3) -> bb4; // scope 1 at $DIR/inline_diverging.rs:30:1: 30:2
++ }
++
++ bb4 (cleanup): {
++ drop(_2) -> bb5; // scope 1 at $DIR/inline_diverging.rs:30:1: 30:2
++ }
++
++ bb5 (cleanup): {
++ resume; // scope 1 at $DIR/inline_diverging.rs:26:1: 30:2
++ }
++
++ bb6: {
++ StorageDead(_5); // scope 1 at $DIR/inline_diverging.rs:27:15: 27:16
++ StorageDead(_4); // scope 1 at $DIR/inline_diverging.rs:27:15: 27:16
++ StorageLive(_6); // scope 2 at $DIR/inline_diverging.rs:28:13: 28:14
++ _6 = &_2; // scope 2 at $DIR/inline_diverging.rs:28:13: 28:14
++ StorageLive(_7); // scope 2 at $DIR/inline_diverging.rs:28:13: 28:16
++ _9 = <fn() -> ! {sleep} as Fn<()>>::call(move _6, move _7) -> [return: bb1, unwind: bb3]; // scope 2 at $DIR/inline_diverging.rs:28:13: 28:16
++ // mir::Constant
++ // + span: $DIR/inline_diverging.rs:28:13: 28:14
++ // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a fn() -> ! {sleep}, ()) -> <fn() -> ! {sleep} as FnOnce<()>>::Output {<fn() -> ! {sleep} as Fn<()>>::call}, val: Value(<ZST>) }
+ }
+ }
+
diff --git a/tests/mir-opt/inline/inline_diverging.rs b/tests/mir-opt/inline/inline_diverging.rs
new file mode 100644
index 000000000..ae6f814c2
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_generator.main.Inline.diff b/tests/mir-opt/inline/inline_generator.main.Inline.diff
new file mode 100644
index 000000000..f27b64c30
--- /dev/null
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.diff
@@ -0,0 +1,136 @@
+- // 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:33: +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:33: 9:46
++ debug a => _7; // in scope 6 at $DIR/inline_generator.rs:15:6: 15:7
++ let mut _8: i32; // in scope 6 at $DIR/inline_generator.rs:15:17: 15:39
++ let mut _9: u32; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ let mut _10: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ let mut _11: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ let mut _12: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ }
+
+ 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:15:5: 15:41
++ discriminant(_4) = 0; // scope 2 at $DIR/inline_generator.rs:15:5: 15:41
+ _3 = &mut _4; // scope 0 at $DIR/inline_generator.rs:+1:23: +1:31
+- _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline_generator.rs:+1:14: +1:32
+- // mir::Constant
+- // + 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<'a> fn(Pin<&'a 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:33: +1:46
++ _7 = const false; // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46
++ _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ _9 = discriminant((*_10)); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ switchInt(move _9) -> [0: bb3, 1: bb8, 3: bb7, otherwise: bb9]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
+ }
+
+- bb3: {
++ bb1: {
++ StorageDead(_7); // scope 0 at $DIR/inline_generator.rs:+1:33: +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: {
++ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:17: 15:39
++ switchInt(move _7) -> [0: bb5, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21
++ }
++
++ bb4: {
++ _8 = const 7_i32; // scope 6 at $DIR/inline_generator.rs:15:24: 15:25
++ goto -> bb6; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39
++ }
++
++ bb5: {
++ _8 = const 13_i32; // scope 6 at $DIR/inline_generator.rs:15:35: 15:37
++ goto -> bb6; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39
++ }
++
++ bb6: {
++ Deinit(_1); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
++ ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
++ discriminant(_1) = 0; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
++ _11 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
++ discriminant((*_11)) = 3; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
++ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:11: 15:39
++ }
++
++ bb7: {
++ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ StorageDead(_8); // scope 6 at $DIR/inline_generator.rs:15:38: 15:39
++ Deinit(_1); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
++ ((_1 as Complete).0: bool) = move _7; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
++ discriminant(_1) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
++ _12 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
++ discriminant((*_12)) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
++ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:41: 15:41
++ }
++
++ bb8: {
++ assert(const false, "generator resumed after completion") -> [success: bb8, unwind: bb2]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ }
++
++ bb9: {
++ unreachable; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
+ }
+ }
+
diff --git a/tests/mir-opt/inline/inline_generator.rs b/tests/mir-opt/inline/inline_generator.rs
new file mode 100644
index 000000000..d11b3e548
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff b/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff
new file mode 100644
index 000000000..f1988ea4b
--- /dev/null
+++ b/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff
@@ -0,0 +1,60 @@
+- // 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
+ let _4: (); // in scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
++ scope 1 (inlined instruction_set_default) { // at $DIR/inline_instruction_set.rs:59:5: 59:30
++ }
++ scope 2 (inlined inline_always_and_using_inline_asm) { // at $DIR/inline_instruction_set.rs:60:5: 60:41
++ scope 3 {
++ }
++ }
+
+ 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:57:5: 57: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:58:5: 58: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:59:5: 59: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
+ StorageLive(_4); // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
+- _4 = inline_always_and_using_inline_asm() -> bb4; // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
+- // mir::Constant
+- // + span: $DIR/inline_instruction_set.rs:60:5: 60:39
+- // + literal: Const { ty: fn() {inline_always_and_using_inline_asm}, val: Value(<ZST>) }
++ asm!("/* do nothing */", options((empty))) -> bb3; // scope 3 at $DIR/inline_instruction_set.rs:43:14: 43:38
+ }
+
+- bb4: {
++ bb3: {
+ StorageDead(_4); // scope 0 at $DIR/inline_instruction_set.rs:+4:41: +4:42
+ _0 = const (); // scope 0 at $DIR/inline_instruction_set.rs:+0:18: +5:2
+ return; // scope 0 at $DIR/inline_instruction_set.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/tests/mir-opt/inline/inline_instruction_set.rs b/tests/mir-opt/inline/inline_instruction_set.rs
new file mode 100644
index 000000000..5dfb04943
--- /dev/null
+++ b/tests/mir-opt/inline/inline_instruction_set.rs
@@ -0,0 +1,61 @@
+// Checks that only functions with the compatible instruction_set attributes are inlined.
+//
+// A function is "compatible" when the *callee* has the same attribute or no attribute.
+//
+// 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() {}
+
+#[inline(always)]
+fn inline_always_and_using_inline_asm() {
+ unsafe { asm!("/* do nothing */") };
+}
+
+// EMIT_MIR inline_instruction_set.t32.Inline.diff
+#[instruction_set(arm::t32)]
+pub fn t32() {
+ instruction_set_a32();
+ instruction_set_t32();
+ instruction_set_default();
+ inline_always_and_using_inline_asm();
+}
+
+// EMIT_MIR inline_instruction_set.default.Inline.diff
+pub fn default() {
+ instruction_set_a32();
+ instruction_set_t32();
+ instruction_set_default();
+ inline_always_and_using_inline_asm();
+}
diff --git a/tests/mir-opt/inline/inline_instruction_set.t32.Inline.diff b/tests/mir-opt/inline/inline_instruction_set.t32.Inline.diff
new file mode 100644
index 000000000..e777b2cc2
--- /dev/null
+++ b/tests/mir-opt/inline/inline_instruction_set.t32.Inline.diff
@@ -0,0 +1,58 @@
+- // 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:+3:5: +3:30
+ let _4: (); // in scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
++ scope 1 (inlined instruction_set_t32) { // at $DIR/inline_instruction_set.rs:50:5: 50:26
++ }
++ scope 2 (inlined instruction_set_default) { // at $DIR/inline_instruction_set.rs:51:5: 51: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:49:5: 49: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:50:5: 50: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:51:5: 51: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
+ StorageLive(_4); // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
+- _4 = inline_always_and_using_inline_asm() -> bb4; // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
++ _4 = inline_always_and_using_inline_asm() -> bb2; // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
+ // mir::Constant
+ // + span: $DIR/inline_instruction_set.rs:52:5: 52:39
+ // + literal: Const { ty: fn() {inline_always_and_using_inline_asm}, val: Value(<ZST>) }
+ }
+
+- bb4: {
++ bb2: {
+ StorageDead(_4); // scope 0 at $DIR/inline_instruction_set.rs:+4:41: +4:42
+ _0 = const (); // scope 0 at $DIR/inline_instruction_set.rs:+0:14: +5:2
+ return; // scope 0 at $DIR/inline_instruction_set.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff
new file mode 100644
index 000000000..a28da146e
--- /dev/null
+++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.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: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
++ let mut _9: 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
+ _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: bb5]; // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
++ StorageLive(_8); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
++ _8 = &mut (*_7); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
++ StorageLive(_9); // scope 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 _; // 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
++ (*_8) = move _9; // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
++ StorageDead(_9); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
++ StorageDead(_8); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
+ _1 = move _5; // scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43
+ StorageDead(_5); // scope 0 at $DIR/inline_into_box_place.rs:+1:42: +1:43
+ _0 = const (); // scope 0 at $DIR/inline_into_box_place.rs:+0:11: +2:2
+- drop(_1) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2
++ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2
+ }
+
+- 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): {
++ bb3 (cleanup): {
+ resume; // scope 0 at $DIR/inline_into_box_place.rs:+0:1: +2:2
+- }
+-
+- bb5 (cleanup): {
+- _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb4; // scope 0 at $DIR/inline_into_box_place.rs:+1:42: +1:43
+- // mir::Constant
+- // + span: $DIR/inline_into_box_place.rs:8:42: 8:43
+- // + literal: Const { ty: unsafe fn(Unique<Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>}, val: Value(<ZST>) }
+ }
+ }
+
diff --git a/tests/mir-opt/inline/inline_into_box_place.rs b/tests/mir-opt/inline/inline_into_box_place.rs
new file mode 100644
index 000000000..232bcc7b2
--- /dev/null
+++ b/tests/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
+
+#![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/tests/mir-opt/inline/inline_options.main.Inline.after.mir b/tests/mir-opt/inline/inline_options.main.Inline.after.mir
new file mode 100644
index 000000000..1c590be94
--- /dev/null
+++ b/tests/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:16:23: 16:26
+ let _4: (); // in scope 1 at $DIR/inline_options.rs:16:28: 16:31
+ let _5: (); // in scope 1 at $DIR/inline_options.rs:16:33: 16:36
+ }
+
+ bb0: {
+ 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:16:23: 16:26
+ _3 = g() -> bb2; // scope 1 at $DIR/inline_options.rs:16:23: 16:26
+ // mir::Constant
+ // + span: $DIR/inline_options.rs:16:23: 16:24
+ // + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_3); // scope 1 at $DIR/inline_options.rs:16:26: 16:27
+ StorageLive(_4); // scope 1 at $DIR/inline_options.rs:16:28: 16:31
+ _4 = g() -> bb3; // scope 1 at $DIR/inline_options.rs:16:28: 16:31
+ // mir::Constant
+ // + span: $DIR/inline_options.rs:16:28: 16:29
+ // + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_4); // scope 1 at $DIR/inline_options.rs:16:31: 16:32
+ StorageLive(_5); // scope 1 at $DIR/inline_options.rs:16:33: 16:36
+ _5 = g() -> bb4; // scope 1 at $DIR/inline_options.rs:16:33: 16:36
+ // mir::Constant
+ // + span: $DIR/inline_options.rs:16:33: 16:34
+ // + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
+ }
+
+ bb4: {
+ StorageDead(_5); // scope 1 at $DIR/inline_options.rs:16:36: 16:37
+ StorageDead(_2); // scope 0 at $DIR/inline_options.rs:+2:21: +2:22
+ _0 = const (); // scope 0 at $DIR/inline_options.rs:+0:11: +3:2
+ return; // scope 0 at $DIR/inline_options.rs:+3:2: +3:2
+ }
+}
diff --git a/tests/mir-opt/inline/inline_options.rs b/tests/mir-opt/inline/inline_options.rs
new file mode 100644
index 000000000..477f050b6
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_retag.bar.Inline.after.mir b/tests/mir-opt/inline/inline_retag.bar.Inline.after.mir
new file mode 100644
index 000000000..60149ff36
--- /dev/null
+++ b/tests/mir-opt/inline/inline_retag.bar.Inline.after.mir
@@ -0,0 +1,68 @@
+// 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<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; // in scope 0 at $DIR/inline_retag.rs:+1:9: +1:10
+ let mut _2: for<'a, 'b> fn(&'a i32, &'b 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:16:8: 16:9
+ debug y => _6; // in scope 2 at $DIR/inline_retag.rs:16:17: 16:18
+ let mut _11: i32; // in scope 2 at $DIR/inline_retag.rs:17:5: 17:7
+ let mut _12: i32; // in scope 2 at $DIR/inline_retag.rs:17:11: 17:13
+ }
+ }
+
+ 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<'a, 'b> fn(&'a i32, &'b 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 _; // 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
+ _3 = &(*_4); // 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 _; // 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
+ _6 = &(*_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
+ Retag(_3); // scope 2 at $DIR/inline_retag.rs:16:8: 16:9
+ Retag(_6); // scope 2 at $DIR/inline_retag.rs:16:17: 16:18
+ StorageLive(_11); // scope 2 at $DIR/inline_retag.rs:17:5: 17:7
+ _11 = (*_3); // scope 2 at $DIR/inline_retag.rs:17:5: 17:7
+ StorageLive(_12); // scope 2 at $DIR/inline_retag.rs:17:11: 17:13
+ _12 = (*_6); // scope 2 at $DIR/inline_retag.rs:17:11: 17:13
+ _0 = Eq(move _11, move _12); // scope 2 at $DIR/inline_retag.rs:17:5: 17:13
+ StorageDead(_12); // scope 2 at $DIR/inline_retag.rs:17:12: 17:13
+ StorageDead(_11); // scope 2 at $DIR/inline_retag.rs:17:12: 17:13
+ StorageDead(_6); // scope 1 at $DIR/inline_retag.rs:+2:14: +2:15
+ StorageDead(_3); // scope 1 at $DIR/inline_retag.rs:+2:14: +2:15
+ StorageDead(_2); // scope 1 at $DIR/inline_retag.rs:+2:14: +2:15
+ 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/tests/mir-opt/inline/inline_retag.rs b/tests/mir-opt/inline/inline_retag.rs
new file mode 100644
index 000000000..c6950f269
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_shims.clone.Inline.diff b/tests/mir-opt/inline/inline_shims.clone.Inline.diff
new file mode 100644
index 000000000..09dd35c4c
--- /dev/null
+++ b/tests/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:7: 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<'a> fn(&'a 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/tests/mir-opt/inline/inline_shims.drop.Inline.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.diff
new file mode 100644
index 000000000..36ddb189e
--- /dev/null
+++ b/tests/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: 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/tests/mir-opt/inline/inline_shims.rs b/tests/mir-opt/inline/inline_shims.rs
new file mode 100644
index 000000000..7c8618f71
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_specialization.main.Inline.diff b/tests/mir-opt/inline/inline_specialization.main.Inline.diff
new file mode 100644
index 000000000..af08296ed
--- /dev/null
+++ b/tests/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:14:31: 14:34
+ _0 = const (); // scope 0 at $DIR/inline_specialization.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline_specialization.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/inline_specialization.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/inline/inline_specialization.rs b/tests/mir-opt/inline/inline_specialization.rs
new file mode 100644
index 000000000..87275b4e5
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_trait_method.rs b/tests/mir-opt/inline/inline_trait_method.rs
new file mode 100644
index 000000000..74be53f55
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_trait_method.test.Inline.after.mir b/tests/mir-opt/inline/inline_trait_method.test.Inline.after.mir
new file mode 100644
index 000000000..637bf282a
--- /dev/null
+++ b/tests/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<'a> fn(&'a 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/tests/mir-opt/inline/inline_trait_method_2.rs b/tests/mir-opt/inline/inline_trait_method_2.rs
new file mode 100644
index 000000000..378e71a25
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
new file mode 100644
index 000000000..73aea719e
--- /dev/null
+++ b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
@@ -0,0 +1,28 @@
+// 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:9:9: 9: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
+ _0 = <dyn X as X>::y(move _2) -> bb1; // scope 1 at $DIR/inline_trait_method_2.rs:10:5: 10:10
+ // mir::Constant
+ // + span: $DIR/inline_trait_method_2.rs:10:7: 10:8
+ // + literal: Const { ty: for<'a> fn(&'a dyn X) -> bool {<dyn X as X>::y}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ 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/tests/mir-opt/inline/issue_106141.outer.Inline.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.diff
new file mode 100644
index 000000000..97361fa5f
--- /dev/null
+++ b/tests/mir-opt/inline/issue_106141.outer.Inline.diff
@@ -0,0 +1,55 @@
+- // MIR for `outer` before Inline
++ // MIR for `outer` after Inline
+
+ fn outer() -> usize {
+ let mut _0: usize; // return place in scope 0 at $DIR/issue_106141.rs:+0:19: +0:24
++ scope 1 (inlined inner) { // at $DIR/issue_106141.rs:2:5: 2:12
++ let mut _1: bool; // in scope 1 at $DIR/issue_106141.rs:13:8: 13:21
++ let mut _2: bool; // in scope 1 at $DIR/issue_106141.rs:13:8: 13:21
++ let mut _3: &[bool; 1]; // in scope 1 at $DIR/issue_106141.rs:11:18: 11:25
++ scope 2 {
++ debug buffer => _3; // in scope 2 at $DIR/issue_106141.rs:11:9: 11:15
++ scope 3 {
++ debug index => _0; // in scope 3 at $DIR/issue_106141.rs:12:9: 12:14
++ }
++ }
++ }
+
+ bb0: {
+- _0 = inner() -> bb1; // scope 0 at $DIR/issue_106141.rs:+1:5: +1:12
++ StorageLive(_3); // scope 0 at $DIR/issue_106141.rs:+1:5: +1:12
++ _3 = const _; // scope 1 at $DIR/issue_106141.rs:11:18: 11:25
+ // mir::Constant
+- // + span: $DIR/issue_106141.rs:2:5: 2:10
+- // + literal: Const { ty: fn() -> usize {inner}, val: Value(<ZST>) }
++ // + span: $DIR/issue_106141.rs:11:18: 11:25
++ // + literal: Const { ty: &[bool; 1], val: Unevaluated(inner, [], Some(promoted[0])) }
++ _0 = index() -> bb1; // scope 2 at $DIR/issue_106141.rs:12:17: 12:24
++ // mir::Constant
++ // + span: $DIR/issue_106141.rs:12:17: 12:22
++ // + literal: Const { ty: fn() -> usize {index}, val: Value(<ZST>) }
+ }
+
+ bb1: {
++ StorageLive(_1); // scope 3 at $DIR/issue_106141.rs:13:8: 13:21
++ _2 = Lt(_0, const 1_usize); // scope 3 at $DIR/issue_106141.rs:13:8: 13:21
++ assert(move _2, "index out of bounds: the length is {} but the index is {}", const 1_usize, _0) -> bb2; // scope 3 at $DIR/issue_106141.rs:13:8: 13:21
++ }
++
++ bb2: {
++ _1 = (*_3)[_0]; // scope 3 at $DIR/issue_106141.rs:13:8: 13:21
++ switchInt(move _1) -> [0: bb3, otherwise: bb4]; // scope 3 at $DIR/issue_106141.rs:13:8: 13:21
++ }
++
++ bb3: {
++ _0 = const 0_usize; // scope 3 at $DIR/issue_106141.rs:16:9: 16:10
++ goto -> bb4; // scope 3 at $DIR/issue_106141.rs:13:5: 17:6
++ }
++
++ bb4: {
++ StorageDead(_1); // scope 3 at $DIR/issue_106141.rs:17:5: 17:6
++ StorageDead(_3); // scope 0 at $DIR/issue_106141.rs:+1:5: +1:12
+ return; // scope 0 at $DIR/issue_106141.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/inline/issue_106141.rs b/tests/mir-opt/inline/issue_106141.rs
new file mode 100644
index 000000000..c8288b7f3
--- /dev/null
+++ b/tests/mir-opt/inline/issue_106141.rs
@@ -0,0 +1,24 @@
+pub fn outer() -> usize {
+ inner()
+}
+
+fn index() -> usize {
+ loop {}
+}
+
+#[inline]
+fn inner() -> usize {
+ let buffer = &[true];
+ let index = index();
+ if buffer[index] {
+ index
+ } else {
+ 0
+ }
+}
+
+fn main() {
+ outer();
+}
+
+// EMIT_MIR issue_106141.outer.Inline.diff
diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir
new file mode 100644
index 000000000..dc0c32350
--- /dev/null
+++ b/tests/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:7: 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/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
new file mode 100644
index 000000000..b6aff3014
--- /dev/null
+++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
@@ -0,0 +1,38 @@
+// 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:7: 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
+ _7 = deref_copy (*_4); // 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
+ _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/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir
new file mode 100644
index 000000000..af830d249
--- /dev/null
+++ b/tests/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:7: 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/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
new file mode 100644
index 000000000..4f9342247
--- /dev/null
+++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
@@ -0,0 +1,26 @@
+// 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:7: 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
+ _4 = deref_copy (*_3); // 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
+ _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/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs
new file mode 100644
index 000000000..94f926d39
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir
new file mode 100644
index 000000000..d99ae1a6c
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs
new file mode 100644
index 000000000..76d806acc
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/issue_78442.bar.Inline.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.diff
new file mode 100644
index 000000000..51a98465f
--- /dev/null
+++ b/tests/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<'a> extern "rust-call" fn(&'a 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/tests/mir-opt/inline/issue_78442.bar.RevealAll.diff b/tests/mir-opt/inline/issue_78442.bar.RevealAll.diff
new file mode 100644
index 000000000..e47466c5e
--- /dev/null
+++ b/tests/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<'a> extern "rust-call" fn(&'a impl Fn(), ()) -> <impl Fn() as FnOnce<()>>::Output {<impl Fn() as Fn<()>>::call}, val: Value(<ZST>) }
++ // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a 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/tests/mir-opt/inline/issue_78442.rs b/tests/mir-opt/inline/issue_78442.rs
new file mode 100644
index 000000000..aa8ede2df
--- /dev/null
+++ b/tests/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/tests/mir-opt/inline/polymorphic_recursion.rs b/tests/mir-opt/inline/polymorphic_recursion.rs
new file mode 100644
index 000000000..7388722b7
--- /dev/null
+++ b/tests/mir-opt/inline/polymorphic_recursion.rs
@@ -0,0 +1,25 @@
+// Make sure that the MIR inliner does not loop indefinitely on polymorphic recursion.
+// compile-flags: --crate-type lib
+
+// Randomize `def_path_hash` by defining them under a module with different names
+macro_rules! emit {
+ ($($m:ident)*) => {$(
+ pub mod $m {
+ pub trait Tr { type Next: Tr; }
+
+ pub fn hoge<const N: usize, T: Tr>() {
+ inner::<N, T>();
+ }
+
+ #[inline(always)]
+ fn inner<const N: usize, T: Tr>()
+ {
+ inner::<N, T::Next>();
+ inner::<N, T::Next>();
+ }
+ }
+ )*};
+}
+
+// Increase the chance of triggering the bug
+emit!(m00 m01 m02 m03 m04 m05 m06 m07 m08 m09 m10 m11 m12 m13 m14 m15 m16 m17 m18 m19);
diff --git a/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
new file mode 100644
index 000000000..a3cee3ecf
--- /dev/null
+++ b/tests/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:20:1 - 22:2; // scope 0 at /the/src/instrument_coverage.rs:+2:2: +2:2
+ _0 = const true; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +1:9
+ return; // scope 0 at /the/src/instrument_coverage.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
new file mode 100644
index 000000000..2f6f5f87e
--- /dev/null
+++ b/tests/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:11:1 - 11:11; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
+ goto -> bb1; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
+ }
+
+ bb1: {
++ Coverage::Expression(4294967295) = 1 + 2 for /the/src/instrument_coverage.rs:12:5 - 13:17; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
+ falseUnwind -> [real: bb2, cleanup: bb6]; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
+ }
+
+ 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:13:12: 13:15
+ // + literal: Const { ty: fn() -> bool {bar}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ switchInt(move _2) -> [0: 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:17:1 - 17:2; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2
++ Coverage::Expression(4294967294) = 4294967295 - 2 for /the/src/instrument_coverage.rs:14:13 - 14:18; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2
+ _0 = const (); // scope 0 at /the/src/instrument_coverage.rs:+3:13: +3:18
+ StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:+4:9: +4:10
+ return; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2
+ }
+
+ bb5: {
++ Coverage::Counter(2) for /the/src/instrument_coverage.rs:15:10 - 15:11; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
+ _1 = const (); // scope 0 at /the/src/instrument_coverage.rs:+4:10: +4:10
+ StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:+4:9: +4:10
+ goto -> bb1; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
+ }
+
+ bb6 (cleanup): {
+ resume; // scope 0 at /the/src/instrument_coverage.rs:+0:1: +6:2
+ }
+ }
+
diff --git a/tests/mir-opt/instrument_coverage.rs b/tests/mir-opt/instrument_coverage.rs
new file mode 100644
index 000000000..7f6a0a0eb
--- /dev/null
+++ b/tests/mir-opt/instrument_coverage.rs
@@ -0,0 +1,37 @@
+// Test that `-C instrument-coverage` injects Coverage statements. The Coverage Counter statements
+// are later converted into LLVM instrprof.increment intrinsics, during codegen.
+
+// unit-test: InstrumentCoverage
+// needs-profiler-support
+// ignore-windows
+// compile-flags: -C instrument-coverage --remap-path-prefix={{src-base}}=/the/src
+
+// 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/tests/mir-opt/issue_101973.inner.ConstProp.diff b/tests/mir-opt/issue_101973.inner.ConstProp.diff
new file mode 100644
index 000000000..b2706e5a4
--- /dev/null
+++ b/tests/mir-opt/issue_101973.inner.ConstProp.diff
@@ -0,0 +1,95 @@
+- // MIR for `inner` before ConstProp
++ // MIR for `inner` after ConstProp
+
+ fn inner(_1: u32) -> i64 {
+ debug fields => _1; // in scope 0 at $DIR/issue_101973.rs:+0:14: +0:20
+ let mut _0: i64; // return place in scope 0 at $DIR/issue_101973.rs:+0:30: +0:33
+ let mut _2: i32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:65
+ let mut _3: u32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:58
+ let mut _4: u32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:17
+ let mut _5: u32; // in scope 0 at $DIR/issue_101973.rs:+1:10: +1:16
+ let mut _6: u32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
+ let mut _7: u32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:52
+ let mut _8: u32; // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
+ let mut _9: u32; // in scope 0 at $DIR/issue_101973.rs:+1:33: +1:39
+ let mut _10: (u32, bool); // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
+ let mut _11: (u32, bool); // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
+ scope 1 (inlined imm8) { // at $DIR/issue_101973.rs:14:5: 14:17
+ debug x => _5; // in scope 1 at $DIR/issue_101973.rs:5:13: 5:14
+ let mut _12: u32; // in scope 1 at $DIR/issue_101973.rs:7:12: 7:27
+ let mut _13: u32; // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20
+ let mut _14: (u32, bool); // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20
+ scope 2 {
+ debug out => _4; // in scope 2 at $DIR/issue_101973.rs:6:9: 6:16
+ }
+ }
+ scope 3 (inlined core::num::<impl u32>::rotate_right) { // at $DIR/issue_101973.rs:14:18: 14:58
+ debug self => _4; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ debug n => _6; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ let mut _15: u32; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ let mut _16: u32; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65
+ StorageLive(_3); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:58
+ StorageLive(_4); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:17
+ StorageLive(_5); // scope 0 at $DIR/issue_101973.rs:+1:10: +1:16
+ _5 = _1; // scope 0 at $DIR/issue_101973.rs:+1:10: +1:16
+ StorageLive(_12); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27
+ StorageLive(_13); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20
+ _14 = CheckedShr(_5, const 0_i32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20
+ assert(!move (_14.1: bool), "attempt to shift right by `{}`, which would overflow", const 0_i32) -> bb3; // scope 2 at $DIR/issue_101973.rs:7:12: 7:20
+ }
+
+ bb1: {
+ _8 = move (_10.0: u32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
+ StorageDead(_9); // scope 0 at $DIR/issue_101973.rs:+1:44: +1:45
+ _7 = BitAnd(move _8, const 15_u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52
+ StorageDead(_8); // scope 0 at $DIR/issue_101973.rs:+1:51: +1:52
+ _11 = CheckedShl(_7, const 1_i32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
+ assert(!move (_11.1: bool), "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
+ }
+
+ bb2: {
+ _6 = move (_11.0: u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
+ StorageDead(_7); // scope 0 at $DIR/issue_101973.rs:+1:56: +1:57
+ StorageLive(_15); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ _15 = _4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ StorageLive(_16); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ _16 = _6; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ _3 = rotate_right::<u32>(move _15, move _16) -> bb4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ // + literal: Const { ty: extern "rust-intrinsic" fn(u32, u32) -> u32 {rotate_right::<u32>}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ _13 = move (_14.0: u32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20
+ _12 = BitAnd(move _13, const 255_u32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27
+ StorageDead(_13); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27
+ _4 = BitOr(const 0_u32, move _12); // scope 2 at $DIR/issue_101973.rs:7:5: 7:27
+ StorageDead(_12); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27
+ StorageDead(_5); // scope 0 at $DIR/issue_101973.rs:+1:16: +1:17
+ StorageLive(_6); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
+ StorageLive(_7); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52
+ StorageLive(_8); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
+ StorageLive(_9); // scope 0 at $DIR/issue_101973.rs:+1:33: +1:39
+ _9 = _1; // scope 0 at $DIR/issue_101973.rs:+1:33: +1:39
+ _10 = CheckedShr(_9, const 8_i32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
+ assert(!move (_10.1: bool), "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
+ }
+
+ bb4: {
+ StorageDead(_16); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ StorageDead(_15); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ StorageDead(_6); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58
+ StorageDead(_4); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58
+ _2 = move _3 as i32 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65
+ StorageDead(_3); // scope 0 at $DIR/issue_101973.rs:+1:64: +1:65
+ _0 = move _2 as i64 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:72
+ StorageDead(_2); // scope 0 at $DIR/issue_101973.rs:+1:71: +1:72
+ return; // scope 0 at $DIR/issue_101973.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/issue_101973.rs b/tests/mir-opt/issue_101973.rs
new file mode 100644
index 000000000..216659a23
--- /dev/null
+++ b/tests/mir-opt/issue_101973.rs
@@ -0,0 +1,20 @@
+// compile-flags: -O -C debug-assertions=on
+// This needs inlining followed by ConstProp to reproduce, so we cannot use "unit-test".
+
+#[inline]
+pub fn imm8(x: u32) -> u32 {
+ let mut out = 0u32;
+ out |= (x >> 0) & 0xff;
+ out
+}
+
+// EMIT_MIR issue_101973.inner.ConstProp.diff
+#[inline(never)]
+pub fn inner(fields: u32) -> i64 {
+ imm8(fields).rotate_right(((fields >> 8) & 0xf) << 1) as i32 as i64
+}
+
+fn main() {
+ let val = inner(0xe32cf20f);
+ assert_eq!(val as u64, 0xfffffffff0000000);
+}
diff --git a/tests/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir
new file mode 100644
index 000000000..b0d5b291b
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/issue_38669.rs b/tests/mir-opt/issue_38669.rs
new file mode 100644
index 000000000..db3f89472
--- /dev/null
+++ b/tests/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/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir b/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir
new file mode 100644
index 000000000..c2ea3ac50
--- /dev/null
+++ b/tests/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) -> [0: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+ }
+}
diff --git a/tests/mir-opt/issue_41110.rs b/tests/mir-opt/issue_41110.rs
new file mode 100644
index 000000000..638dc601e
--- /dev/null
+++ b/tests/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/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir b/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir
new file mode 100644
index 000000000..82989c3f0
--- /dev/null
+++ b/tests/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) -> [0: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+ }
+}
diff --git a/tests/mir-opt/issue_41697.rs b/tests/mir-opt/issue_41697.rs
new file mode 100644
index 000000000..cbd8633a3
--- /dev/null
+++ b/tests/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 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/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir b/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
new file mode 100644
index 000000000..8af087d84
--- /dev/null
+++ b/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.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/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir b/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir
new file mode 100644
index 000000000..005042732
--- /dev/null
+++ b/tests/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) -> [0: 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: 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: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ }
+
+ bb20: {
+ switchInt(_7) -> [0: 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: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ }
+
+ bb22 (cleanup): {
+ switchInt(_7) -> [0: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ }
+}
diff --git a/tests/mir-opt/issue_41888.rs b/tests/mir-opt/issue_41888.rs
new file mode 100644
index 000000000..c1046c14d
--- /dev/null
+++ b/tests/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/tests/mir-opt/issue_62289.rs b/tests/mir-opt/issue_62289.rs
new file mode 100644
index 000000000..37e3390d5
--- /dev/null
+++ b/tests/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/tests/mir-opt/issue_62289.test.ElaborateDrops.before.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.mir
new file mode 100644
index 000000000..adfa3a773
--- /dev/null
+++ b/tests/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: bb3, 1: 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/tests/mir-opt/issue_72181.bar.built.after.mir b/tests/mir-opt/issue_72181.bar.built.after.mir
new file mode 100644
index 000000000..ebee89001
--- /dev/null
+++ b/tests/mir-opt/issue_72181.bar.built.after.mir
@@ -0,0 +1,17 @@
+// MIR for `bar` after built
+
+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/tests/mir-opt/issue_72181.foo.built.after.mir b/tests/mir-opt/issue_72181.foo.built.after.mir
new file mode 100644
index 000000000..90c978520
--- /dev/null
+++ b/tests/mir-opt/issue_72181.foo.built.after.mir
@@ -0,0 +1,27 @@
+// MIR for `foo` after built
+
+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/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir
new file mode 100644
index 000000000..e86836927
--- /dev/null
+++ b/tests/mir-opt/issue_72181.main.built.after.mir
@@ -0,0 +1,62 @@
+// MIR for `main` after built
+
+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/tests/mir-opt/issue_72181.rs b/tests/mir-opt/issue_72181.rs
new file mode 100644
index 000000000..6a32d4bbe
--- /dev/null
+++ b/tests/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 issue_72181.foo.built.after.mir
+fn foo(xs: [(Never, u32); 1]) -> u32 { xs[0].1 }
+
+// EMIT_MIR issue_72181.bar.built.after.mir
+fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { x }
+
+
+// EMIT_MIR issue_72181.main.built.after.mir
+fn main() {
+ let _ = mem::size_of::<Foo>();
+
+ let f = [Foo { a: 42 }, Foo { a: 10 }];
+ let _ = unsafe { f[0].a };
+}
diff --git a/tests/mir-opt/issue_72181_1.f.built.after.mir b/tests/mir-opt/issue_72181_1.f.built.after.mir
new file mode 100644
index 000000000..4086da520
--- /dev/null
+++ b/tests/mir-opt/issue_72181_1.f.built.after.mir
@@ -0,0 +1,29 @@
+// MIR for `f` after built
+
+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/tests/mir-opt/issue_72181_1.main.built.after.mir b/tests/mir-opt/issue_72181_1.main.built.after.mir
new file mode 100644
index 000000000..2172f3aa9
--- /dev/null
+++ b/tests/mir-opt/issue_72181_1.main.built.after.mir
@@ -0,0 +1,57 @@
+// MIR for `main` after built
+
+| 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/tests/mir-opt/issue_72181_1.rs b/tests/mir-opt/issue_72181_1.rs
new file mode 100644
index 000000000..8ae2599ec
--- /dev/null
+++ b/tests/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.built.after.mir
+fn f(v: Void) -> ! {
+ match v {}
+}
+
+// EMIT_MIR issue_72181_1.main.built.after.mir
+fn main() {
+ let v: Void = unsafe {
+ std::mem::transmute::<(), Void>(())
+ };
+
+ f(v);
+}
diff --git a/tests/mir-opt/issue_73223.main.SimplifyArmIdentity.diff b/tests/mir-opt/issue_73223.main.SimplifyArmIdentity.diff
new file mode 100644
index 000000000..bf3bcfdb5
--- /dev/null
+++ b/tests/mir-opt/issue_73223.main.SimplifyArmIdentity.diff
@@ -0,0 +1,156 @@
+- // 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 _6: i32; // in scope 0 at $DIR/issue_73223.rs:+6:22: +6:27
+ let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _8: &i32; // 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: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _13: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _14: i32; // 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: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _19: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _20: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _21: &i32; // 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 mut _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
+ scope 1 {
+ debug split => _1; // in scope 1 at $DIR/issue_73223.rs:+1:9: +1:14
+ let _5: std::option::Option<i32>; // in scope 1 at $DIR/issue_73223.rs:+6:9: +6:14
+ scope 3 {
+ debug _prev => _5; // in scope 3 at $DIR/issue_73223.rs:+6:9: +6:14
+ let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _10: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _23: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 4 {
+ debug left_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ debug right_val => _10; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _15: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 5 {
+ debug kind => _15; // 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 -> bb3; // scope 0 at $DIR/issue_73223.rs:+1:17: +1:30
+ }
+
+ bb1: {
+ 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: {
+ unreachable; // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
+ }
+
+ bb3: {
+ StorageLive(_4); // scope 0 at $DIR/issue_73223.rs:+2:14: +2:15
+ _4 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue_73223.rs:+2:14: +2:15
+ _1 = _4; // scope 2 at $DIR/issue_73223.rs:+2:20: +2:21
+ 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(_5); // scope 1 at $DIR/issue_73223.rs:+6:9: +6:14
+ StorageLive(_6); // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27
+ _6 = _1; // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27
+ Deinit(_5); // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28
+ ((_5 as Some).0: i32) = move _6; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28
+ discriminant(_5) = 1; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28
+ StorageDead(_6); // scope 1 at $DIR/issue_73223.rs:+6:27: +6:28
+ StorageLive(_24); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_25); // 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
+ _7 = &_1; // 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
+ _23 = const _; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
+ _8 = _23; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_24); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_25); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _24 = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _25 = move _8; // 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(_7); // 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 = _24; // 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 = _25; // scope 3 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
+ StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _13 = (*_9); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_14); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _14 = const 1_i32; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _12 = Eq(move _13, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_14); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _11 = Not(move _12); // 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
+ switchInt(move _11) -> [0: bb5, otherwise: bb4]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb4: {
+ StorageLive(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ discriminant(_15) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_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
+ _17 = 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(_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
+ _19 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _18 = _19; // 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
+ StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _21 = _10; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _20 = _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
+ Deinit(_22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ discriminant(_22) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _16 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _18, move _20, move _22); // 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<'a, 'b, 'c> fn(core::panicking::AssertKind, &'a i32, &'b i32, Option<Arguments<'c>>) -> ! {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)) }
+ }
+
+ bb5: {
+ StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_10); // 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(_24); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_25); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_5); // 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/tests/mir-opt/issue_73223.rs b/tests/mir-opt/issue_73223.rs
new file mode 100644
index 000000000..be114cab7
--- /dev/null
+++ b/tests/mir-opt/issue_73223.rs
@@ -0,0 +1,12 @@
+fn main() {
+ let split = match Some(1) {
+ Some(v) => v,
+ None => return,
+ };
+
+ let _prev = Some(split);
+ assert_eq!(split, 1);
+}
+
+
+// EMIT_MIR issue_73223.main.SimplifyArmIdentity.diff
diff --git a/tests/mir-opt/issue_76432.rs b/tests/mir-opt/issue_76432.rs
new file mode 100644
index 000000000..c8b405ca8
--- /dev/null
+++ b/tests/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/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
new file mode 100644
index 000000000..c24543dae
--- /dev/null
+++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
@@ -0,0 +1,84 @@
+- // 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 mut _9: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33
+ let mut _10: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33
+ let mut _11: bool; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33
+ let mut _15: !; // in scope 0 at $SRC_DIR/core/src/panic.rs:LL:COL
+ scope 1 {
+ debug v => _2; // in scope 1 at $DIR/issue_76432.rs:+1:9: +1:10
+ let _12: &T; // in scope 1 at $DIR/issue_76432.rs:+3:10: +3:16
+ let _13: &T; // in scope 1 at $DIR/issue_76432.rs:+3:18: +3:24
+ let _14: &T; // in scope 1 at $DIR/issue_76432.rs:+3:26: +3:32
+ scope 2 {
+ debug v1 => _12; // in scope 2 at $DIR/issue_76432.rs:+3:10: +3:16
+ debug v2 => _13; // in scope 2 at $DIR/issue_76432.rs:+3:18: +3:24
+ debug v3 => _14; // in scope 2 at $DIR/issue_76432.rs:+3:26: +3:32
+ }
+ }
+
+ 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
+ _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
+ _9 = Len((*_2)); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+ _10 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+- _11 = Eq(move _9, const 3_usize); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+- switchInt(move _11) -> [0: bb1, otherwise: bb2]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
++ nop; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
++ switchInt(move _9) -> [3: bb2, otherwise: bb1]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+ }
+
+ bb1: {
+ StorageLive(_15); // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL
+ _15 = 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(_12); // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16
+ _12 = &(*_2)[0 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16
+ StorageLive(_13); // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24
+ _13 = &(*_2)[1 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24
+ StorageLive(_14); // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32
+ _14 = &(*_2)[2 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32
+ StorageDead(_14); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85
+ StorageDead(_13); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85
+ StorageDead(_12); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85
+ StorageDead(_5); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2
+ StorageDead(_2); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/issue_76432.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/tests/mir-opt/issue_78192.f.InstCombine.diff b/tests/mir-opt/issue_78192.f.InstCombine.diff
new file mode 100644
index 000000000..116ca304c
--- /dev/null
+++ b/tests/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/tests/mir-opt/issue_78192.rs b/tests/mir-opt/issue_78192.rs
new file mode 100644
index 000000000..39f665402
--- /dev/null
+++ b/tests/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/tests/mir-opt/issue_91633.bar.built.after.mir b/tests/mir-opt/issue_91633.bar.built.after.mir
new file mode 100644
index 000000000..c3fb90e84
--- /dev/null
+++ b/tests/mir-opt/issue_91633.bar.built.after.mir
@@ -0,0 +1,39 @@
+// MIR for `bar` after built
+
+fn bar(_1: Box<[T]>) -> () {
+ debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:12: +0:14
+ let mut _0: (); // return place in scope 0 at $DIR/issue_91633.rs:+1:2: +1:2
+ let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue_91633.rs:+4:14: +4:19
+ let mut _3: &[T]; // in scope 0 at $DIR/issue_91633.rs:+4:14: +4:16
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:19
+ StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:16
+ _3 = &(*_1); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:16
+ _2 = <[T] as Index<usize>>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue_91633.rs:+4:14: +4:19
+ // mir::Constant
+ // + span: $DIR/issue_91633.rs:15:14: 15:19
+ // + literal: Const { ty: for<'a> fn(&'a [T], usize) -> &'a <[T] as Index<usize>>::Output {<[T] as Index<usize>>::index}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+4:18: +4:19
+ StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:19: +4:20
+ _0 = const (); // scope 0 at $DIR/issue_91633.rs:+3:2: +5:3
+ drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3
+ }
+
+ bb2: {
+ return; // scope 0 at $DIR/issue_91633.rs:+5:3: +5:3
+ }
+
+ bb3 (cleanup): {
+ drop(_1) -> bb4; // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3
+ }
+
+ bb4 (cleanup): {
+ resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +5:3
+ }
+}
diff --git a/tests/mir-opt/issue_91633.foo.built.after.mir b/tests/mir-opt/issue_91633.foo.built.after.mir
new file mode 100644
index 000000000..4e3dd365e
--- /dev/null
+++ b/tests/mir-opt/issue_91633.foo.built.after.mir
@@ -0,0 +1,57 @@
+// MIR for `foo` after built
+
+fn foo(_1: Box<[T]>) -> T {
+ debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:19: +0:21
+ let mut _0: T; // return place in scope 0 at $DIR/issue_91633.rs:+0:36: +0:37
+ let _2: T; // in scope 0 at $DIR/issue_91633.rs:+2:10: +2:11
+ let mut _3: &T; // in scope 0 at $DIR/issue_91633.rs:+2:14: +2:27
+ let _4: usize; // in scope 0 at $DIR/issue_91633.rs:+2:17: +2:18
+ let mut _5: usize; // in scope 0 at $DIR/issue_91633.rs:+2:14: +2:19
+ let mut _6: bool; // in scope 0 at $DIR/issue_91633.rs:+2:14: +2:19
+ scope 1 {
+ debug f => _2; // in scope 1 at $DIR/issue_91633.rs:+2:10: +2:11
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11
+ StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+2:14: +2:27
+ StorageLive(_4); // scope 0 at $DIR/issue_91633.rs:+2:17: +2:18
+ _4 = const 0_usize; // scope 0 at $DIR/issue_91633.rs:+2:17: +2:18
+ _5 = Len((*_1)); // scope 0 at $DIR/issue_91633.rs:+2:14: +2:19
+ _6 = Lt(_4, _5); // scope 0 at $DIR/issue_91633.rs:+2:14: +2:19
+ assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind: bb5]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:19
+ }
+
+ bb1: {
+ _3 = &(*_1)[_4]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:27
+ _2 = <T as Clone>::clone(move _3) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:27
+ // mir::Constant
+ // + span: $DIR/issue_91633.rs:28:20: 28:25
+ // + literal: Const { ty: for<'a> fn(&'a T) -> T {<T as Clone>::clone}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+2:26: +2:27
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11
+ StorageDead(_4); // scope 0 at $DIR/issue_91633.rs:+2:27: +2:28
+ _0 = move _2; // scope 1 at $DIR/issue_91633.rs:+3:6: +3:7
+ drop(_2) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3
+ drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/issue_91633.rs:+4:3: +4:3
+ }
+
+ bb5 (cleanup): {
+ drop(_1) -> bb6; // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3
+ }
+
+ bb6 (cleanup): {
+ resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +4:3
+ }
+}
diff --git a/tests/mir-opt/issue_91633.fun.built.after.mir b/tests/mir-opt/issue_91633.fun.built.after.mir
new file mode 100644
index 000000000..42486d3a5
--- /dev/null
+++ b/tests/mir-opt/issue_91633.fun.built.after.mir
@@ -0,0 +1,35 @@
+// MIR for `fun` after built
+
+fn fun(_1: &[T]) -> &T {
+ debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:12: +0:14
+ let mut _0: &T; // return place in scope 0 at $DIR/issue_91633.rs:+0:25: +0:27
+ let _2: &T; // in scope 0 at $DIR/issue_91633.rs:+2:10: +2:11
+ let _3: usize; // in scope 0 at $DIR/issue_91633.rs:+2:18: +2:19
+ let mut _4: usize; // in scope 0 at $DIR/issue_91633.rs:+2:15: +2:20
+ let mut _5: bool; // in scope 0 at $DIR/issue_91633.rs:+2:15: +2:20
+ scope 1 {
+ debug f => _2; // in scope 1 at $DIR/issue_91633.rs:+2:10: +2:11
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11
+ StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+2:18: +2:19
+ _3 = const 0_usize; // scope 0 at $DIR/issue_91633.rs:+2:18: +2:19
+ _4 = Len((*_1)); // scope 0 at $DIR/issue_91633.rs:+2:15: +2:20
+ _5 = Lt(_3, _4); // scope 0 at $DIR/issue_91633.rs:+2:15: +2:20
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue_91633.rs:+2:15: +2:20
+ }
+
+ bb1: {
+ _2 = &(*_1)[_3]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:20
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11
+ _0 = &(*_2); // scope 1 at $DIR/issue_91633.rs:+3:6: +3:7
+ StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3
+ StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3
+ return; // scope 0 at $DIR/issue_91633.rs:+4:3: +4:3
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +4:3
+ }
+}
diff --git a/tests/mir-opt/issue_91633.hey.built.after.mir b/tests/mir-opt/issue_91633.hey.built.after.mir
new file mode 100644
index 000000000..ccb06dd59
--- /dev/null
+++ b/tests/mir-opt/issue_91633.hey.built.after.mir
@@ -0,0 +1,35 @@
+// MIR for `hey` after built
+
+fn hey(_1: &[T]) -> () {
+ debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:12: +0:14
+ let mut _0: (); // return place in scope 0 at $DIR/issue_91633.rs:+1:2: +1:2
+ let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue_91633.rs:+4:14: +4:20
+ let _3: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue_91633.rs:+4:15: +4:20
+ let mut _4: &[T]; // in scope 0 at $DIR/issue_91633.rs:+4:15: +4:17
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:20
+ StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+4:15: +4:20
+ StorageLive(_4); // scope 0 at $DIR/issue_91633.rs:+4:15: +4:17
+ _4 = &(*_1); // scope 0 at $DIR/issue_91633.rs:+4:15: +4:17
+ _3 = <[T] as Index<usize>>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/issue_91633.rs:+4:15: +4:20
+ // mir::Constant
+ // + span: $DIR/issue_91633.rs:7:15: 7:20
+ // + literal: Const { ty: for<'a> fn(&'a [T], usize) -> &'a <[T] as Index<usize>>::Output {<[T] as Index<usize>>::index}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_4); // scope 0 at $DIR/issue_91633.rs:+4:19: +4:20
+ _2 = &(*_3); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:20
+ StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:20: +4:21
+ _0 = const (); // scope 0 at $DIR/issue_91633.rs:+3:2: +5:3
+ StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3
+ return; // scope 0 at $DIR/issue_91633.rs:+5:3: +5:3
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +5:3
+ }
+}
diff --git a/tests/mir-opt/issue_91633.rs b/tests/mir-opt/issue_91633.rs
new file mode 100644
index 000000000..9127cacc9
--- /dev/null
+++ b/tests/mir-opt/issue_91633.rs
@@ -0,0 +1,31 @@
+// compile-flags: -Z mir-opt-level=0
+// EMIT_MIR issue_91633.hey.built.after.mir
+fn hey<T> (it: &[T])
+ where
+ [T] : std::ops::Index<usize>,
+ {
+ let _ = &it[0];
+ }
+
+// EMIT_MIR issue_91633.bar.built.after.mir
+fn bar<T> (it: Box<[T]>)
+ where
+ [T] : std::ops::Index<usize>,
+ {
+ let _ = it[0];
+ }
+
+// EMIT_MIR issue_91633.fun.built.after.mir
+fn fun<T> (it: &[T]) -> &T
+ {
+ let f = &it[0];
+ f
+ }
+
+// EMIT_MIR issue_91633.foo.built.after.mir
+fn foo<T: Clone> (it: Box<[T]>) -> T
+ {
+ let f = it[0].clone();
+ f
+ }
+ fn main(){}
diff --git a/tests/mir-opt/issue_99325.main.built.after.mir b/tests/mir-opt/issue_99325.main.built.after.mir
new file mode 100644
index 000000000..3e035c18d
--- /dev/null
+++ b/tests/mir-opt/issue_99325.main.built.after.mir
@@ -0,0 +1,295 @@
+// MIR for `main` after built
+
+| 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(UnevaluatedConst { 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: [] }) }], 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<'a, 'b> fn(&'a &[u8], &'b &[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) -> [0: 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<'a, 'b, 'c> fn(core::panicking::AssertKind, &'a &[u8], &'b &[u8; 4], Option<Arguments<'c>>) -> ! {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<'a, 'b> fn(&'a &[u8], &'b &[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) -> [0: 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<'a, 'b, 'c> fn(core::panicking::AssertKind, &'a &[u8], &'b &[u8; 4], Option<Arguments<'c>>) -> ! {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/tests/mir-opt/issue_99325.rs b/tests/mir-opt/issue_99325.rs
new file mode 100644
index 000000000..fe819cddb
--- /dev/null
+++ b/tests/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.built.after.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/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir
new file mode 100644
index 000000000..c17d221f8
--- /dev/null
+++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir
@@ -0,0 +1,92 @@
+// 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: std::option::Option<u32>; // in scope 0 at $DIR/issue_59352.rs:+2:26: +2:41
+ let mut _3: u32; // in scope 0 at $DIR/issue_59352.rs:+2:12: +2:23
+ let mut _9: 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:12: 14:23
+ debug self => _1; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ debug radix => _3; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ let mut _4: &std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ let _5: std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ let mut _6: 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 => _4; // 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:42: 14:50
+ debug self => _2; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ let mut _7: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ let mut _8: !; // 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(_3); // scope 0 at $DIR/issue_59352.rs:+2:12: +2:23
+ StorageLive(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageLive(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageLive(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ _6 = _1; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ _5 = char::methods::<impl char>::to_digit(move _6, 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: {
+ StorageLive(_2); // scope 0 at $DIR/issue_59352.rs:+2:26: +2:41
+ _2 = char::methods::<impl char>::to_digit(move _1, 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: {
+ _7 = discriminant(_2); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ switchInt(move _7) -> [0: bb6, 1: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ }
+
+ bb3: {
+ _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: {
+ _4 = &_5; // 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
+ _9 = discriminant((*_4)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL
+ StorageDead(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageDead(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageDead(_3); // scope 0 at $DIR/issue_59352.rs:+2:12: +2:23
+ switchInt(move _9) -> [1: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23
+ }
+
+ bb6: {
+ StorageLive(_8); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ _8 = 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 ((_2 as Some).0: u32); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ StorageDead(_2); // 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/tests/mir-opt/issues/issue_59352.rs b/tests/mir-opt/issues/issue_59352.rs
new file mode 100644
index 000000000..1e0045555
--- /dev/null
+++ b/tests/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/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
new file mode 100644
index 000000000..938047803
--- /dev/null
+++ b/tests/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:8:37: 8: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: bb2, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30
+ }
+
+ bb2: {
+ switchInt(_2[1 of 4]) -> [0: bb3, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30
+ }
+
+ bb3: {
+ switchInt(_2[2 of 4]) -> [0: bb5, 4294901760: 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:11:23: 11: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/tests/mir-opt/issues/issue_75439.rs b/tests/mir-opt/issues/issue_75439.rs
new file mode 100644
index 000000000..4c749a150
--- /dev/null
+++ b/tests/mir-opt/issues/issue_75439.rs
@@ -0,0 +1,19 @@
+// EMIT_MIR issue_75439.foo.MatchBranchSimplification.diff
+// ignore-endian-big
+
+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/tests/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir b/tests/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir
new file mode 100644
index 000000000..4ee2dae49
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/loop_test.rs b/tests/mir-opt/loop_test.rs
new file mode 100644
index 000000000..7ded5b575
--- /dev/null
+++ b/tests/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/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff
new file mode 100644
index 000000000..9bc7060e9
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff
new file mode 100644
index 000000000..cf427cfd1
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff
new file mode 100644
index 000000000..3ed68f5f7
--- /dev/null
+++ b/tests/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/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff
new file mode 100644
index 000000000..f0e0cdcfd
--- /dev/null
+++ b/tests/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/tests/mir-opt/lower_array_len.rs b/tests/mir-opt/lower_array_len.rs
new file mode 100644
index 000000000..ea0224b21
--- /dev/null
+++ b/tests/mir-opt/lower_array_len.rs
@@ -0,0 +1,40 @@
+// unit-test: NormalizeArrayLen
+// compile-flags: -Zmir-enable-passes=+LowerSliceLenCalls
+
+// EMIT_MIR lower_array_len.array_bound.NormalizeArrayLen.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
+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
+pub fn array_len<const N: usize>(arr: &[u8; N]) -> usize {
+ arr.len()
+}
+
+// EMIT_MIR lower_array_len.array_len_by_value.NormalizeArrayLen.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/tests/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir b/tests/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir
new file mode 100644
index 000000000..701c2ad70
--- /dev/null
+++ b/tests/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir
@@ -0,0 +1,45 @@
+// MIR for `array_bound` after PreCodegen
+
+fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
+ debug index => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:36: +0:41
+ debug slice => _2; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:50: +0:55
+ let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:70: +0:72
+ let mut _3: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ let mut _4: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
+ let mut _5: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+ let mut _6: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ let mut _7: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
+ _4 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
+ StorageLive(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+ _5 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ StorageDead(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
+ switchInt(move _3) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ }
+
+ bb1: {
+ _6 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ _7 = Lt(_1, _6); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _1) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ }
+
+ bb2: {
+ _0 = (*_2)[_1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ goto -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +5:6
+ }
+
+ bb3: {
+ _0 = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:11
+ goto -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +5:6
+ }
+
+ bb4: {
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+5:5: +5:6
+ return; // scope 0 at $DIR/lower_array_len_e2e.rs:+6:2: +6:2
+ }
+}
diff --git a/tests/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir b/tests/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
new file mode 100644
index 000000000..0440cfce2
--- /dev/null
+++ b/tests/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
@@ -0,0 +1,58 @@
+// MIR for `array_bound_mut` after PreCodegen
+
+fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
+ debug index => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:40: +0:45
+ debug slice => _2; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:54: +0:59
+ let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:78: +0:80
+ let mut _3: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ let mut _4: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
+ let mut _5: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+ let mut _6: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ let mut _7: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ let _8: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
+ let mut _9: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ let mut _10: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
+ _4 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
+ StorageLive(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+ _5 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ StorageDead(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
+ switchInt(move _3) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ }
+
+ bb1: {
+ _6 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ _7 = Lt(_1, _6); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _1) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ }
+
+ bb2: {
+ _0 = (*_2)[_1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ goto -> bb5; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +7:6
+ }
+
+ bb3: {
+ StorageLive(_8); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
+ _8 = const 0_usize; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
+ _9 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ _10 = Lt(const 0_usize, _9); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ }
+
+ bb4: {
+ (*_2)[_8] = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:22
+ StorageDead(_8); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:22: +4:23
+ _0 = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+6:9: +6:11
+ goto -> bb5; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +7:6
+ }
+
+ bb5: {
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+7:5: +7:6
+ return; // scope 0 at $DIR/lower_array_len_e2e.rs:+8:2: +8:2
+ }
+}
diff --git a/tests/mir-opt/lower_array_len_e2e.array_len.PreCodegen.after.mir b/tests/mir-opt/lower_array_len_e2e.array_len.PreCodegen.after.mir
new file mode 100644
index 000000000..4b19f6795
--- /dev/null
+++ b/tests/mir-opt/lower_array_len_e2e.array_len.PreCodegen.after.mir
@@ -0,0 +1,11 @@
+// MIR for `array_len` after PreCodegen
+
+fn array_len(_1: &[u8; N]) -> usize {
+ debug arr => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:34: +0:37
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:52: +0:57
+
+ bb0: {
+ _0 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +1:14
+ return; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:2: +2:2
+ }
+}
diff --git a/tests/mir-opt/lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir b/tests/mir-opt/lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir
new file mode 100644
index 000000000..4dc0ba9a2
--- /dev/null
+++ b/tests/mir-opt/lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir
@@ -0,0 +1,11 @@
+// MIR for `array_len_by_value` after PreCodegen
+
+fn array_len_by_value(_1: [u8; N]) -> usize {
+ debug arr => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:43: +0:46
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:60: +0:65
+
+ bb0: {
+ _0 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +1:14
+ return; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:2: +2:2
+ }
+}
diff --git a/tests/mir-opt/lower_array_len_e2e.rs b/tests/mir-opt/lower_array_len_e2e.rs
new file mode 100644
index 000000000..d8e4e521e
--- /dev/null
+++ b/tests/mir-opt/lower_array_len_e2e.rs
@@ -0,0 +1,39 @@
+// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts
+
+// EMIT_MIR lower_array_len_e2e.array_bound.PreCodegen.after.mir
+pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 {
+ if index < slice.len() {
+ slice[index]
+ } else {
+ 42
+ }
+}
+
+// EMIT_MIR lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
+pub fn array_bound_mut<const N: usize>(index: usize, slice: &mut [u8; N]) -> u8 {
+ if index < slice.len() {
+ slice[index]
+ } else {
+ slice[0] = 42;
+
+ 42
+ }
+}
+
+// EMIT_MIR lower_array_len_e2e.array_len.PreCodegen.after.mir
+pub fn array_len<const N: usize>(arr: &[u8; N]) -> usize {
+ arr.len()
+}
+
+// EMIT_MIR lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir
+pub fn array_len_by_value<const N: usize>(arr: [u8; N]) -> usize {
+ arr.len()
+}
+
+fn main() {
+ let _ = array_bound(3, &[0, 1, 2, 3]);
+ let mut tmp = [0, 1, 2, 3, 4];
+ let _ = array_bound_mut(3, &mut [0, 1, 2, 3]);
+ let _ = array_len(&[0]);
+ let _ = array_len_by_value([0, 2]);
+}
diff --git a/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff
new file mode 100644
index 000000000..3389db733
--- /dev/null
+++ b/tests/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:21:5: 21:40
+- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::min_align_of::<T>}, val: Value(<ZST>) }
++ _0 = AlignOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42
++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42
+ }
+
+ bb1: {
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff
new file mode 100644
index 000000000..d9898d8e0
--- /dev/null
+++ b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff
@@ -0,0 +1,26 @@
+- // MIR for `assume` before LowerIntrinsics
++ // MIR for `assume` after LowerIntrinsics
+
+ fn assume() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:17
+ let _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:38
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
+- _1 = std::intrinsics::assume(const true) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:72:9: 72:32
+- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(bool) {std::intrinsics::assume}, val: Value(<ZST>) }
++ assume(const true); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:38: +2:39
+ _0 = const (); // scope 1 at $DIR/lower_intrinsics.rs:+1:5: +3:6
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
new file mode 100644
index 000000000..d962ef8cb
--- /dev/null
+++ b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
@@ -0,0 +1,119 @@
+- // 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:49:5: 49:41
+- // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a 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 _; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
+ // mir::Constant
+ // + span: $DIR/lower_intrinsics.rs:50:42: 50:44
+ // + literal: Const { ty: &i32, val: Unevaluated(discriminant, [T], Some(promoted[2])) }
+ _7 = &(*_19); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
+ _6 = &(*_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
+- _5 = discriminant_value::<i32>(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:50:5: 50:41
+- // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a 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 _; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
+ // mir::Constant
+ // + span: $DIR/lower_intrinsics.rs:51:42: 51:45
+ // + literal: Const { ty: &(), val: Unevaluated(discriminant, [T], Some(promoted[1])) }
+ _11 = &(*_18); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
+ _10 = &(*_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
+- _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:51:5: 51:41
+- // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a ()) -> <() 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 _; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
+ // mir::Constant
+ // + span: $DIR/lower_intrinsics.rs:52:42: 52:47
+ // + literal: Const { ty: &E, val: Unevaluated(discriminant, [T], Some(promoted[0])) }
+ _15 = &(*_17); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
+ _14 = &(*_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
+- _13 = discriminant_value::<E>(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:52:5: 52:41
+- // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a 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) -> [return: bb5, unwind: bb6]; // scope 0 at $DIR/lower_intrinsics.rs:+5:1: +5:2
+ }
+
+ bb5: {
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+5:2: +5:2
+ }
+
+ bb6 (cleanup): {
+ resume; // scope 0 at $DIR/lower_intrinsics.rs:+0:1: +5:2
+ }
+ }
+
diff --git a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff
new file mode 100644
index 000000000..ec15fd1ef
--- /dev/null
+++ b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff
@@ -0,0 +1,72 @@
+- // MIR for `f_copy_nonoverlapping` before LowerIntrinsics
++ // MIR for `f_copy_nonoverlapping` after LowerIntrinsics
+
+ fn f_copy_nonoverlapping() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:32: +0:32
+ let _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:12
+ let _3: (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:9: +4:95
+ let mut _4: *const i32; // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:59
+ let mut _5: *const (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+ let mut _6: *const (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+ let _7: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:33
+ let mut _8: *mut i32; // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:91
+ let mut _9: *mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+ let mut _10: *mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+ let mut _11: &mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:69
+ scope 1 {
+ debug src => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:12
+ let mut _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:16
+ scope 2 {
+ debug dst => _2; // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:16
+ scope 3 {
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:12
+ Deinit(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:15: +1:17
+ StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:16
+ Deinit(_2); // scope 1 at $DIR/lower_intrinsics.rs:+2:19: +2:21
+ StorageLive(_3); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
+ StorageLive(_4); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:59
+ StorageLive(_5); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+ StorageLive(_6); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+ StorageLive(_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33
+ _7 = &_1; // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33
+ _6 = &raw const (*_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33
+ _5 = _6; // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+ _4 = move _5 as *const i32 (PtrToPtr); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:59
+ StorageDead(_5); // scope 3 at $DIR/lower_intrinsics.rs:+4:58: +4:59
+ StorageLive(_8); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:91
+ StorageLive(_9); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+ StorageLive(_10); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+ StorageLive(_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69
+ _11 = &mut _2; // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69
+ _10 = &raw mut (*_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69
+ _9 = _10; // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+ _8 = move _9 as *mut i32 (PtrToPtr); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:91
+ StorageDead(_9); // scope 3 at $DIR/lower_intrinsics.rs:+4:90: +4:91
+- _3 = copy_nonoverlapping::<i32>(move _4, move _8, const 0_usize) -> bb1; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:65:9: 65:28
+- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32, *mut i32, usize) {copy_nonoverlapping::<i32>}, val: Value(<ZST>) }
++ copy_nonoverlapping(dst = move _8, src = move _4, count = const 0_usize); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
++ goto -> bb1; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
+ }
+
+ bb1: {
+ StorageDead(_8); // scope 3 at $DIR/lower_intrinsics.rs:+4:94: +4:95
+ StorageDead(_4); // scope 3 at $DIR/lower_intrinsics.rs:+4:94: +4:95
+ StorageDead(_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+ StorageDead(_10); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+ StorageDead(_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+ StorageDead(_6); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+ StorageDead(_3); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+ _0 = const (); // scope 3 at $DIR/lower_intrinsics.rs:+3:5: +5:6
+ StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+6:1: +6:2
+ StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff
new file mode 100644
index 000000000..4cbbc02c9
--- /dev/null
+++ b/tests/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:26:5: 26:29
+- // + literal: Const { ty: extern "rust-intrinsic" fn(T) {std::intrinsics::forget::<T>}, val: Value(<ZST>) }
++ _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32
++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32
+ }
+
+ 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/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff
new file mode 100644
index 000000000..d8cd5f59a
--- /dev/null
+++ b/tests/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:37:21: 37:51
+ // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}, val: Value(<ZST>) }
+ StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14
+ _2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14
+- _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/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs
new file mode 100644
index 000000000..66dae0e46
--- /dev/null
+++ b/tests/mir-opt/lower_intrinsics.rs
@@ -0,0 +1,74 @@
+// unit-test: LowerIntrinsics
+// ignore-wasm32 compiled with panic=abort by default
+
+#![feature(core_intrinsics, intrinsics)]
+#![crate_type = "lib"]
+
+// EMIT_MIR lower_intrinsics.wrapping.LowerIntrinsics.diff
+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.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);
+}
+
+extern "rust-intrinsic" {
+ // Cannot use `std::intrinsics::copy_nonoverlapping` as that is a wrapper function
+ fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+}
+
+// EMIT_MIR lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff
+pub fn f_copy_nonoverlapping() {
+ let src = ();
+ let mut dst = ();
+ unsafe {
+ copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0);
+ }
+}
+
+// EMIT_MIR lower_intrinsics.assume.LowerIntrinsics.diff
+pub fn assume() {
+ unsafe {
+ std::intrinsics::assume(true);
+ }
+}
diff --git a/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff
new file mode 100644
index 000000000..cf0ab73a5
--- /dev/null
+++ b/tests/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:16:5: 16:35
+- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}, val: Value(<ZST>) }
++ _0 = SizeOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37
++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37
+ }
+
+ bb1: {
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
new file mode 100644
index 000000000..6f17d4451
--- /dev/null
+++ b/tests/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:31:14: 31:43
+- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value(<ZST>) }
++ unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
+ }
+ }
+
diff --git a/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff
new file mode 100644
index 000000000..22ef75fd8
--- /dev/null
+++ b/tests/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:9:14: 9:44
+- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_add::<i32>}, val: Value(<ZST>) }
++ _3 = Add(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
+ }
+
+ 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:10:14: 10:44
+- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_sub::<i32>}, val: Value(<ZST>) }
++ _6 = Sub(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
++ goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
+ }
+
+ 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:11:14: 11:44
+- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_mul::<i32>}, val: Value(<ZST>) }
++ _9 = Mul(move _10, move _11); // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50
++ goto -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50
+ }
+
+ 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/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir b/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir
new file mode 100644
index 000000000..f6d8bdd74
--- /dev/null
+++ b/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir
@@ -0,0 +1,27 @@
+// MIR for `f_u64` after PreCodegen
+
+fn f_u64() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:16: +0:16
+ let mut _1: u64; // in scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
+ scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:15:5: 15:21
+ debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23
+ let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
+ scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
+ StorageLive(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
+ _2 = f_non_zst::<u64>(const 0_u64) -> bb1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
+ // mir::Constant
+ // + span: $DIR/lower_intrinsics_e2e.rs:23:9: 23:18
+ // + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:21: 23:22
+ StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
+ return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2
+ }
+}
diff --git a/tests/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir b/tests/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir
new file mode 100644
index 000000000..b672e1a6e
--- /dev/null
+++ b/tests/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir
@@ -0,0 +1,27 @@
+// MIR for `f_unit` after PreCodegen
+
+fn f_unit() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:17: +0:17
+ let mut _1: (); // in scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:16: +1:18
+ scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics_e2e.rs:9:5: 9:19
+ debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23
+ let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
+ scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:16: +1:18
+ StorageLive(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
+ _2 = f_zst::<()>(move _1) -> bb1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
+ // mir::Constant
+ // + span: $DIR/lower_intrinsics_e2e.rs:21:9: 21:14
+ // + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:17: 21:18
+ StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:18: +1:19
+ return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2
+ }
+}
diff --git a/tests/mir-opt/lower_intrinsics_e2e.rs b/tests/mir-opt/lower_intrinsics_e2e.rs
new file mode 100644
index 000000000..872ef59b0
--- /dev/null
+++ b/tests/mir-opt/lower_intrinsics_e2e.rs
@@ -0,0 +1,32 @@
+// Checks that we do not have any branches in the MIR for the two tested functions.
+
+// compile-flags: -Cpanic=abort
+#![feature(core_intrinsics)]
+#![crate_type = "lib"]
+
+// EMIT_MIR lower_intrinsics_e2e.f_unit.PreCodegen.after.mir
+pub fn f_unit() {
+ f_dispatch(());
+}
+
+
+// EMIT_MIR lower_intrinsics_e2e.f_u64.PreCodegen.after.mir
+pub fn f_u64() {
+ f_dispatch(0u64);
+}
+
+#[inline(always)]
+pub fn f_dispatch<T>(t: T) {
+ if std::mem::size_of::<T>() == 0 {
+ f_zst(t);
+ } else {
+ f_non_zst(t);
+ }
+}
+
+#[inline(never)]
+pub fn f_zst<T>(_t: T) {
+}
+
+#[inline(never)]
+pub fn f_non_zst<T>(_t: T) {}
diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff
new file mode 100644
index 000000000..2b0370cf3
--- /dev/null
+++ b/tests/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<'a> fn(&'a [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) -> [0: 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/tests/mir-opt/lower_slice_len.rs b/tests/mir-opt/lower_slice_len.rs
new file mode 100644
index 000000000..12955aed1
--- /dev/null
+++ b/tests/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/tests/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff
new file mode 100644
index 000000000..84e4d35f9
--- /dev/null
+++ b/tests/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)) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16
++ switchInt((_2.0: bool)) -> [0: 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)) -> [0: bb10, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16
+ }
+
+ bb2: {
+- switchInt((_2.1: bool)) -> [0: bb3, otherwise: bb4]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16
++ switchInt((_2.0: bool)) -> [0: 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)) -> [0: 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) -> [0: bb10, otherwise: bb9]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49
++ switchInt(move _10) -> [0: 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) -> [0: bb12, otherwise: bb11]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
++ switchInt(move _9) -> [0: 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) -> [0: bb15, otherwise: bb14]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49
++ switchInt(move _13) -> [0: 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) -> [0: bb17, otherwise: bb16]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
++ switchInt(move _12) -> [0: 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/tests/mir-opt/match_arm_scopes.rs b/tests/mir-opt/match_arm_scopes.rs
new file mode 100644
index 000000000..7b7de7788
--- /dev/null
+++ b/tests/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/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir
new file mode 100644
index 000000000..d51dbf425
--- /dev/null
+++ b/tests/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) -> [0: 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) -> [0: 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) -> [0: 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) -> [0: 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) -> [4294967295: 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) -> [0: 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/tests/mir-opt/match_test.rs b/tests/mir-opt/match_test.rs
new file mode 100644
index 000000000..3a2107790
--- /dev/null
+++ b/tests/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/tests/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff
new file mode 100644
index 000000000..be91b0bfe
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.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: 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
+- Deinit(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
+- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
+- }
+-
+- 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
+ Deinit(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
+- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
+- }
+-
+- 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/tests/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff
new file mode 100644
index 000000000..aa8092ece
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff
@@ -0,0 +1,55 @@
+- // MIR for `foo` before MatchBranchSimplification
++ // MIR for `foo` after MatchBranchSimplification
+
+ fn foo(_1: Option<()>) -> () {
+ debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
+ let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
+ let mut _2: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _3: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
++ let mut _4: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
+- switchInt(move _3) -> [0: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ StorageLive(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ _4 = move _3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ _2 = Eq(_4, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ StorageDead(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb1: {
+- _2 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb2: {
+- _2 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb3: {
+- switchInt(move _2) -> [0: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb4: {
+ Deinit(_0); // scope 0 at $DIR/matches_reduce_branches.rs:+2:9: +2:11
+- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
++ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
+ }
+
+- bb5: {
++ bb2: {
+ _0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:+3:6: +3:6
+- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
++ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
+ }
+
+- bb6: {
++ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+3:5: +3:6
+ return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff
new file mode 100644
index 000000000..193104dd3
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff
@@ -0,0 +1,113 @@
+- // MIR for `match_nested_if` before MatchBranchSimplification
++ // MIR for `match_nested_if` after MatchBranchSimplification
+
+ fn match_nested_if() -> bool {
+ let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29
+ let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+ let mut _2: (); // in scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
+ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+ let mut _4: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+ let mut _5: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+ let mut _6: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++ let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++ let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
++ let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
++ let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+ scope 1 {
+ debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+ StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
+ Deinit(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
+ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+ StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+ StorageLive(_5); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+ StorageLive(_6); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ _6 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+- switchInt(move _6) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+- }
+-
+- bb1: {
+- _5 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:31: +2:35
+- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+- }
+-
+- bb2: {
+- _5 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
+- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+- }
+-
+- bb3: {
++ StorageLive(_7); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++ _7 = move _6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++ _5 = Ne(_7, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
++ StorageDead(_7); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
+- switchInt(move _5) -> [0: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+- }
+-
+- bb4: {
+- _4 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:55: +2:59
+- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+- }
+-
+- bb5: {
+- _4 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
+- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+- }
+-
+- bb6: {
++ StorageLive(_8); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
++ _8 = move _5; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
++ _4 = Ne(_8, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
++ StorageDead(_8); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+ StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:+2:75: +2:76
+- switchInt(move _4) -> [0: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+- }
+-
+- bb7: {
+- _3 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+3:13: +3:17
+- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+- }
+-
+- bb8: {
+- _3 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
+- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+- }
+-
+- bb9: {
+- switchInt(move _3) -> [0: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+- }
+-
+- bb10: {
++ StorageLive(_9); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
++ _9 = move _4; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
++ _3 = Ne(_9, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
++ StorageDead(_9); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
++ StorageLive(_10); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
++ _10 = move _3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+ StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
+ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
+- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
+- goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
+- }
+-
+- bb11: {
+- StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
+- StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
+- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+- goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+- }
+-
+- bb12: {
++ _1 = Ne(_10, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
++ StorageDead(_10); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+ StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+11:6: +11:7
+ _0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8
+ StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2
+ return; // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2
+ }
+ }
+
diff --git a/tests/mir-opt/matches_reduce_branches.rs b/tests/mir-opt/matches_reduce_branches.rs
new file mode 100644
index 000000000..a81d5f7b4
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.rs
@@ -0,0 +1,60 @@
+// unit-test: MatchBranchSimplification
+
+
+// EMIT_MIR matches_reduce_branches.foo.MatchBranchSimplification.diff
+// 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/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff b/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff
new file mode 100644
index 000000000..3766d99a4
--- /dev/null
+++ b/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff
@@ -0,0 +1,32 @@
+- // 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: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = const 1_u8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ goto -> bb4; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
+ }
+
+ bb3: {
+ _0 = const 0_u8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ goto -> bb4; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff b/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff
new file mode 100644
index 000000000..b5146cd53
--- /dev/null
+++ b/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff
@@ -0,0 +1,32 @@
+- // 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: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = const 1_i8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ goto -> bb4; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
+ }
+
+ bb3: {
+ _0 = const 0_i8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ goto -> bb4; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/tests/mir-opt/matches_u8.rs b/tests/mir-opt/matches_u8.rs
new file mode 100644
index 000000000..422c3a95e
--- /dev/null
+++ b/tests/mir-opt/matches_u8.rs
@@ -0,0 +1,34 @@
+// unit-test: MatchBranchSimplification
+
+
+// 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/tests/mir-opt/multiple_return_terminators.rs b/tests/mir-opt/multiple_return_terminators.rs
new file mode 100644
index 000000000..a2b902d14
--- /dev/null
+++ b/tests/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/tests/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff b/tests/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff
new file mode 100644
index 000000000..48a11c950
--- /dev/null
+++ b/tests/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/tests/mir-opt/nll/named_lifetimes_basic.rs b/tests/mir-opt/nll/named_lifetimes_basic.rs
new file mode 100644
index 000000000..843716033
--- /dev/null
+++ b/tests/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/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir b/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir
new file mode 100644
index 000000000..6cd6d8b77
--- /dev/null
+++ b/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir
@@ -0,0 +1,47 @@
+// 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 | {bb0[0..=1], '_#1r}
+| '_#6r | U0 | {bb0[0..=1], '_#2r}
+| '_#7r | U0 | {bb0[0..=1], '_#1r}
+| '_#8r | U0 | {bb0[0..=1], '_#3r}
+|
+| Inference Constraints
+| '_#0r live at {bb0[0..=1]}
+| '_#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: '_#5r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:26: 12:27) ($DIR/named_lifetimes_basic.rs:12:26: 12:27 (#0)
+| '_#1r: '_#7r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:54: 12:55) ($DIR/named_lifetimes_basic.rs:12:54: 12:55 (#0)
+| '_#2r: '_#6r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:42: 12:43) ($DIR/named_lifetimes_basic.rs:12:42: 12:43 (#0)
+| '_#3r: '_#8r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:66: 12:67) ($DIR/named_lifetimes_basic.rs:12:66: 12:67 (#0)
+| '_#5r: '_#1r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:26: 12:27) ($DIR/named_lifetimes_basic.rs:12:26: 12:27 (#0)
+| '_#6r: '_#2r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:42: 12:43) ($DIR/named_lifetimes_basic.rs:12:42: 12:43 (#0)
+| '_#7r: '_#1r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:54: 12:55) ($DIR/named_lifetimes_basic.rs:12:54: 12:55 (#0)
+| '_#8r: '_#3r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:66: 12:67) ($DIR/named_lifetimes_basic.rs:12:66: 12:67 (#0)
+|
+fn use_x(_1: &'_#5r mut i32, _2: &'_#6r u32, _3: &'_#7r u32, _4: &'_#8r u32) -> bool {
+ debug w => _1; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:26: +0:27
+ debug x => _2; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:42: +0:43
+ debug y => _3; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:54: +0:55
+ 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/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
new file mode 100644
index 000000000..798e45df8
--- /dev/null
+++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
@@ -0,0 +1,111 @@
+// 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 | {bb1[0..=7], bb2[0..=2]}
+| '_#3r | U0 | {bb1[1..=7], bb2[0..=2]}
+| '_#4r | U0 | {bb1[4..=7], bb2[0..=2]}
+|
+| Inference Constraints
+| '_#0r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]}
+| '_#1r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]}
+| '_#2r live at {bb1[0]}
+| '_#3r live at {bb1[1..=3]}
+| '_#4r live at {bb1[4..=7], bb2[0..=2]}
+| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:18:13: 18:18 (#0)
+| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:19:13: 19:14 (#0)
+|
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11
+ let mut _1: [usize; Const(Value(Leaf(0x00000003)): usize)]; // 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: &'_#3r usize; // in scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
+ scope 2 {
+ debug p => _2; // in scope 2 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
+ let _6: &'_#4r usize; // in scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
+ scope 3 {
+ debug q => _6; // in scope 3 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ 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 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region_subtyping_basic.rs:+2:13: +2:18
+ FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
+ StorageLive(_6); // bb1[2]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
+ _6 = _2; // bb1[3]: scope 2 at $DIR/region_subtyping_basic.rs:+3:13: +3:14
+ 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) -> [0: 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/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
new file mode 100644
index 000000000..4767bfc76
--- /dev/null
+++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
@@ -0,0 +1,111 @@
+// 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 | {bb1[0..=7], bb2[0..=2]}
+| '_#3r | U0 | {bb1[1..=7], bb2[0..=2]}
+| '_#4r | U0 | {bb1[4..=7], bb2[0..=2]}
+|
+| Inference Constraints
+| '_#0r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]}
+| '_#1r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]}
+| '_#2r live at {bb1[0]}
+| '_#3r live at {bb1[1..=3]}
+| '_#4r live at {bb1[4..=7], bb2[0..=2]}
+| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:18:13: 18:18 (#0)
+| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:19:13: 19:14 (#0)
+|
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11
+ let mut _1: [usize; Const(Value(Leaf(0x0000000000000003)): usize)]; // 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: &'_#3r usize; // in scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
+ scope 2 {
+ debug p => _2; // in scope 2 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
+ let _6: &'_#4r usize; // in scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
+ scope 3 {
+ debug q => _6; // in scope 3 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ 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 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region_subtyping_basic.rs:+2:13: +2:18
+ FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
+ StorageLive(_6); // bb1[2]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
+ _6 = _2; // bb1[3]: scope 2 at $DIR/region_subtyping_basic.rs:+3:13: +3:14
+ 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) -> [0: 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/tests/mir-opt/nll/region_subtyping_basic.rs b/tests/mir-opt/nll/region_subtyping_basic.rs
new file mode 100644
index 000000000..64332f302
--- /dev/null
+++ b/tests/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/tests/mir-opt/no_drop_for_inactive_variant.rs b/tests/mir-opt/no_drop_for_inactive_variant.rs
new file mode 100644
index 000000000..34e2b1a13
--- /dev/null
+++ b/tests/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/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..69327b7af
--- /dev/null
+++ b/tests/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: bb1, 1: 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/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir
new file mode 100644
index 000000000..0cb34a2f2
--- /dev/null
+++ b/tests/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<'a> fn(&'a 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/tests/mir-opt/no_spurious_drop_after_call.rs b/tests/mir-opt/no_spurious_drop_after_call.rs
new file mode 100644
index 000000000..bb5bb9aa4
--- /dev/null
+++ b/tests/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/tests/mir-opt/not_equal_false.opt.InstCombine.diff b/tests/mir-opt/not_equal_false.opt.InstCombine.diff
new file mode 100644
index 000000000..b558c35ac
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/not_equal_false.rs b/tests/mir-opt/not_equal_false.rs
new file mode 100644
index 000000000..2ae03da40
--- /dev/null
+++ b/tests/mir-opt/not_equal_false.rs
@@ -0,0 +1,10 @@
+// unit-test: InstCombine
+// 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/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff
new file mode 100644
index 000000000..61a16065b
--- /dev/null
+++ b/tests/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<'a> fn(&'a 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<'a> fn(&'a 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/tests/mir-opt/nrvo_simple.rs b/tests/mir-opt/nrvo_simple.rs
new file mode 100644
index 000000000..5786ae621
--- /dev/null
+++ b/tests/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/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..e52253486
--- /dev/null
+++ b/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,60 @@
+// 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
+ Deinit(_3); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41
+ (_3.0: usize) = const 0_usize; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41
+ Deinit(_2); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42
+ (_2.0: Droppy) = move _3; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42
+ StorageDead(_3); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:41: +1:42
+ Deinit(_1); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:17: +1:43
+ (_1.0: Aligned) = move _2; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:17: +1:43
+ StorageDead(_2); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:42: +1:43
+ StorageLive(_4); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29
+ StorageLive(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28
+ Deinit(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28
+ (_5.0: usize) = const 0_usize; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28
+ Deinit(_4); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29
+ (_4.0: Droppy) = move _5; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29
+ StorageDead(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:28: +2:29
+ StorageLive(_6); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8
+ _6 = move (_1.0: Aligned); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8
+ 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/tests/mir-opt/packed_struct_drop_aligned.rs b/tests/mir-opt/packed_struct_drop_aligned.rs
new file mode 100644
index 000000000..cb6524260
--- /dev/null
+++ b/tests/mir-opt/packed_struct_drop_aligned.rs
@@ -0,0 +1,17 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+
+
+// 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/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff b/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff
new file mode 100644
index 000000000..0b3da98a5
--- /dev/null
+++ b/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff
@@ -0,0 +1,74 @@
+- // MIR for `match_guard` before CleanupPostBorrowck
++ // MIR for `match_guard` after CleanupPostBorrowck
+
+ 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: 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: bb3, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+1:5: +1:12
+ }
+
+ bb3: {
+- falseEdge -> [real: bb4, imaginary: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16
++ 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) -> [0: 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
+- falseEdge -> [real: bb1, imaginary: bb1]; // 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
+ }
+ }
+
diff --git a/tests/mir-opt/remove_fake_borrows.rs b/tests/mir-opt/remove_fake_borrows.rs
new file mode 100644
index 000000000..d26c6f5d7
--- /dev/null
+++ b/tests/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.CleanupPostBorrowck.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/tests/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir b/tests/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir
new file mode 100644
index 000000000..8eb0e9c8f
--- /dev/null
+++ b/tests/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/tests/mir-opt/remove_never_const.rs b/tests/mir-opt/remove_never_const.rs
new file mode 100644
index 000000000..160cc9555
--- /dev/null
+++ b/tests/mir-opt/remove_never_const.rs
@@ -0,0 +1,21 @@
+// 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
+// tests/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)]
+
+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/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff b/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff
new file mode 100644
index 000000000..ed1d0b87f
--- /dev/null
+++ b/tests/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
+ }
+ }
+ }
+
+ 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 = <std::ops::Range<i32> as IntoIterator>::into_iter(move _3) -> bb1; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ // mir::Constant
+ // + span: $DIR/remove_storage_markers.rs:10:14: 10:19
+ // + literal: Const { ty: fn(std::ops::Range<i32>) -> <std::ops::Range<i32> as IntoIterator>::IntoIter {<std::ops::Range<i32> as IntoIterator>::into_iter}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+- StorageDead(_3); // scope 1 at $DIR/remove_storage_markers.rs:+2:18: +2:19
+- StorageLive(_4); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ _4 = move _2; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ goto -> bb2; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
+ }
+
+ bb2: {
+- StorageLive(_6); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+- StorageLive(_7); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+- StorageLive(_8); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+- StorageLive(_9); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ _9 = &mut _4; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ _8 = &mut (*_9); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ _7 = <std::ops::Range<i32> as Iterator>::next(move _8) -> bb3; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ // mir::Constant
+ // + span: $DIR/remove_storage_markers.rs:10:14: 10:19
+ // + literal: Const { ty: for<'a> fn(&'a mut std::ops::Range<i32>) -> Option<<std::ops::Range<i32> as Iterator>::Item> {<std::ops::Range<i32> as Iterator>::next}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+- StorageDead(_8); // scope 2 at $DIR/remove_storage_markers.rs:+2:18: +2:19
+ _10 = discriminant(_7); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ }
+
+ bb4: {
+- StorageLive(_12); // scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10
+ _12 = ((_7 as Some).0: i32); // scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10
+- StorageLive(_13); // scope 3 at $DIR/remove_storage_markers.rs:+3:16: +3:17
+ _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 -> bb2; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
+ }
+
+ bb5: {
+ unreachable; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ }
+
+ bb6: {
+ _0 = const (); // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
+- StorageDead(_9); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
+- StorageDead(_7); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
+- 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
+ }
+ }
+
diff --git a/tests/mir-opt/remove_storage_markers.rs b/tests/mir-opt/remove_storage_markers.rs
new file mode 100644
index 000000000..f00b82691
--- /dev/null
+++ b/tests/mir-opt/remove_storage_markers.rs
@@ -0,0 +1,13 @@
+// unit-test: RemoveStorageMarkers
+
+// 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/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff
new file mode 100644
index 000000000..07e4dd418
--- /dev/null
+++ b/tests/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/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff
new file mode 100644
index 000000000..e809ca4e9
--- /dev/null
+++ b/tests/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/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff
new file mode 100644
index 000000000..087f76dbd
--- /dev/null
+++ b/tests/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/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff
new file mode 100644
index 000000000..933d6895f
--- /dev/null
+++ b/tests/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/tests/mir-opt/remove_unneeded_drops.rs b/tests/mir-opt/remove_unneeded_drops.rs
new file mode 100644
index 000000000..1052f2886
--- /dev/null
+++ b/tests/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/tests/mir-opt/remove_zsts.get_union.PreCodegen.after.mir b/tests/mir-opt/remove_zsts.get_union.PreCodegen.after.mir
new file mode 100644
index 000000000..12e914e25
--- /dev/null
+++ b/tests/mir-opt/remove_zsts.get_union.PreCodegen.after.mir
@@ -0,0 +1,10 @@
+// MIR for `get_union` after PreCodegen
+
+fn get_union() -> Foo {
+ let mut _0: Foo; // return place in scope 0 at $DIR/remove_zsts.rs:+0:19: +0:22
+
+ bb0: {
+ Deinit(_0); // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18
+ return; // scope 0 at $DIR/remove_zsts.rs:+2:2: +2:2
+ }
+}
diff --git a/tests/mir-opt/remove_zsts.get_union.RemoveZsts.diff b/tests/mir-opt/remove_zsts.get_union.RemoveZsts.diff
new file mode 100644
index 000000000..169b7b105
--- /dev/null
+++ b/tests/mir-opt/remove_zsts.get_union.RemoveZsts.diff
@@ -0,0 +1,19 @@
+- // MIR for `get_union` before RemoveZsts
++ // MIR for `get_union` after RemoveZsts
+
+ fn get_union() -> Foo {
+ let mut _0: Foo; // return place in scope 0 at $DIR/remove_zsts.rs:+0:19: +0:22
+ let mut _1: (); // in scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16
+- Deinit(_1); // scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16
++ nop; // scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16
+ Deinit(_0); // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18
+- (_0.0: ()) = move _1; // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18
++ nop; // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18
+ StorageDead(_1); // scope 0 at $DIR/remove_zsts.rs:+1:17: +1:18
+ return; // scope 0 at $DIR/remove_zsts.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/remove_zsts.rs b/tests/mir-opt/remove_zsts.rs
new file mode 100644
index 000000000..1cf7ad6e3
--- /dev/null
+++ b/tests/mir-opt/remove_zsts.rs
@@ -0,0 +1,14 @@
+union Foo {
+ x: (),
+ y: u64,
+}
+
+// EMIT_MIR remove_zsts.get_union.RemoveZsts.diff
+// EMIT_MIR remove_zsts.get_union.PreCodegen.after.mir
+fn get_union() -> Foo {
+ Foo { x: () }
+}
+
+fn main() {
+ get_union();
+}
diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..19b726e74
--- /dev/null
+++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,192 @@
+// 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
+ _3 = &raw mut (*_4); // 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:61:17: 61: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
+ _10 = &raw const (*_11); // 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:65:28: 65: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
+ StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _35 = const _; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: &usize, val: Unevaluated(array_casts, [], Some(promoted[0])) }
+ Retag(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ (_13.0: &usize) = move _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ (_13.1: &usize) = move _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ 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) -> [0: 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
+ Deinit(_27); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ discriminant(_27) = 0; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_28); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_29); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _29 = move _27; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ 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
+ _30 = &(*_31); // 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
+ _32 = &(*_33); // 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
+ Deinit(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ discriminant(_34) = 0; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: for<'a, 'b, 'c> fn(core::panicking::AssertKind, &'a usize, &'b usize, Option<Arguments<'c>>) -> ! {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/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir
new file mode 100644
index 000000000..f495f147b
--- /dev/null
+++ b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir
@@ -0,0 +1,22 @@
+// 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: &mut Test; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ let mut _4: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+
+ bb0: {
+ _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ Retag([fn entry] _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _3 = &mut (*_2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ _4 = <Test as Drop>::drop(move _3) -> 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<'a> fn(&'a 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/tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..9e5c119a2
--- /dev/null
+++ b/tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,21 @@
+// 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: +3:6
+ Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:32: +0:33
+ StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:13: +1:15
+ _3 = _2; // scope 0 at $DIR/retag.rs:+1:18: +1:19
+ Retag(_3); // scope 0 at $DIR/retag.rs:+1:18: +1:19
+ _0 = &(*_2); // scope 1 at $DIR/retag.rs:+2:9: +2:10
+ StorageDead(_3); // scope 0 at $DIR/retag.rs:+3:5: +3:6
+ return; // scope 0 at $DIR/retag.rs:+3:6: +3:6
+ }
+}
diff --git a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..b853e4505
--- /dev/null
+++ b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,194 @@
+// 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<'a> fn(&'a i32) -> &'a 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<'a> fn(&'a i32) -> &'a 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
+ Deinit(_5); // scope 1 at $DIR/retag.rs:+3:17: +3:24
+ (_5.0: i32) = const 0_i32; // scope 1 at $DIR/retag.rs:+3:17: +3:24
+ _4 = &_5; // scope 1 at $DIR/retag.rs:+3:17: +3:36
+ 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
+ _6 = &mut (*_7); // 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:33:25: 33:28
+ // + literal: Const { ty: for<'a, 'x> fn(&'a 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
+ 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
+ _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
+ Deinit(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6
+ Retag(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6
+ _13 = move _14 as for<'a> fn(&'a i32) -> &'a 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
+ _17 = &(*_18); // 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
+ Deinit(_21); // scope 7 at $DIR/retag.rs:+18:5: +18:12
+ (_21.0: i32) = const 0_i32; // scope 7 at $DIR/retag.rs:+18:5: +18:12
+ _20 = &_21; // scope 7 at $DIR/retag.rs:+18:5: +18:24
+ 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 _; // scope 7 at $DIR/retag.rs:+18:21: +18:23
+ // mir::Constant
+ // + span: $DIR/retag.rs:48:21: 48:23
+ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
+ Retag(_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23
+ _23 = &(*_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23
+ _22 = &(*_23); // 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:48:13: 48:20
+ // + literal: Const { ty: for<'a, 'x> fn(&'a 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
+ _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:53:5: 53: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/tests/mir-opt/retag.rs b/tests/mir-opt/retag.rs
new file mode 100644
index 000000000..86deb0e7c
--- /dev/null
+++ b/tests/mir-opt/retag.rs
@@ -0,0 +1,66 @@
+// unit-test: AddRetag
+// ignore-wasm32-bare compiled with panic=abort by default
+// ignore-tidy-linelength
+// compile-flags: -Z mir-emit-retag -Z mir-opt-level=0 -Z span_free_formats
+
+#![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/tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..4b50205fa
--- /dev/null
+++ b/tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,18 @@
+// MIR for `<impl at $DIR/retag.rs:12:1: 12:10>::foo` after SimplifyCfg-elaborate-drops
+
+fn <impl at $DIR/retag.rs:12:1: 12:10>::foo(_1: &Test, _2: &mut i32) -> &mut i32 {
+ debug self => _1; // in scope 0 at $DIR/retag.rs:+0:16: +0:21
+ debug x => _2; // in scope 0 at $DIR/retag.rs:+0:23: +0:24
+ let mut _0: &mut i32; // return place in scope 0 at $DIR/retag.rs:+0:42: +0:53
+ let mut _3: &mut i32; // in scope 0 at $DIR/retag.rs:+1:9: +1:10
+
+ bb0: {
+ Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:16: +0:21
+ Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:23: +0:24
+ StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10
+ _3 = &mut (*_2); // scope 0 at $DIR/retag.rs:+1:9: +1:10
+ _0 = &mut (*_3); // 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/tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644
index 000000000..f32a84e4c
--- /dev/null
+++ b/tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir
@@ -0,0 +1,15 @@
+// MIR for `<impl at $DIR/retag.rs:12:1: 12:10>::foo_shr` after SimplifyCfg-elaborate-drops
+
+fn <impl at $DIR/retag.rs:12:1: 12:10>::foo_shr(_1: &Test, _2: &i32) -> &i32 {
+ debug self => _1; // in scope 0 at $DIR/retag.rs:+0:20: +0:25
+ debug x => _2; // in scope 0 at $DIR/retag.rs:+0:27: +0:28
+ let mut _0: &i32; // return place in scope 0 at $DIR/retag.rs:+0:42: +0:49
+
+ bb0: {
+ Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:20: +0:25
+ Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:27: +0:28
+ _0 = _2; // scope 0 at $DIR/retag.rs:+1:9: +1:10
+ Retag(_0); // scope 0 at $DIR/retag.rs:+1:9: +1:10
+ return; // scope 0 at $DIR/retag.rs:+2:6: +2:6
+ }
+}
diff --git a/tests/mir-opt/return_an_array.rs b/tests/mir-opt/return_an_array.rs
new file mode 100644
index 000000000..bea3c317c
--- /dev/null
+++ b/tests/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/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
new file mode 100644
index 000000000..e57544e09
--- /dev/null
+++ b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
@@ -0,0 +1,156 @@
+- // 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:25:8: 25:10
+ debug residual => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _17: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ 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:25:8: 25:10
+ debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _10: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ 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
+ _10 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+- switchInt(move _10) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
++ switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+
+ bb1: {
+- 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: bb2, 1: bb4, 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: {
+ unreachable; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ }
+
+- bb4: {
++ bb3: {
+ StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageLive(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ _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
+ }
+
+- bb5: {
++ bb4: {
+ StorageLive(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ _13 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+ 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(_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: bb1, 1: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ }
+
+- bb6: {
++ bb5: {
+ unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
+
+- bb7: {
++ bb6: {
+ StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ _11 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageLive(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ _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(_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: bb1, 1: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ }
+ }
+
diff --git a/tests/mir-opt/separate_const_switch.rs b/tests/mir-opt/separate_const_switch.rs
new file mode 100644
index 000000000..c809e5629
--- /dev/null
+++ b/tests/mir-opt/separate_const_switch.rs
@@ -0,0 +1,31 @@
+#![feature(control_flow_enum)]
+#![feature(try_trait_v2)]
+
+use std::ops::ControlFlow;
+
+// EMIT_MIR separate_const_switch.too_complex.SeparateConstSwitch.diff
+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
+fn identity(x: Result<i32, i32>) -> Result<i32, i32> {
+ Ok(x?)
+}
+
+fn main() {
+ too_complex(Ok(0));
+ identity(Ok(0));
+}
diff --git a/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff
new file mode 100644
index 000000000..8cc0c6a18
--- /dev/null
+++ b/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff
@@ -0,0 +1,111 @@
+- // 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: bb3, 1: bb1, otherwise: bb2]; // 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 -> bb4; // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
++ _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
++ switchInt(move _8) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16
+ }
+
+ bb3: {
+ StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
+ StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
+ _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 -> bb4; // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
+- }
+-
+- bb4: {
+ _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
+- switchInt(move _8) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
++ switchInt(move _8) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
+ }
+
+- bb5: {
++ bb4: {
+ StorageLive(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ _11 = ((_2 as Break).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
+ Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
+ discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
+ StorageDead(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
+- goto -> bb8; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
++ goto -> bb7; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
+ }
+
+- bb6: {
++ bb5: {
+ unreachable; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
+ }
+
+- bb7: {
++ bb6: {
+ StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ _9 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
+ StorageLive(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
+ _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 -> bb8; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
++ goto -> bb7; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
+ }
+
+- bb8: {
++ bb7: {
+ StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2
+ return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2
+ }
+ }
+
diff --git a/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir b/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir
new file mode 100644
index 000000000..916f99049
--- /dev/null
+++ b/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir
@@ -0,0 +1,52 @@
+// MIR for `ezmap` after PreCodegen
+
+fn ezmap(_1: Option<i32>) -> Option<i32> {
+ debug x => _1; // in scope 0 at $DIR/simple_option_map_e2e.rs:+0:14: +0:15
+ let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/simple_option_map_e2e.rs:+0:33: +0:44
+ let mut _2: [closure@$DIR/simple_option_map_e2e.rs:14:12: 14:15]; // in scope 0 at $DIR/simple_option_map_e2e.rs:+1:12: +1:21
+ scope 1 (inlined map::<i32, i32, [closure@$DIR/simple_option_map_e2e.rs:14:12: 14:15]>) { // at $DIR/simple_option_map_e2e.rs:14:5: 14:22
+ debug slf => _1; // in scope 1 at $DIR/simple_option_map_e2e.rs:2:17: 2:20
+ debug f => _2; // in scope 1 at $DIR/simple_option_map_e2e.rs:2:33: 2:34
+ let mut _3: isize; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:9: 7:16
+ let mut _4: i32; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
+ let mut _5: i32; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
+ scope 2 {
+ debug x => _5; // in scope 2 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
+ scope 3 (inlined ezmap::{closure#0}) { // at $DIR/simple_option_map_e2e.rs:7:25: 7:29
+ debug n => _5; // in scope 3 at $DIR/simple_option_map_e2e.rs:+1:13: +1:14
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/simple_option_map_e2e.rs:+1:12: +1:21
+ _3 = discriminant(_1); // scope 1 at $DIR/simple_option_map_e2e.rs:6:11: 6:14
+ switchInt(move _3) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 1 at $DIR/simple_option_map_e2e.rs:6:5: 6:14
+ }
+
+ bb1: {
+ Deinit(_0); // scope 1 at $DIR/simple_option_map_e2e.rs:8:17: 8:21
+ discriminant(_0) = 0; // scope 1 at $DIR/simple_option_map_e2e.rs:8:17: 8:21
+ goto -> bb4; // scope 1 at $DIR/simple_option_map_e2e.rs:8:17: 8:21
+ }
+
+ bb2: {
+ unreachable; // scope 1 at $DIR/simple_option_map_e2e.rs:6:11: 6:14
+ }
+
+ bb3: {
+ _5 = move ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
+ StorageLive(_4); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
+ _4 = Add(move _5, const 1_i32); // scope 3 at $DIR/simple_option_map_e2e.rs:+1:16: +1:21
+ Deinit(_0); // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30
+ ((_0 as Some).0: i32) = move _4; // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30
+ discriminant(_0) = 1; // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30
+ StorageDead(_4); // scope 2 at $DIR/simple_option_map_e2e.rs:7:29: 7:30
+ goto -> bb4; // scope 1 at $DIR/simple_option_map_e2e.rs:10:1: 10:2
+ }
+
+ bb4: {
+ StorageDead(_2); // scope 0 at $DIR/simple_option_map_e2e.rs:+1:21: +1:22
+ return; // scope 0 at $DIR/simple_option_map_e2e.rs:+2:2: +2:2
+ }
+}
diff --git a/tests/mir-opt/simple_option_map_e2e.rs b/tests/mir-opt/simple_option_map_e2e.rs
new file mode 100644
index 000000000..2acd2a227
--- /dev/null
+++ b/tests/mir-opt/simple_option_map_e2e.rs
@@ -0,0 +1,19 @@
+#[inline(always)]
+fn map<T, U, F>(slf: Option<T>, f: F) -> Option<U>
+where
+ F: FnOnce(T) -> U,
+{
+ match slf {
+ Some(x) => Some(f(x)),
+ None => None,
+ }
+}
+
+// EMIT_MIR simple_option_map_e2e.ezmap.PreCodegen.after.mir
+pub fn ezmap(x: Option<i32>) -> Option<i32> {
+ map(x, |n| n + 1)
+}
+
+fn main() {
+ assert_eq!(None, ezmap(None));
+}
diff --git a/tests/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff b/tests/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff
new file mode 100644
index 000000000..cff9afc38
--- /dev/null
+++ b/tests/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:27:21: 27:22
+ }
+ }
+ scope 3 {
+ debug v => _10; // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13
+ }
+ scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33
+ debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:23:22: 23: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:24:5: 24:6
+ StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33
+ _5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
+ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33
+ }
+
+ 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:28:9: 28:10
+ Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
+ StorageDead(_8); // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51
+ StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51
+ StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
+ 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/tests/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff b/tests/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff
new file mode 100644
index 000000000..9d38b9350
--- /dev/null
+++ b/tests/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:27:21: 27:22
+ }
+ }
+ scope 3 {
+ debug v => _10; // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13
+ }
+ scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33
+ debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:23:22: 23: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:24:5: 24:6
+ StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33
+ _5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
+ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33
+ }
+
+ 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:28:9: 28:10
+ Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
+ StorageDead(_8); // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51
+ StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51
+ StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
+ 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/tests/mir-opt/simplify_arm.rs b/tests/mir-opt/simplify_arm.rs
new file mode 100644
index 000000000..c247872e2
--- /dev/null
+++ b/tests/mir-opt/simplify_arm.rs
@@ -0,0 +1,50 @@
+// 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
+
+// This pass is broken since deaggregation changed
+// ignore-test
+
+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/tests/mir-opt/simplify_arm_identity.rs b/tests/mir-opt/simplify_arm_identity.rs
new file mode 100644
index 000000000..cf6ff57aa
--- /dev/null
+++ b/tests/mir-opt/simplify_arm_identity.rs
@@ -0,0 +1,26 @@
+// 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
+
+// This pass is broken since deaggregation changed
+// ignore-test
+
+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/tests/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff b/tests/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff
new file mode 100644
index 000000000..8eb1aa1f3
--- /dev/null
+++ b/tests/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) -> [0: bb5, otherwise: bb4]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17
++ bb2: {
++ switchInt(move _2) -> [0: 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/tests/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff b/tests/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff
new file mode 100644
index 000000000..1e66b1f70
--- /dev/null
+++ b/tests/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) -> [0: 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/tests/mir-opt/simplify_cfg.rs b/tests/mir-opt/simplify_cfg.rs
new file mode 100644
index 000000000..cf7eac440
--- /dev/null
+++ b/tests/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/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff
new file mode 100644
index 000000000..f9e22866b
--- /dev/null
+++ b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff
@@ -0,0 +1,38 @@
+- // 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) -> [0: 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
+ goto -> bb4; // scope 0 at $DIR/simplify_if.rs:+1:5: +3:6
+ }
+
+ bb3: {
+ 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/tests/mir-opt/simplify_if.rs b/tests/mir-opt/simplify_if.rs
new file mode 100644
index 000000000..2d093d926
--- /dev/null
+++ b/tests/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/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff
new file mode 100644
index 000000000..1be27e963
--- /dev/null
+++ b/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff
@@ -0,0 +1,33 @@
+- // MIR for `c` before SimplifyLocals-before-const-prop
++ // MIR for `c` after SimplifyLocals-before-const-prop
+
+ 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/tests/mir-opt/simplify_locals.d1.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.d1.SimplifyLocals-before-const-prop.diff
new file mode 100644
index 000000000..981738030
--- /dev/null
+++ b/tests/mir-opt/simplify_locals.d1.SimplifyLocals-before-const-prop.diff
@@ -0,0 +1,19 @@
+- // MIR for `d1` before SimplifyLocals-before-const-prop
++ // MIR for `d1` after SimplifyLocals-before-const-prop
+
+ 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/tests/mir-opt/simplify_locals.d2.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.d2.SimplifyLocals-before-const-prop.diff
new file mode 100644
index 000000000..b152dc8cc
--- /dev/null
+++ b/tests/mir-opt/simplify_locals.d2.SimplifyLocals-before-const-prop.diff
@@ -0,0 +1,29 @@
+- // MIR for `d2` before SimplifyLocals-before-const-prop
++ // MIR for `d2` after SimplifyLocals-before-const-prop
+
+ 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/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff
new file mode 100644
index 000000000..9ca1dbbd0
--- /dev/null
+++ b/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff
@@ -0,0 +1,21 @@
+- // MIR for `expose_addr` before SimplifyLocals-before-const-prop
++ // MIR for `expose_addr` after SimplifyLocals-before-const-prop
+
+ 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/tests/mir-opt/simplify_locals.r.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.r.SimplifyLocals-before-const-prop.diff
new file mode 100644
index 000000000..19dacb427
--- /dev/null
+++ b/tests/mir-opt/simplify_locals.r.SimplifyLocals-before-const-prop.diff
@@ -0,0 +1,31 @@
+- // MIR for `r` before SimplifyLocals-before-const-prop
++ // MIR for `r` after SimplifyLocals-before-const-prop
+
+ 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/tests/mir-opt/simplify_locals.rs b/tests/mir-opt/simplify_locals.rs
new file mode 100644
index 000000000..7bbc0481c
--- /dev/null
+++ b/tests/mir-opt/simplify_locals.rs
@@ -0,0 +1,81 @@
+// unit-test: SimplifyLocals-before-const-prop
+
+
+#![feature(thread_local)]
+
+#[derive(Copy, Clone)]
+enum E {
+ A,
+ B,
+}
+
+// EMIT_MIR simplify_locals.c.SimplifyLocals-before-const-prop.diff
+fn c() {
+ let bytes = [0u8; 10];
+ // Unused cast
+ let _: &[u8] = &bytes;
+}
+
+// EMIT_MIR simplify_locals.d1.SimplifyLocals-before-const-prop.diff
+fn d1() {
+ // Unused set discriminant
+ let _ = E::A;
+}
+
+// EMIT_MIR simplify_locals.d2.SimplifyLocals-before-const-prop.diff
+fn d2() {
+ // Unused set discriminant
+ {(10, E::A)}.1 = E::B;
+}
+
+// EMIT_MIR simplify_locals.r.SimplifyLocals-before-const-prop.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-before-const-prop.diff
+fn t1() {
+ // Unused thread local
+ unsafe { X };
+}
+
+// EMIT_MIR simplify_locals.t2.SimplifyLocals-before-const-prop.diff
+fn t2() {
+ // Unused thread local
+ unsafe { &mut X };
+}
+
+// EMIT_MIR simplify_locals.t3.SimplifyLocals-before-const-prop.diff
+fn t3() {
+ // Unused thread local
+ unsafe { *&mut X };
+}
+
+// EMIT_MIR simplify_locals.t4.SimplifyLocals-before-const-prop.diff
+fn t4() -> u32 {
+ // Used thread local
+ unsafe { X + 1 }
+}
+
+// EMIT_MIR simplify_locals.expose_addr.SimplifyLocals-before-const-prop.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/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff
new file mode 100644
index 000000000..1b2e1158e
--- /dev/null
+++ b/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff
@@ -0,0 +1,22 @@
+- // MIR for `t1` before SimplifyLocals-before-const-prop
++ // MIR for `t1` after SimplifyLocals-before-const-prop
+
+ 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/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff
new file mode 100644
index 000000000..cf019357b
--- /dev/null
+++ b/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff
@@ -0,0 +1,22 @@
+- // MIR for `t2` before SimplifyLocals-before-const-prop
++ // MIR for `t2` after SimplifyLocals-before-const-prop
+
+ 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/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff
new file mode 100644
index 000000000..90ee21580
--- /dev/null
+++ b/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff
@@ -0,0 +1,26 @@
+- // MIR for `t3` before SimplifyLocals-before-const-prop
++ // MIR for `t3` after SimplifyLocals-before-const-prop
+
+ 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/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff
new file mode 100644
index 000000000..9add9a6c5
--- /dev/null
+++ b/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff
@@ -0,0 +1,22 @@
+- // MIR for `t4` before SimplifyLocals-before-const-prop
++ // MIR for `t4` after SimplifyLocals-before-const-prop
+
+ 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/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff
new file mode 100644
index 000000000..f888c622d
--- /dev/null
+++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff
@@ -0,0 +1,62 @@
+- // MIR for `foo` before SimplifyLocals-final
++ // MIR for `foo` after SimplifyLocals-final
+
+ 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: 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: 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/tests/mir-opt/simplify_locals_fixedpoint.rs b/tests/mir-opt/simplify_locals_fixedpoint.rs
new file mode 100644
index 000000000..1fdba6e99
--- /dev/null
+++ b/tests/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-final.diff
diff --git a/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff
new file mode 100644
index 000000000..efb2b0961
--- /dev/null
+++ b/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff
@@ -0,0 +1,109 @@
+- // MIR for `main` before SimplifyLocals-before-const-prop
++ // MIR for `main` after SimplifyLocals-before-const-prop
+
+ 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 mut _3: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16
++ let mut _4: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20
++ let _5: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35
++ let mut _6: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34
++ let mut _7: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30
++ let mut _8: Temp; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
+ scope 1 {
+ }
+
+ bb0: {
+- StorageLive(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28
+- StorageLive(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23
+- Deinit(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23
+- StorageLive(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27
+- Deinit(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27
+- Deinit(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28
+- (_1.0: ()) = move _2; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28
+- (_1.1: ()) = move _3; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28
+- StorageDead(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:27: +1:28
+- StorageDead(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:27: +1:28
+- StorageDead(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:28: +1:29
+- StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22
+- StorageLive(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
+- StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16
+- Deinit(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16
+- StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20
+- Deinit(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20
+- Deinit(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
+- (_5.0: ()) = move _6; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
+- (_5.1: ()) = move _7; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
+- StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21
+- StorageDead(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21
+- _4 = use_zst(move _5) -> bb1; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22
++ StorageLive(_1); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22
++ StorageLive(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
++ StorageLive(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16
++ Deinit(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16
++ StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20
++ Deinit(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20
++ Deinit(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
++ (_2.0: ()) = move _3; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
++ (_2.1: ()) = move _4; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
++ StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21
++ StorageDead(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21
++ _1 = use_zst(move _2) -> bb1; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22
+ // mir::Constant
+ // + span: $DIR/simplify_locals_removes_unused_consts.rs:15:5: 15: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
+- Deinit(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
+- (_11.0: u8) = const 40_u8; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
+- _10 = (_11.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30
+- _9 = Add(move _10, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34
+- StorageDead(_10); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34
+- _8 = use_u8(move _9) -> bb2; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35
++ StorageDead(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:21: +2:22
++ StorageDead(_1); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:22: +2:23
++ StorageLive(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35
++ StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34
++ StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30
++ StorageLive(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
++ Deinit(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
++ (_8.0: u8) = const 40_u8; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
++ _7 = (_8.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30
++ _6 = Add(move _7, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34
++ StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34
++ _5 = use_u8(move _6) -> bb2; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35
+ // mir::Constant
+ // + span: $DIR/simplify_locals_removes_unused_consts.rs:17:5: 17:11
+ // + literal: Const { ty: fn(u8) {use_u8}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+- StorageDead(_9); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35
+- StorageDead(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36
++ StorageDead(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35
+ StorageDead(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36
++ StorageDead(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36
+ _0 = const (); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+0:11: +5:2
+ return; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/tests/mir-opt/simplify_locals_removes_unused_consts.rs b/tests/mir-opt/simplify_locals_removes_unused_consts.rs
new file mode 100644
index 000000000..7a03a2837
--- /dev/null
+++ b/tests/mir-opt/simplify_locals_removes_unused_consts.rs
@@ -0,0 +1,18 @@
+// unit-test: SimplifyLocals-before-const-prop
+// 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-before-const-prop.diff
+fn main() {
+ let ((), ()) = ((), ());
+ use_zst(((), ()));
+
+ use_u8((Temp { x: 40 }).x + 2);
+}
diff --git a/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff
new file mode 100644
index 000000000..027c983e6
--- /dev/null
+++ b/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff
@@ -0,0 +1,52 @@
+- // MIR for `map` before SimplifyLocals-before-const-prop
++ // MIR for `map` after SimplifyLocals-before-const-prop
+
+ 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 => _3; // in scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15
+ }
+
+ bb0: {
+- _5 = const false; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12
+- _5 = const true; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12
+ _2 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12
+ switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ StorageLive(_3); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15
+ _3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15
+ StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26
+ _4 = move _3; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26
+ Deinit(_0); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27
+ ((_0 as Some).0: std::boxed::Box<()>) = move _4; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27
+ discriminant(_0) = 1; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27
+ StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27
+ StorageDead(_3); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27
+ goto -> bb4; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12
+ }
+
+ bb3: {
+ Deinit(_0); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21
+ discriminant(_0) = 0; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21
+ goto -> bb4; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21
+ }
+
+ bb4: {
+- _6 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs b/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs
new file mode 100644
index 000000000..de6585741
--- /dev/null
+++ b/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs
@@ -0,0 +1,14 @@
+// unit-test: SimplifyLocals-before-const-prop
+
+fn map(x: Option<Box<()>>) -> Option<Box<()>> {
+ match x {
+ None => None,
+ Some(x) => Some(x),
+ }
+}
+
+fn main() {
+ map(None);
+}
+
+// EMIT_MIR simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff
diff --git a/tests/mir-opt/simplify_match.main.ConstProp.diff b/tests/mir-opt/simplify_match.main.ConstProp.diff
new file mode 100644
index 000000000..70bfbf1b3
--- /dev/null
+++ b/tests/mir-opt/simplify_match.main.ConstProp.diff
@@ -0,0 +1,39 @@
+- // 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) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31
++ switchInt(const false) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31
+ }
+
+ bb1: {
+ 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/tests/mir-opt/simplify_match.rs b/tests/mir-opt/simplify_match.rs
new file mode 100644
index 000000000..216203f9f
--- /dev/null
+++ b/tests/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/tests/mir-opt/simplify_try_if_let.rs b/tests/mir-opt/simplify_try_if_let.rs
new file mode 100644
index 000000000..fba67de40
--- /dev/null
+++ b/tests/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/tests/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff b/tests/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff
new file mode 100644
index 000000000..11f6b5337
--- /dev/null
+++ b/tests/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/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
new file mode 100644
index 000000000..391b00eff
--- /dev/null
+++ b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.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) -> [0: 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) -> [0: 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) -> [0: 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) -> [0: 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 (PtrToPtr); // 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: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+ }
+}
diff --git a/tests/mir-opt/slice_drop_shim.rs b/tests/mir-opt/slice_drop_shim.rs
new file mode 100644
index 000000000..344c1af2c
--- /dev/null
+++ b/tests/mir-opt/slice_drop_shim.rs
@@ -0,0 +1,7 @@
+// compile-flags: -Zmir-opt-level=0
+
+
+// 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/tests/mir-opt/spanview_block.main.built.after.html b/tests/mir-opt/spanview_block.main.built.after.html
new file mode 100644
index 000000000..b962d80c5
--- /dev/null
+++ b/tests/mir-opt/spanview_block.main.built.after.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>spanview_block.main.built.after</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/tests/mir-opt/spanview_block.rs b/tests/mir-opt/spanview_block.rs
new file mode 100644
index 000000000..0ecf35ad6
--- /dev/null
+++ b/tests/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.built.after.html
+fn main() {}
diff --git a/tests/mir-opt/spanview_statement.main.built.after.html b/tests/mir-opt/spanview_statement.main.built.after.html
new file mode 100644
index 000000000..43bff7d09
--- /dev/null
+++ b/tests/mir-opt/spanview_statement.main.built.after.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>spanview_statement.main.built.after</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/tests/mir-opt/spanview_statement.rs b/tests/mir-opt/spanview_statement.rs
new file mode 100644
index 000000000..457052617
--- /dev/null
+++ b/tests/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.built.after.html
+fn main() {}
diff --git a/tests/mir-opt/spanview_terminator.main.built.after.html b/tests/mir-opt/spanview_terminator.main.built.after.html
new file mode 100644
index 000000000..aa7e44c15
--- /dev/null
+++ b/tests/mir-opt/spanview_terminator.main.built.after.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>spanview_terminator.main.built.after</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/tests/mir-opt/spanview_terminator.rs b/tests/mir-opt/spanview_terminator.rs
new file mode 100644
index 000000000..76fced188
--- /dev/null
+++ b/tests/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.built.after.html
+fn main() {}
diff --git a/tests/mir-opt/sroa.dropping.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.dropping.ScalarReplacementOfAggregates.diff
new file mode 100644
index 000000000..eb8830446
--- /dev/null
+++ b/tests/mir-opt/sroa.dropping.ScalarReplacementOfAggregates.diff
@@ -0,0 +1,50 @@
+- // MIR for `dropping` before ScalarReplacementOfAggregates
++ // MIR for `dropping` after ScalarReplacementOfAggregates
+
+ fn dropping() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:19: +0:19
+ let _1: Tag; // in scope 0 at $DIR/sroa.rs:+1:5: +1:32
+ let mut _2: S; // in scope 0 at $DIR/sroa.rs:+1:5: +1:30
+ let mut _3: Tag; // in scope 0 at $DIR/sroa.rs:+1:7: +1:13
+ let mut _4: Tag; // in scope 0 at $DIR/sroa.rs:+1:15: +1:21
+ let mut _5: Tag; // in scope 0 at $DIR/sroa.rs:+1:23: +1:29
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/sroa.rs:+1:5: +1:32
+ StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:5: +1:30
+ StorageLive(_3); // scope 0 at $DIR/sroa.rs:+1:7: +1:13
+ Deinit(_3); // scope 0 at $DIR/sroa.rs:+1:7: +1:13
+ (_3.0: usize) = const 0_usize; // scope 0 at $DIR/sroa.rs:+1:7: +1:13
+ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+1:15: +1:21
+ Deinit(_4); // scope 0 at $DIR/sroa.rs:+1:15: +1:21
+ (_4.0: usize) = const 1_usize; // scope 0 at $DIR/sroa.rs:+1:15: +1:21
+ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:23: +1:29
+ Deinit(_5); // scope 0 at $DIR/sroa.rs:+1:23: +1:29
+ (_5.0: usize) = const 2_usize; // scope 0 at $DIR/sroa.rs:+1:23: +1:29
+ Deinit(_2); // scope 0 at $DIR/sroa.rs:+1:5: +1:30
+ (_2.0: Tag) = move _3; // scope 0 at $DIR/sroa.rs:+1:5: +1:30
+ (_2.1: Tag) = move _4; // scope 0 at $DIR/sroa.rs:+1:5: +1:30
+ (_2.2: Tag) = move _5; // scope 0 at $DIR/sroa.rs:+1:5: +1:30
+ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:29: +1:30
+ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+1:29: +1:30
+ StorageDead(_3); // scope 0 at $DIR/sroa.rs:+1:29: +1:30
+ _1 = move (_2.1: Tag); // scope 0 at $DIR/sroa.rs:+1:5: +1:32
+ drop(_1) -> bb1; // scope 0 at $DIR/sroa.rs:+1:32: +1:33
+ }
+
+ bb1: {
+ drop((_2.0: Tag)) -> bb3; // scope 0 at $DIR/sroa.rs:+1:32: +1:33
+ }
+
+ bb2: {
+ StorageDead(_2); // scope 0 at $DIR/sroa.rs:+1:32: +1:33
+ StorageDead(_1); // scope 0 at $DIR/sroa.rs:+1:32: +1:33
+ _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +2:2
+ return; // scope 0 at $DIR/sroa.rs:+2:2: +2:2
+ }
+
+ bb3: {
+ drop((_2.2: Tag)) -> bb2; // scope 0 at $DIR/sroa.rs:+1:32: +1:33
+ }
+ }
+
diff --git a/tests/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff
new file mode 100644
index 000000000..a5488c1ec
--- /dev/null
+++ b/tests/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff
@@ -0,0 +1,45 @@
+- // MIR for `enums` before ScalarReplacementOfAggregates
++ // MIR for `enums` after ScalarReplacementOfAggregates
+
+ fn enums(_1: usize) -> usize {
+ debug a => _1; // in scope 0 at $DIR/sroa.rs:+0:14: +0:15
+ let mut _0: usize; // return place in scope 0 at $DIR/sroa.rs:+0:27: +0:32
+ let mut _2: std::option::Option<usize>; // in scope 0 at $DIR/sroa.rs:+1:22: +1:29
+ let mut _3: usize; // in scope 0 at $DIR/sroa.rs:+1:27: +1:28
+ let mut _4: isize; // in scope 0 at $DIR/sroa.rs:+1:12: +1:19
+ scope 1 {
+ debug a => _5; // in scope 1 at $DIR/sroa.rs:+1:17: +1:18
+ let _5: usize; // in scope 1 at $DIR/sroa.rs:+1:17: +1:18
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 1 at $DIR/sroa.rs:+1:22: +1:29
+ StorageLive(_3); // scope 1 at $DIR/sroa.rs:+1:27: +1:28
+ _3 = _1; // scope 1 at $DIR/sroa.rs:+1:27: +1:28
+ Deinit(_2); // scope 1 at $DIR/sroa.rs:+1:22: +1:29
+ ((_2 as Some).0: usize) = move _3; // scope 1 at $DIR/sroa.rs:+1:22: +1:29
+ discriminant(_2) = 1; // scope 1 at $DIR/sroa.rs:+1:22: +1:29
+ StorageDead(_3); // scope 1 at $DIR/sroa.rs:+1:28: +1:29
+ _4 = discriminant(_2); // scope 1 at $DIR/sroa.rs:+1:12: +1:19
+ switchInt(move _4) -> [1: bb1, otherwise: bb2]; // scope 1 at $DIR/sroa.rs:+1:12: +1:19
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 1 at $DIR/sroa.rs:+1:17: +1:18
+ _5 = ((_2 as Some).0: usize); // scope 1 at $DIR/sroa.rs:+1:17: +1:18
+ _0 = _5; // scope 1 at $DIR/sroa.rs:+1:32: +1:33
+ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:34: +1:35
+ goto -> bb3; // scope 0 at $DIR/sroa.rs:+1:5: +1:46
+ }
+
+ bb2: {
+ _0 = const 0_usize; // scope 0 at $DIR/sroa.rs:+1:43: +1:44
+ goto -> bb3; // scope 0 at $DIR/sroa.rs:+1:5: +1:46
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/sroa.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/sroa.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff
new file mode 100644
index 000000000..64559b58f
--- /dev/null
+++ b/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff
@@ -0,0 +1,47 @@
+- // MIR for `escaping` before ScalarReplacementOfAggregates
++ // MIR for `escaping` after ScalarReplacementOfAggregates
+
+ fn escaping() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:19: +0:19
+ let _1: (); // in scope 0 at $DIR/sroa.rs:+2:5: +2:42
+ let mut _2: *const u32; // in scope 0 at $DIR/sroa.rs:+2:7: +2:41
+ let _3: &u32; // in scope 0 at $DIR/sroa.rs:+2:7: +2:41
+ let _4: Escaping; // in scope 0 at $DIR/sroa.rs:+2:8: +2:39
+ let mut _5: u32; // in scope 0 at $DIR/sroa.rs:+2:34: +2:37
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/sroa.rs:+2:5: +2:42
+ StorageLive(_2); // scope 0 at $DIR/sroa.rs:+2:7: +2:41
+ StorageLive(_3); // scope 0 at $DIR/sroa.rs:+2:7: +2:41
+ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+2:8: +2:39
+ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+2:34: +2:37
+ _5 = g() -> bb1; // scope 0 at $DIR/sroa.rs:+2:34: +2:37
+ // mir::Constant
+ // + span: $DIR/sroa.rs:78:34: 78:35
+ // + literal: Const { ty: fn() -> u32 {g}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ Deinit(_4); // scope 0 at $DIR/sroa.rs:+2:8: +2:39
+ (_4.0: u32) = const 1_u32; // scope 0 at $DIR/sroa.rs:+2:8: +2:39
+ (_4.1: u32) = const 2_u32; // scope 0 at $DIR/sroa.rs:+2:8: +2:39
+ (_4.2: u32) = move _5; // scope 0 at $DIR/sroa.rs:+2:8: +2:39
+ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+2:38: +2:39
+ _3 = &(_4.0: u32); // scope 0 at $DIR/sroa.rs:+2:7: +2:41
+ _2 = &raw const (*_3); // scope 0 at $DIR/sroa.rs:+2:7: +2:41
+ _1 = f(move _2) -> bb2; // scope 0 at $DIR/sroa.rs:+2:5: +2:42
+ // mir::Constant
+ // + span: $DIR/sroa.rs:78:5: 78:6
+ // + literal: Const { ty: fn(*const u32) {f}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_2); // scope 0 at $DIR/sroa.rs:+2:41: +2:42
+ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+2:42: +2:43
+ StorageDead(_3); // scope 0 at $DIR/sroa.rs:+2:42: +2:43
+ StorageDead(_1); // scope 0 at $DIR/sroa.rs:+2:42: +2:43
+ _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +3:2
+ return; // scope 0 at $DIR/sroa.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/tests/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff
new file mode 100644
index 000000000..d4c04d5e6
--- /dev/null
+++ b/tests/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff
@@ -0,0 +1,87 @@
+- // MIR for `flat` before ScalarReplacementOfAggregates
++ // MIR for `flat` after ScalarReplacementOfAggregates
+
+ fn flat() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:15: +0:15
+ let _1: u8; // in scope 0 at $DIR/sroa.rs:+1:15: +1:16
+ let _2: (); // in scope 0 at $DIR/sroa.rs:+1:18: +1:19
+ let _3: &str; // in scope 0 at $DIR/sroa.rs:+1:21: +1:22
+ let _4: std::option::Option<isize>; // in scope 0 at $DIR/sroa.rs:+1:24: +1:25
+ let mut _5: Foo; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
+ let mut _6: (); // in scope 0 at $DIR/sroa.rs:+1:45: +1:47
+ let mut _7: std::option::Option<isize>; // in scope 0 at $DIR/sroa.rs:+1:60: +1:68
++ let mut _8: u8; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ let mut _9: (); // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ let mut _10: &str; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ let mut _11: std::option::Option<isize>; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/sroa.rs:+1:15: +1:16
+ debug b => _2; // in scope 1 at $DIR/sroa.rs:+1:18: +1:19
+ debug c => _3; // in scope 1 at $DIR/sroa.rs:+1:21: +1:22
+ debug d => _4; // in scope 1 at $DIR/sroa.rs:+1:24: +1:25
+ scope 2 {
+ scope 3 {
+ scope 4 {
+ scope 5 {
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+- StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ StorageLive(_8); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ StorageLive(_9); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ StorageLive(_10); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ StorageLive(_11); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
+ StorageLive(_6); // scope 0 at $DIR/sroa.rs:+1:45: +1:47
+ Deinit(_6); // scope 0 at $DIR/sroa.rs:+1:45: +1:47
+ StorageLive(_7); // scope 0 at $DIR/sroa.rs:+1:60: +1:68
+ Deinit(_7); // scope 0 at $DIR/sroa.rs:+1:60: +1:68
+ ((_7 as Some).0: isize) = const -4_isize; // scope 0 at $DIR/sroa.rs:+1:60: +1:68
+ discriminant(_7) = 1; // scope 0 at $DIR/sroa.rs:+1:60: +1:68
+- Deinit(_5); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
+- (_5.0: u8) = const 5_u8; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
+- (_5.1: ()) = move _6; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
+- (_5.2: &str) = const "a"; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ Deinit(_8); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ Deinit(_9); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ Deinit(_10); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ Deinit(_11); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ _8 = const 5_u8; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ _9 = move _6; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ _10 = const "a"; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
+ // mir::Constant
+ // + span: $DIR/sroa.rs:57:52: 57:55
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+- (_5.3: std::option::Option<isize>) = move _7; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ _11 = move _7; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
+ StorageDead(_7); // scope 0 at $DIR/sroa.rs:+1:69: +1:70
+ StorageDead(_6); // scope 0 at $DIR/sroa.rs:+1:69: +1:70
+ StorageLive(_1); // scope 0 at $DIR/sroa.rs:+1:15: +1:16
+- _1 = (_5.0: u8); // scope 0 at $DIR/sroa.rs:+1:15: +1:16
++ _1 = _8; // scope 0 at $DIR/sroa.rs:+1:15: +1:16
+ StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:18: +1:19
+- _2 = (_5.1: ()); // scope 0 at $DIR/sroa.rs:+1:18: +1:19
++ _2 = _9; // scope 0 at $DIR/sroa.rs:+1:18: +1:19
+ StorageLive(_3); // scope 0 at $DIR/sroa.rs:+1:21: +1:22
+- _3 = (_5.2: &str); // scope 0 at $DIR/sroa.rs:+1:21: +1:22
++ _3 = _10; // scope 0 at $DIR/sroa.rs:+1:21: +1:22
+ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+1:24: +1:25
+- _4 = (_5.3: std::option::Option<isize>); // scope 0 at $DIR/sroa.rs:+1:24: +1:25
+- StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
++ _4 = _11; // scope 0 at $DIR/sroa.rs:+1:24: +1:25
++ StorageDead(_8); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
++ StorageDead(_9); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
++ StorageDead(_10); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
++ StorageDead(_11); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
+ _0 = const (); // scope 0 at $DIR/sroa.rs:+0:15: +6:2
+ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
+ StorageDead(_3); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
+ StorageDead(_2); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
+ StorageDead(_1); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/sroa.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/tests/mir-opt/sroa.rs b/tests/mir-opt/sroa.rs
new file mode 100644
index 000000000..ff8deb40d
--- /dev/null
+++ b/tests/mir-opt/sroa.rs
@@ -0,0 +1,88 @@
+// unit-test: ScalarReplacementOfAggregates
+// compile-flags: -Cpanic=abort
+// no-prefer-dynamic
+
+struct Tag(usize);
+
+#[repr(C)]
+struct S(Tag, Tag, Tag);
+
+impl Drop for Tag {
+ #[inline(never)]
+ fn drop(&mut self) {}
+}
+
+// EMIT_MIR sroa.dropping.ScalarReplacementOfAggregates.diff
+pub fn dropping() {
+ S(Tag(0), Tag(1), Tag(2)).1;
+}
+
+// EMIT_MIR sroa.enums.ScalarReplacementOfAggregates.diff
+pub fn enums(a: usize) -> usize {
+ if let Some(a) = Some(a) { a } else { 0 }
+}
+
+// EMIT_MIR sroa.structs.ScalarReplacementOfAggregates.diff
+pub fn structs(a: f32) -> f32 {
+ struct U {
+ _foo: usize,
+ a: f32,
+ }
+
+ U { _foo: 0, a }.a
+}
+
+// EMIT_MIR sroa.unions.ScalarReplacementOfAggregates.diff
+pub fn unions(a: f32) -> u32 {
+ union Repr {
+ f: f32,
+ u: u32,
+ }
+ unsafe { Repr { f: a }.u }
+}
+
+struct Foo {
+ a: u8,
+ b: (),
+ c: &'static str,
+ d: Option<isize>,
+}
+
+fn g() -> u32 {
+ 3
+}
+
+// EMIT_MIR sroa.flat.ScalarReplacementOfAggregates.diff
+pub fn flat() {
+ let Foo { a, b, c, d } = Foo { a: 5, b: (), c: "a", d: Some(-4) };
+ let _ = a;
+ let _ = b;
+ let _ = c;
+ let _ = d;
+}
+
+#[repr(C)]
+struct Escaping {
+ a: u32,
+ b: u32,
+ c: u32,
+}
+
+fn f(a: *const u32) {
+ println!("{}", unsafe { *a.add(2) });
+}
+
+// EMIT_MIR sroa.escaping.ScalarReplacementOfAggregates.diff
+pub fn escaping() {
+ // Verify this struct is not flattened.
+ f(&Escaping { a: 1, b: 2, c: g() }.a);
+}
+
+fn main() {
+ dropping();
+ enums(5);
+ structs(5.);
+ unions(5.);
+ flat();
+ escaping();
+}
diff --git a/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff
new file mode 100644
index 000000000..69d74c351
--- /dev/null
+++ b/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff
@@ -0,0 +1,34 @@
+- // MIR for `structs` before ScalarReplacementOfAggregates
++ // MIR for `structs` after ScalarReplacementOfAggregates
+
+ fn structs(_1: f32) -> f32 {
+ debug a => _1; // in scope 0 at $DIR/sroa.rs:+0:16: +0:17
+ let mut _0: f32; // return place in scope 0 at $DIR/sroa.rs:+0:27: +0:30
+ let mut _2: structs::U; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21
+ let mut _3: f32; // in scope 0 at $DIR/sroa.rs:+6:18: +6:19
++ let mut _4: usize; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ let mut _5: f32; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21
+
+ bb0: {
+- StorageLive(_2); // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+6:5: +6:21
+ StorageLive(_3); // scope 0 at $DIR/sroa.rs:+6:18: +6:19
+ _3 = _1; // scope 0 at $DIR/sroa.rs:+6:18: +6:19
+- Deinit(_2); // scope 0 at $DIR/sroa.rs:+6:5: +6:21
+- (_2.0: usize) = const 0_usize; // scope 0 at $DIR/sroa.rs:+6:5: +6:21
+- (_2.1: f32) = move _3; // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ Deinit(_4); // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ Deinit(_5); // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ _4 = const 0_usize; // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ _5 = move _3; // scope 0 at $DIR/sroa.rs:+6:5: +6:21
+ StorageDead(_3); // scope 0 at $DIR/sroa.rs:+6:20: +6:21
+- _0 = (_2.1: f32); // scope 0 at $DIR/sroa.rs:+6:5: +6:23
+- StorageDead(_2); // scope 0 at $DIR/sroa.rs:+7:1: +7:2
++ _0 = _5; // scope 0 at $DIR/sroa.rs:+6:5: +6:23
++ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+7:1: +7:2
++ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/sroa.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/tests/mir-opt/sroa.unions.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.unions.ScalarReplacementOfAggregates.diff
new file mode 100644
index 000000000..03ca976df
--- /dev/null
+++ b/tests/mir-opt/sroa.unions.ScalarReplacementOfAggregates.diff
@@ -0,0 +1,24 @@
+- // MIR for `unions` before ScalarReplacementOfAggregates
++ // MIR for `unions` after ScalarReplacementOfAggregates
+
+ fn unions(_1: f32) -> u32 {
+ debug a => _1; // in scope 0 at $DIR/sroa.rs:+0:15: +0:16
+ let mut _0: u32; // return place in scope 0 at $DIR/sroa.rs:+0:26: +0:29
+ let mut _2: unions::Repr; // in scope 0 at $DIR/sroa.rs:+5:14: +5:27
+ let mut _3: f32; // in scope 0 at $DIR/sroa.rs:+5:24: +5:25
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 1 at $DIR/sroa.rs:+5:14: +5:27
+ StorageLive(_3); // scope 1 at $DIR/sroa.rs:+5:24: +5:25
+ _3 = _1; // scope 1 at $DIR/sroa.rs:+5:24: +5:25
+ Deinit(_2); // scope 1 at $DIR/sroa.rs:+5:14: +5:27
+ (_2.0: f32) = move _3; // scope 1 at $DIR/sroa.rs:+5:14: +5:27
+ StorageDead(_3); // scope 1 at $DIR/sroa.rs:+5:26: +5:27
+ _0 = (_2.1: u32); // scope 1 at $DIR/sroa.rs:+5:14: +5:29
+ StorageDead(_2); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/sroa.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/tests/mir-opt/storage_ranges.main.nll.0.mir b/tests/mir-opt/storage_ranges.main.nll.0.mir
new file mode 100644
index 000000000..8e10e70f1
--- /dev/null
+++ b/tests/mir-opt/storage_ranges.main.nll.0.mir
@@ -0,0 +1,63 @@
+// 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 | {bb0[10..=11]}
+| '_#3r | U0 | {bb0[11]}
+|
+| Inference Constraints
+| '_#0r live at {bb0[0..=22]}
+| '_#1r live at {bb0[0..=22]}
+| '_#2r live at {bb0[10]}
+| '_#3r live at {bb0[11]}
+| '_#2r: '_#3r due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0)
+|
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/storage_ranges.rs:+0:11: +0:11
+ 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/tests/mir-opt/storage_ranges.rs b/tests/mir-opt/storage_ranges.rs
new file mode 100644
index 000000000..996051a29
--- /dev/null
+++ b/tests/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/tests/mir-opt/tls_access.main.PreCodegen.after.mir b/tests/mir-opt/tls_access.main.PreCodegen.after.mir
new file mode 100644
index 000000000..09453b8ba
--- /dev/null
+++ b/tests/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/tests/mir-opt/tls_access.rs b/tests/mir-opt/tls_access.rs
new file mode 100644
index 000000000..19344c868
--- /dev/null
+++ b/tests/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/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir b/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir
new file mode 100644
index 000000000..b254bfeb7
--- /dev/null
+++ b/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir
@@ -0,0 +1,71 @@
+// MIR for `new` after PreCodegen
+
+fn new(_1: Result<T, E>) -> Result<T, E> {
+ debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15
+ let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46
+ let mut _2: std::ops::ControlFlow<E, T>; // in scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ let mut _3: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:22
+ let mut _4: T; // in scope 0 at $DIR/try_identity_e2e.rs:+4:48: +4:49
+ let mut _5: E; // in scope 0 at $DIR/try_identity_e2e.rs:+5:46: +5:47
+ let mut _6: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+8:13: +8:37
+ let _7: T; // in scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
+ let mut _8: E; // in scope 0 at $DIR/try_identity_e2e.rs:+9:49: +9:50
+ scope 1 {
+ debug v => _4; // in scope 1 at $DIR/try_identity_e2e.rs:+4:20: +4:21
+ }
+ scope 2 {
+ debug e => _5; // in scope 2 at $DIR/try_identity_e2e.rs:+5:21: +5:22
+ }
+ scope 3 {
+ debug v => _7; // in scope 3 at $DIR/try_identity_e2e.rs:+8:35: +8:36
+ }
+ scope 4 {
+ debug e => _8; // in scope 4 at $DIR/try_identity_e2e.rs:+9:32: +9:33
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ _3 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20
+ switchInt(move _3) -> [0: bb2, 1: bb1, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:20
+ }
+
+ bb1: {
+ _5 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
+ Deinit(_2); // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
+ ((_2 as Break).0: E) = move _5; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
+ discriminant(_2) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
+ _6 = discriminant(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ switchInt(move _6) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10
+ }
+
+ bb2: {
+ _4 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
+ Deinit(_2); // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
+ ((_2 as Continue).0: T) = move _4; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
+ discriminant(_2) = 0; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
+ _6 = discriminant(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ switchInt(move _6) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10
+ }
+
+ bb3: {
+ _8 = move ((_2 as Break).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
+ Deinit(_0); // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
+ ((_0 as Err).0: E) = move _8; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
+ discriminant(_0) = 1; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
+ StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
+ return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
+ }
+
+ bb4: {
+ unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ }
+
+ bb5: {
+ _7 = move ((_2 as Continue).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
+ Deinit(_0); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
+ ((_0 as Ok).0: T) = move _7; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
+ discriminant(_0) = 0; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
+ StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
+ return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
+ }
+}
diff --git a/tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir b/tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir
new file mode 100644
index 000000000..cdbc0681c
--- /dev/null
+++ b/tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir
@@ -0,0 +1,40 @@
+// MIR for `old` after PreCodegen
+
+fn old(_1: Result<T, E>) -> Result<T, E> {
+ debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15
+ let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46
+ let mut _2: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:18
+ let _3: T; // in scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
+ let mut _4: E; // in scope 0 at $DIR/try_identity_e2e.rs:+4:34: +4:35
+ scope 1 {
+ debug v => _3; // in scope 1 at $DIR/try_identity_e2e.rs:+3:16: +3:17
+ }
+ scope 2 {
+ debug e => _4; // in scope 2 at $DIR/try_identity_e2e.rs:+4:17: +4:18
+ }
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16
+ switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +2:16
+ }
+
+ bb1: {
+ _4 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
+ Deinit(_0); // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
+ ((_0 as Err).0: E) = move _4; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
+ discriminant(_0) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
+ return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16
+ }
+
+ bb3: {
+ _3 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
+ Deinit(_0); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
+ ((_0 as Ok).0: T) = move _3; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
+ discriminant(_0) = 0; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
+ return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2
+ }
+}
diff --git a/tests/mir-opt/try_identity_e2e.rs b/tests/mir-opt/try_identity_e2e.rs
new file mode 100644
index 000000000..00cb80f50
--- /dev/null
+++ b/tests/mir-opt/try_identity_e2e.rs
@@ -0,0 +1,34 @@
+// Track the status of MIR optimizations simplifying `Ok(res?)` for both the old and new desugarings
+// of that syntax.
+
+use std::ops::ControlFlow;
+
+// EMIT_MIR try_identity_e2e.new.PreCodegen.after.mir
+fn new<T, E>(x: Result<T, E>) -> Result<T, E> {
+ Ok(
+ match {
+ match x {
+ Ok(v) => ControlFlow::Continue(v),
+ Err(e) => ControlFlow::Break(e),
+ }
+ } {
+ ControlFlow::Continue(v) => v,
+ ControlFlow::Break(e) => return Err(e),
+ }
+ )
+}
+
+// EMIT_MIR try_identity_e2e.old.PreCodegen.after.mir
+fn old<T, E>(x: Result<T, E>) -> Result<T, E> {
+ Ok(
+ match x {
+ Ok(v) => v,
+ Err(e) => return Err(e),
+ }
+ )
+}
+
+fn main() {
+ let _ = new::<(), ()>(Ok(()));
+ let _ = old::<(), ()>(Ok(()));
+}
diff --git a/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir b/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir
new file mode 100644
index 000000000..b4fb330f3
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir
@@ -0,0 +1,16 @@
+// MIR for `process_never` after SimplifyLocals-final
+
+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: {
+ unreachable; // scope 0 at $DIR/uninhabited_enum.rs:+0:39: +2:2
+ }
+}
diff --git a/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir b/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir
new file mode 100644
index 000000000..2af864998
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir
@@ -0,0 +1,18 @@
+// MIR for `process_void` after SimplifyLocals-final
+
+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/tests/mir-opt/uninhabited_enum.rs b/tests/mir-opt/uninhabited_enum.rs
new file mode 100644
index 000000000..19db54815
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum.rs
@@ -0,0 +1,19 @@
+#![feature(never_type)]
+
+pub enum Void {}
+
+// EMIT_MIR uninhabited_enum.process_never.SimplifyLocals-final.after.mir
+#[no_mangle]
+pub fn process_never(input: *const !) {
+ let _input = unsafe { &*input };
+}
+
+// EMIT_MIR uninhabited_enum.process_void.SimplifyLocals-final.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/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
new file mode 100644
index 000000000..39ec05277
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
@@ -0,0 +1,75 @@
+// 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
+ switchInt(move _3) -> [2: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
+ _5 = const "C"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
+ // mir::Constant
+ // + 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: bb5, 5: bb3, otherwise: bb4]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ }
+
+ bb3: {
+ StorageLive(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
+ _9 = const "E"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
+ // mir::Constant
+ // + 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 -> bb6; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24
+ }
+
+ bb4: {
+ unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ }
+
+ bb5: {
+ _6 = const "D"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching.rs:27:21: 27:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ goto -> bb6; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
+ }
+
+ bb6: {
+ StorageDead(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7
+ StorageDead(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7
+ _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +11:2
+ return; // scope 0 at $DIR/uninhabited_enum_branching.rs:+11:2: +11:2
+ }
+}
diff --git a/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff
new file mode 100644
index 000000000..598413a1d
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff
@@ -0,0 +1,101 @@
+- // 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: bb3, 1: bb4, 2: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19
++ switchInt(move _3) -> [2: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
+ _5 = const "C"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
+ // mir::Constant
+ // + 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 -> bb5; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:23: +4:24
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ }
+
+ bb3: {
+ _1 = const "A(Empty)"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+2:24: +2:34
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching.rs:21:24: 21:34
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ goto -> bb5; // scope 0 at $DIR/uninhabited_enum_branching.rs:+2:24: +2:34
+ }
+
+ bb4: {
+ StorageLive(_4); // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34
+ _4 = const "B(Empty)"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34
+ // mir::Constant
+ // + 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 -> bb5; // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:33: +3:34
+ }
+
+ bb5: {
+ StorageDead(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+5:6: +5:7
+ StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching.rs:+5:6: +5:7
+ StorageLive(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +10:6
+ 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: bb8, 5: bb6, otherwise: bb7]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19
+ }
+
+ bb6: {
+ StorageLive(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
+ _9 = const "E"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
+ // mir::Constant
+ // + 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 -> bb9; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24
+ }
+
+ bb7: {
+ unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ }
+
+ bb8: {
+ _6 = const "D"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching.rs:27:21: 27:24
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ goto -> bb9; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
+ }
+
+ bb9: {
+ StorageDead(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7
+ StorageDead(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7
+ _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +11:2
+ return; // scope 0 at $DIR/uninhabited_enum_branching.rs:+11:2: +11:2
+ }
+ }
+
diff --git a/tests/mir-opt/uninhabited_enum_branching.rs b/tests/mir-opt/uninhabited_enum_branching.rs
new file mode 100644
index 000000000..0ef604c30
--- /dev/null
+++ b/tests/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/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
new file mode 100644
index 000000000..c8cd6f6c1
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
@@ -0,0 +1,104 @@
+// 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: bb3, 3: bb1, otherwise: bb2]; // 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 -> bb4; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24
+ }
+
+ bb2: {
+ unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
+ }
+
+ bb3: {
+ StorageLive(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
+ _7 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
+ // mir::Constant
+ // + 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 -> bb4; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24
+ }
+
+ bb4: {
+ StorageDead(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7
+ StorageDead(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7
+ StorageLive(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6
+ _10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21
+ switchInt(move _10) -> [2: bb7, 3: bb5, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21
+ }
+
+ bb5: {
+ StorageLive(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
+ _13 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
+ // mir::Constant
+ // + 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 -> bb8; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24
+ }
+
+ bb6: {
+ unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21
+ }
+
+ bb7: {
+ StorageLive(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
+ _12 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
+ // mir::Constant
+ // + 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 -> bb8; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24
+ }
+
+ bb8: {
+ StorageDead(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+15:6: +15:7
+ _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +16:2
+ StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:1: +16:2
+ return; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:2: +16:2
+ }
+}
diff --git a/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff
new file mode 100644
index 000000000..2aee6d268
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff
@@ -0,0 +1,146 @@
+- // 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: bb3, 1: bb4, 2: bb5, 3: bb1, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22
++ switchInt(move _5) -> [2: bb5, 3: bb1, otherwise: bb2]; // 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 -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24
+ }
+
+ bb2: {
+ unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
+ }
+
+ bb3: {
+ _3 = const "A(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+4:24: +4:34
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:22:24: 22:34
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+4:24: +4:34
+ }
+
+ bb4: {
+ StorageLive(_6); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34
+ _6 = const "B(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34
+ // mir::Constant
+ // + 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 -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:33: +5:34
+ }
+
+ bb5: {
+ StorageLive(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
+ _7 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
+ // mir::Constant
+ // + 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 -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24
+ }
+
+ bb6: {
+ StorageDead(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7
+ StorageDead(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7
+ StorageLive(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6
+ _10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21
+- switchInt(move _10) -> [0: bb9, 1: bb10, 2: bb11, 3: bb7, otherwise: bb8]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21
++ switchInt(move _10) -> [2: bb11, 3: bb7, otherwise: bb8]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21
+ }
+
+ bb7: {
+ StorageLive(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
+ _13 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
+ // mir::Constant
+ // + 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 -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24
+ }
+
+ bb8: {
+ unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21
+ }
+
+ bb9: {
+ _9 = const "A(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34
+ // mir::Constant
+ // + span: $DIR/uninhabited_enum_branching2.rs:29:24: 29:34
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ goto -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34
+ }
+
+ bb10: {
+ StorageLive(_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34
+ _11 = const "B(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34
+ // mir::Constant
+ // + 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 -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:33: +12:34
+ }
+
+ bb11: {
+ StorageLive(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
+ _12 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
+ // mir::Constant
+ // + 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 -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24
+ }
+
+ bb12: {
+ StorageDead(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+15:6: +15:7
+ _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +16:2
+ StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:1: +16:2
+ return; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:2: +16:2
+ }
+ }
+
diff --git a/tests/mir-opt/uninhabited_enum_branching2.rs b/tests/mir-opt/uninhabited_enum_branching2.rs
new file mode 100644
index 000000000..e22e94314
--- /dev/null
+++ b/tests/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/tests/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff
new file mode 100644
index 000000000..58e085dd0
--- /dev/null
+++ b/tests/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: bb3, 2: bb2, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12
++ switchInt(move _2) -> [1: bb3, 2: 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/tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff
new file mode 100644
index 000000000..e765851eb
--- /dev/null
+++ b/tests/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: bb2, 1: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12
++ switchInt(move _2) -> [1: 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/tests/mir-opt/uninhabited_fallthrough_elimination.rs b/tests/mir-opt/uninhabited_fallthrough_elimination.rs
new file mode 100644
index 000000000..0853883f8
--- /dev/null
+++ b/tests/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/tests/mir-opt/unreachable.main.UnreachablePropagation.diff b/tests/mir-opt/unreachable.main.UnreachablePropagation.diff
new file mode 100644
index 000000000..848bff1d4
--- /dev/null
+++ b/tests/mir-opt/unreachable.main.UnreachablePropagation.diff
@@ -0,0 +1,70 @@
+- // 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: bb2, otherwise: bb6]; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20
++ switchInt(move _2) -> [1: bb2, otherwise: bb3]; // 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) -> [0: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16
++ unreachable; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16
+ }
+
+ bb3: {
+- _4 = const 21_i32; // scope 2 at $DIR/unreachable.rs:+5:13: +5:20
+- _5 = const (); // scope 2 at $DIR/unreachable.rs:+4:17: +6:10
+- goto -> bb5; // scope 2 at $DIR/unreachable.rs:+4:9: +8:10
+- }
+-
+- 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/tests/mir-opt/unreachable.rs b/tests/mir-opt/unreachable.rs
new file mode 100644
index 000000000..6098b525b
--- /dev/null
+++ b/tests/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/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff b/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff
new file mode 100644
index 000000000..fb778470e
--- /dev/null
+++ b/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff
@@ -0,0 +1,71 @@
+- // 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: bb2, otherwise: bb6]; // 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) -> [0: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13
+ }
+
+ bb3: {
+ _5 = loop_forever() -> bb5; // scope 2 at $DIR/unreachable_diverging.rs:+4:13: +4:27
+ // 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
++ unreachable; // scope 2 at $DIR/unreachable_diverging.rs:+3:9: +5:10
+ }
+
+ bb5: {
+- StorageDead(_6); // scope 2 at $DIR/unreachable_diverging.rs:+5:9: +5:10
+- StorageDead(_5); // scope 2 at $DIR/unreachable_diverging.rs:+5:9: +5:10
+- StorageLive(_7); // scope 2 at $DIR/unreachable_diverging.rs:+6:9: +6:22
+ unreachable; // scope 2 at $DIR/unreachable_diverging.rs:+6:15: +6:19
+ }
+
+ bb6: {
+ _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/tests/mir-opt/unreachable_diverging.rs b/tests/mir-opt/unreachable_diverging.rs
new file mode 100644
index 000000000..bbf28efc7
--- /dev/null
+++ b/tests/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/tests/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir b/tests/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir
new file mode 100644
index 000000000..5257491f0
--- /dev/null
+++ b/tests/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `E::V::{constant#0}` after built
+
+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/tests/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir b/tests/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir
new file mode 100644
index 000000000..ee0296763
--- /dev/null
+++ b/tests/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir
@@ -0,0 +1,12 @@
+// MIR for `Test::X` after built
+
+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/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir b/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir
new file mode 100644
index 000000000..ed9f3bdbd
--- /dev/null
+++ b/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.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<'a> fn(&'a mut Vec<i32>) {<Vec<i32> as Drop>::drop}, val: Value(<ZST>) }
+ }
+}
diff --git a/tests/mir-opt/unusual_item_types.rs b/tests/mir-opt/unusual_item_types.rs
new file mode 100644
index 000000000..6dad63641
--- /dev/null
+++ b/tests/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
+
+
+struct A;
+
+// EMIT_MIR unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir
+impl A {
+ const ASSOCIATED_CONSTANT: i32 = 2;
+}
+
+// See #59021
+// EMIT_MIR unusual_item_types.Test-X-{constructor#0}.built.after.mir
+enum Test {
+ X(usize),
+ Y { a: usize },
+}
+
+// EMIT_MIR unusual_item_types.E-V-{constant#0}.built.after.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/tests/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir b/tests/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir
new file mode 100644
index 000000000..90444b481
--- /dev/null
+++ b/tests/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `<impl at $DIR/unusual_item_types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` after built
+
+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:40
+ }
+}
diff --git a/tests/mir-opt/while_let_loops.change_loop_body.ConstProp.diff b/tests/mir-opt/while_let_loops.change_loop_body.ConstProp.diff
new file mode 100644
index 000000000..bb1de59d4
--- /dev/null
+++ b/tests/mir-opt/while_let_loops.change_loop_body.ConstProp.diff
@@ -0,0 +1,46 @@
+- // 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: std::option::Option<u32>; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32
+ let mut _3: isize; // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25
+ 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(_2); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
+ Deinit(_2); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
+ discriminant(_2) = 0; // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
+- _3 = discriminant(_2); // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
+- switchInt(move _3) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
++ _3 = const 0_isize; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
++ switchInt(const 0_isize) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
+ }
+
+ bb1: {
+ switchInt(((_2 as Some).0: u32)) -> [0: 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
+ goto -> bb4; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
+ }
+
+ bb3: {
+ goto -> bb4; // scope 1 at no-location
+ }
+
+ bb4: {
+ StorageDead(_2); // 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/tests/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir b/tests/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir
new file mode 100644
index 000000000..15b0aece8
--- /dev/null
+++ b/tests/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.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/tests/mir-opt/while_let_loops.rs b/tests/mir-opt/while_let_loops.rs
new file mode 100644
index 000000000..fc56cd698
--- /dev/null
+++ b/tests/mir-opt/while_let_loops.rs
@@ -0,0 +1,14 @@
+// EMIT_MIR while_let_loops.change_loop_body.ConstProp.diff
+// EMIT_MIR while_let_loops.change_loop_body.PreCodegen.after.mir
+
+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/tests/mir-opt/while_storage.rs b/tests/mir-opt/while_storage.rs
new file mode 100644
index 000000000..afd083acb
--- /dev/null
+++ b/tests/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/tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir
new file mode 100644
index 000000000..b95d91b13
--- /dev/null
+++ b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir
@@ -0,0 +1,60 @@
+// 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) -> [0: 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) -> [0: 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 -> bb7; // 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: {
+ 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
+ }
+}