]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #101506 - notriddle:notriddle/rustdoc-main-since-2, r=GuillaumeGomez
authorMatthias Krüger <matthias.krueger@famsik.de>
Wed, 7 Sep 2022 19:48:17 +0000 (21:48 +0200)
committerGitHub <noreply@github.com>
Wed, 7 Sep 2022 19:48:17 +0000 (21:48 +0200)
rustdoc: remove unused CSS `#main-content > .since`

I missed one from #101298

246 files changed:
compiler/rustc_ast_lowering/src/asm.rs
compiler/rustc_ast_lowering/src/block.rs
compiler/rustc_ast_lowering/src/expr.rs
compiler/rustc_ast_lowering/src/item.rs
compiler/rustc_ast_lowering/src/lib.rs
compiler/rustc_ast_lowering/src/pat.rs
compiler/rustc_ast_lowering/src/path.rs
compiler/rustc_attr/src/builtin.rs
compiler/rustc_borrowck/src/dataflow.rs
compiler/rustc_borrowck/src/invalidation.rs
compiler/rustc_borrowck/src/lib.rs
compiler/rustc_borrowck/src/type_check/mod.rs
compiler/rustc_codegen_cranelift/src/base.rs
compiler/rustc_codegen_cranelift/src/constant.rs
compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
compiler/rustc_codegen_gcc/src/common.rs
compiler/rustc_codegen_llvm/src/common.rs
compiler/rustc_codegen_ssa/src/back/link.rs
compiler/rustc_codegen_ssa/src/back/linker.rs
compiler/rustc_codegen_ssa/src/base.rs
compiler/rustc_codegen_ssa/src/lib.rs
compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
compiler/rustc_codegen_ssa/src/mir/operand.rs
compiler/rustc_codegen_ssa/src/mir/statement.rs
compiler/rustc_codegen_ssa/src/traits/consts.rs
compiler/rustc_const_eval/src/interpret/intrinsics.rs
compiler/rustc_const_eval/src/interpret/step.rs
compiler/rustc_const_eval/src/transform/check_consts/check.rs
compiler/rustc_const_eval/src/transform/validate.rs
compiler/rustc_hir/src/weak_lang_items.rs
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_infer/src/infer/mod.rs
compiler/rustc_infer/src/infer/outlives/verify.rs
compiler/rustc_interface/src/passes.rs
compiler/rustc_middle/src/mir/mod.rs
compiler/rustc_middle/src/mir/spanview.rs
compiler/rustc_middle/src/mir/syntax.rs
compiler/rustc_middle/src/mir/visit.rs
compiler/rustc_middle/src/ty/flags.rs
compiler/rustc_middle/src/ty/generics.rs
compiler/rustc_middle/src/ty/mod.rs
compiler/rustc_middle/src/ty/print/pretty.rs
compiler/rustc_middle/src/ty/relate.rs
compiler/rustc_middle/src/ty/structural_impls.rs
compiler/rustc_middle/src/ty/walk.rs
compiler/rustc_mir_dataflow/src/impls/liveness.rs
compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
compiler/rustc_mir_dataflow/src/move_paths/builder.rs
compiler/rustc_mir_transform/src/check_unsafety.rs
compiler/rustc_mir_transform/src/coverage/spans.rs
compiler/rustc_mir_transform/src/dead_store_elimination.rs
compiler/rustc_mir_transform/src/dest_prop.rs
compiler/rustc_mir_transform/src/generator.rs
compiler/rustc_mir_transform/src/lower_intrinsics.rs
compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
compiler/rustc_mir_transform/src/separate_const_switch.rs
compiler/rustc_mir_transform/src/simplify.rs
compiler/rustc_parse/src/parser/expr.rs
compiler/rustc_passes/src/check_attr.rs
compiler/rustc_passes/src/hir_id_validator.rs
compiler/rustc_resolve/src/late/lifetimes.rs
compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
compiler/rustc_symbol_mangling/src/v0.rs
compiler/rustc_trait_selection/src/traits/auto_trait.rs
compiler/rustc_trait_selection/src/traits/project.rs
compiler/rustc_trait_selection/src/traits/wf.rs
compiler/rustc_typeck/src/astconv/mod.rs
compiler/rustc_typeck/src/check/method/mod.rs
compiler/rustc_typeck/src/collect.rs
compiler/rustc_typeck/src/collect/item_bounds.rs
compiler/rustc_typeck/src/variance/constraints.rs
library/std/src/io/stdio.rs
library/std/src/macros.rs
library/std/src/sys/windows/fs.rs
src/doc/rustc/src/platform-support/fuchsia.md
src/librustdoc/clean/mod.rs
src/librustdoc/html/static/css/rustdoc.css
src/test/codegen/issue-98294-get-mut-copy-from-slice-opt.rs [new file with mode: 0644]
src/test/incremental/issue-100521-change-struct-name-assocty.rs [new file with mode: 0644]
src/test/mir-opt/array-index-is-temporary.rs
src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir [deleted file]
src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir [deleted file]
src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir [new file with mode: 0644]
src/test/mir-opt/inline/inline-into-box-place.rs
src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff [deleted file]
src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff [deleted file]
src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff [new file with mode: 0644]
src/test/mir-opt/issue-41697.rs
src/test/mir-opt/issue-72181.rs
src/test/mir-opt/issue-73223.rs
src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir [deleted file]
src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir [deleted file]
src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir [new file with mode: 0644]
src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir [deleted file]
src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir [deleted file]
src/test/mir-opt/issue_72181.bar.mir_map.0.mir [new file with mode: 0644]
src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir [deleted file]
src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir [deleted file]
src/test/mir-opt/issue_72181.foo.mir_map.0.mir [new file with mode: 0644]
src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir [deleted file]
src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir [deleted file]
src/test/mir-opt/issue_72181.main.mir_map.0.mir [new file with mode: 0644]
src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff [deleted file]
src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff [deleted file]
src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff [new file with mode: 0644]
src/test/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff [new file with mode: 0644]
src/test/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff [new file with mode: 0644]
src/test/mir-opt/lower_intrinsics.rs
src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff [deleted file]
src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff [deleted file]
src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff [new file with mode: 0644]
src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff [deleted file]
src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff [deleted file]
src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff [new file with mode: 0644]
src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff [deleted file]
src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff [deleted file]
src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff [new file with mode: 0644]
src/test/mir-opt/matches_reduce_branches.rs
src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff [deleted file]
src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff [deleted file]
src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff [new file with mode: 0644]
src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff [deleted file]
src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff [deleted file]
src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff [new file with mode: 0644]
src/test/mir-opt/matches_u8.rs
src/test/mir-opt/packed-struct-drop-aligned.rs
src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir [deleted file]
src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir [deleted file]
src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir [new file with mode: 0644]
src/test/mir-opt/separate_const_switch.identity.ConstProp.diff [deleted file]
src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir [deleted file]
src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff [deleted file]
src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir [deleted file]
src/test/mir-opt/simple-match.rs
src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir [deleted file]
src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir [deleted file]
src/test/mir-opt/simple_match.match_bool.mir_map.0.mir [new file with mode: 0644]
src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs
src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff [deleted file]
src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff [deleted file]
src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff [new file with mode: 0644]
src/test/mir-opt/slice-drop-shim.rs
src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir [deleted file]
src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir [deleted file]
src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir [new file with mode: 0644]
src/test/mir-opt/unusual-item-types.rs
src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir [deleted file]
src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir [deleted file]
src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.mir [new file with mode: 0644]
src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir [deleted file]
src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir [deleted file]
src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir [new file with mode: 0644]
src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir [deleted file]
src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir [deleted file]
src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir [new file with mode: 0644]
src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir [deleted file]
src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir [deleted file]
src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir [new file with mode: 0644]
src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff [deleted file]
src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff [deleted file]
src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff [new file with mode: 0644]
src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir [deleted file]
src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir [deleted file]
src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir [new file with mode: 0644]
src/test/mir-opt/while_let_loops.rs
src/test/run-make/track-pgo-dep-info/Makefile [new file with mode: 0644]
src/test/run-make/track-pgo-dep-info/main.rs [new file with mode: 0644]
src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2015.stderr [new file with mode: 0644]
src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr [new file with mode: 0644]
src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs [new file with mode: 0644]
src/test/ui/issues/issue-43988.stderr
src/test/ui/parser/do-not-suggest-semicolon-before-array.rs [new file with mode: 0644]
src/test/ui/parser/do-not-suggest-semicolon-before-array.stderr [new file with mode: 0644]
src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs [new file with mode: 0644]
src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr [new file with mode: 0644]
src/test/ui/parser/do-not-suggest-suggest-semicolon-before-array.rs [deleted file]
src/test/ui/parser/do-not-suggest-suggest-semicolon-before-array.stderr [deleted file]
src/test/ui/parser/suggest-semicolon-before-array.fixed [new file with mode: 0644]
src/test/ui/parser/suggest-semicolon-before-array.rs [new file with mode: 0644]
src/test/ui/parser/suggest-semicolon-before-array.stderr [new file with mode: 0644]
src/test/ui/parser/suggest-suggest-semicolon-before-array.fixed [deleted file]
src/test/ui/parser/suggest-suggest-semicolon-before-array.rs [deleted file]
src/test/ui/parser/suggest-suggest-semicolon-before-array.stderr [deleted file]
src/test/ui/repr/invalid_repr_list_help.rs [new file with mode: 0644]
src/test/ui/repr/invalid_repr_list_help.stderr [new file with mode: 0644]
src/tools/clippy/clippy_lints/src/dereference.rs
src/tools/clippy/clippy_lints/src/methods/mod.rs
src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
src/tools/miri
src/tools/rust-analyzer/.github/workflows/ci.yaml
src/tools/rust-analyzer/.github/workflows/release.yaml
src/tools/rust-analyzer/crates/hir-def/src/body.rs
src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs
src/tools/rust-analyzer/crates/hir-def/src/expr.rs
src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
src/tools/rust-analyzer/crates/hir-expand/src/name.rs
src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs
src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/deconstruct_pat.rs
src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/usefulness.rs
src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs [new file with mode: 0644]
src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs
src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
src/tools/rust-analyzer/crates/hir/src/lib.rs
src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs [new file with mode: 0644]
src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs [new file with mode: 0644]
src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs
src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs [new file with mode: 0644]
src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rast [new file with mode: 0644]
src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rs [new file with mode: 0644]
src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs
src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
src/tools/rust-analyzer/crates/syntax/rust.ungram
src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs
src/tools/rust-analyzer/lib/la-arena/src/lib.rs

index b0e9fe0469c41baab379f1b599301efda043f76f..90bb01aa2165dee8b9deaf969f7b243e73dd2436 100644 (file)
@@ -220,7 +220,7 @@ pub(crate) fn lower_inline_asm(
                                 &sym.qself,
                                 &sym.path,
                                 ParamMode::Optional,
-                                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                                &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                             );
                             hir::InlineAsmOperand::SymStatic { path, def_id }
                         } else {
index 7cbfe143b4d83d3701a7b30e5571f8e4d4322c1c..7465706d1a9bb78b039f86ebdf8df23ab6ac7ecf 100644 (file)
@@ -84,10 +84,9 @@ fn lower_stmts(
     }
 
     fn lower_local(&mut self, l: &Local) -> &'hir hir::Local<'hir> {
-        let ty = l
-            .ty
-            .as_ref()
-            .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
+        let ty = l.ty.as_ref().map(|t| {
+            self.lower_ty(t, &mut ImplTraitContext::Disallowed(ImplTraitPosition::Variable))
+        });
         let init = l.kind.init().map(|init| self.lower_expr(init));
         let hir_id = self.lower_node_id(l.id);
         let pat = self.lower_pat(&l.pat);
index 77babeb5d39d186099b6b9f2505b6522c0d9a928..6fa8d7f0fcdd9b52c0b0b75fe6012791c6d25354 100644 (file)
@@ -66,7 +66,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
                         seg,
                         ParamMode::Optional,
                         ParenthesizedGenericArgs::Err,
-                        ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     ));
                     let receiver = self.lower_expr(receiver);
                     let args =
@@ -89,14 +89,14 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
                 }
                 ExprKind::Cast(ref expr, ref ty) => {
                     let expr = self.lower_expr(expr);
-                    let ty =
-                        self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+                    let ty = self
+                        .lower_ty(ty, &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type));
                     hir::ExprKind::Cast(expr, ty)
                 }
                 ExprKind::Type(ref expr, ref ty) => {
                     let expr = self.lower_expr(expr);
-                    let ty =
-                        self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+                    let ty = self
+                        .lower_ty(ty, &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type));
                     hir::ExprKind::Type(expr, ty)
                 }
                 ExprKind::AddrOf(k, m, ref ohs) => {
@@ -219,7 +219,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
                         qself,
                         path,
                         ParamMode::Optional,
-                        ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     );
                     hir::ExprKind::Path(qpath)
                 }
@@ -253,7 +253,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
                             &se.qself,
                             &se.path,
                             ParamMode::Optional,
-                            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         )),
                         self.arena
                             .alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))),
@@ -550,12 +550,14 @@ pub(super) fn make_async_expr(
         async_gen_kind: hir::AsyncGeneratorKind,
         body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
     ) -> hir::ExprKind<'hir> {
-        let output = match ret_ty {
-            Some(ty) => hir::FnRetTy::Return(
-                self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock)),
-            ),
-            None => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
-        };
+        let output =
+            match ret_ty {
+                Some(ty) => hir::FnRetTy::Return(self.lower_ty(
+                    &ty,
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock),
+                )),
+                None => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
+            };
 
         // Resume argument type. We let the compiler infer this to simplify the lowering. It is
         // fully constrained by `future::from_generator`.
@@ -1123,7 +1125,7 @@ fn destructure_assign_mut(
                         qself,
                         path,
                         ParamMode::Optional,
-                        ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     );
                     // Destructure like a tuple struct.
                     let tuple_struct_pat =
@@ -1139,7 +1141,7 @@ fn destructure_assign_mut(
                         qself,
                         path,
                         ParamMode::Optional,
-                        ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     );
                     // Destructure like a unit struct.
                     let unit_struct_pat = hir::PatKind::Path(qpath);
@@ -1163,7 +1165,7 @@ fn destructure_assign_mut(
                     &se.qself,
                     &se.path,
                     ParamMode::Optional,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                 );
                 let fields_omitted = match &se.rest {
                     StructRest::Base(e) => {
index 76f63d1d78a90c284aa3df5ff290ee356f0df509..f0717b51d4b18f8489090d69692a86e21055613e 100644 (file)
@@ -264,8 +264,8 @@ fn lower_item_kind(
                     let body_id =
                         this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref());
 
-                    let itctx = ImplTraitContext::Universal;
-                    let (generics, decl) = this.lower_generics(generics, id, itctx, |this| {
+                    let mut itctx = ImplTraitContext::Universal;
+                    let (generics, decl) = this.lower_generics(generics, id, &mut itctx, |this| {
                         let ret_id = asyncness.opt_return_id();
                         this.lower_fn_decl(&decl, Some(id), FnDeclKind::Fn, ret_id)
                     });
@@ -311,8 +311,8 @@ fn lower_item_kind(
                 let (generics, ty) = self.lower_generics(
                     &generics,
                     id,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
-                    |this| this.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy),
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    |this| this.lower_ty(ty, &mut ImplTraitContext::TypeAliasesOpaqueTy),
                 );
                 hir::ItemKind::TyAlias(ty, generics)
             }
@@ -324,7 +324,7 @@ fn lower_item_kind(
                 let (generics, ty) = self.lower_generics(
                     &generics,
                     id,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| this.arena.alloc(this.ty(span, hir::TyKind::Err)),
                 );
                 hir::ItemKind::TyAlias(ty, generics)
@@ -333,7 +333,7 @@ fn lower_item_kind(
                 let (generics, variants) = self.lower_generics(
                     generics,
                     id,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
                         this.arena.alloc_from_iter(
                             enum_definition.variants.iter().map(|x| this.lower_variant(x)),
@@ -346,7 +346,7 @@ fn lower_item_kind(
                 let (generics, struct_def) = self.lower_generics(
                     generics,
                     id,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| this.lower_variant_data(hir_id, struct_def),
                 );
                 hir::ItemKind::Struct(struct_def, generics)
@@ -355,7 +355,7 @@ fn lower_item_kind(
                 let (generics, vdata) = self.lower_generics(
                     generics,
                     id,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| this.lower_variant_data(hir_id, vdata),
                 );
                 hir::ItemKind::Union(vdata, generics)
@@ -383,18 +383,20 @@ fn lower_item_kind(
                 // method, it will not be considered an in-band
                 // lifetime to be added, but rather a reference to a
                 // parent lifetime.
-                let itctx = ImplTraitContext::Universal;
+                let mut itctx = ImplTraitContext::Universal;
                 let (generics, (trait_ref, lowered_ty)) =
-                    self.lower_generics(ast_generics, id, itctx, |this| {
+                    self.lower_generics(ast_generics, id, &mut itctx, |this| {
                         let trait_ref = trait_ref.as_ref().map(|trait_ref| {
                             this.lower_trait_ref(
                                 trait_ref,
-                                ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
+                                &mut ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
                             )
                         });
 
-                        let lowered_ty = this
-                            .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+                        let lowered_ty = this.lower_ty(
+                            ty,
+                            &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type),
+                        );
 
                         (trait_ref, lowered_ty)
                     });
@@ -433,11 +435,11 @@ fn lower_item_kind(
                 let (generics, (unsafety, items, bounds)) = self.lower_generics(
                     generics,
                     id,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
                         let bounds = this.lower_param_bounds(
                             bounds,
-                            ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                            &mut ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
                         );
                         let items = this.arena.alloc_from_iter(
                             items.iter().map(|item| this.lower_trait_item_ref(item)),
@@ -452,11 +454,11 @@ fn lower_item_kind(
                 let (generics, bounds) = self.lower_generics(
                     generics,
                     id,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
                         this.lower_param_bounds(
                             bounds,
-                            ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                            &mut ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
                         )
                     },
                 );
@@ -479,7 +481,7 @@ fn lower_const_item(
         span: Span,
         body: Option<&Expr>,
     ) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
-        let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+        let ty = self.lower_ty(ty, &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type));
         (ty, self.lower_const_body(span, body))
     }
 
@@ -652,9 +654,9 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir
             kind: match i.kind {
                 ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => {
                     let fdec = &sig.decl;
-                    let itctx = ImplTraitContext::Universal;
+                    let mut itctx = ImplTraitContext::Universal;
                     let (generics, (fn_dec, fn_args)) =
-                        self.lower_generics(generics, i.id, itctx, |this| {
+                        self.lower_generics(generics, i.id, &mut itctx, |this| {
                             (
                                 // Disallow `impl Trait` in foreign items.
                                 this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None),
@@ -665,8 +667,8 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir
                     hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
                 }
                 ForeignItemKind::Static(ref t, m, _) => {
-                    let ty =
-                        self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+                    let ty = self
+                        .lower_ty(t, &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type));
                     hir::ForeignItemKind::Static(ty, m)
                 }
                 ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
@@ -734,11 +736,11 @@ fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'
                 qself,
                 path,
                 ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
-                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
             );
             self.arena.alloc(t)
         } else {
-            self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
+            self.lower_ty(&f.ty, &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type))
         };
         let hir_id = self.lower_node_id(f.id);
         self.lower_attrs(hir_id, &f.attrs);
@@ -761,7 +763,8 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
 
         let (generics, kind, has_default) = match i.kind {
             AssocItemKind::Const(_, ref ty, ref default) => {
-                let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+                let ty =
+                    self.lower_ty(ty, &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type));
                 let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
                 (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some())
             }
@@ -796,15 +799,18 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
                 let (generics, kind) = self.lower_generics(
                     &generics,
                     i.id,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
                         let ty = ty.as_ref().map(|x| {
-                            this.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
+                            this.lower_ty(
+                                x,
+                                &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type),
+                            )
                         });
                         hir::TraitItemKind::Type(
                             this.lower_param_bounds(
                                 bounds,
-                                ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                                &mut ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                             ),
                             ty,
                         )
@@ -857,7 +863,8 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
 
         let (generics, kind) = match &i.kind {
             AssocItemKind::Const(_, ty, expr) => {
-                let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+                let ty =
+                    self.lower_ty(ty, &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type));
                 (
                     hir::Generics::empty(),
                     hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())),
@@ -884,14 +891,14 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
                 self.lower_generics(
                     &generics,
                     i.id,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| match ty {
                         None => {
                             let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err));
                             hir::ImplItemKind::TyAlias(ty)
                         }
                         Some(ty) => {
-                            let ty = this.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy);
+                            let ty = this.lower_ty(ty, &mut ImplTraitContext::TypeAliasesOpaqueTy);
                             hir::ImplItemKind::TyAlias(ty)
                         }
                     },
@@ -1234,8 +1241,8 @@ fn lower_method_sig(
         is_async: Option<NodeId>,
     ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
         let header = self.lower_fn_header(sig.header);
-        let itctx = ImplTraitContext::Universal;
-        let (generics, decl) = self.lower_generics(generics, id, itctx, |this| {
+        let mut itctx = ImplTraitContext::Universal;
+        let (generics, decl) = self.lower_generics(generics, id, &mut itctx, |this| {
             this.lower_fn_decl(&sig.decl, Some(id), kind, is_async)
         });
         (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
@@ -1301,7 +1308,7 @@ fn lower_generics<T>(
         &mut self,
         generics: &Generics,
         parent_node_id: NodeId,
-        itctx: ImplTraitContext,
+        itctx: &mut ImplTraitContext,
         f: impl FnOnce(&mut Self) -> T,
     ) -> (&'hir hir::Generics<'hir>, T) {
         debug_assert!(self.impl_trait_defs.is_empty());
@@ -1406,7 +1413,7 @@ pub(super) fn lower_generic_bound_predicate(
         id: NodeId,
         kind: &GenericParamKind,
         bounds: &[GenericBound],
-        itctx: ImplTraitContext,
+        itctx: &mut ImplTraitContext,
         origin: PredicateOrigin,
     ) -> Option<hir::WherePredicate<'hir>> {
         // Do not create a clause if we do not have anything inside it.
@@ -1481,12 +1488,14 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
                 span,
             }) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
                 bound_generic_params: self.lower_generic_params(bound_generic_params),
-                bounded_ty: self
-                    .lower_ty(bounded_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
+                bounded_ty: self.lower_ty(
+                    bounded_ty,
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type),
+                ),
                 bounds: self.arena.alloc_from_iter(bounds.iter().map(|bound| {
                     self.lower_param_bound(
                         bound,
-                        ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                        &mut ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
                     )
                 })),
                 span: self.lower_span(span),
@@ -1501,16 +1510,20 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
                 lifetime: self.lower_lifetime(lifetime),
                 bounds: self.lower_param_bounds(
                     bounds,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
                 ),
                 in_where_clause: true,
             }),
             WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span }) => {
                 hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
-                    lhs_ty: self
-                        .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
-                    rhs_ty: self
-                        .lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
+                    lhs_ty: self.lower_ty(
+                        lhs_ty,
+                        &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type),
+                    ),
+                    rhs_ty: self.lower_ty(
+                        rhs_ty,
+                        &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type),
+                    ),
                     span: self.lower_span(span),
                 })
             }
index 3a94c7a91b23f7adf1c60e43ffd678decd950be6..e7bbf7dbdec295d2084e5d4f5845a279fa27414b 100644 (file)
@@ -660,6 +660,7 @@ fn hash_owner(
     /// actually used in the HIR, as that would trigger an assertion in the
     /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
     /// properly. Calling the method twice with the same `NodeId` is fine though.
+    #[instrument(level = "debug", skip(self), ret)]
     fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
         assert_ne!(ast_node_id, DUMMY_NODE_ID);
 
@@ -693,6 +694,7 @@ fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
     }
 
     /// Generate a new `HirId` without a backing `NodeId`.
+    #[instrument(level = "debug", skip(self), ret)]
     fn next_id(&mut self) -> hir::HirId {
         let owner = self.current_hir_id_owner;
         let local_id = self.item_local_id_counter;
@@ -953,7 +955,7 @@ fn lower_mac_args(&self, args: &MacArgs) -> MacArgs {
     fn lower_assoc_ty_constraint(
         &mut self,
         constraint: &AssocConstraint,
-        itctx: ImplTraitContext,
+        itctx: &mut ImplTraitContext,
     ) -> hir::TypeBinding<'hir> {
         debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
         // lower generic arguments of identifier in constraint
@@ -976,6 +978,7 @@ fn lower_assoc_ty_constraint(
         } else {
             self.arena.alloc(hir::GenericArgs::none())
         };
+        let mut itctx_tait = ImplTraitContext::TypeAliasesOpaqueTy;
 
         let kind = match constraint.kind {
             AssocConstraintKind::Equality { ref term } => {
@@ -1014,7 +1017,7 @@ fn lower_assoc_ty_constraint(
                     //
                     // FIXME: this is only needed until `impl Trait` is allowed in type aliases.
                     ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => {
-                        (true, ImplTraitContext::TypeAliasesOpaqueTy)
+                        (true, &mut itctx_tait)
                     }
 
                     // We are in the parameter position, but not within a dyn type:
@@ -1096,7 +1099,7 @@ fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
     fn lower_generic_arg(
         &mut self,
         arg: &ast::GenericArg,
-        itctx: ImplTraitContext,
+        itctx: &mut ImplTraitContext,
     ) -> hir::GenericArg<'hir> {
         match arg {
             ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
@@ -1158,7 +1161,7 @@ fn lower_generic_arg(
     }
 
     #[instrument(level = "debug", skip(self))]
-    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
+    fn lower_ty(&mut self, t: &Ty, itctx: &mut ImplTraitContext) -> &'hir hir::Ty<'hir> {
         self.arena.alloc(self.lower_ty_direct(t, itctx))
     }
 
@@ -1168,7 +1171,7 @@ fn lower_path_ty(
         qself: &Option<QSelf>,
         path: &Path,
         param_mode: ParamMode,
-        itctx: ImplTraitContext,
+        itctx: &mut ImplTraitContext,
     ) -> hir::Ty<'hir> {
         // Check whether we should interpret this as a bare trait object.
         // This check mirrors the one in late resolution.  We only introduce this special case in
@@ -1210,7 +1213,7 @@ fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
         self.ty(span, hir::TyKind::Tup(tys))
     }
 
-    fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
+    fn lower_ty_direct(&mut self, t: &Ty, itctx: &mut ImplTraitContext) -> hir::Ty<'hir> {
         let kind = match t.kind {
             TyKind::Infer => hir::TyKind::Infer,
             TyKind::Err => hir::TyKind::Err,
@@ -1307,16 +1310,16 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir>
                 let span = t.span;
                 match itctx {
                     ImplTraitContext::ReturnPositionOpaqueTy { origin } => {
-                        self.lower_opaque_impl_trait(span, origin, def_node_id, bounds, itctx)
+                        self.lower_opaque_impl_trait(span, *origin, def_node_id, bounds, itctx)
                     }
                     ImplTraitContext::TypeAliasesOpaqueTy => {
-                        let nested_itctx = ImplTraitContext::TypeAliasesOpaqueTy;
+                        let mut nested_itctx = ImplTraitContext::TypeAliasesOpaqueTy;
                         self.lower_opaque_impl_trait(
                             span,
                             hir::OpaqueTyOrigin::TyAlias,
                             def_node_id,
                             bounds,
-                            nested_itctx,
+                            &mut nested_itctx,
                         )
                     }
                     ImplTraitContext::Universal => {
@@ -1381,14 +1384,14 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir>
     /// added explicitly in the HIR). But this includes all the lifetimes, and we only want to
     /// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters
     /// for the lifetimes that get captured (`'x`, in our example above) and reference those.
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self), ret)]
     fn lower_opaque_impl_trait(
         &mut self,
         span: Span,
         origin: hir::OpaqueTyOrigin,
         opaque_ty_node_id: NodeId,
         bounds: &GenericBounds,
-        itctx: ImplTraitContext,
+        itctx: &mut ImplTraitContext,
     ) -> hir::TyKind<'hir> {
         // Make sure we know that some funky desugaring has been going on here.
         // This is a first: there is code in other places like for loop
@@ -1561,8 +1564,7 @@ fn create_lifetime_defs(
 
                 LifetimeRes::Fresh { param, binder: _ } => {
                     debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);
-                    let old_def_id = self.local_def_id(param);
-                    if remapping.get(&old_def_id).is_none() {
+                    if let Some(old_def_id) = self.opt_local_def_id(param) && remapping.get(&old_def_id).is_none() {
                         let node_id = self.next_node_id();
 
                         let new_def_id = self.create_def(
@@ -1636,11 +1638,11 @@ fn lower_fn_decl(
         }
         let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
             if fn_node_id.is_some() {
-                self.lower_ty_direct(&param.ty, ImplTraitContext::Universal)
+                self.lower_ty_direct(&param.ty, &mut ImplTraitContext::Universal)
             } else {
                 self.lower_ty_direct(
                     &param.ty,
-                    ImplTraitContext::Disallowed(match kind {
+                    &mut ImplTraitContext::Disallowed(match kind {
                         FnDeclKind::Fn | FnDeclKind::Inherent => {
                             unreachable!("fn should allow in-band lifetimes")
                         }
@@ -1663,7 +1665,7 @@ fn lower_fn_decl(
         } else {
             match decl.output {
                 FnRetTy::Ty(ref ty) => {
-                    let context = match fn_node_id {
+                    let mut context = match fn_node_id {
                         Some(fn_node_id) if kind.impl_trait_return_allowed() => {
                             let fn_def_id = self.local_def_id(fn_node_id);
                             ImplTraitContext::ReturnPositionOpaqueTy {
@@ -1681,7 +1683,7 @@ fn lower_fn_decl(
                             FnDeclKind::Impl => ImplTraitPosition::ImplReturn,
                         }),
                     };
-                    hir::FnRetTy::Return(self.lower_ty(ty, context))
+                    hir::FnRetTy::Return(self.lower_ty(ty, &mut context))
                 }
                 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
             }
@@ -1960,10 +1962,10 @@ fn lower_async_fn_output_type_to_future_bound(
                 // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
                 // `impl Future` opaque type that `async fn` implicitly
                 // generates.
-                let context = ImplTraitContext::ReturnPositionOpaqueTy {
+                let mut context = ImplTraitContext::ReturnPositionOpaqueTy {
                     origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
                 };
-                self.lower_ty(ty, context)
+                self.lower_ty(ty, &mut context)
             }
             FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
         };
@@ -1989,7 +1991,7 @@ fn lower_async_fn_output_type_to_future_bound(
     fn lower_param_bound(
         &mut self,
         tpb: &GenericBound,
-        itctx: ImplTraitContext,
+        itctx: &mut ImplTraitContext,
     ) -> hir::GenericBound<'hir> {
         match tpb {
             GenericBound::Trait(p, modifier) => hir::GenericBound::Trait(
@@ -2101,7 +2103,7 @@ fn lower_generic_param_kind(
             GenericParamKind::Type { ref default, .. } => {
                 let kind = hir::GenericParamKind::Type {
                     default: default.as_ref().map(|x| {
-                        self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
+                        self.lower_ty(x, &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type))
                     }),
                     synthetic: false,
                 };
@@ -2109,7 +2111,8 @@ fn lower_generic_param_kind(
                 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
             }
             GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
-                let ty = self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+                let ty =
+                    self.lower_ty(&ty, &mut ImplTraitContext::Disallowed(ImplTraitPosition::Type));
                 let default = default.as_ref().map(|def| self.lower_anon_const(def));
                 (
                     hir::ParamName::Plain(self.lower_ident(param.ident)),
@@ -2119,7 +2122,11 @@ fn lower_generic_param_kind(
         }
     }
 
-    fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext) -> hir::TraitRef<'hir> {
+    fn lower_trait_ref(
+        &mut self,
+        p: &TraitRef,
+        itctx: &mut ImplTraitContext,
+    ) -> hir::TraitRef<'hir> {
         let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
             hir::QPath::Resolved(None, path) => path,
             qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
@@ -2131,7 +2138,7 @@ fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext) -> hir::Tra
     fn lower_poly_trait_ref(
         &mut self,
         p: &PolyTraitRef,
-        itctx: ImplTraitContext,
+        itctx: &mut ImplTraitContext,
     ) -> hir::PolyTraitRef<'hir> {
         let bound_generic_params =
             self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
@@ -2139,26 +2146,29 @@ fn lower_poly_trait_ref(
         hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
     }
 
-    fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
+    fn lower_mt(&mut self, mt: &MutTy, itctx: &mut ImplTraitContext) -> hir::MutTy<'hir> {
         hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
     }
 
+    #[instrument(level = "debug", skip(self), ret)]
     fn lower_param_bounds(
         &mut self,
         bounds: &[GenericBound],
-        itctx: ImplTraitContext,
+        itctx: &mut ImplTraitContext,
     ) -> hir::GenericBounds<'hir> {
         self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
     }
 
-    fn lower_param_bounds_mut<'s>(
+    fn lower_param_bounds_mut<'s, 'b>(
         &'s mut self,
         bounds: &'s [GenericBound],
-        itctx: ImplTraitContext,
-    ) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> {
+        itctx: &'b mut ImplTraitContext,
+    ) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> + Captures<'b>
+    {
         bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
     }
 
+    #[instrument(level = "debug", skip(self), ret)]
     fn lower_generic_and_bounds(
         &mut self,
         node_id: NodeId,
@@ -2184,7 +2194,7 @@ fn lower_generic_and_bounds(
             node_id,
             &GenericParamKind::Type { default: None },
             bounds,
-            ImplTraitContext::Universal,
+            &mut ImplTraitContext::Universal,
             hir::PredicateOrigin::ImplTrait,
         );
 
index a1eee1be7984f63dfd174cc414d26c42820f50a5..69e6c2c8ad0bc2ea9d5ad69d168fdc0eb1a71c25 100644 (file)
@@ -37,7 +37,7 @@ pub(crate) fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> {
                             qself,
                             path,
                             ParamMode::Optional,
-                            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         );
                         let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
                         break hir::PatKind::TupleStruct(qpath, pats, ddpos);
@@ -53,7 +53,7 @@ pub(crate) fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> {
                             qself,
                             path,
                             ParamMode::Optional,
-                            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         );
                         break hir::PatKind::Path(qpath);
                     }
@@ -63,7 +63,7 @@ pub(crate) fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> {
                             qself,
                             path,
                             ParamMode::Optional,
-                            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         );
 
                         let fs = self.arena.alloc_from_iter(fields.iter().map(|f| {
index de1467b1b07d6bee2031d423ca2b7d847e585ec5..a3d864023a9ff6319eb6991f427870a566ca25a6 100644 (file)
@@ -22,7 +22,7 @@ pub(crate) fn lower_qpath(
         qself: &Option<QSelf>,
         p: &Path,
         param_mode: ParamMode,
-        itctx: ImplTraitContext,
+        itctx: &mut ImplTraitContext,
     ) -> hir::QPath<'hir> {
         let qself_position = qself.as_ref().map(|q| q.position);
         let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
@@ -156,7 +156,7 @@ pub(crate) fn lower_path_extra(
                     segment,
                     param_mode,
                     ParenthesizedGenericArgs::Err,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                 )
             })),
             span: self.lower_span(p.span),
@@ -180,7 +180,7 @@ pub(crate) fn lower_path_segment(
         segment: &PathSegment,
         param_mode: ParamMode,
         parenthesized_generic_args: ParenthesizedGenericArgs,
-        itctx: ImplTraitContext,
+        itctx: &mut ImplTraitContext,
     ) -> hir::PathSegment<'hir> {
         debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,);
         let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args {
@@ -316,7 +316,7 @@ pub(crate) fn lower_angle_bracketed_parameter_data(
         &mut self,
         data: &AngleBracketedArgs,
         param_mode: ParamMode,
-        itctx: ImplTraitContext,
+        itctx: &mut ImplTraitContext,
     ) -> (GenericArgsCtor<'hir>, bool) {
         let has_non_lt_args = data.args.iter().any(|arg| match arg {
             AngleBracketedArg::Arg(ast::GenericArg::Lifetime(_))
@@ -350,12 +350,14 @@ fn lower_parenthesized_parameter_data(
         // we generally don't permit such things (see #51008).
         let ParenthesizedArgs { span, inputs, inputs_span, output } = data;
         let inputs = self.arena.alloc_from_iter(inputs.iter().map(|ty| {
-            self.lower_ty_direct(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
+            self.lower_ty_direct(
+                ty,
+                &mut ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam),
+            )
         }));
         let output_ty = match output {
-            FnRetTy::Ty(ty) => {
-                self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
-            }
+            FnRetTy::Ty(ty) => self
+                .lower_ty(&ty, &mut ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)),
             FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])),
         };
         let args = smallvec![GenericArg::Type(self.arena.alloc(self.ty_tup(*inputs_span, inputs)))];
index e1404ab15efa37add14cfed8823837b20c016c7a..bb972a18acbd8d5c4bdae5faa65a9d614b17e991 100644 (file)
@@ -1045,18 +1045,16 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
                                 &name,
                             ),
                         });
-                    } else {
-                        if matches!(
-                            meta_item.name_or_empty(),
-                            sym::C | sym::simd | sym::transparent
-                        ) || int_type_of_word(meta_item.name_or_empty()).is_some()
-                        {
-                            recognised = true;
-                            sess.emit_err(session_diagnostics::InvalidReprHintNoValue {
-                                span: meta_item.span,
-                                name: meta_item.name_or_empty().to_ident_string(),
-                            });
-                        }
+                    } else if matches!(
+                        meta_item.name_or_empty(),
+                        sym::C | sym::simd | sym::transparent
+                    ) || int_type_of_word(meta_item.name_or_empty()).is_some()
+                    {
+                        recognised = true;
+                        sess.emit_err(session_diagnostics::InvalidReprHintNoValue {
+                            span: meta_item.span,
+                            name: meta_item.name_or_empty().to_ident_string(),
+                        });
                     }
                 } else if let MetaItemKind::List(_) = meta_item.kind {
                     if meta_item.has_name(sym::align) {
index 816288eb50b293e35518b7af57063dc19bc688d9..9f7a4d49989ab6b3aeddac712161c6168a120de3 100644 (file)
@@ -391,7 +391,7 @@ fn statement_effect(
             | mir::StatementKind::Retag { .. }
             | mir::StatementKind::AscribeUserType(..)
             | mir::StatementKind::Coverage(..)
-            | mir::StatementKind::CopyNonOverlapping(..)
+            | mir::StatementKind::Intrinsic(..)
             | mir::StatementKind::Nop => {}
         }
     }
index ec521b1cf0afdfa0fe7786725a174a679b0113b9..3157f861d93bec9fc047fd81d750d218d2248f7b 100644 (file)
@@ -1,6 +1,6 @@
 use rustc_data_structures::graph::dominators::Dominators;
 use rustc_middle::mir::visit::Visitor;
-use rustc_middle::mir::{BasicBlock, Body, Location, Place, Rvalue};
+use rustc_middle::mir::{self, BasicBlock, Body, Location, NonDivergingIntrinsic, Place, Rvalue};
 use rustc_middle::mir::{BorrowKind, Mutability, Operand};
 use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind};
 use rustc_middle::mir::{Statement, StatementKind};
@@ -63,23 +63,24 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
             StatementKind::FakeRead(box (_, _)) => {
                 // Only relevant for initialized/liveness/safety checks.
             }
-            StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
+            StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => {
+                self.consume_operand(location, op);
+            }
+            StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
                 ref src,
                 ref dst,
                 ref count,
-            }) => {
+            })) => {
                 self.consume_operand(location, src);
                 self.consume_operand(location, dst);
                 self.consume_operand(location, count);
             }
-            StatementKind::Nop
+            // Only relevant for mir typeck
+            StatementKind::AscribeUserType(..)
+            // Doesn't have any language semantics
             | StatementKind::Coverage(..)
-            | StatementKind::AscribeUserType(..)
-            | StatementKind::Retag { .. }
-            | StatementKind::StorageLive(..) => {
-                // `Nop`, `AscribeUserType`, `Retag`, and `StorageLive` are irrelevant
-                // to borrow check.
-            }
+            // Does not actually affect borrowck
+            | StatementKind::StorageLive(..) => {}
             StatementKind::StorageDead(local) => {
                 self.access_place(
                     location,
@@ -88,7 +89,10 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
                     LocalMutationIsAllowed::Yes,
                 );
             }
-            StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
+            StatementKind::Nop
+            | StatementKind::Retag { .. }
+            | StatementKind::Deinit(..)
+            | StatementKind::SetDiscriminant { .. } => {
                 bug!("Statement not allowed in this MIR phase")
             }
         }
index 20c22575bd1fadcd27e20412204801a0f34184d0..ec652f852179a43c6aff5401317ea097894dfe39 100644 (file)
@@ -26,8 +26,8 @@
 use rustc_index::vec::IndexVec;
 use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
 use rustc_middle::mir::{
-    traversal, Body, ClearCrossCrate, Local, Location, Mutability, Operand, Place, PlaceElem,
-    PlaceRef, VarDebugInfoContents,
+    traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand,
+    Place, PlaceElem, PlaceRef, VarDebugInfoContents,
 };
 use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
 use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
@@ -591,22 +591,19 @@ fn visit_statement_before_primary_effect(
                     flow_state,
                 );
             }
-            StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
-                ..
-            }) => {
-                span_bug!(
+            StatementKind::Intrinsic(box ref kind) => match kind {
+                NonDivergingIntrinsic::Assume(op) => self.consume_operand(location, (op, span), flow_state),
+                NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
                     span,
                     "Unexpected CopyNonOverlapping, should only appear after lower_intrinsics",
                 )
             }
-            StatementKind::Nop
+            // Only relevant for mir typeck
+            StatementKind::AscribeUserType(..)
+            // Doesn't have any language semantics
             | StatementKind::Coverage(..)
-            | StatementKind::AscribeUserType(..)
-            | StatementKind::Retag { .. }
-            | StatementKind::StorageLive(..) => {
-                // `Nop`, `AscribeUserType`, `Retag`, and `StorageLive` are irrelevant
-                // to borrow check.
-            }
+            // Does not actually affect borrowck
+            | StatementKind::StorageLive(..) => {}
             StatementKind::StorageDead(local) => {
                 self.access_place(
                     location,
@@ -616,7 +613,10 @@ fn visit_statement_before_primary_effect(
                     flow_state,
                 );
             }
-            StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
+            StatementKind::Nop
+            | StatementKind::Retag { .. }
+            | StatementKind::Deinit(..)
+            | StatementKind::SetDiscriminant { .. } => {
                 bug!("Statement not allowed in this MIR phase")
             }
         }
index a620c987052ba0b987175df02e70fc9e5d3b9cd6..fc0e95f30c98fa8202508b35bf53493a57e3624c 100644 (file)
@@ -1302,12 +1302,13 @@ fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Lo
                     );
                 }
             }
-            StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
-                ..
-            }) => span_bug!(
-                stmt.source_info.span,
-                "Unexpected StatementKind::CopyNonOverlapping, should only appear after lowering_intrinsics",
-            ),
+            StatementKind::Intrinsic(box ref kind) => match kind {
+                NonDivergingIntrinsic::Assume(op) => self.check_operand(op, location),
+                NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
+                    stmt.source_info.span,
+                    "Unexpected NonDivergingIntrinsic::CopyNonOverlapping, should only appear after lowering_intrinsics",
+                ),
+            },
             StatementKind::FakeRead(..)
             | StatementKind::StorageLive(..)
             | StatementKind::StorageDead(..)
index c412e451a033e9619f2630e5362b5e0c12b4e08c..2aa11ac2eeaa653d1c0b2243afbf31e62effc467 100644 (file)
@@ -794,20 +794,31 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
         | StatementKind::AscribeUserType(..) => {}
 
         StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"),
-        StatementKind::CopyNonOverlapping(inner) => {
-            let dst = codegen_operand(fx, &inner.dst);
-            let pointee = dst
-                .layout()
-                .pointee_info_at(fx, rustc_target::abi::Size::ZERO)
-                .expect("Expected pointer");
-            let dst = dst.load_scalar(fx);
-            let src = codegen_operand(fx, &inner.src).load_scalar(fx);
-            let count = codegen_operand(fx, &inner.count).load_scalar(fx);
-            let elem_size: u64 = pointee.size.bytes();
-            let bytes =
-                if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) } else { count };
-            fx.bcx.call_memcpy(fx.target_config, dst, src, bytes);
-        }
+        StatementKind::Intrinsic(ref intrinsic) => match &**intrinsic {
+            // We ignore `assume` intrinsics, they are only useful for optimizations
+            NonDivergingIntrinsic::Assume(_) => {}
+            NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
+                src,
+                dst,
+                count,
+            }) => {
+                let dst = codegen_operand(fx, dst);
+                let pointee = dst
+                    .layout()
+                    .pointee_info_at(fx, rustc_target::abi::Size::ZERO)
+                    .expect("Expected pointer");
+                let dst = dst.load_scalar(fx);
+                let src = codegen_operand(fx, src).load_scalar(fx);
+                let count = codegen_operand(fx, count).load_scalar(fx);
+                let elem_size: u64 = pointee.size.bytes();
+                let bytes = if elem_size != 1 {
+                    fx.bcx.ins().imul_imm(count, elem_size as i64)
+                } else {
+                    count
+                };
+                fx.bcx.call_memcpy(fx.target_config, dst, src, bytes);
+            }
+        },
     }
 }
 
index 9224f499339cbd8e14cf6d5d75e8adaf608362a0..0305341da784e28dba54a1bdbb2892c1a937a994 100644 (file)
@@ -536,9 +536,11 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
                         {
                             return None;
                         }
-                        StatementKind::CopyNonOverlapping(_) => {
-                            return None;
-                        } // conservative handling
+                        StatementKind::Intrinsic(ref intrinsic) => match **intrinsic {
+                            NonDivergingIntrinsic::CopyNonOverlapping(..) => return None,
+                            NonDivergingIntrinsic::Assume(..) => {}
+                        },
+                        // conservative handling
                         StatementKind::Assign(_)
                         | StatementKind::FakeRead(_)
                         | StatementKind::SetDiscriminant { .. }
index 39e9e784a478b12a68268e2fa6c0b6209f864365..0cd9332a58befab6a824ea3873f1f053300c20fa 100644 (file)
@@ -357,9 +357,6 @@ fn codegen_regular_intrinsic_call<'tcx>(
     let usize_layout = fx.layout_of(fx.tcx.types.usize);
 
     match intrinsic {
-        sym::assume => {
-            intrinsic_args!(fx, args => (_a); intrinsic);
-        }
         sym::likely | sym::unlikely => {
             intrinsic_args!(fx, args => (a); intrinsic);
 
index ccb6cbbc2c8a74bb98ab5a977c8698dea5b7c769..aa1c271c31cb46d7695995756b2d09e69311bab4 100644 (file)
@@ -158,10 +158,6 @@ fn const_to_opt_u128(&self, _v: RValue<'gcc>, _sign_ext: bool) -> Option<u128> {
         None
     }
 
-    fn zst_to_backend(&self, _ty: Type<'gcc>) -> RValue<'gcc> {
-        self.const_undef(self.type_ix(0))
-    }
-
     fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, ty: Type<'gcc>) -> RValue<'gcc> {
         let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
         match cv {
index 13e437cfbf7fb1b52d06589eb20c068ad140a131..488ea72c3b77991a7146f71ea24aac66cc981653 100644 (file)
@@ -226,10 +226,6 @@ fn const_to_opt_u128(&self, v: &'ll Value, sign_ext: bool) -> Option<u128> {
         })
     }
 
-    fn zst_to_backend(&self, _llty: &'ll Type) -> &'ll Value {
-        self.const_undef(self.type_ix(0))
-    }
-
     fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: &'ll Type) -> &'ll Value {
         let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
         match cv {
index e9171823c242c7c1be928306c1b50d76025066a4..a3fed88cc4baaf0e6005a5c619351837daacc4f8 100644 (file)
@@ -1,6 +1,6 @@
 use rustc_arena::TypedArena;
 use rustc_ast::CRATE_NODE_ID;
-use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::temp_dir::MaybeTempDir;
 use rustc_errors::{ErrorGuaranteed, Handler};
@@ -1714,6 +1714,13 @@ fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor
 /// that are necessary for the linking. They are only present in symbol table but not actually
 /// used in any sections, so the linker will therefore pick relevant rlibs for linking, but
 /// unused `#[no_mangle]` or `#[used]` can still be discard by GC sections.
+///
+/// There's a few internal crates in the standard library (aka libcore and
+/// libstd) which actually have a circular dependence upon one another. This
+/// currently arises through "weak lang items" where libcore requires things
+/// like `rust_begin_unwind` but libstd ends up defining it. To get this
+/// circular dependence to work correctly we declare some of these things
+/// in this synthetic object.
 fn add_linked_symbol_object(
     cmd: &mut dyn Linker,
     sess: &Session,
@@ -2333,65 +2340,10 @@ fn add_upstream_rust_crates<'a>(
     // crates.
     let deps = &codegen_results.crate_info.used_crates;
 
-    // There's a few internal crates in the standard library (aka libcore and
-    // libstd) which actually have a circular dependence upon one another. This
-    // currently arises through "weak lang items" where libcore requires things
-    // like `rust_begin_unwind` but libstd ends up defining it. To get this
-    // circular dependence to work correctly in all situations we'll need to be
-    // sure to correctly apply the `--start-group` and `--end-group` options to
-    // GNU linkers, otherwise if we don't use any other symbol from the standard
-    // library it'll get discarded and the whole application won't link.
-    //
-    // In this loop we're calculating the `group_end`, after which crate to
-    // pass `--end-group` and `group_start`, before which crate to pass
-    // `--start-group`. We currently do this by passing `--end-group` after
-    // the first crate (when iterating backwards) that requires a lang item
-    // defined somewhere else. Once that's set then when we've defined all the
-    // necessary lang items we'll pass `--start-group`.
-    //
-    // Note that this isn't amazing logic for now but it should do the trick
-    // for the current implementation of the standard library.
-    let mut group_end = None;
-    let mut group_start = None;
-    // Crates available for linking thus far.
-    let mut available = FxHashSet::default();
-    // Crates required to satisfy dependencies discovered so far.
-    let mut required = FxHashSet::default();
-
-    let info = &codegen_results.crate_info;
-    for &cnum in deps.iter().rev() {
-        if let Some(missing) = info.missing_lang_items.get(&cnum) {
-            let missing_crates = missing.iter().map(|i| info.lang_item_to_crate.get(i).copied());
-            required.extend(missing_crates);
-        }
-
-        required.insert(Some(cnum));
-        available.insert(Some(cnum));
-
-        if required.len() > available.len() && group_end.is_none() {
-            group_end = Some(cnum);
-        }
-        if required.len() == available.len() && group_end.is_some() {
-            group_start = Some(cnum);
-            break;
-        }
-    }
-
-    // If we didn't end up filling in all lang items from upstream crates then
-    // we'll be filling it in with our crate. This probably means we're the
-    // standard library itself, so skip this for now.
-    if group_end.is_some() && group_start.is_none() {
-        group_end = None;
-    }
-
     let mut compiler_builtins = None;
     let search_path = OnceCell::new();
 
     for &cnum in deps.iter() {
-        if group_start == Some(cnum) {
-            cmd.group_start();
-        }
-
         // We may not pass all crates through to the linker. Some crates may
         // appear statically in an existing dylib, meaning we'll pick up all the
         // symbols from the dylib.
@@ -2451,6 +2403,14 @@ fn add_upstream_rust_crates<'a>(
                                 bundle: Some(false),
                                 whole_archive: Some(false) | None,
                             } => {
+                                // HACK/FIXME: Fixup a circular dependency between libgcc and libc
+                                // with glibc. This logic should be moved to the libc crate.
+                                if sess.target.os == "linux"
+                                    && sess.target.env == "gnu"
+                                    && name == "c"
+                                {
+                                    cmd.link_staticlib("gcc", false);
+                                }
                                 cmd.link_staticlib(name, lib.verbatim.unwrap_or(false));
                             }
                             NativeLibKind::LinkArg => {
@@ -2470,10 +2430,6 @@ fn add_upstream_rust_crates<'a>(
             }
             Linkage::Dynamic => add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0),
         }
-
-        if group_end == Some(cnum) {
-            cmd.group_end();
-        }
     }
 
     // compiler-builtins are always placed last to ensure that they're
index 8c6f526b054bc5ec213eddf5fac9d8505029d9d5..949a356fce1fcd2f98c077a925dcf88d776ac0de 100644 (file)
@@ -183,8 +183,6 @@ pub trait Linker {
     fn no_default_libraries(&mut self);
     fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]);
     fn subsystem(&mut self, subsystem: &str);
-    fn group_start(&mut self);
-    fn group_end(&mut self);
     fn linker_plugin_lto(&mut self);
     fn add_eh_frame_header(&mut self) {}
     fn add_no_exec(&mut self) {}
@@ -730,18 +728,6 @@ fn reset_per_library_state(&mut self) {
         self.hint_dynamic(); // Reset to default before returning the composed command line.
     }
 
-    fn group_start(&mut self) {
-        if self.takes_hints() {
-            self.linker_arg("--start-group");
-        }
-    }
-
-    fn group_end(&mut self) {
-        if self.takes_hints() {
-            self.linker_arg("--end-group");
-        }
-    }
-
     fn linker_plugin_lto(&mut self) {
         match self.sess.opts.cg.linker_plugin_lto {
             LinkerPluginLto::Disabled => {
@@ -1019,10 +1005,6 @@ fn subsystem(&mut self, subsystem: &str) {
         }
     }
 
-    // MSVC doesn't need group indicators
-    fn group_start(&mut self) {}
-    fn group_end(&mut self) {}
-
     fn linker_plugin_lto(&mut self) {
         // Do nothing
     }
@@ -1165,10 +1147,6 @@ fn subsystem(&mut self, _subsystem: &str) {
         // noop
     }
 
-    // Appears not necessary on Emscripten
-    fn group_start(&mut self) {}
-    fn group_end(&mut self) {}
-
     fn linker_plugin_lto(&mut self) {
         // Do nothing
     }
@@ -1344,10 +1322,6 @@ fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[
 
     fn subsystem(&mut self, _subsystem: &str) {}
 
-    // Not needed for now with LLD
-    fn group_start(&mut self) {}
-    fn group_end(&mut self) {}
-
     fn linker_plugin_lto(&mut self) {
         // Do nothing for now
     }
@@ -1476,14 +1450,6 @@ fn reset_per_library_state(&mut self) {
         self.hint_static(); // Reset to default before returning the composed command line.
     }
 
-    fn group_start(&mut self) {
-        self.cmd.arg("--start-group");
-    }
-
-    fn group_end(&mut self) {
-        self.cmd.arg("--end-group");
-    }
-
     fn linker_plugin_lto(&mut self) {}
 
     fn control_flow_guard(&mut self) {}
@@ -1664,10 +1630,6 @@ fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, _symbols: &
 
     fn subsystem(&mut self, _subsystem: &str) {}
 
-    fn group_start(&mut self) {}
-
-    fn group_end(&mut self) {}
-
     fn linker_plugin_lto(&mut self) {}
 }
 
@@ -1777,9 +1739,5 @@ fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[S
 
     fn subsystem(&mut self, _subsystem: &str) {}
 
-    fn group_start(&mut self) {}
-
-    fn group_end(&mut self) {}
-
     fn linker_plugin_lto(&mut self) {}
 }
index 6e482062383d451884f06dd08dbe887dd2b73274..5f140d709d838364a3470a74aa9b79f717e56ff5 100644 (file)
@@ -12,7 +12,7 @@
 use crate::{CachedModuleCodegen, CompiledModule, CrateInfo, MemFlags, ModuleCodegen, ModuleKind};
 
 use rustc_attr as attr;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
 
 use rustc_data_structures::sync::par_iter;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::lang_items::LangItem;
+use rustc_hir::weak_lang_items::WEAK_ITEMS_SYMBOLS;
 use rustc_index::vec::Idx;
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::middle::exported_symbols;
+use rustc_middle::middle::exported_symbols::SymbolExportKind;
 use rustc_middle::middle::lang_items;
 use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
@@ -34,6 +36,7 @@
 use rustc_session::config::{self, CrateType, EntryFnType, OutputType};
 use rustc_session::Session;
 use rustc_span::symbol::sym;
+use rustc_span::Symbol;
 use rustc_span::{DebuggerVisualizerFile, DebuggerVisualizerType};
 use rustc_target::abi::{Align, VariantIdx};
 
@@ -815,21 +818,16 @@ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
             crate_name: Default::default(),
             used_crates,
             used_crate_source: Default::default(),
-            lang_item_to_crate: Default::default(),
-            missing_lang_items: Default::default(),
             dependency_formats: tcx.dependency_formats(()).clone(),
             windows_subsystem,
             natvis_debugger_visualizers: Default::default(),
         };
-        let lang_items = tcx.lang_items();
-
         let crates = tcx.crates(());
 
         let n_crates = crates.len();
         info.native_libraries.reserve(n_crates);
         info.crate_name.reserve(n_crates);
         info.used_crate_source.reserve(n_crates);
-        info.missing_lang_items.reserve(n_crates);
 
         for &cnum in crates.iter() {
             info.native_libraries
@@ -847,17 +845,37 @@ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
             if tcx.is_no_builtins(cnum) {
                 info.is_no_builtins.insert(cnum);
             }
-            let missing = tcx.missing_lang_items(cnum);
-            for &item in missing.iter() {
-                if let Ok(id) = lang_items.require(item) {
-                    info.lang_item_to_crate.insert(item, id.krate);
-                }
-            }
+        }
 
-            // No need to look for lang items that don't actually need to exist.
-            let missing =
-                missing.iter().cloned().filter(|&l| lang_items::required(tcx, l)).collect();
-            info.missing_lang_items.insert(cnum, missing);
+        // Handle circular dependencies in the standard library.
+        // See comment before `add_linked_symbol_object` function for the details.
+        // With msvc-like linkers it's both unnecessary (they support circular dependencies),
+        // and causes linking issues (when weak lang item symbols are "privatized" by LTO).
+        let target = &tcx.sess.target;
+        if !target.is_like_msvc {
+            let missing_weak_lang_items: FxHashSet<&Symbol> = info
+                .used_crates
+                .iter()
+                .flat_map(|cnum| {
+                    tcx.missing_lang_items(*cnum)
+                        .iter()
+                        .filter(|l| lang_items::required(tcx, **l))
+                        .filter_map(|item| WEAK_ITEMS_SYMBOLS.get(item))
+                })
+                .collect();
+            let prefix = if target.is_like_windows && target.arch == "x86" { "_" } else { "" };
+            info.linked_symbols
+                .iter_mut()
+                .filter(|(crate_type, _)| {
+                    !matches!(crate_type, CrateType::Rlib | CrateType::Staticlib)
+                })
+                .for_each(|(_, linked_symbols)| {
+                    linked_symbols.extend(
+                        missing_weak_lang_items
+                            .iter()
+                            .map(|item| (format!("{prefix}{item}"), SymbolExportKind::Text)),
+                    )
+                });
         }
 
         let embed_visualizers = tcx.sess.crate_types().iter().any(|&crate_type| match crate_type {
@@ -878,7 +896,7 @@ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
             }
         });
 
-        if tcx.sess.target.is_like_msvc && embed_visualizers {
+        if target.is_like_msvc && embed_visualizers {
             info.natvis_debugger_visualizers =
                 collect_debugger_visualizers_transitive(tcx, DebuggerVisualizerType::Natvis);
         }
index 0faf51b062b4ce81f684c936da6a9ab68d3a94ef..52da7abcac54e128f7c02bf92814249f36569736 100644 (file)
@@ -25,7 +25,6 @@
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::Lrc;
 use rustc_hir::def_id::CrateNum;
-use rustc_hir::LangItem;
 use rustc_middle::dep_graph::WorkProduct;
 use rustc_middle::middle::dependency_format::Dependencies;
 use rustc_middle::middle::exported_symbols::SymbolExportKind;
@@ -152,8 +151,6 @@ pub struct CrateInfo {
     pub used_libraries: Vec<NativeLib>,
     pub used_crate_source: FxHashMap<CrateNum, Lrc<CrateSource>>,
     pub used_crates: Vec<CrateNum>,
-    pub lang_item_to_crate: FxHashMap<LangItem, CrateNum>,
-    pub missing_lang_items: FxHashMap<CrateNum, Vec<LangItem>>,
     pub dependency_formats: Lrc<Dependencies>,
     pub windows_subsystem: Option<String>,
     pub natvis_debugger_visualizers: BTreeSet<DebuggerVisualizerFile>,
index 16aad07194da8afa048c5fcf94a02a6caa5d134b..6393dd9d634fc01f6acb4ea132e399d3b3df7f40 100644 (file)
@@ -77,10 +77,6 @@ pub fn codegen_intrinsic_call(
         let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout);
 
         let llval = match name {
-            sym::assume => {
-                bx.assume(args[0].immediate());
-                return;
-            }
             sym::abort => {
                 bx.abort();
                 return;
index c612634fce2a6609cd5fc9368dca9aad53163561..37b1e036247bfcd8c4c2863c87bcd6385406816d 100644 (file)
@@ -72,10 +72,6 @@ pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
     ) -> Self {
         let layout = bx.layout_of(ty);
 
-        if layout.is_zst() {
-            return OperandRef::new_zst(bx, layout);
-        }
-
         let val = match val {
             ConstValue::Scalar(x) => {
                 let Abi::Scalar(scalar) = layout.abi else {
@@ -84,10 +80,7 @@ pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
                 let llval = bx.scalar_to_backend(x, scalar, bx.immediate_backend_type(layout));
                 OperandValue::Immediate(llval)
             }
-            ConstValue::ZeroSized => {
-                let llval = bx.zst_to_backend(bx.immediate_backend_type(layout));
-                OperandValue::Immediate(llval)
-            }
+            ConstValue::ZeroSized => return OperandRef::new_zst(bx, layout),
             ConstValue::Slice { data, start, end } => {
                 let Abi::ScalarPair(a_scalar, _) = layout.abi else {
                     bug!("from_const: invalid ScalarPair layout: {:#?}", layout);
index f452f29883f939a86d35bd16b92b81913eac60d1..1db0fb3a6f1b0381da9eb2a1ca06eb6e3689af75 100644 (file)
@@ -1,4 +1,5 @@
 use rustc_middle::mir;
+use rustc_middle::mir::NonDivergingIntrinsic;
 
 use super::FunctionCx;
 use super::LocalRef;
@@ -73,11 +74,14 @@ pub fn codegen_statement(&mut self, mut bx: Bx, statement: &mir::Statement<'tcx>
                 self.codegen_coverage(&mut bx, coverage.clone(), statement.source_info.scope);
                 bx
             }
-            mir::StatementKind::CopyNonOverlapping(box mir::CopyNonOverlapping {
-                ref src,
-                ref dst,
-                ref count,
-            }) => {
+            mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(ref op)) => {
+                let op_val = self.codegen_operand(&mut bx, op);
+                bx.assume(op_val.immediate());
+                bx
+            }
+            mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(
+                mir::CopyNonOverlapping { ref count, ref src, ref dst },
+            )) => {
                 let dst_val = self.codegen_operand(&mut bx, dst);
                 let src_val = self.codegen_operand(&mut bx, src);
                 let count = self.codegen_operand(&mut bx, count).immediate();
index 8a91d4735ba0d5db6e46e9f3499e9be4b214d29f..fdc7a30e841ed1b7e4d64ff077a3fd6e1b26baf4 100644 (file)
@@ -29,7 +29,6 @@ pub trait ConstMethods<'tcx>: BackendTypes {
     fn const_data_from_alloc(&self, alloc: ConstAllocation<'tcx>) -> Self::Value;
 
     fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: Self::Type) -> Self::Value;
-    fn zst_to_backend(&self, llty: Self::Type) -> Self::Value;
     fn from_const_alloc(
         &self,
         layout: TyAndLayout<'tcx>,
index adda9639990d0e38934100bce1856cb15c67c518..2f415a8c9c7090152235f670fa7448f014b548ac 100644 (file)
@@ -8,7 +8,7 @@
 use rustc_middle::mir::{
     self,
     interpret::{ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar},
-    BinOp,
+    BinOp, NonDivergingIntrinsic,
 };
 use rustc_middle::ty;
 use rustc_middle::ty::layout::LayoutOf as _;
@@ -506,12 +506,6 @@ pub fn emulate_intrinsic(
                 // These just return their argument
                 self.copy_op(&args[0], dest, /*allow_transmute*/ false)?;
             }
-            sym::assume => {
-                let cond = self.read_scalar(&args[0])?.to_bool()?;
-                if !cond {
-                    throw_ub_format!("`assume` intrinsic called with `false`");
-                }
-            }
             sym::raw_eq => {
                 let result = self.raw_eq_intrinsic(&args[0], &args[1])?;
                 self.write_scalar(result, dest)?;
@@ -536,6 +530,32 @@ pub fn emulate_intrinsic(
         Ok(true)
     }
 
+    pub(super) fn emulate_nondiverging_intrinsic(
+        &mut self,
+        intrinsic: &NonDivergingIntrinsic<'tcx>,
+    ) -> InterpResult<'tcx> {
+        match intrinsic {
+            NonDivergingIntrinsic::Assume(op) => {
+                let op = self.eval_operand(op, None)?;
+                let cond = self.read_scalar(&op)?.to_bool()?;
+                if !cond {
+                    throw_ub_format!("`assume` called with `false`");
+                }
+                Ok(())
+            }
+            NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
+                count,
+                src,
+                dst,
+            }) => {
+                let src = self.eval_operand(src, None)?;
+                let dst = self.eval_operand(dst, None)?;
+                let count = self.eval_operand(count, None)?;
+                self.copy_intrinsic(&src, &dst, &count, /* nonoverlapping */ true)
+            }
+        }
+    }
+
     pub fn exact_div(
         &mut self,
         a: &ImmTy<'tcx, M::Provenance>,
index 6b827149f505ea60f6c7c44e1d7fb39652eb67fa..c6e04cbfb6bf344200dcc916378ad8df4adcd454 100644 (file)
@@ -114,13 +114,7 @@ pub fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> InterpResult<'tcx> {
                 M::retag(self, *kind, &dest)?;
             }
 
-            // Call CopyNonOverlapping
-            CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { src, dst, count }) => {
-                let src = self.eval_operand(src, None)?;
-                let dst = self.eval_operand(dst, None)?;
-                let count = self.eval_operand(count, None)?;
-                self.copy_intrinsic(&src, &dst, &count, /* nonoverlapping */ true)?;
-            }
+            Intrinsic(box ref intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?,
 
             // Statements we do not track.
             AscribeUserType(..) => {}
index cbfdb47dd1a4072eb30b9c919873f69e38b69b32..3fa40dc305952ae2694937246c13e8360ff69716 100644 (file)
@@ -678,7 +678,7 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
             | StatementKind::Retag { .. }
             | StatementKind::AscribeUserType(..)
             | StatementKind::Coverage(..)
-            | StatementKind::CopyNonOverlapping(..)
+            | StatementKind::Intrinsic(..)
             | StatementKind::Nop => {}
         }
     }
index b798862583952eb5d1604a56750c14850ac8c6ab..783ab350faac3842d51627525c5f827d6945a00c 100644 (file)
@@ -7,9 +7,10 @@
 use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
 use rustc_middle::mir::visit::{PlaceContext, Visitor};
 use rustc_middle::mir::{
-    traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, CastKind, Local, Location,
-    MirPass, MirPhase, Operand, Place, PlaceElem, PlaceRef, ProjectionElem, RuntimePhase, Rvalue,
-    SourceScope, Statement, StatementKind, Terminator, TerminatorKind, UnOp, START_BLOCK,
+    traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping,
+    Local, Location, MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef,
+    ProjectionElem, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
+    TerminatorKind, UnOp, START_BLOCK,
 };
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::subst::Subst;
@@ -636,11 +637,18 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
                     );
                 }
             }
-            StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
-                ref src,
-                ref dst,
-                ref count,
-            }) => {
+            StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => {
+                let ty = op.ty(&self.body.local_decls, self.tcx);
+                if !ty.is_bool() {
+                    self.fail(
+                        location,
+                        format!("`assume` argument must be `bool`, but got: `{}`", ty),
+                    );
+                }
+            }
+            StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(
+                CopyNonOverlapping { src, dst, count },
+            )) => {
                 let src_ty = src.ty(&self.body.local_decls, self.tcx);
                 let op_src_ty = if let Some(src_deref) = src_ty.builtin_deref(true) {
                     src_deref.ty
index b6a85c0472e02e43f851927a8b66053128d487ef..da9c9c1216e9d7c574ae8e3d7beb0ea3b18a84ed 100644 (file)
@@ -18,6 +18,12 @@ macro_rules! weak_lang_items {
     map
 });
 
+pub static WEAK_ITEMS_SYMBOLS: LazyLock<FxIndexMap<LangItem, Symbol>> = LazyLock::new(|| {
+    let mut map = FxIndexMap::default();
+    $(map.insert(LangItem::$item, sym::$sym);)*
+    map
+});
+
 pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol>
 {
     lang_items::extract(attrs).and_then(|(name, _)| {
index d9252d426d82b8ed0aebc06353f08c6eb60f3c04..0196bd262179eac45c502a874f2b6d5f7df2cd4d 100644 (file)
@@ -1586,28 +1586,31 @@ enum Mismatch<'a> {
             Some(values) => {
                 let values = self.resolve_vars_if_possible(values);
                 let (is_simple_error, exp_found) = match values {
-                    ValuePairs::Terms(infer::ExpectedFound {
-                        expected: ty::Term::Ty(expected),
-                        found: ty::Term::Ty(found),
-                    }) => {
-                        let is_simple_err = expected.is_simple_text() && found.is_simple_text();
-                        OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
-                            .report(diag);
-
-                        (
-                            is_simple_err,
-                            Mismatch::Variable(infer::ExpectedFound { expected, found }),
-                        )
+                    ValuePairs::Terms(infer::ExpectedFound { expected, found }) => {
+                        match (expected.unpack(), found.unpack()) {
+                            (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
+                                let is_simple_err =
+                                    expected.is_simple_text() && found.is_simple_text();
+                                OpaqueTypesVisitor::visit_expected_found(
+                                    self.tcx, expected, found, span,
+                                )
+                                .report(diag);
+
+                                (
+                                    is_simple_err,
+                                    Mismatch::Variable(infer::ExpectedFound { expected, found }),
+                                )
+                            }
+                            (ty::TermKind::Const(_), ty::TermKind::Const(_)) => {
+                                (false, Mismatch::Fixed("constant"))
+                            }
+                            _ => (false, Mismatch::Fixed("type")),
+                        }
                     }
-                    ValuePairs::Terms(infer::ExpectedFound {
-                        expected: ty::Term::Const(_),
-                        found: ty::Term::Const(_),
-                    }) => (false, Mismatch::Fixed("constant")),
                     ValuePairs::TraitRefs(_) | ValuePairs::PolyTraitRefs(_) => {
                         (false, Mismatch::Fixed("trait"))
                     }
                     ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")),
-                    _ => (false, Mismatch::Fixed("type")),
                 };
                 let vals = match self.values_str(values) {
                     Some((expected, found)) => Some((expected, found)),
@@ -2273,11 +2276,11 @@ fn expected_found_str_term(
             return None;
         }
 
-        Some(match (exp_found.expected, exp_found.found) {
-            (ty::Term::Ty(expected), ty::Term::Ty(found)) => self.cmp(expected, found),
-            (expected, found) => (
-                DiagnosticStyledString::highlighted(expected.to_string()),
-                DiagnosticStyledString::highlighted(found.to_string()),
+        Some(match (exp_found.expected.unpack(), exp_found.found.unpack()) {
+            (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => self.cmp(expected, found),
+            _ => (
+                DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
+                DiagnosticStyledString::highlighted(exp_found.found.to_string()),
             ),
         })
     }
index fe037a458a7f85106d756c92aef897a779552738..bbbc044b85a48e7f17a899116691a99e36e816d4 100644 (file)
@@ -353,12 +353,11 @@ pub enum ValuePairs<'tcx> {
 
 impl<'tcx> ValuePairs<'tcx> {
     pub fn ty(&self) -> Option<(Ty<'tcx>, Ty<'tcx>)> {
-        if let ValuePairs::Terms(ExpectedFound {
-            expected: ty::Term::Ty(expected),
-            found: ty::Term::Ty(found),
-        }) = self
+        if let ValuePairs::Terms(ExpectedFound { expected, found }) = self
+            && let Some(expected) = expected.ty()
+            && let Some(found) = found.ty()
         {
-            Some((*expected, *found))
+            Some((expected, found))
         } else {
             None
         }
index c7d7ef40d9d413ae64a541371e73a6f3154ca9de..75233495040ca561dfed4ab9a4425641bd816e64 100644 (file)
@@ -50,13 +50,13 @@ pub fn generic_bound(&self, generic: GenericKind<'tcx>) -> VerifyBound<'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> {
-        debug!("param_bound(param_ty={:?})", param_ty);
-
         // Start with anything like `T: 'a` we can scrape from the
         // environment. If the environment contains something like
         // `for<'a> T: 'a`, then we know that `T` outlives everything.
         let declared_bounds_from_env = self.declared_generic_bounds_from_env(param_ty);
+        debug!(?declared_bounds_from_env);
         let mut param_bounds = vec![];
         for declared_bound in declared_bounds_from_env {
             let bound_region = declared_bound.map_bound(|outlives| outlives.1);
@@ -65,6 +65,7 @@ fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> {
                 param_bounds.push(VerifyBound::OutlivedBy(region));
             } else {
                 // This is `for<'a> T: 'a`. This means that `T` outlives everything! All done here.
+                debug!("found that {param_ty:?} outlives any lifetime, returning empty vector");
                 return VerifyBound::AllBounds(vec![]);
             }
         }
@@ -72,6 +73,7 @@ fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> {
         // Add in the default bound of fn body that applies to all in
         // scope type parameters:
         if let Some(r) = self.implicit_region_bound {
+            debug!("adding implicit region bound of {r:?}");
             param_bounds.push(VerifyBound::OutlivedBy(r));
         }
 
index bb534a3c7afce6399abb885ae5dfe2984e22aab9..c41b154c3e066cb936a5b76a3cce35bbaaf823db 100644 (file)
@@ -573,13 +573,24 @@ fn write_out_deps(
         // Account for explicitly marked-to-track files
         // (e.g. accessed in proc macros).
         let file_depinfo = sess.parse_sess.file_depinfo.borrow();
-        let extra_tracked_files = file_depinfo.iter().map(|path_sym| {
-            let path = PathBuf::from(path_sym.as_str());
+
+        let normalize_path = |path: PathBuf| {
             let file = FileName::from(path);
             escape_dep_filename(&file.prefer_local().to_string())
-        });
+        };
+
+        let extra_tracked_files =
+            file_depinfo.iter().map(|path_sym| normalize_path(PathBuf::from(path_sym.as_str())));
         files.extend(extra_tracked_files);
 
+        // We also need to track used PGO profile files
+        if let Some(ref profile_instr) = sess.opts.cg.profile_use {
+            files.push(normalize_path(profile_instr.as_path().to_path_buf()));
+        }
+        if let Some(ref profile_sample) = sess.opts.unstable_opts.profile_sample_use {
+            files.push(normalize_path(profile_sample.as_path().to_path_buf()));
+        }
+
         if sess.binary_dep_depinfo() {
             if let Some(ref backend) = sess.opts.unstable_opts.codegen_backend {
                 if backend.contains('.') {
index c5a450b0e2e5393e6ae2601893cef89e808ae7d8..753e1f4b9daaf72f247ef14fc91debed7ad3e573 100644 (file)
@@ -1362,13 +1362,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
                 write!(fmt, "Coverage::{:?} for {:?}", kind, rgn)
             }
             Coverage(box ref coverage) => write!(fmt, "Coverage::{:?}", coverage.kind),
-            CopyNonOverlapping(box crate::mir::CopyNonOverlapping {
-                ref src,
-                ref dst,
-                ref count,
-            }) => {
-                write!(fmt, "copy_nonoverlapping(src={:?}, dst={:?}, count={:?})", src, dst, count)
-            }
+            Intrinsic(box ref intrinsic) => write!(fmt, "{intrinsic}"),
             Nop => write!(fmt, "nop"),
         }
     }
@@ -1470,7 +1464,9 @@ pub fn is_indirect(&self) -> bool {
     /// It's guaranteed to be in the first place
     pub fn has_deref(&self) -> bool {
         // To make sure this is not accidently used in wrong mir phase
-        debug_assert!(!self.projection[1..].contains(&PlaceElem::Deref));
+        debug_assert!(
+            self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
+        );
         self.projection.first() == Some(&PlaceElem::Deref)
     }
 
index 6e64a3b80c1fb18beaff270d864d96235c348890..4e06d91012c0dfc9c0f0eb50d1792357df25a2ef 100644 (file)
@@ -249,7 +249,7 @@ pub fn statement_kind_name(statement: &Statement<'_>) -> &'static str {
         Retag(..) => "Retag",
         AscribeUserType(..) => "AscribeUserType",
         Coverage(..) => "Coverage",
-        CopyNonOverlapping(..) => "CopyNonOverlapping",
+        Intrinsic(..) => "Intrinsic",
         Nop => "Nop",
     }
 }
index d7b9d59eced51eee813171db11a11635a881378e..bf63b8efaf7a2deb135060eb56f99e4d414e4b95 100644 (file)
@@ -327,6 +327,34 @@ pub enum StatementKind<'tcx> {
     /// executed.
     Coverage(Box<Coverage>),
 
+    /// Denotes a call to an intrinsic that does not require an unwind path and always returns.
+    /// This avoids adding a new block and a terminator for simple intrinsics.
+    Intrinsic(Box<NonDivergingIntrinsic<'tcx>>),
+
+    /// No-op. Useful for deleting instructions without affecting statement indices.
+    Nop,
+}
+
+#[derive(
+    Clone,
+    TyEncodable,
+    TyDecodable,
+    Debug,
+    PartialEq,
+    Hash,
+    HashStable,
+    TypeFoldable,
+    TypeVisitable
+)]
+pub enum NonDivergingIntrinsic<'tcx> {
+    /// Denotes a call to the intrinsic function `assume`.
+    ///
+    /// The operand must be a boolean. Optimizers may use the value of the boolean to backtrack its
+    /// computation to infer information about other variables. So if the boolean came from a
+    /// `x < y` operation, subsequent operations on `x` and `y` could elide various bound checks.
+    /// If the argument is `false`, this operation is equivalent to `TerminatorKind::Unreachable`.
+    Assume(Operand<'tcx>),
+
     /// Denotes a call to the intrinsic function `copy_nonoverlapping`.
     ///
     /// First, all three operands are evaluated. `src` and `dest` must each be a reference, pointer,
@@ -340,10 +368,18 @@ pub enum StatementKind<'tcx> {
     ///
     /// **Needs clarification**: Is this typed or not, ie is there a typed load and store involved?
     /// I vaguely remember Ralf saying somewhere that he thought it should not be.
-    CopyNonOverlapping(Box<CopyNonOverlapping<'tcx>>),
+    CopyNonOverlapping(CopyNonOverlapping<'tcx>),
+}
 
-    /// No-op. Useful for deleting instructions without affecting statement indices.
-    Nop,
+impl std::fmt::Display for NonDivergingIntrinsic<'_> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Self::Assume(op) => write!(f, "assume({op:?})"),
+            Self::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => {
+                write!(f, "copy_nonoverlapping(dst = {dst:?}, src = {src:?}, count = {count:?})")
+            }
+        }
+    }
 }
 
 /// Describes what kind of retag is to be performed.
index 7bd65f42e3f925a2b2d799cb681394ba2410a835..708ea4398c852102f8c7c1d3ce12cddf4364ccd3 100644 (file)
@@ -425,14 +425,15 @@ fn super_statement(&mut self,
                             location
                         )
                     }
-                    StatementKind::CopyNonOverlapping(box crate::mir::CopyNonOverlapping{
-                        src,
-                        dst,
-                        count,
-                    }) => {
-                      self.visit_operand(src, location);
-                      self.visit_operand(dst, location);
-                      self.visit_operand(count, location)
+                    StatementKind::Intrinsic(box ref $($mutability)? intrinsic) => {
+                        match intrinsic {
+                            NonDivergingIntrinsic::Assume(op) => self.visit_operand(op, location),
+                            NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => {
+                                self.visit_operand(src, location);
+                                self.visit_operand(dst, location);
+                                self.visit_operand(count, location);
+                            }
+                        }
                     }
                     StatementKind::Nop => {}
                 }
index ea6bb8a7abd4b8941a7d57c4dedae0fbb093e8a7..c22c899c5cce17104de0d82db5ea8052be002b3a 100644 (file)
@@ -1,5 +1,5 @@
 use crate::ty::subst::{GenericArg, GenericArgKind};
-use crate::ty::{self, InferConst, Term, Ty, TypeFlags};
+use crate::ty::{self, InferConst, Ty, TypeFlags};
 use std::slice;
 
 #[derive(Debug)]
@@ -243,9 +243,9 @@ fn add_predicate_atom(&mut self, atom: ty::PredicateKind<'_>) {
             }
             ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
                 self.add_projection_ty(projection_ty);
-                match term {
-                    Term::Ty(ty) => self.add_ty(ty),
-                    Term::Const(c) => self.add_const(c),
+                match term.unpack() {
+                    ty::TermKind::Ty(ty) => self.add_ty(ty),
+                    ty::TermKind::Const(c) => self.add_const(c),
                 }
             }
             ty::PredicateKind::WellFormed(arg) => {
@@ -320,9 +320,9 @@ fn add_unevaluated_const<P>(&mut self, ct: ty::Unevaluated<'_, P>) {
 
     fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
         self.add_substs(projection.substs);
-        match projection.term {
-            ty::Term::Ty(ty) => self.add_ty(ty),
-            ty::Term::Const(ct) => self.add_const(ct),
+        match projection.term.unpack() {
+            ty::TermKind::Ty(ty) => self.add_ty(ty),
+            ty::TermKind::Const(ct) => self.add_const(ct),
         }
     }
 
index a1d980af921afeb05590a6ae722dc0436146dbb5..8631ee91fa456c280b9b01eb80339c1565e20519 100644 (file)
@@ -328,6 +328,7 @@ pub fn instantiate_own(
         }
     }
 
+    #[instrument(level = "debug", skip(self, tcx))]
     fn instantiate_into(
         &self,
         tcx: TyCtxt<'tcx>,
index a3f7880b9a5684f3a044ea44218be79ec3aec958..ee4e8ff50f82434c3903c1170186cc7f8182e6d7 100644 (file)
@@ -41,6 +41,7 @@
 use rustc_index::vec::IndexVec;
 use rustc_macros::HashStable;
 use rustc_query_system::ich::StableHashingContext;
+use rustc_serialize::{Decodable, Encodable};
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{ExpnId, Span};
@@ -50,6 +51,9 @@
 
 use std::fmt::Debug;
 use std::hash::{Hash, Hasher};
+use std::marker::PhantomData;
+use std::mem;
+use std::num::NonZeroUsize;
 use std::ops::ControlFlow;
 use std::{fmt, str};
 
@@ -459,15 +463,6 @@ pub(crate) struct TyS<'tcx> {
     outer_exclusive_binder: ty::DebruijnIndex,
 }
 
-// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(TyS<'_>, 40);
-
-// We are actually storing a stable hash cache next to the type, so let's
-// also check the full size
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(WithStableHash<TyS<'_>>, 56);
-
 /// Use this rather than `TyS`, whenever possible.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
 #[rustc_diagnostic_item = "Ty"]
@@ -524,10 +519,6 @@ pub(crate) struct PredicateS<'tcx> {
     outer_exclusive_binder: ty::DebruijnIndex,
 }
 
-// This type is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(PredicateS<'_>, 56);
-
 /// Use this rather than `PredicateS`, whenever possible.
 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
 #[rustc_pass_by_value]
@@ -911,42 +902,122 @@ pub struct CoercePredicate<'tcx> {
 }
 pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
 
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
-pub enum Term<'tcx> {
-    Ty(Ty<'tcx>),
-    Const(Const<'tcx>),
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct Term<'tcx> {
+    ptr: NonZeroUsize,
+    marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
 }
 
 impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
     fn from(ty: Ty<'tcx>) -> Self {
-        Term::Ty(ty)
+        TermKind::Ty(ty).pack()
     }
 }
 
 impl<'tcx> From<Const<'tcx>> for Term<'tcx> {
     fn from(c: Const<'tcx>) -> Self {
-        Term::Const(c)
+        TermKind::Const(c).pack()
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Term<'tcx> {
+    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
+        self.unpack().hash_stable(hcx, hasher);
+    }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for Term<'tcx> {
+    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+        Ok(self.unpack().try_fold_with(folder)?.pack())
+    }
+}
+
+impl<'tcx> TypeVisitable<'tcx> for Term<'tcx> {
+    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+        self.unpack().visit_with(visitor)
+    }
+}
+
+impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for Term<'tcx> {
+    fn encode(&self, e: &mut E) {
+        self.unpack().encode(e)
+    }
+}
+
+impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for Term<'tcx> {
+    fn decode(d: &mut D) -> Self {
+        let res: TermKind<'tcx> = Decodable::decode(d);
+        res.pack()
     }
 }
 
 impl<'tcx> Term<'tcx> {
+    #[inline]
+    pub fn unpack(self) -> TermKind<'tcx> {
+        let ptr = self.ptr.get();
+        // SAFETY: use of `Interned::new_unchecked` here is ok because these
+        // pointers were originally created from `Interned` types in `pack()`,
+        // and this is just going in the other direction.
+        unsafe {
+            match ptr & TAG_MASK {
+                TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
+                    &*((ptr & !TAG_MASK) as *const WithStableHash<ty::TyS<'tcx>>),
+                ))),
+                CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
+                    &*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>),
+                ))),
+                _ => core::intrinsics::unreachable(),
+            }
+        }
+    }
+
     pub fn ty(&self) -> Option<Ty<'tcx>> {
-        if let Term::Ty(ty) = self { Some(*ty) } else { None }
+        if let TermKind::Ty(ty) = self.unpack() { Some(ty) } else { None }
     }
 
     pub fn ct(&self) -> Option<Const<'tcx>> {
-        if let Term::Const(c) = self { Some(*c) } else { None }
+        if let TermKind::Const(c) = self.unpack() { Some(c) } else { None }
     }
 
     pub fn into_arg(self) -> GenericArg<'tcx> {
-        match self {
-            Term::Ty(ty) => ty.into(),
-            Term::Const(c) => c.into(),
+        match self.unpack() {
+            TermKind::Ty(ty) => ty.into(),
+            TermKind::Const(c) => c.into(),
         }
     }
 }
 
+const TAG_MASK: usize = 0b11;
+const TYPE_TAG: usize = 0b00;
+const CONST_TAG: usize = 0b01;
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable)]
+pub enum TermKind<'tcx> {
+    Ty(Ty<'tcx>),
+    Const(Const<'tcx>),
+}
+
+impl<'tcx> TermKind<'tcx> {
+    #[inline]
+    fn pack(self) -> Term<'tcx> {
+        let (tag, ptr) = match self {
+            TermKind::Ty(ty) => {
+                // Ensure we can use the tag bits.
+                assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
+                (TYPE_TAG, ty.0.0 as *const WithStableHash<ty::TyS<'tcx>> as usize)
+            }
+            TermKind::Const(ct) => {
+                // Ensure we can use the tag bits.
+                assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
+                (CONST_TAG, ct.0.0 as *const ty::ConstS<'tcx> as usize)
+            }
+        };
+
+        Term { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
+    }
+}
+
 /// This kind of predicate has no *direct* correspondent in the
 /// syntax, but it roughly corresponds to the syntactic forms:
 ///
@@ -2531,3 +2602,14 @@ pub struct DestructuredConst<'tcx> {
     pub variant: Option<VariantIdx>,
     pub fields: &'tcx [ty::Const<'tcx>],
 }
+
+// Some types are used a lot. Make sure they don't unintentionally get bigger.
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+mod size_asserts {
+    use super::*;
+    use rustc_data_structures::static_assert_size;
+    // These are in alphabetical order, which is easy to maintain.
+    static_assert_size!(PredicateS<'_>, 48);
+    static_assert_size!(TyS<'_>, 40);
+    static_assert_size!(WithStableHash<TyS<'_>>, 56);
+}
index 329478f27b73c80ec2846f4b7e2e6a89a986b41d..1ae3063dae4e7f51d3ffcb0704c3e27d0cccdd87 100644 (file)
@@ -1,7 +1,7 @@
 use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
 use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
 use crate::ty::{
-    self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable,
+    self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable,
     TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
 };
 use rustc_apfloat::ieee::{Double, Single};
@@ -855,7 +855,7 @@ fn pretty_print_opaque_impl_type(
                         }
 
                         p!(")");
-                        if let Term::Ty(ty) = return_ty.skip_binder() {
+                        if let Some(ty) = return_ty.skip_binder().ty() {
                             if !ty.is_unit() {
                                 p!(" -> ", print(return_ty));
                             }
@@ -942,13 +942,9 @@ fn pretty_print_opaque_impl_type(
 
                         p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name));
 
-                        match term {
-                            Term::Ty(ty) => {
-                                p!(print(ty))
-                            }
-                            Term::Const(c) => {
-                                p!(print(c));
-                            }
+                        match term.unpack() {
+                            TermKind::Ty(ty) => p!(print(ty)),
+                            TermKind::Const(c) => p!(print(c)),
                         };
                     }
 
@@ -2608,9 +2604,9 @@ pub struct PrintClosureAsImpl<'tcx> {
     }
 
     ty::Term<'tcx> {
-      match self {
-        ty::Term::Ty(ty) => p!(print(ty)),
-        ty::Term::Const(c) => p!(print(c)),
+      match self.unpack() {
+        ty::TermKind::Ty(ty) => p!(print(ty)),
+        ty::TermKind::Const(c) => p!(print(c)),
       }
     }
 
index 818affa7113a17c5abb644ad7ab36db2692b1854..109a4df83b02947b6b728d0838c3d83229aba157 100644 (file)
@@ -6,7 +6,7 @@
 
 use crate::ty::error::{ExpectedFound, TypeError};
 use crate::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
-use crate::ty::{self, ImplSubject, Term, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{self, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable};
 use rustc_hir as ast;
 use rustc_hir::def_id::DefId;
 use rustc_span::DUMMY_SP;
@@ -803,15 +803,15 @@ fn relate<R: TypeRelation<'tcx>>(
     }
 }
 
-impl<'tcx> Relate<'tcx> for ty::Term<'tcx> {
+impl<'tcx> Relate<'tcx> for Term<'tcx> {
     fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: Self,
         b: Self,
     ) -> RelateResult<'tcx, Self> {
-        Ok(match (a, b) {
-            (Term::Ty(a), Term::Ty(b)) => relation.relate(a, b)?.into(),
-            (Term::Const(a), Term::Const(b)) => relation.relate(a, b)?.into(),
+        Ok(match (a.unpack(), b.unpack()) {
+            (TermKind::Ty(a), TermKind::Ty(b)) => relation.relate(a, b)?.into(),
+            (TermKind::Const(a), TermKind::Const(b)) => relation.relate(a, b)?.into(),
             _ => return Err(TypeError::Mismatch),
         })
     }
index 57555433f55b745b54247219bbd1846116c16463..e6bd2eed565a15d96c34306b60b0556f0990b4fe 100644 (file)
@@ -7,7 +7,7 @@
 use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
 use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
 use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
-use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt};
+use crate::ty::{self, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
 use rustc_data_structures::functor::IdFunctor;
 use rustc_hir as hir;
 use rustc_hir::def::Namespace;
@@ -344,10 +344,13 @@ fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
 impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
     type Lifted = ty::Term<'tcx>;
     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        Some(match self {
-            Term::Ty(ty) => Term::Ty(tcx.lift(ty)?),
-            Term::Const(c) => Term::Const(tcx.lift(c)?),
-        })
+        Some(
+            match self.unpack() {
+                TermKind::Ty(ty) => TermKind::Ty(tcx.lift(ty)?),
+                TermKind::Const(c) => TermKind::Const(tcx.lift(c)?),
+            }
+            .pack(),
+        )
     }
 }
 
index 02fe1f3a7bded3f801ff8a02caced7c5a7c23e76..831724bc4b09bec92079c2d999ac5e648da5570f 100644 (file)
@@ -165,9 +165,9 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
                         }
                     };
 
-                    substs.iter().rev().chain(opt_ty.map(|term| match term {
-                        ty::Term::Ty(ty) => ty.into(),
-                        ty::Term::Const(ct) => ct.into(),
+                    substs.iter().rev().chain(opt_ty.map(|term| match term.unpack() {
+                        ty::TermKind::Ty(ty) => ty.into(),
+                        ty::TermKind::Const(ct) => ct.into(),
                     }))
                 }));
             }
index 483c1e274aa7809d6b3cffeb5ab5be003072d642..3e08a8799ef9aadacd88614c862367ee9c3d34c8 100644 (file)
@@ -270,7 +270,7 @@ fn apply_statement_effect(
             | StatementKind::Retag(..)
             | StatementKind::AscribeUserType(..)
             | StatementKind::Coverage(..)
-            | StatementKind::CopyNonOverlapping(..)
+            | StatementKind::Intrinsic(..)
             | StatementKind::Nop => None,
         };
         if let Some(destination) = destination {
index f6b5af90a85c8e6e97300a7b5d35633397711b75..18760b6c6fa543328b69ec269cc9c3c4a265afd2 100644 (file)
@@ -142,7 +142,7 @@ fn before_statement_effect(
             | StatementKind::FakeRead(..)
             | StatementKind::Nop
             | StatementKind::Retag(..)
-            | StatementKind::CopyNonOverlapping(..)
+            | StatementKind::Intrinsic(..)
             | StatementKind::StorageLive(..) => {}
         }
     }
index c325838622399e7c32d16b2e9ca1fe49df42068c..f46fd118bde5d165106bfcb047dd7d2d5f494232 100644 (file)
@@ -330,7 +330,7 @@ fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
             StatementKind::Retag { .. }
             | StatementKind::AscribeUserType(..)
             | StatementKind::Coverage(..)
-            | StatementKind::CopyNonOverlapping(..)
+            | StatementKind::Intrinsic(..)
             | StatementKind::Nop => {}
         }
     }
index 0f5fd77f7ab164368e67dda28392af2c125ebc6a..beff19a3ab2e1d908f8a09a4848c8ddeb5065c33 100644 (file)
@@ -105,7 +105,8 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
                 // safe (at least as emitted during MIR construction)
             }
 
-            StatementKind::CopyNonOverlapping(..) => unreachable!(),
+            // Move to above list once mir construction uses it.
+            StatementKind::Intrinsic(..) => unreachable!(),
         }
         self.super_statement(statement, location);
     }
index 423e78317aadbc1f21639b2a6ea0f7af77f6b28b..9f842c929dc2478034f6962b05a8c4b63ac05419 100644 (file)
@@ -825,7 +825,7 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span>
 
         // Retain spans from all other statements
         StatementKind::FakeRead(box (_, _)) // Not including `ForGuardBinding`
-        | StatementKind::CopyNonOverlapping(..)
+        | StatementKind::Intrinsic(..)
         | StatementKind::Assign(_)
         | StatementKind::SetDiscriminant { .. }
         | StatementKind::Deinit(..)
index 9163672f570396113e372faf60addc21b5e3278d..3f3870cc7bad2f0d0a866518a7cab212bc195586 100644 (file)
@@ -52,7 +52,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
                 | StatementKind::StorageLive(_)
                 | StatementKind::StorageDead(_)
                 | StatementKind::Coverage(_)
-                | StatementKind::CopyNonOverlapping(_)
+                | StatementKind::Intrinsic(_)
                 | StatementKind::Nop => (),
 
                 StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => {
index da55510920e12ec6eaf3de10dd0bbfebcd2170b3..9bc47613e4c67885075bc43cf62725b3428644b7 100644 (file)
@@ -537,7 +537,7 @@ fn record_statement_conflicts(&mut self, stmt: &Statement<'_>) {
             | StatementKind::FakeRead(..)
             | StatementKind::AscribeUserType(..)
             | StatementKind::Coverage(..)
-            | StatementKind::CopyNonOverlapping(..)
+            | StatementKind::Intrinsic(..)
             | StatementKind::Nop => {}
         }
     }
index dbff4a6bd696e01df9595a630fd99fe625efa71b..705cf776fb29ef6be0c283d4beeaafe20042430d 100644 (file)
@@ -1452,7 +1452,7 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
             | StatementKind::Retag(..)
             | StatementKind::AscribeUserType(..)
             | StatementKind::Coverage(..)
-            | StatementKind::CopyNonOverlapping(..)
+            | StatementKind::Intrinsic(..)
             | StatementKind::Nop => {}
         }
     }
index b7ba616510c28874b2356f294ba7155b6a7f8bb7..9892580e63dcb4f1655ce08c463e1e47d32c79b3 100644 (file)
@@ -46,12 +46,31 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
                         let mut args = args.drain(..);
                         block.statements.push(Statement {
                             source_info: terminator.source_info,
-                            kind: StatementKind::CopyNonOverlapping(Box::new(
-                                rustc_middle::mir::CopyNonOverlapping {
-                                    src: args.next().unwrap(),
-                                    dst: args.next().unwrap(),
-                                    count: args.next().unwrap(),
-                                },
+                            kind: StatementKind::Intrinsic(Box::new(
+                                NonDivergingIntrinsic::CopyNonOverlapping(
+                                    rustc_middle::mir::CopyNonOverlapping {
+                                        src: args.next().unwrap(),
+                                        dst: args.next().unwrap(),
+                                        count: args.next().unwrap(),
+                                    },
+                                ),
+                            )),
+                        });
+                        assert_eq!(
+                            args.next(),
+                            None,
+                            "Extra argument for copy_non_overlapping intrinsic"
+                        );
+                        drop(args);
+                        terminator.kind = TerminatorKind::Goto { target };
+                    }
+                    sym::assume => {
+                        let target = target.unwrap();
+                        let mut args = args.drain(..);
+                        block.statements.push(Statement {
+                            source_info: terminator.source_info,
+                            kind: StatementKind::Intrinsic(Box::new(
+                                NonDivergingIntrinsic::Assume(args.next().unwrap()),
                             )),
                         });
                         assert_eq!(
index 41a0bfac41aed2151cf9771f906fc693d25e4951..f1bbf2ea7e8ea3aaf7b40307ba110dcd7346b4a3 100644 (file)
@@ -51,7 +51,7 @@ fn is_nop_landing_pad(
                 StatementKind::Assign { .. }
                 | StatementKind::SetDiscriminant { .. }
                 | StatementKind::Deinit(..)
-                | StatementKind::CopyNonOverlapping(..)
+                | StatementKind::Intrinsic(..)
                 | StatementKind::Retag { .. } => {
                     return false;
                 }
index 190f9c1ac158c39bea8b48beb819ad5f0595e4e9..2f116aaa95849bd075b94179109e2bc1a210d1d9 100644 (file)
@@ -249,7 +249,7 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData<
             | StatementKind::AscribeUserType(_, _)
             | StatementKind::Coverage(_)
             | StatementKind::StorageDead(_)
-            | StatementKind::CopyNonOverlapping(_)
+            | StatementKind::Intrinsic(_)
             | StatementKind::Nop => {}
         }
     }
@@ -317,7 +317,7 @@ fn find_determining_place<'tcx>(
             | StatementKind::Retag(_, _)
             | StatementKind::AscribeUserType(_, _)
             | StatementKind::Coverage(_)
-            | StatementKind::CopyNonOverlapping(_)
+            | StatementKind::Intrinsic(_)
             | StatementKind::Nop => {}
 
             // If the discriminant is set, it is always set
index bed48db959a53a2e7b9e289c975c6bb41cfcc434..57d372fda5697f508c9a799d06f8cac051f18af9 100644 (file)
@@ -499,7 +499,7 @@ fn visit_lhs(&mut self, place: &Place<'_>, location: Location) {
 impl<'tcx> Visitor<'tcx> for UsedLocals {
     fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
         match statement.kind {
-            StatementKind::CopyNonOverlapping(..)
+            StatementKind::Intrinsic(..)
             | StatementKind::Retag(..)
             | StatementKind::Coverage(..)
             | StatementKind::FakeRead(..)
index 7addf519872f03f82332881aad134a28edd4bb11..ed37ede65d514bf992c4e3fe9bb9a7b33054db58 100644 (file)
@@ -1977,6 +1977,9 @@ fn suggest_missing_semicolon_before_array(
         open_delim_span: Span,
     ) -> PResult<'a, ()> {
         if self.token.kind == token::Comma {
+            if !self.sess.source_map().is_multiline(prev_span.until(self.token.span)) {
+                return Ok(());
+            }
             let mut snapshot = self.create_snapshot_for_diagnostic();
             snapshot.bump();
             match snapshot.parse_seq_to_before_end(
index a63af4159e8cbd075bae75ff2f6a6be653bc0663..d0b46aa2c4530a97893b48e77f15c17603ee0990 100644 (file)
@@ -1651,6 +1651,7 @@ fn check_repr(
                         E0552,
                         "unrecognized representation hint"
                     )
+                    .help("valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`")
                     .emit();
 
                     continue;
index 212ea9e57a37b5badcf63151f87b220c108fefa8..3bb8c0bb48c5f3b00771355529f517a7686296b0 100644 (file)
@@ -103,7 +103,7 @@ fn check<F: FnOnce(&mut HirIdValidator<'a, 'hir>)>(&mut self, owner: LocalDefId,
             self.error(|| {
                 format!(
                     "ItemLocalIds not assigned densely in {}. \
-                Max ItemLocalId = {}, missing IDs = {:?}; seens IDs = {:?}",
+                Max ItemLocalId = {}, missing IDs = {:#?}; seens IDs = {:#?}",
                     self.hir_map.def_path(owner).to_string_no_crate_verbose(),
                     max,
                     missing_items,
index c72981ed96f6788b0c840ff7c420349aace8e42d..101679aa6dc93fade0f481b74e1cd03dff34f7dd 100644 (file)
@@ -525,6 +525,7 @@ fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
         }
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         match &item.kind {
             hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => {
@@ -839,6 +840,7 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
         }
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
         use self::hir::TraitItemKind::*;
         match trait_item.kind {
@@ -888,6 +890,7 @@ fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
         }
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
         use self::hir::ImplItemKind::*;
         match impl_item.kind {
index cb61f76af1d73669c5b05086aa9a19713255499b..b1de979e8f8ec4f82f4c83b61930923b2e4fd4c8 100644 (file)
@@ -13,7 +13,7 @@
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
 use rustc_middle::ty::{
     self, Binder, Const, ExistentialPredicate, FloatTy, FnSig, IntTy, List, Region, RegionKind,
-    Term, Ty, TyCtxt, UintTy,
+    TermKind, Ty, TyCtxt, UintTy,
 };
 use rustc_span::def_id::DefId;
 use rustc_span::symbol::sym;
@@ -243,13 +243,9 @@ fn encode_predicate<'tcx>(
             let name = encode_ty_name(tcx, projection.item_def_id);
             let _ = write!(s, "u{}{}", name.len(), &name);
             s.push_str(&encode_substs(tcx, projection.substs, dict, options));
-            match projection.term {
-                Term::Ty(ty) => {
-                    s.push_str(&encode_ty(tcx, ty, dict, options));
-                }
-                Term::Const(c) => {
-                    s.push_str(&encode_const(tcx, c, dict, options));
-                }
+            match projection.term.unpack() {
+                TermKind::Ty(ty) => s.push_str(&encode_ty(tcx, ty, dict, options)),
+                TermKind::Const(c) => s.push_str(&encode_const(tcx, c, dict, options)),
             }
         }
         ty::ExistentialPredicate::AutoTrait(def_id) => {
index 71fa5a44887082048871a594d10214acbef1117a..cfb8d47e54534d3b2b1187652b2e71cf30aaff7d 100644 (file)
@@ -543,9 +543,9 @@ fn print_dyn_existential(
                         let name = cx.tcx.associated_item(projection.item_def_id).name;
                         cx.push("p");
                         cx.push_ident(name.as_str());
-                        cx = match projection.term {
-                            ty::Term::Ty(ty) => ty.print(cx),
-                            ty::Term::Const(c) => c.print(cx),
+                        cx = match projection.term.unpack() {
+                            ty::TermKind::Ty(ty) => ty.print(cx),
+                            ty::TermKind::Const(c) => c.print(cx),
                         }?;
                     }
                     ty::ExistentialPredicate::AutoTrait(def_id) => {
index 1223c7ced7abcb9e04bdaeb1b879ec240092bcf7..98e93ad3fc5046fdd8b38c4f91bffed2ba49a8d4 100644 (file)
@@ -10,7 +10,7 @@
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::visit::TypeVisitable;
-use rustc_middle::ty::{Region, RegionVid, Term};
+use rustc_middle::ty::{Region, RegionVid};
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 
@@ -612,7 +612,7 @@ pub fn is_of_param(&self, ty: Ty<'_>) -> bool {
     }
 
     fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
-        if let Term::Ty(ty) = p.term().skip_binder() {
+        if let Some(ty) = p.term().skip_binder().ty() {
             matches!(ty.kind(), ty::Projection(proj) if proj == &p.skip_binder().projection_ty)
         } else {
             false
index 398635674abcfd19a69c7de02f88af6787e209f9..76c1ade0680c5b4f5847fc554682f95ce7677daa 100644 (file)
@@ -552,7 +552,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                     )
                     .ok()
                     .flatten()
-                    .unwrap_or_else(|| ty::Term::Ty(ty.super_fold_with(self)))
+                    .unwrap_or_else(|| ty.super_fold_with(self).into())
                 };
                 // For cases like #95134 we would like to catch overflows early
                 // otherwise they slip away away and cause ICE.
index bb6009cb22a37b2df733bb9019e164eae8d5288b..9a571837e9f5a04521b7aeaa9553af7d18e41003 100644 (file)
@@ -129,9 +129,9 @@ pub fn predicate_obligations<'a, 'tcx>(
         }
         ty::PredicateKind::Projection(t) => {
             wf.compute_projection(t.projection_ty);
-            wf.compute(match t.term {
-                ty::Term::Ty(ty) => ty.into(),
-                ty::Term::Const(c) => c.into(),
+            wf.compute(match t.term.unpack() {
+                ty::TermKind::Ty(ty) => ty.into(),
+                ty::TermKind::Const(c) => c.into(),
             })
         }
         ty::PredicateKind::WellFormed(arg) => {
@@ -434,6 +434,7 @@ fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<
     }
 
     /// Pushes all the predicates needed to validate that `ty` is WF into `out`.
+    #[instrument(level = "debug", skip(self))]
     fn compute(&mut self, arg: GenericArg<'tcx>) {
         let mut walker = arg.walk();
         let param_env = self.param_env;
@@ -488,6 +489,8 @@ fn compute(&mut self, arg: GenericArg<'tcx>) {
                 }
             };
 
+            debug!("wf bounds for ty={:?} ty.kind={:#?}", ty, ty.kind());
+
             match *ty.kind() {
                 ty::Bool
                 | ty::Char
index 14f04ddc8688bc2ae9b44b7ffa7e6e9ec61812c2..801063583e633e42928ee7b42e1ab92092d4bf19 100644 (file)
@@ -1183,11 +1183,11 @@ fn add_predicates_for_ast_type_binding(
                 // `<T as Iterator>::Item = u32`
                 let assoc_item_def_id = projection_ty.skip_binder().item_def_id;
                 let def_kind = tcx.def_kind(assoc_item_def_id);
-                match (def_kind, term) {
-                    (hir::def::DefKind::AssocTy, ty::Term::Ty(_))
-                    | (hir::def::DefKind::AssocConst, ty::Term::Const(_)) => (),
+                match (def_kind, term.unpack()) {
+                    (hir::def::DefKind::AssocTy, ty::TermKind::Ty(_))
+                    | (hir::def::DefKind::AssocConst, ty::TermKind::Const(_)) => (),
                     (_, _) => {
-                        let got = if let ty::Term::Ty(_) = term { "type" } else { "constant" };
+                        let got = if let Some(_) = term.ty() { "type" } else { "constant" };
                         let expected = def_kind.descr(assoc_item_def_id);
                         tcx.sess
                             .struct_span_err(
@@ -1375,9 +1375,11 @@ trait here instead: `trait NewTrait: {} {{}}`",
                         let pred = bound_predicate.rebind(pred);
                         // A `Self` within the original bound will be substituted with a
                         // `trait_object_dummy_self`, so check for that.
-                        let references_self = match pred.skip_binder().term {
-                            ty::Term::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()),
-                            ty::Term::Const(c) => c.ty().walk().any(|arg| arg == dummy_self.into()),
+                        let references_self = match pred.skip_binder().term.unpack() {
+                            ty::TermKind::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()),
+                            ty::TermKind::Const(c) => {
+                                c.ty().walk().any(|arg| arg == dummy_self.into())
+                            }
                         };
 
                         // If the projection output contains `Self`, force the user to
@@ -2695,6 +2697,7 @@ fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool, in_path: bool
         result_ty
     }
 
+    #[instrument(level = "debug", skip(self), ret)]
     fn impl_trait_ty_to_ty(
         &self,
         def_id: DefId,
@@ -2743,9 +2746,7 @@ fn impl_trait_ty_to_ty(
         });
         debug!("impl_trait_ty_to_ty: substs={:?}", substs);
 
-        let ty = tcx.mk_opaque(def_id, substs);
-        debug!("impl_trait_ty_to_ty: {}", ty);
-        ty
+        tcx.mk_opaque(def_id, substs)
     }
 
     pub fn ty_of_arg(&self, ty: &hir::Ty<'_>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> {
index a9071cd1fd949efe57c2bfd122425fb0b5277dd7..c597efbe7468ebce3b6d12ffb5bd6967a242b186 100644 (file)
@@ -21,7 +21,7 @@
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
 use rustc_middle::ty::{
-    self, AssocKind, DefIdTree, GenericParamDefKind, ProjectionPredicate, ProjectionTy, Term,
+    self, AssocKind, DefIdTree, GenericParamDefKind, ProjectionPredicate, ProjectionTy,
     ToPredicate, Ty, TypeVisitable,
 };
 use rustc_span::symbol::Ident;
@@ -349,7 +349,7 @@ pub(super) fn obligation_for_op_method(
             opt_output_ty.zip(opt_output_assoc_item).map(|(output_ty, output_assoc_item)| {
                 ty::Binder::dummy(ty::PredicateKind::Projection(ProjectionPredicate {
                     projection_ty: ProjectionTy { substs, item_def_id: output_assoc_item.def_id },
-                    term: Term::Ty(output_ty),
+                    term: output_ty.into(),
                 }))
                 .to_predicate(self.tcx)
             });
index 6236ad370df60e1bcd30a14c92b70a2fbd498dac..e70f728d7dcce3db1bdff7e48aa5e20b8be200a5 100644 (file)
@@ -573,6 +573,7 @@ fn get_new_lifetime_name<'tcx>(
 
 /// Returns the predicates defined on `item_def_id` of the form
 /// `X: Foo` where `X` is the type parameter `def_id`.
+#[instrument(level = "trace", skip(tcx))]
 fn type_param_predicates(
     tcx: TyCtxt<'_>,
     (item_def_id, def_id, assoc_name): (DefId, LocalDefId, Ident),
@@ -679,7 +680,7 @@ fn type_parameter_bounds_in_generics(
         assoc_name: Option<Ident>,
     ) -> Vec<(ty::Predicate<'tcx>, Span)> {
         let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id();
-        debug!(?param_def_id);
+        trace!(?param_def_id);
         ast_generics
             .predicates
             .iter()
@@ -708,9 +709,8 @@ fn type_parameter_bounds_in_generics(
             .collect()
     }
 
+    #[instrument(level = "trace", skip(self))]
     fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
-        debug!("bound_defines_assoc_item(b={:?}, assoc_name={:?})", b, assoc_name);
-
         match b {
             hir::GenericBound::Trait(poly_trait_ref, _) => {
                 let trait_ref = &poly_trait_ref.trait_ref;
@@ -2105,11 +2105,10 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
 
 /// Returns a list of user-specified type predicates for the definition with ID `def_id`.
 /// N.B., this does not include any implied/inferred constraints.
+#[instrument(level = "trace", skip(tcx), ret)]
 fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
     use rustc_hir::*;
 
-    debug!("explicit_predicates_of(def_id={:?})", def_id);
-
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
     let node = tcx.hir().get(hir_id);
 
@@ -2224,6 +2223,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
         + has_own_self as u32
         + early_bound_lifetimes_from_generics(tcx, ast_generics).count() as u32;
 
+    trace!(?predicates);
+    trace!(?ast_generics);
+
     // Collect the predicates that were written inline by the user on each
     // type parameter (e.g., `<T: Foo>`).
     for param in ast_generics.params {
@@ -2244,7 +2246,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
                     Some((param.hir_id, ast_generics.predicates)),
                     param.span,
                 );
+                trace!(?bounds);
                 predicates.extend(bounds.predicates(tcx, param_ty));
+                trace!(?predicates);
             }
             GenericParamKind::Const { .. } => {
                 // Bounds on const parameters are currently not possible.
@@ -2253,6 +2257,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
         }
     }
 
+    trace!(?predicates);
     // Add in the bounds that appear in the where-clause.
     for predicate in ast_generics.predicates {
         match predicate {
@@ -2338,12 +2343,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
         );
     }
 
-    let result = ty::GenericPredicates {
+    ty::GenericPredicates {
         parent: generics.parent,
         predicates: tcx.arena.alloc_from_iter(predicates),
-    };
-    debug!("explicit_predicates_of(def_id={:?}) = {:?}", def_id, result);
-    result
+    }
 }
 
 fn const_evaluatable_predicates_of<'tcx>(
index 0d2b75d3328fcc3bfb27b9ac27d48db7414b2a4d..318e8f581f7c8b42f711887229ff2133ebfe058b 100644 (file)
@@ -53,6 +53,7 @@ fn associated_type_bounds<'tcx>(
 /// impl trait it isn't possible to write a suitable predicate on the
 /// containing function and for type-alias impl trait we don't have a backwards
 /// compatibility issue.
+#[instrument(level = "trace", skip(tcx), ret)]
 fn opaque_type_bounds<'tcx>(
     tcx: TyCtxt<'tcx>,
     opaque_def_id: DefId,
@@ -67,6 +68,8 @@ fn opaque_type_bounds<'tcx>(
         let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
         // Opaque types are implicitly sized unless a `?Sized` bound is found
         <dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span);
+        debug!(?bounds);
+
         tcx.arena.alloc_from_iter(bounds.predicates(tcx, item_ty))
     })
 }
index d79450e1ae707c30a171f85ee0277df03aca63bc..4fe213ffeea35bcf69026b18a67b9177dadf188b 100644 (file)
@@ -271,11 +271,11 @@ fn add_constraints_from_ty(
                 }
 
                 for projection in data.projection_bounds() {
-                    match projection.skip_binder().term {
-                        ty::Term::Ty(ty) => {
+                    match projection.skip_binder().term.unpack() {
+                        ty::TermKind::Ty(ty) => {
                             self.add_constraints_from_ty(current, ty, self.invariant);
                         }
-                        ty::Term::Const(c) => {
+                        ty::TermKind::Const(c) => {
                             self.add_constraints_from_const(current, c, self.invariant)
                         }
                     }
index 91cff3217d21bce19ad24ebdd7632d66729a91e5..2dc12a18a8a66f029d657cfcb54af6185288a5c6 100644 (file)
@@ -992,6 +992,9 @@ pub fn set_output_capture(sink: Option<LocalStream>) -> Option<LocalStream> {
 /// the global stream.
 ///
 /// However, if the actual I/O causes an error, this function does panic.
+///
+/// Writing to non-blocking stdout/stderr can cause an error, which will lead
+/// this function to panic.
 fn print_to<T>(args: fmt::Arguments<'_>, global_s: fn() -> T, label: &str)
 where
     T: Write,
index a5003c66fcad72224b5ebc007c60d95c0ff0ba5e..6e4ba1404e55172333fe7897b6f78e62e07c4486 100644 (file)
@@ -49,6 +49,9 @@ macro_rules! panic {
 ///
 /// Panics if writing to `io::stdout()` fails.
 ///
+/// Writing to non-blocking stdout can cause an error, which will lead
+/// this macro to panic.
+///
 /// # Examples
 ///
 /// ```
@@ -107,6 +110,9 @@ macro_rules! print {
 ///
 /// Panics if writing to [`io::stdout`] fails.
 ///
+/// Writing to non-blocking stdout can cause an error, which will lead
+/// this macro to panic.
+///
 /// [`io::stdout`]: crate::io::stdout
 ///
 /// # Examples
@@ -147,6 +153,9 @@ macro_rules! println {
 ///
 /// Panics if writing to `io::stderr` fails.
 ///
+/// Writing to non-blocking stdout can cause an error, which will lead
+/// this macro to panic.
+///
 /// # Examples
 ///
 /// ```
@@ -179,6 +188,9 @@ macro_rules! eprint {
 ///
 /// Panics if writing to `io::stderr` fails.
 ///
+/// Writing to non-blocking stdout can cause an error, which will lead
+/// this macro to panic.
+///
 /// # Examples
 ///
 /// ```
index c2ad592dfea73379ca8a433aab2179307a7f2ab0..155d0297e49acfdfd8881c948645acbbdcd4f9e9 100644 (file)
@@ -403,7 +403,7 @@ pub fn file_attr(&self) -> io::Result<FileAttr> {
                     mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(),
                 ))?;
                 if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
-                    reparse_tag = attr_tag.ReparseTag;
+                    attr.reparse_tag = attr_tag.ReparseTag;
                 }
             }
             Ok(attr)
index 3c9eecbe128d6ca9b04272b1e1bbe6b454e4466c..1d5ad3cce1840bd44930b80f62e83642b88d84b1 100644 (file)
@@ -422,6 +422,7 @@ Next, we'll build a package manifest as defined by our manifest:
 
 ```sh
 ${SDK_PATH}/tools/${ARCH}/pm \
+    -api-level $(${SDK_PATH}/tools/${ARCH}/ffx version -v | grep "api-level" | head -1 |  awk -F ' ' '{print $2}') \
     -o pkg/hello_fuchsia_manifest \
     -m pkg/hello_fuchsia.manifest \
     build \
index be2227f47af613c50797412a1f30d55160049c30..980a1485b59b7674e296099d2a4816986d8615a9 100644 (file)
@@ -370,9 +370,9 @@ fn clean_type_outlives_predicate<'tcx>(
 }
 
 fn clean_middle_term<'tcx>(term: ty::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term {
-    match term {
-        ty::Term::Ty(ty) => Term::Type(clean_middle_ty(ty, cx, None)),
-        ty::Term::Const(c) => Term::Constant(clean_middle_const(c, cx)),
+    match term.unpack() {
+        ty::TermKind::Ty(ty) => Term::Type(clean_middle_ty(ty, cx, None)),
+        ty::TermKind::Const(c) => Term::Constant(clean_middle_const(c, cx)),
     }
 }
 
index fcb357e8d8ecaa43a3b1cd59540ad1eafadd4702..02c49b9a8492abb4e6674fc6eda4f5220346fa1f 100644 (file)
@@ -609,11 +609,6 @@ h2.location a {
        text-align: center;
 }
 
-#results > table {
-       width: 100%;
-       table-layout: fixed;
-}
-
 .content > .example-wrap pre.line-numbers {
        position: relative;
        -webkit-user-select: none;
@@ -767,10 +762,6 @@ pre, .rustdoc.source .example-wrap {
        margin-left: 24px;
 }
 
-.sub-variant > div > .item-info {
-       margin-top: initial;
-}
-
 .content .impl-items .docblock, .content .impl-items .item-info {
        margin-bottom: .6em;
 }
diff --git a/src/test/codegen/issue-98294-get-mut-copy-from-slice-opt.rs b/src/test/codegen/issue-98294-get-mut-copy-from-slice-opt.rs
new file mode 100644 (file)
index 0000000..7da29cd
--- /dev/null
@@ -0,0 +1,19 @@
+// min-llvm-version: 15.0.0
+// ignore-debug: The debug assertions get in the way
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// There should be no calls to panic / len_mismatch_fail.
+
+#[no_mangle]
+pub fn test(a: &mut [u8], offset: usize, bytes: &[u8]) {
+    // CHECK-LABEL: @test(
+    // CHECK-NOT: call
+    // CHECK: call void @llvm.memcpy
+    // CHECK-NOT: call
+    // CHECK: }
+    if let Some(dst) = a.get_mut(offset..offset + bytes.len()) {
+        dst.copy_from_slice(bytes);
+    }
+}
diff --git a/src/test/incremental/issue-100521-change-struct-name-assocty.rs b/src/test/incremental/issue-100521-change-struct-name-assocty.rs
new file mode 100644 (file)
index 0000000..7f8d1e6
--- /dev/null
@@ -0,0 +1,65 @@
+// revisions: rpass1 rpass2
+
+pub fn foo() {
+    bar();
+    baz::<()>();
+}
+
+fn bar()
+where
+    <() as Table>::AllColumns:,
+{
+}
+
+fn baz<W>()
+where
+    W: AsQuery,
+    <W as AsQuery>::Query:,
+{
+}
+
+trait AsQuery {
+    type Query;
+}
+
+trait UnimplementedTrait {}
+
+impl<T> AsQuery for T
+where
+    T: UnimplementedTrait,
+{
+    type Query = ();
+}
+
+struct Wrapper<Expr>(Expr);
+
+impl<Ret> AsQuery for Wrapper<Ret> {
+    type Query = ();
+}
+
+impl AsQuery for ()
+where
+    Wrapper<<() as Table>::AllColumns>: AsQuery,
+{
+    type Query = ();
+}
+
+trait Table {
+    type AllColumns;
+}
+
+#[cfg(rpass1)]
+impl Table for () {
+    type AllColumns = Checksum1;
+}
+#[cfg(rpass1)]
+struct Checksum1;
+
+#[cfg(rpass2)]
+impl Table for () {
+    type AllColumns = Checksum2;
+}
+#[cfg(rpass2)]
+struct Checksum2;
+
+fn main() {}
index 0e4c486e4640f03eb070d338c3a5103866087044..e7bde81d4ca36204fe9642958546f34714226aa2 100644 (file)
@@ -7,7 +7,7 @@ unsafe fn foo(z: *mut usize) -> u32 {
     99
 }
 
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 // EMIT_MIR array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
 fn main() {
     let mut x = [42, 43, 44];
diff --git a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir
deleted file mode 100644 (file)
index 27f883e..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-// MIR for `main` after SimplifyCfg-elaborate-drops
-
-fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +0:11
-    let mut _1: [u32; 3];                // in scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
-    let mut _4: &mut usize;              // in scope 0 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
-    let mut _5: u32;                     // in scope 0 at $DIR/array-index-is-temporary.rs:+4:12: +4:29
-    let mut _6: *mut usize;              // in scope 0 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
-    let _7: usize;                       // in scope 0 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
-    let mut _8: usize;                   // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
-    let mut _9: bool;                    // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
-    scope 1 {
-        debug x => _1;                   // in scope 1 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
-        let mut _2: usize;               // in scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
-        scope 2 {
-            debug y => _2;               // in scope 2 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
-            let _3: *mut usize;          // in scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
-            scope 3 {
-                debug z => _3;           // in scope 3 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
-                scope 4 {
-                }
-            }
-        }
-    }
-
-    bb0: {
-        StorageLive(_1);                 // scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
-        _1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array-index-is-temporary.rs:+1:17: +1:29
-        StorageLive(_2);                 // scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
-        _2 = const 1_usize;              // scope 1 at $DIR/array-index-is-temporary.rs:+2:17: +2:18
-        StorageLive(_3);                 // scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
-        StorageLive(_4);                 // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
-        _4 = &mut _2;                    // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
-        _3 = &raw mut (*_4);             // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
-        StorageDead(_4);                 // scope 2 at $DIR/array-index-is-temporary.rs:+3:31: +3:32
-        StorageLive(_5);                 // scope 3 at $DIR/array-index-is-temporary.rs:+4:12: +4:29
-        StorageLive(_6);                 // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
-        _6 = _3;                         // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
-        _5 = foo(move _6) -> bb1;        // scope 4 at $DIR/array-index-is-temporary.rs:+4:21: +4:27
-                                         // mir::Constant
-                                         // + span: $DIR/array-index-is-temporary.rs:16:21: 16:24
-                                         // + literal: Const { ty: unsafe fn(*mut usize) -> u32 {foo}, val: Value(<ZST>) }
-    }
-
-    bb1: {
-        StorageDead(_6);                 // scope 4 at $DIR/array-index-is-temporary.rs:+4:26: +4:27
-        StorageLive(_7);                 // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
-        _7 = _2;                         // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
-        _8 = Len(_1);                    // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
-        _9 = Lt(_7, _8);                 // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
-        assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
-    }
-
-    bb2: {
-        _1[_7] = move _5;                // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:29
-        StorageDead(_5);                 // scope 3 at $DIR/array-index-is-temporary.rs:+4:28: +4:29
-        StorageDead(_7);                 // scope 3 at $DIR/array-index-is-temporary.rs:+4:29: +4:30
-        _0 = const ();                   // scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +5:2
-        StorageDead(_3);                 // scope 2 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
-        StorageDead(_2);                 // scope 1 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
-        StorageDead(_1);                 // scope 0 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
-        return;                          // scope 0 at $DIR/array-index-is-temporary.rs:+5:2: +5:2
-    }
-}
diff --git a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir
deleted file mode 100644 (file)
index 27f883e..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-// MIR for `main` after SimplifyCfg-elaborate-drops
-
-fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +0:11
-    let mut _1: [u32; 3];                // in scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
-    let mut _4: &mut usize;              // in scope 0 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
-    let mut _5: u32;                     // in scope 0 at $DIR/array-index-is-temporary.rs:+4:12: +4:29
-    let mut _6: *mut usize;              // in scope 0 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
-    let _7: usize;                       // in scope 0 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
-    let mut _8: usize;                   // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
-    let mut _9: bool;                    // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
-    scope 1 {
-        debug x => _1;                   // in scope 1 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
-        let mut _2: usize;               // in scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
-        scope 2 {
-            debug y => _2;               // in scope 2 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
-            let _3: *mut usize;          // in scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
-            scope 3 {
-                debug z => _3;           // in scope 3 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
-                scope 4 {
-                }
-            }
-        }
-    }
-
-    bb0: {
-        StorageLive(_1);                 // scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
-        _1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array-index-is-temporary.rs:+1:17: +1:29
-        StorageLive(_2);                 // scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
-        _2 = const 1_usize;              // scope 1 at $DIR/array-index-is-temporary.rs:+2:17: +2:18
-        StorageLive(_3);                 // scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
-        StorageLive(_4);                 // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
-        _4 = &mut _2;                    // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
-        _3 = &raw mut (*_4);             // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
-        StorageDead(_4);                 // scope 2 at $DIR/array-index-is-temporary.rs:+3:31: +3:32
-        StorageLive(_5);                 // scope 3 at $DIR/array-index-is-temporary.rs:+4:12: +4:29
-        StorageLive(_6);                 // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
-        _6 = _3;                         // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
-        _5 = foo(move _6) -> bb1;        // scope 4 at $DIR/array-index-is-temporary.rs:+4:21: +4:27
-                                         // mir::Constant
-                                         // + span: $DIR/array-index-is-temporary.rs:16:21: 16:24
-                                         // + literal: Const { ty: unsafe fn(*mut usize) -> u32 {foo}, val: Value(<ZST>) }
-    }
-
-    bb1: {
-        StorageDead(_6);                 // scope 4 at $DIR/array-index-is-temporary.rs:+4:26: +4:27
-        StorageLive(_7);                 // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
-        _7 = _2;                         // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
-        _8 = Len(_1);                    // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
-        _9 = Lt(_7, _8);                 // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
-        assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
-    }
-
-    bb2: {
-        _1[_7] = move _5;                // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:29
-        StorageDead(_5);                 // scope 3 at $DIR/array-index-is-temporary.rs:+4:28: +4:29
-        StorageDead(_7);                 // scope 3 at $DIR/array-index-is-temporary.rs:+4:29: +4:30
-        _0 = const ();                   // scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +5:2
-        StorageDead(_3);                 // scope 2 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
-        StorageDead(_2);                 // scope 1 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
-        StorageDead(_1);                 // scope 0 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
-        return;                          // scope 0 at $DIR/array-index-is-temporary.rs:+5:2: +5:2
-    }
-}
diff --git a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644 (file)
index 0000000..27f883e
--- /dev/null
@@ -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
+    }
+}
index 049a97816f68bed68afe9b216a3d1309dc9f9047..232bcc7b27d465dc327ed666410f825ecd34ada2 100644 (file)
@@ -1,7 +1,7 @@
 // ignore-endian-big
 // ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: -Z mir-opt-level=4
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 #![feature(box_syntax)]
 // EMIT_MIR inline_into_box_place.main.Inline.diff
 fn main() {
diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff
deleted file mode 100644 (file)
index 7017413..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-- // MIR for `main` before Inline
-+ // MIR for `main` after Inline
-  
-  fn main() -> () {
-      let mut _0: ();                      // return place in scope 0 at $DIR/inline-into-box-place.rs:+0:11: +0:11
-      let _1: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11
-      let mut _2: usize;                   // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-      let mut _3: usize;                   // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-      let mut _4: *mut u8;                 // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-      let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-      let mut _6: ();                      // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
-      let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-+     let mut _8: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-      scope 1 {
-          debug _x => _1;                  // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11
-      }
-      scope 2 {
-      }
-+     scope 3 (inlined Vec::<u32>::new) {  // at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         let mut _9: 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 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         _9 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-                                           // mir::Constant
--                                          // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
--                                          // + user_ty: UserType(1)
--                                          // + literal: Const { ty: fn() -> Vec<u32> {Vec::<u32>::new}, val: Value(<ZST>) }
--     }
-- 
--     bb2: {
-+                                          // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+                                          // + user_ty: UserType(0)
-+                                          // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) }
-+         Deinit((*_8));                   // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         ((*_8).0: alloc::raw_vec::RawVec<u32>) = move _9; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         ((*_8).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         StorageDead(_9);                 // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         StorageDead(_8);                 // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-          _1 = move _5;                    // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-          StorageDead(_5);                 // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
-          _0 = const ();                   // scope 0 at $DIR/inline-into-box-place.rs:+0:11: +2:2
--         drop(_1) -> [return: bb3, unwind: 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/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff
deleted file mode 100644 (file)
index 7017413..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-- // MIR for `main` before Inline
-+ // MIR for `main` after Inline
-  
-  fn main() -> () {
-      let mut _0: ();                      // return place in scope 0 at $DIR/inline-into-box-place.rs:+0:11: +0:11
-      let _1: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11
-      let mut _2: usize;                   // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-      let mut _3: usize;                   // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-      let mut _4: *mut u8;                 // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-      let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-      let mut _6: ();                      // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
-      let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-+     let mut _8: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-      scope 1 {
-          debug _x => _1;                  // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11
-      }
-      scope 2 {
-      }
-+     scope 3 (inlined Vec::<u32>::new) {  // at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         let mut _9: 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 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         _9 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-                                           // mir::Constant
--                                          // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
--                                          // + user_ty: UserType(1)
--                                          // + literal: Const { ty: fn() -> Vec<u32> {Vec::<u32>::new}, val: Value(<ZST>) }
--     }
-- 
--     bb2: {
-+                                          // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+                                          // + user_ty: UserType(0)
-+                                          // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) }
-+         Deinit((*_8));                   // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         ((*_8).0: alloc::raw_vec::RawVec<u32>) = move _9; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         ((*_8).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         StorageDead(_9);                 // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         StorageDead(_8);                 // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-          _1 = move _5;                    // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-          StorageDead(_5);                 // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
-          _0 = const ();                   // scope 0 at $DIR/inline-into-box-place.rs:+0:11: +2:2
--         drop(_1) -> [return: bb3, unwind: 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/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff
new file mode 100644 (file)
index 0000000..7017413
--- /dev/null
@@ -0,0 +1,82 @@
+- // 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
+      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 _9: 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 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         _9 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+                                           // mir::Constant
+-                                          // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
+-                                          // + user_ty: UserType(1)
+-                                          // + literal: Const { ty: fn() -> Vec<u32> {Vec::<u32>::new}, val: Value(<ZST>) }
+-     }
+- 
+-     bb2: {
++                                          // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++                                          // + user_ty: UserType(0)
++                                          // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) }
++         Deinit((*_8));                   // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         ((*_8).0: alloc::raw_vec::RawVec<u32>) = move _9; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         ((*_8).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         StorageDead(_9);                 // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         StorageDead(_8);                 // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+          _1 = move _5;                    // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+          StorageDead(_5);                 // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
+          _0 = const ();                   // scope 0 at $DIR/inline-into-box-place.rs:+0:11: +2:2
+-         drop(_1) -> [return: bb3, unwind: 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>) }
+      }
+  }
+  
index 5c34d8e68d0c054710bd6b75320f00a428ec157d..cbd8633a345c7fdf16fa3bf449272ccf545db7ee 100644 (file)
@@ -13,7 +13,7 @@ trait Foo {
     fn get(&self) -> [u8; 2];
 }
 
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 // EMIT_MIR issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
 impl Foo for [u8; 1+1] {
     fn get(&self) -> [u8; 2] {
index 844d53a4b2bcebab09c302847c8e31dd68a68057..ebb5f5042fccb7084b85226017187e67d603f417 100644 (file)
@@ -11,14 +11,14 @@ union Foo {
     b: Never
 }
 
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 // EMIT_MIR issue_72181.foo.mir_map.0.mir
 fn foo(xs: [(Never, u32); 1]) -> u32 { xs[0].1 }
 
 // EMIT_MIR issue_72181.bar.mir_map.0.mir
 fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { x }
 
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 // EMIT_MIR issue_72181.main.mir_map.0.mir
 fn main() {
     let _ = mem::size_of::<Foo>();
index 9e731c40908790c8a9c30440333ca8bc7c8bbca9..be114cab719c0c77fb5abdb715f464b549126fdc 100644 (file)
@@ -8,5 +8,5 @@ fn main() {
     assert_eq!(split, 1);
 }
 
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 // EMIT_MIR issue_73223.main.SimplifyArmIdentity.diff
diff --git a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir
deleted file mode 100644 (file)
index 047b24d..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// MIR for `<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}` after SimplifyCfg-promote-consts
-
-<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}: usize = {
-    let mut _0: usize;                   // return place in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-    let mut _1: (usize, bool);           // in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-
-    bb0: {
-        _1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-        assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-    }
-
-    bb1: {
-        _0 = move (_1.0: usize);         // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-        return;                          // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-    }
-
-    bb2 (cleanup): {
-        resume;                          // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-    }
-}
diff --git a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir
deleted file mode 100644 (file)
index 047b24d..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// MIR for `<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}` after SimplifyCfg-promote-consts
-
-<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}: usize = {
-    let mut _0: usize;                   // return place in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-    let mut _1: (usize, bool);           // in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-
-    bb0: {
-        _1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-        assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-    }
-
-    bb1: {
-        _0 = move (_1.0: usize);         // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-        return;                          // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-    }
-
-    bb2 (cleanup): {
-        resume;                          // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-    }
-}
diff --git a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
new file mode 100644 (file)
index 0000000..047b24d
--- /dev/null
@@ -0,0 +1,20 @@
+// MIR for `<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}` after SimplifyCfg-promote-consts
+
+<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}: usize = {
+    let mut _0: usize;                   // return place in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+    let mut _1: (usize, bool);           // in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+
+    bb0: {
+        _1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+        assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+    }
+
+    bb1: {
+        _0 = move (_1.0: usize);         // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+        return;                          // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+    }
+
+    bb2 (cleanup): {
+        resume;                          // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+    }
+}
diff --git a/src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir
deleted file mode 100644 (file)
index 972ce1d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// MIR for `bar` 0 mir_map
-
-fn bar(_1: [(Never, u32); 1]) -> u32 {
-    let mut _0: u32;                     // return place in scope 0 at $DIR/issue-72181.rs:+0:40: +0:43
-    let _2: u32;                         // in scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
-    scope 1 {
-        debug x => _2;                   // in scope 1 at $DIR/issue-72181.rs:+0:13: +0:14
-    }
-
-    bb0: {
-        StorageLive(_2);                 // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
-        _2 = (_1[0 of 1].1: u32);        // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
-        _0 = _2;                         // scope 1 at $DIR/issue-72181.rs:+0:46: +0:47
-        StorageDead(_2);                 // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
-        return;                          // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
-    }
-}
diff --git a/src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir
deleted file mode 100644 (file)
index 972ce1d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// MIR for `bar` 0 mir_map
-
-fn bar(_1: [(Never, u32); 1]) -> u32 {
-    let mut _0: u32;                     // return place in scope 0 at $DIR/issue-72181.rs:+0:40: +0:43
-    let _2: u32;                         // in scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
-    scope 1 {
-        debug x => _2;                   // in scope 1 at $DIR/issue-72181.rs:+0:13: +0:14
-    }
-
-    bb0: {
-        StorageLive(_2);                 // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
-        _2 = (_1[0 of 1].1: u32);        // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
-        _0 = _2;                         // scope 1 at $DIR/issue-72181.rs:+0:46: +0:47
-        StorageDead(_2);                 // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
-        return;                          // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
-    }
-}
diff --git a/src/test/mir-opt/issue_72181.bar.mir_map.0.mir b/src/test/mir-opt/issue_72181.bar.mir_map.0.mir
new file mode 100644 (file)
index 0000000..972ce1d
--- /dev/null
@@ -0,0 +1,17 @@
+// MIR for `bar` 0 mir_map
+
+fn bar(_1: [(Never, u32); 1]) -> u32 {
+    let mut _0: u32;                     // return place in scope 0 at $DIR/issue-72181.rs:+0:40: +0:43
+    let _2: u32;                         // in scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
+    scope 1 {
+        debug x => _2;                   // in scope 1 at $DIR/issue-72181.rs:+0:13: +0:14
+    }
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
+        _2 = (_1[0 of 1].1: u32);        // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
+        _0 = _2;                         // scope 1 at $DIR/issue-72181.rs:+0:46: +0:47
+        StorageDead(_2);                 // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
+        return;                          // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
+    }
+}
diff --git a/src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir
deleted file mode 100644 (file)
index 534f131..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// MIR for `foo` 0 mir_map
-
-fn foo(_1: [(Never, u32); 1]) -> u32 {
-    debug xs => _1;                      // in scope 0 at $DIR/issue-72181.rs:+0:8: +0:10
-    let mut _0: u32;                     // return place in scope 0 at $DIR/issue-72181.rs:+0:34: +0:37
-    let _2: usize;                       // in scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
-    let mut _3: usize;                   // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
-    let mut _4: bool;                    // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
-
-    bb0: {
-        StorageLive(_2);                 // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
-        _2 = const 0_usize;              // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
-        _3 = Len(_1);                    // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
-        _4 = Lt(_2, _3);                 // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
-        assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
-    }
-
-    bb1: {
-        _0 = (_1[_2].1: u32);            // scope 0 at $DIR/issue-72181.rs:+0:40: +0:47
-        StorageDead(_2);                 // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
-        return;                          // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
-    }
-
-    bb2 (cleanup): {
-        resume;                          // scope 0 at $DIR/issue-72181.rs:+0:1: +0:49
-    }
-}
diff --git a/src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir
deleted file mode 100644 (file)
index 534f131..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// MIR for `foo` 0 mir_map
-
-fn foo(_1: [(Never, u32); 1]) -> u32 {
-    debug xs => _1;                      // in scope 0 at $DIR/issue-72181.rs:+0:8: +0:10
-    let mut _0: u32;                     // return place in scope 0 at $DIR/issue-72181.rs:+0:34: +0:37
-    let _2: usize;                       // in scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
-    let mut _3: usize;                   // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
-    let mut _4: bool;                    // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
-
-    bb0: {
-        StorageLive(_2);                 // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
-        _2 = const 0_usize;              // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
-        _3 = Len(_1);                    // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
-        _4 = Lt(_2, _3);                 // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
-        assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
-    }
-
-    bb1: {
-        _0 = (_1[_2].1: u32);            // scope 0 at $DIR/issue-72181.rs:+0:40: +0:47
-        StorageDead(_2);                 // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
-        return;                          // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
-    }
-
-    bb2 (cleanup): {
-        resume;                          // scope 0 at $DIR/issue-72181.rs:+0:1: +0:49
-    }
-}
diff --git a/src/test/mir-opt/issue_72181.foo.mir_map.0.mir b/src/test/mir-opt/issue_72181.foo.mir_map.0.mir
new file mode 100644 (file)
index 0000000..534f131
--- /dev/null
@@ -0,0 +1,27 @@
+// MIR for `foo` 0 mir_map
+
+fn foo(_1: [(Never, u32); 1]) -> u32 {
+    debug xs => _1;                      // in scope 0 at $DIR/issue-72181.rs:+0:8: +0:10
+    let mut _0: u32;                     // return place in scope 0 at $DIR/issue-72181.rs:+0:34: +0:37
+    let _2: usize;                       // in scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
+    let mut _3: usize;                   // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+    let mut _4: bool;                    // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
+        _2 = const 0_usize;              // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
+        _3 = Len(_1);                    // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+        _4 = Lt(_2, _3);                 // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+        assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+    }
+
+    bb1: {
+        _0 = (_1[_2].1: u32);            // scope 0 at $DIR/issue-72181.rs:+0:40: +0:47
+        StorageDead(_2);                 // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
+        return;                          // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
+    }
+
+    bb2 (cleanup): {
+        resume;                          // scope 0 at $DIR/issue-72181.rs:+0:1: +0:49
+    }
+}
diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir
deleted file mode 100644 (file)
index 425906f..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-// MIR for `main` 0 mir_map
-
-fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/issue-72181.rs:+0:11: +0:11
-    let mut _1: usize;                   // in scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
-    let mut _3: Foo;                     // in scope 0 at $DIR/issue-72181.rs:+3:14: +3:27
-    let mut _4: Foo;                     // in scope 0 at $DIR/issue-72181.rs:+3:29: +3:42
-    let mut _5: u64;                     // in scope 0 at $DIR/issue-72181.rs:+4:13: +4:30
-    let _6: usize;                       // in scope 0 at $DIR/issue-72181.rs:+4:24: +4:25
-    let mut _7: usize;                   // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
-    let mut _8: bool;                    // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
-    scope 1 {
-        let _2: [Foo; 2];                // in scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
-        scope 2 {
-            debug f => _2;               // in scope 2 at $DIR/issue-72181.rs:+3:9: +3:10
-            scope 3 {
-            }
-            scope 4 {
-            }
-        }
-    }
-
-    bb0: {
-        StorageLive(_1);                 // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
-        _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
-                                         // mir::Constant
-                                         // + span: $DIR/issue-72181.rs:24:13: 24:32
-                                         // + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(<ZST>) }
-    }
-
-    bb1: {
-        StorageDead(_1);                 // scope 0 at $DIR/issue-72181.rs:+1:34: +1:35
-        StorageLive(_2);                 // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
-        StorageLive(_3);                 // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
-        _3 = Foo { a: const 42_u64 };    // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
-        StorageLive(_4);                 // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
-        _4 = Foo { a: const 10_u64 };    // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
-        _2 = [move _3, move _4];         // scope 1 at $DIR/issue-72181.rs:+3:13: +3:43
-        StorageDead(_4);                 // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
-        StorageDead(_3);                 // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
-        FakeRead(ForLet(None), _2);      // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
-        StorageLive(_5);                 // scope 2 at $DIR/issue-72181.rs:+4:13: +4:30
-        StorageLive(_6);                 // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
-        _6 = const 0_usize;              // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
-        _7 = Len(_2);                    // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
-        _8 = Lt(_6, _7);                 // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
-        assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
-    }
-
-    bb2: {
-        _5 = (_2[_6].0: u64);            // scope 4 at $DIR/issue-72181.rs:+4:22: +4:28
-        StorageDead(_6);                 // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
-        StorageDead(_5);                 // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
-        _0 = const ();                   // scope 0 at $DIR/issue-72181.rs:+0:11: +5:2
-        StorageDead(_2);                 // scope 1 at $DIR/issue-72181.rs:+5:1: +5:2
-        return;                          // scope 0 at $DIR/issue-72181.rs:+5:2: +5:2
-    }
-
-    bb3 (cleanup): {
-        resume;                          // scope 0 at $DIR/issue-72181.rs:+0:1: +5:2
-    }
-}
diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir
deleted file mode 100644 (file)
index 425906f..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-// MIR for `main` 0 mir_map
-
-fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/issue-72181.rs:+0:11: +0:11
-    let mut _1: usize;                   // in scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
-    let mut _3: Foo;                     // in scope 0 at $DIR/issue-72181.rs:+3:14: +3:27
-    let mut _4: Foo;                     // in scope 0 at $DIR/issue-72181.rs:+3:29: +3:42
-    let mut _5: u64;                     // in scope 0 at $DIR/issue-72181.rs:+4:13: +4:30
-    let _6: usize;                       // in scope 0 at $DIR/issue-72181.rs:+4:24: +4:25
-    let mut _7: usize;                   // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
-    let mut _8: bool;                    // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
-    scope 1 {
-        let _2: [Foo; 2];                // in scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
-        scope 2 {
-            debug f => _2;               // in scope 2 at $DIR/issue-72181.rs:+3:9: +3:10
-            scope 3 {
-            }
-            scope 4 {
-            }
-        }
-    }
-
-    bb0: {
-        StorageLive(_1);                 // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
-        _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
-                                         // mir::Constant
-                                         // + span: $DIR/issue-72181.rs:24:13: 24:32
-                                         // + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(<ZST>) }
-    }
-
-    bb1: {
-        StorageDead(_1);                 // scope 0 at $DIR/issue-72181.rs:+1:34: +1:35
-        StorageLive(_2);                 // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
-        StorageLive(_3);                 // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
-        _3 = Foo { a: const 42_u64 };    // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
-        StorageLive(_4);                 // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
-        _4 = Foo { a: const 10_u64 };    // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
-        _2 = [move _3, move _4];         // scope 1 at $DIR/issue-72181.rs:+3:13: +3:43
-        StorageDead(_4);                 // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
-        StorageDead(_3);                 // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
-        FakeRead(ForLet(None), _2);      // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
-        StorageLive(_5);                 // scope 2 at $DIR/issue-72181.rs:+4:13: +4:30
-        StorageLive(_6);                 // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
-        _6 = const 0_usize;              // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
-        _7 = Len(_2);                    // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
-        _8 = Lt(_6, _7);                 // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
-        assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
-    }
-
-    bb2: {
-        _5 = (_2[_6].0: u64);            // scope 4 at $DIR/issue-72181.rs:+4:22: +4:28
-        StorageDead(_6);                 // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
-        StorageDead(_5);                 // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
-        _0 = const ();                   // scope 0 at $DIR/issue-72181.rs:+0:11: +5:2
-        StorageDead(_2);                 // scope 1 at $DIR/issue-72181.rs:+5:1: +5:2
-        return;                          // scope 0 at $DIR/issue-72181.rs:+5:2: +5:2
-    }
-
-    bb3 (cleanup): {
-        resume;                          // scope 0 at $DIR/issue-72181.rs:+0:1: +5:2
-    }
-}
diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.mir
new file mode 100644 (file)
index 0000000..425906f
--- /dev/null
@@ -0,0 +1,62 @@
+// MIR for `main` 0 mir_map
+
+fn main() -> () {
+    let mut _0: ();                      // return place in scope 0 at $DIR/issue-72181.rs:+0:11: +0:11
+    let mut _1: usize;                   // in scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
+    let mut _3: Foo;                     // in scope 0 at $DIR/issue-72181.rs:+3:14: +3:27
+    let mut _4: Foo;                     // in scope 0 at $DIR/issue-72181.rs:+3:29: +3:42
+    let mut _5: u64;                     // in scope 0 at $DIR/issue-72181.rs:+4:13: +4:30
+    let _6: usize;                       // in scope 0 at $DIR/issue-72181.rs:+4:24: +4:25
+    let mut _7: usize;                   // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
+    let mut _8: bool;                    // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
+    scope 1 {
+        let _2: [Foo; 2];                // in scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
+        scope 2 {
+            debug f => _2;               // in scope 2 at $DIR/issue-72181.rs:+3:9: +3:10
+            scope 3 {
+            }
+            scope 4 {
+            }
+        }
+    }
+
+    bb0: {
+        StorageLive(_1);                 // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
+        _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
+                                         // mir::Constant
+                                         // + span: $DIR/issue-72181.rs:24:13: 24:32
+                                         // + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(<ZST>) }
+    }
+
+    bb1: {
+        StorageDead(_1);                 // scope 0 at $DIR/issue-72181.rs:+1:34: +1:35
+        StorageLive(_2);                 // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
+        StorageLive(_3);                 // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
+        _3 = Foo { a: const 42_u64 };    // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
+        StorageLive(_4);                 // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
+        _4 = Foo { a: const 10_u64 };    // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
+        _2 = [move _3, move _4];         // scope 1 at $DIR/issue-72181.rs:+3:13: +3:43
+        StorageDead(_4);                 // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
+        StorageDead(_3);                 // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
+        FakeRead(ForLet(None), _2);      // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
+        StorageLive(_5);                 // scope 2 at $DIR/issue-72181.rs:+4:13: +4:30
+        StorageLive(_6);                 // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
+        _6 = const 0_usize;              // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
+        _7 = Len(_2);                    // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
+        _8 = Lt(_6, _7);                 // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
+        assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
+    }
+
+    bb2: {
+        _5 = (_2[_6].0: u64);            // scope 4 at $DIR/issue-72181.rs:+4:22: +4:28
+        StorageDead(_6);                 // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
+        StorageDead(_5);                 // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
+        _0 = const ();                   // scope 0 at $DIR/issue-72181.rs:+0:11: +5:2
+        StorageDead(_2);                 // scope 1 at $DIR/issue-72181.rs:+5:1: +5:2
+        return;                          // scope 0 at $DIR/issue-72181.rs:+5:2: +5:2
+    }
+
+    bb3 (cleanup): {
+        resume;                          // scope 0 at $DIR/issue-72181.rs:+0:1: +5:2
+    }
+}
diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff
deleted file mode 100644 (file)
index ac7fe31..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-- // MIR for `main` before SimplifyArmIdentity
-+ // MIR for `main` after SimplifyArmIdentity
-  
-  fn main() -> () {
-      let mut _0: ();                      // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
-      let _1: i32;                         // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
-      let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
-      let mut _3: isize;                   // in scope 0 at $DIR/issue-73223.rs:+2:9: +2:16
-      let _4: i32;                         // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
-      let mut _5: !;                       // in scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
-      let mut _7: i32;                     // in scope 0 at $DIR/issue-73223.rs:+6:22: +6:27
-      let _8: ();                          // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _9: (&i32, &i32);            // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _10: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _11: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let _12: i32;                        // in scope 0 at $DIR/issue-73223.rs:+7:23: +7:24
-      let mut _15: bool;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _16: bool;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _17: i32;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _18: i32;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _19: !;                      // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let _21: !;                          // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _22: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _23: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let _24: &i32;                       // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _25: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let _26: &i32;                       // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _27: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      scope 1 {
-          debug split => _1;               // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
-          let _6: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
-          scope 3 {
-              debug _prev => _6;           // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
-              let _13: &i32;               // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-              let _14: &i32;               // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-              let mut _28: &i32;           // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-              scope 4 {
-                  debug left_val => _13;   // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                  debug right_val => _14;  // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                  let _20: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                  scope 5 {
-                      debug kind => _20;   // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                  }
-              }
-          }
-      }
-      scope 2 {
-          debug v => _4;                   // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
-      }
-  
-      bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
-          StorageLive(_2);                 // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
-          Deinit(_2);                      // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
-          ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
-          discriminant(_2) = 1;            // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
-          _3 = const 1_isize;              // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
-          goto -> bb3;                     // scope 0 at $DIR/issue-73223.rs:+1:17: +1:30
-      }
-  
-      bb1: {
-          nop;                             // scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
-          StorageDead(_2);                 // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
-          StorageDead(_1);                 // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
-          return;                          // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
-      }
-  
-      bb2: {
-          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(_6);                 // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
-          StorageLive(_7);                 // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
-          _7 = _1;                         // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
-          Deinit(_6);                      // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
-          ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
-          discriminant(_6) = 1;            // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
-          StorageDead(_7);                 // scope 1 at $DIR/issue-73223.rs:+6:27: +6:28
-          StorageLive(_8);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_9);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_10);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _10 = &_1;                       // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_11);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _28 = const main::promoted[0];   // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // mir::Constant
-                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
-          _11 = _28;                       // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          Deinit(_9);                      // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          (_9.0: &i32) = move _10;         // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          (_9.1: &i32) = move _11;         // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_11);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_10);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_13);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _13 = (_9.0: &i32);              // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_14);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _14 = (_9.1: &i32);              // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_15);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_16);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_17);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _17 = (*_13);                    // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_18);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _18 = const 1_i32;               // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _16 = Eq(move _17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_18);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_17);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _15 = Not(move _16);             // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_16);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          switchInt(move _15) -> [false: bb5, otherwise: bb4]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      }
-  
-      bb4: {
-          StorageLive(_20);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          Deinit(_20);                     // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          discriminant(_20) = 0;           // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_21);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_22);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _22 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // mir::Constant
-                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
-          StorageLive(_23);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_24);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _24 = _13;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _23 = _24;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_25);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_26);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _26 = _14;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _25 = _26;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_27);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          Deinit(_27);                     // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          discriminant(_27) = 0;           // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _21 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _23, move _25, move _27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // mir::Constant
-                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
-                                           // mir::Constant
-                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
-      }
-  
-      bb5: {
-          nop;                             // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_15);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_14);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_13);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_9);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_8);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          nop;                             // scope 0 at $DIR/issue-73223.rs:+0:11: +8:2
-          StorageDead(_6);                 // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
-          StorageDead(_1);                 // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
-          return;                          // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff
deleted file mode 100644 (file)
index ac7fe31..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-- // MIR for `main` before SimplifyArmIdentity
-+ // MIR for `main` after SimplifyArmIdentity
-  
-  fn main() -> () {
-      let mut _0: ();                      // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
-      let _1: i32;                         // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
-      let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
-      let mut _3: isize;                   // in scope 0 at $DIR/issue-73223.rs:+2:9: +2:16
-      let _4: i32;                         // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
-      let mut _5: !;                       // in scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
-      let mut _7: i32;                     // in scope 0 at $DIR/issue-73223.rs:+6:22: +6:27
-      let _8: ();                          // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _9: (&i32, &i32);            // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _10: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _11: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let _12: i32;                        // in scope 0 at $DIR/issue-73223.rs:+7:23: +7:24
-      let mut _15: bool;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _16: bool;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _17: i32;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _18: i32;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _19: !;                      // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let _21: !;                          // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _22: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _23: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let _24: &i32;                       // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _25: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let _26: &i32;                       // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _27: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      scope 1 {
-          debug split => _1;               // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
-          let _6: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
-          scope 3 {
-              debug _prev => _6;           // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
-              let _13: &i32;               // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-              let _14: &i32;               // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-              let mut _28: &i32;           // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-              scope 4 {
-                  debug left_val => _13;   // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                  debug right_val => _14;  // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                  let _20: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                  scope 5 {
-                      debug kind => _20;   // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                  }
-              }
-          }
-      }
-      scope 2 {
-          debug v => _4;                   // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
-      }
-  
-      bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
-          StorageLive(_2);                 // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
-          Deinit(_2);                      // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
-          ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
-          discriminant(_2) = 1;            // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
-          _3 = const 1_isize;              // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
-          goto -> bb3;                     // scope 0 at $DIR/issue-73223.rs:+1:17: +1:30
-      }
-  
-      bb1: {
-          nop;                             // scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
-          StorageDead(_2);                 // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
-          StorageDead(_1);                 // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
-          return;                          // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
-      }
-  
-      bb2: {
-          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(_6);                 // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
-          StorageLive(_7);                 // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
-          _7 = _1;                         // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
-          Deinit(_6);                      // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
-          ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
-          discriminant(_6) = 1;            // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
-          StorageDead(_7);                 // scope 1 at $DIR/issue-73223.rs:+6:27: +6:28
-          StorageLive(_8);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_9);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_10);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _10 = &_1;                       // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_11);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _28 = const main::promoted[0];   // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // mir::Constant
-                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
-          _11 = _28;                       // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          Deinit(_9);                      // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          (_9.0: &i32) = move _10;         // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          (_9.1: &i32) = move _11;         // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_11);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_10);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_13);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _13 = (_9.0: &i32);              // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_14);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _14 = (_9.1: &i32);              // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_15);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_16);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_17);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _17 = (*_13);                    // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_18);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _18 = const 1_i32;               // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _16 = Eq(move _17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_18);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_17);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _15 = Not(move _16);             // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_16);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          switchInt(move _15) -> [false: bb5, otherwise: bb4]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      }
-  
-      bb4: {
-          StorageLive(_20);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          Deinit(_20);                     // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          discriminant(_20) = 0;           // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_21);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_22);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _22 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // mir::Constant
-                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
-          StorageLive(_23);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_24);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _24 = _13;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _23 = _24;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_25);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_26);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _26 = _14;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _25 = _26;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_27);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          Deinit(_27);                     // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          discriminant(_27) = 0;           // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _21 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _23, move _25, move _27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // mir::Constant
-                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
-                                           // mir::Constant
-                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
-      }
-  
-      bb5: {
-          nop;                             // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_15);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_14);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_13);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_9);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_8);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          nop;                             // scope 0 at $DIR/issue-73223.rs:+0:11: +8:2
-          StorageDead(_6);                 // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
-          StorageDead(_1);                 // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
-          return;                          // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff
new file mode 100644 (file)
index 0000000..ac7fe31
--- /dev/null
@@ -0,0 +1,161 @@
+- // MIR for `main` before SimplifyArmIdentity
++ // MIR for `main` after SimplifyArmIdentity
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
+      let _1: i32;                         // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
+      let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+      let mut _3: isize;                   // in scope 0 at $DIR/issue-73223.rs:+2:9: +2:16
+      let _4: i32;                         // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
+      let mut _5: !;                       // in scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
+      let mut _7: i32;                     // in scope 0 at $DIR/issue-73223.rs:+6:22: +6:27
+      let _8: ();                          // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _9: (&i32, &i32);            // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _10: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _11: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let _12: i32;                        // in scope 0 at $DIR/issue-73223.rs:+7:23: +7:24
+      let mut _15: bool;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _16: bool;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _17: i32;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _18: i32;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _19: !;                      // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let _21: !;                          // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _22: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _23: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let _24: &i32;                       // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _25: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let _26: &i32;                       // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _27: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      scope 1 {
+          debug split => _1;               // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
+          let _6: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
+          scope 3 {
+              debug _prev => _6;           // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
+              let _13: &i32;               // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+              let _14: &i32;               // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+              let mut _28: &i32;           // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+              scope 4 {
+                  debug left_val => _13;   // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                  debug right_val => _14;  // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                  let _20: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                  scope 5 {
+                      debug kind => _20;   // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                  }
+              }
+          }
+      }
+      scope 2 {
+          debug v => _4;                   // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
+          StorageLive(_2);                 // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+          Deinit(_2);                      // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+          ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+          discriminant(_2) = 1;            // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+          _3 = const 1_isize;              // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+          goto -> bb3;                     // scope 0 at $DIR/issue-73223.rs:+1:17: +1:30
+      }
+  
+      bb1: {
+          nop;                             // scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
+          StorageDead(_2);                 // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
+          StorageDead(_1);                 // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
+          return;                          // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
+      }
+  
+      bb2: {
+          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(_6);                 // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
+          StorageLive(_7);                 // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
+          _7 = _1;                         // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
+          Deinit(_6);                      // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
+          ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
+          discriminant(_6) = 1;            // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
+          StorageDead(_7);                 // scope 1 at $DIR/issue-73223.rs:+6:27: +6:28
+          StorageLive(_8);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_9);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_10);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _10 = &_1;                       // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_11);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _28 = const main::promoted[0];   // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                                           // mir::Constant
+                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                                           // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
+          _11 = _28;                       // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          Deinit(_9);                      // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          (_9.0: &i32) = move _10;         // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          (_9.1: &i32) = move _11;         // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageDead(_11);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageDead(_10);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_13);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _13 = (_9.0: &i32);              // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_14);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _14 = (_9.1: &i32);              // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_15);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_16);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_17);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _17 = (*_13);                    // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_18);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _18 = const 1_i32;               // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _16 = Eq(move _17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageDead(_18);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageDead(_17);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _15 = Not(move _16);             // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageDead(_16);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          switchInt(move _15) -> [false: bb5, otherwise: bb4]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      }
+  
+      bb4: {
+          StorageLive(_20);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          Deinit(_20);                     // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          discriminant(_20) = 0;           // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_21);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_22);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _22 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                                           // mir::Constant
+                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                                           // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
+          StorageLive(_23);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_24);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _24 = _13;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _23 = _24;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_25);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_26);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _26 = _14;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _25 = _26;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageLive(_27);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          Deinit(_27);                     // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          discriminant(_27) = 0;           // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _21 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _23, move _25, move _27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                                           // mir::Constant
+                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                                           // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
+                                           // mir::Constant
+                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                                           // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
+      }
+  
+      bb5: {
+          nop;                             // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageDead(_15);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageDead(_14);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageDead(_13);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageDead(_9);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          StorageDead(_8);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          nop;                             // scope 0 at $DIR/issue-73223.rs:+0:11: +8:2
+          StorageDead(_6);                 // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
+          StorageDead(_1);                 // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
+          return;                          // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff
new file mode 100644 (file)
index 0000000..d9898d8
--- /dev/null
@@ -0,0 +1,26 @@
+- // MIR for `assume` before LowerIntrinsics
++ // MIR for `assume` after LowerIntrinsics
+  
+  fn assume() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:17
+      let _1: ();                          // in scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:38
+      scope 1 {
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
+-         _1 = std::intrinsics::assume(const true) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
+-                                          // mir::Constant
+-                                          // + span: $DIR/lower_intrinsics.rs:72:9: 72:32
+-                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(bool) {std::intrinsics::assume}, val: Value(<ZST>) }
++         assume(const true);              // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
++         goto -> bb1;                     // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
+      }
+  
+      bb1: {
+          StorageDead(_1);                 // scope 1 at $DIR/lower_intrinsics.rs:+2:38: +2:39
+          _0 = const ();                   // scope 1 at $DIR/lower_intrinsics.rs:+1:5: +3:6
+          return;                          // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff
new file mode 100644 (file)
index 0000000..4fb6752
--- /dev/null
@@ -0,0 +1,72 @@
+- // MIR for `f_copy_nonoverlapping` before LowerIntrinsics
++ // MIR for `f_copy_nonoverlapping` after LowerIntrinsics
+  
+  fn f_copy_nonoverlapping() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:32: +0:32
+      let _1: ();                          // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:12
+      let _3: ();                          // in scope 0 at $DIR/lower_intrinsics.rs:+4:9: +4:95
+      let mut _4: *const i32;              // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:59
+      let mut _5: *const ();               // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+      let mut _6: *const ();               // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+      let _7: &();                         // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:33
+      let mut _8: *mut i32;                // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:91
+      let mut _9: *mut ();                 // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+      let mut _10: *mut ();                // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+      let mut _11: &mut ();                // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:69
+      scope 1 {
+          debug src => _1;                 // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:12
+          let mut _2: ();                  // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:16
+          scope 2 {
+              debug dst => _2;             // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:16
+              scope 3 {
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:12
+          Deinit(_1);                      // scope 0 at $DIR/lower_intrinsics.rs:+1:15: +1:17
+          StorageLive(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:16
+          Deinit(_2);                      // scope 1 at $DIR/lower_intrinsics.rs:+2:19: +2:21
+          StorageLive(_3);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
+          StorageLive(_4);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:59
+          StorageLive(_5);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+          StorageLive(_6);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+          StorageLive(_7);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33
+          _7 = &_1;                        // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33
+          _6 = &raw const (*_7);           // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33
+          _5 = _6;                         // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+          _4 = move _5 as *const i32 (Misc); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:59
+          StorageDead(_5);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:58: +4:59
+          StorageLive(_8);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:91
+          StorageLive(_9);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+          StorageLive(_10);                // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+          StorageLive(_11);                // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69
+          _11 = &mut _2;                   // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69
+          _10 = &raw mut (*_11);           // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69
+          _9 = _10;                        // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+          _8 = move _9 as *mut i32 (Misc); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:91
+          StorageDead(_9);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:90: +4:91
+-         _3 = copy_nonoverlapping::<i32>(move _4, move _8, const 0_usize) -> bb1; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
+-                                          // mir::Constant
+-                                          // + span: $DIR/lower_intrinsics.rs:65:9: 65:28
+-                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32, *mut i32, usize) {copy_nonoverlapping::<i32>}, val: Value(<ZST>) }
++         copy_nonoverlapping(dst = move _8, src = move _4, count = const 0_usize); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
++         goto -> bb1;                     // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
+      }
+  
+      bb1: {
+          StorageDead(_8);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:94: +4:95
+          StorageDead(_4);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:94: +4:95
+          StorageDead(_11);                // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+          StorageDead(_10);                // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+          StorageDead(_7);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+          StorageDead(_6);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+          StorageDead(_3);                 // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+          _0 = const ();                   // scope 3 at $DIR/lower_intrinsics.rs:+3:5: +5:6
+          StorageDead(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:+6:1: +6:2
+          StorageDead(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:+6:1: +6:2
+          return;                          // scope 0 at $DIR/lower_intrinsics.rs:+6:2: +6:2
+      }
+  }
+  
index 195543d42bb5ba157b8a46c5d2b5fed5c1a96a13..66dae0e46b9d7a15912ad5d6c02394dd58f4fee9 100644 (file)
@@ -1,7 +1,7 @@
 // unit-test: LowerIntrinsics
 // ignore-wasm32 compiled with panic=abort by default
 
-#![feature(core_intrinsics)]
+#![feature(core_intrinsics, intrinsics)]
 #![crate_type = "lib"]
 
 // EMIT_MIR lower_intrinsics.wrapping.LowerIntrinsics.diff
@@ -51,3 +51,24 @@ pub fn discriminant<T>(t: T) {
     core::intrinsics::discriminant_value(&());
     core::intrinsics::discriminant_value(&E::B);
 }
+
+extern "rust-intrinsic" {
+    // Cannot use `std::intrinsics::copy_nonoverlapping` as that is a wrapper function
+    fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+}
+
+// EMIT_MIR lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff
+pub fn f_copy_nonoverlapping() {
+    let src = ();
+    let mut dst = ();
+    unsafe {
+        copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0);
+    }
+}
+
+// EMIT_MIR lower_intrinsics.assume.LowerIntrinsics.diff
+pub fn assume() {
+    unsafe {
+        std::intrinsics::assume(true);
+    }
+}
diff --git a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff
deleted file mode 100644 (file)
index f9eeb1e..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-- // MIR for `bar` before MatchBranchSimplification
-+ // MIR for `bar` after MatchBranchSimplification
-  
-  fn bar(_1: i32) -> (bool, bool, bool, bool) {
-      debug i => _1;                       // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:9
-      let mut _0: (bool, bool, bool, bool); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:19: +0:43
-      let _2: bool;                        // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
-      let _6: ();                          // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +21:6
-      let mut _7: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+23:6: +23:7
-      let mut _8: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+23:9: +23:10
-      let mut _9: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+23:12: +23:13
-      let mut _10: bool;                   // in scope 0 at $DIR/matches_reduce_branches.rs:+23:15: +23:16
-+     let mut _11: i32;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
-      scope 1 {
-          debug a => _2;                   // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
-          let _3: bool;                    // in scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
-          scope 2 {
-              debug b => _3;               // in scope 2 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
-              let _4: bool;                // in scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
-              scope 3 {
-                  debug c => _4;           // in scope 3 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
-                  let _5: bool;            // in scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
-                  scope 4 {
-                      debug d => _5;       // in scope 4 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
-                  }
-              }
-          }
-      }
-  
-      bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
-          StorageLive(_3);                 // scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
-          StorageLive(_4);                 // scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
-          StorageLive(_5);                 // scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
-          StorageLive(_6);                 // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +21:6
--         switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
--     }
-- 
--     bb1: {
--         _2 = const true;                 // scope 4 at $DIR/matches_reduce_branches.rs:+15:13: +15:21
--         _3 = const false;                // scope 4 at $DIR/matches_reduce_branches.rs:+16:13: +16:22
--         _4 = const false;                // scope 4 at $DIR/matches_reduce_branches.rs:+17:13: +17:22
--         _5 = const true;                 // scope 4 at $DIR/matches_reduce_branches.rs:+18:13: +18:21
--         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/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff
deleted file mode 100644 (file)
index f9eeb1e..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-- // MIR for `bar` before MatchBranchSimplification
-+ // MIR for `bar` after MatchBranchSimplification
-  
-  fn bar(_1: i32) -> (bool, bool, bool, bool) {
-      debug i => _1;                       // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:9
-      let mut _0: (bool, bool, bool, bool); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:19: +0:43
-      let _2: bool;                        // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
-      let _6: ();                          // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +21:6
-      let mut _7: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+23:6: +23:7
-      let mut _8: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+23:9: +23:10
-      let mut _9: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+23:12: +23:13
-      let mut _10: bool;                   // in scope 0 at $DIR/matches_reduce_branches.rs:+23:15: +23:16
-+     let mut _11: i32;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
-      scope 1 {
-          debug a => _2;                   // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
-          let _3: bool;                    // in scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
-          scope 2 {
-              debug b => _3;               // in scope 2 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
-              let _4: bool;                // in scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
-              scope 3 {
-                  debug c => _4;           // in scope 3 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
-                  let _5: bool;            // in scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
-                  scope 4 {
-                      debug d => _5;       // in scope 4 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
-                  }
-              }
-          }
-      }
-  
-      bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
-          StorageLive(_3);                 // scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
-          StorageLive(_4);                 // scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
-          StorageLive(_5);                 // scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
-          StorageLive(_6);                 // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +21:6
--         switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
--     }
-- 
--     bb1: {
--         _2 = const true;                 // scope 4 at $DIR/matches_reduce_branches.rs:+15:13: +15:21
--         _3 = const false;                // scope 4 at $DIR/matches_reduce_branches.rs:+16:13: +16:22
--         _4 = const false;                // scope 4 at $DIR/matches_reduce_branches.rs:+17:13: +17:22
--         _5 = const true;                 // scope 4 at $DIR/matches_reduce_branches.rs:+18:13: +18:21
--         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/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff
new file mode 100644 (file)
index 0000000..f9eeb1e
--- /dev/null
@@ -0,0 +1,88 @@
+- // MIR for `bar` before MatchBranchSimplification
++ // MIR for `bar` after MatchBranchSimplification
+  
+  fn bar(_1: i32) -> (bool, bool, bool, bool) {
+      debug i => _1;                       // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:9
+      let mut _0: (bool, bool, bool, bool); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:19: +0:43
+      let _2: bool;                        // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
+      let _6: ();                          // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +21:6
+      let mut _7: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+23:6: +23:7
+      let mut _8: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+23:9: +23:10
+      let mut _9: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+23:12: +23:13
+      let mut _10: bool;                   // in scope 0 at $DIR/matches_reduce_branches.rs:+23:15: +23:16
++     let mut _11: i32;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
+      scope 1 {
+          debug a => _2;                   // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
+          let _3: bool;                    // in scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
+          scope 2 {
+              debug b => _3;               // in scope 2 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
+              let _4: bool;                // in scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
+              scope 3 {
+                  debug c => _4;           // in scope 3 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
+                  let _5: bool;            // in scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
+                  scope 4 {
+                      debug d => _5;       // in scope 4 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
+          StorageLive(_3);                 // scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
+          StorageLive(_4);                 // scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
+          StorageLive(_5);                 // scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
+          StorageLive(_6);                 // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +21:6
+-         switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
+-     }
+- 
+-     bb1: {
+-         _2 = const true;                 // scope 4 at $DIR/matches_reduce_branches.rs:+15:13: +15:21
+-         _3 = const false;                // scope 4 at $DIR/matches_reduce_branches.rs:+16:13: +16:22
+-         _4 = const false;                // scope 4 at $DIR/matches_reduce_branches.rs:+17:13: +17:22
+-         _5 = const true;                 // scope 4 at $DIR/matches_reduce_branches.rs:+18:13: +18:21
+-         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/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff
deleted file mode 100644 (file)
index 0b40b3b..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-- // MIR for `foo` before MatchBranchSimplification
-+ // MIR for `foo` after MatchBranchSimplification
-  
-  fn foo(_1: Option<()>) -> () {
-      debug bar => _1;                     // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
-      let mut _0: ();                      // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
-      let mut _2: bool;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _3: isize;                   // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
-+     let mut _4: isize;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-  
-      bb0: {
-          StorageLive(_2);                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _3 = discriminant(_1);           // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
--         switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+         StorageLive(_4);                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+         _4 = move _3;                    // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+         _2 = Eq(_4, const 0_isize);      // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+         StorageDead(_4);                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+         switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      }
-  
-      bb1: {
--         _2 = const false;                // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
--         goto -> bb3;                     // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
--     }
-- 
--     bb2: {
--         _2 = const true;                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
--         goto -> bb3;                     // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
--     }
-- 
--     bb3: {
--         switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
--     }
-- 
--     bb4: {
-          Deinit(_0);                      // scope 0 at $DIR/matches_reduce_branches.rs:+2:9: +2:11
--         goto -> bb6;                     // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
-+         goto -> bb3;                     // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
-      }
-  
--     bb5: {
-+     bb2: {
-          _0 = const ();                   // scope 0 at $DIR/matches_reduce_branches.rs:+3:6: +3:6
--         goto -> bb6;                     // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
-+         goto -> bb3;                     // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
-      }
-  
--     bb6: {
-+     bb3: {
-          StorageDead(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:+3:5: +3:6
-          return;                          // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff
deleted file mode 100644 (file)
index 0b40b3b..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-- // MIR for `foo` before MatchBranchSimplification
-+ // MIR for `foo` after MatchBranchSimplification
-  
-  fn foo(_1: Option<()>) -> () {
-      debug bar => _1;                     // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
-      let mut _0: ();                      // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
-      let mut _2: bool;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _3: isize;                   // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
-+     let mut _4: isize;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-  
-      bb0: {
-          StorageLive(_2);                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _3 = discriminant(_1);           // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
--         switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+         StorageLive(_4);                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+         _4 = move _3;                    // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+         _2 = Eq(_4, const 0_isize);      // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+         StorageDead(_4);                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+         switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      }
-  
-      bb1: {
--         _2 = const false;                // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
--         goto -> bb3;                     // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
--     }
-- 
--     bb2: {
--         _2 = const true;                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
--         goto -> bb3;                     // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
--     }
-- 
--     bb3: {
--         switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
--     }
-- 
--     bb4: {
-          Deinit(_0);                      // scope 0 at $DIR/matches_reduce_branches.rs:+2:9: +2:11
--         goto -> bb6;                     // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
-+         goto -> bb3;                     // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
-      }
-  
--     bb5: {
-+     bb2: {
-          _0 = const ();                   // scope 0 at $DIR/matches_reduce_branches.rs:+3:6: +3:6
--         goto -> bb6;                     // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
-+         goto -> bb3;                     // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
-      }
-  
--     bb6: {
-+     bb3: {
-          StorageDead(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:+3:5: +3:6
-          return;                          // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff
new file mode 100644 (file)
index 0000000..0b40b3b
--- /dev/null
@@ -0,0 +1,55 @@
+- // MIR for `foo` before MatchBranchSimplification
++ // MIR for `foo` after MatchBranchSimplification
+  
+  fn foo(_1: Option<()>) -> () {
+      debug bar => _1;                     // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
+      let mut _0: ();                      // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
+      let mut _2: bool;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _3: isize;                   // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
++     let mut _4: isize;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _3 = discriminant(_1);           // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
+-         switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++         StorageLive(_4);                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++         _4 = move _3;                    // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++         _2 = Eq(_4, const 0_isize);      // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++         StorageDead(_4);                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++         switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      }
+  
+      bb1: {
+-         _2 = const false;                // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+-         goto -> bb3;                     // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+-     }
+- 
+-     bb2: {
+-         _2 = const true;                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+-         goto -> bb3;                     // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+-     }
+- 
+-     bb3: {
+-         switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+-     }
+- 
+-     bb4: {
+          Deinit(_0);                      // scope 0 at $DIR/matches_reduce_branches.rs:+2:9: +2:11
+-         goto -> bb6;                     // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
++         goto -> bb3;                     // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
+      }
+  
+-     bb5: {
++     bb2: {
+          _0 = const ();                   // scope 0 at $DIR/matches_reduce_branches.rs:+3:6: +3:6
+-         goto -> bb6;                     // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
++         goto -> bb3;                     // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
+      }
+  
+-     bb6: {
++     bb3: {
+          StorageDead(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:+3:5: +3:6
+          return;                          // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff
deleted file mode 100644 (file)
index b8c7722..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-- // MIR for `match_nested_if` before MatchBranchSimplification
-+ // MIR for `match_nested_if` after MatchBranchSimplification
-  
-  fn match_nested_if() -> bool {
-      let mut _0: bool;                    // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29
-      let _1: bool;                        // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
-      let mut _2: ();                      // in scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
-      let mut _3: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
-      let mut _4: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
-      let mut _5: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
-      let mut _6: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-+     let mut _7: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-+     let mut _8: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
-+     let mut _9: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
-+     let mut _10: bool;                   // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
-      scope 1 {
-          debug val => _1;                 // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
-      }
-  
-      bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
-          StorageLive(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
-          Deinit(_2);                      // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
-          StorageLive(_3);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
-          StorageLive(_4);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
-          StorageLive(_5);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
-          StorageLive(_6);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-          _6 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
--         switchInt(move _6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
--     }
-- 
--     bb1: {
--         _5 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:31: +2:35
--         goto -> bb3;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
--     }
-- 
--     bb2: {
--         _5 = const false;                // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
--         goto -> bb3;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
--     }
-- 
--     bb3: {
-+         StorageLive(_7);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-+         _7 = move _6;                    // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-+         _5 = Ne(_7, const false);        // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
-+         StorageDead(_7);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-          StorageDead(_6);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
--         switchInt(move _5) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
--     }
-- 
--     bb4: {
--         _4 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:55: +2:59
--         goto -> bb6;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
--     }
-- 
--     bb5: {
--         _4 = const false;                // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
--         goto -> bb6;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
--     }
-- 
--     bb6: {
-+         StorageLive(_8);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
-+         _8 = move _5;                    // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
-+         _4 = Ne(_8, const false);        // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
-+         StorageDead(_8);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
-          StorageDead(_5);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:75: +2:76
--         switchInt(move _4) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
--     }
-- 
--     bb7: {
--         _3 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+3:13: +3:17
--         goto -> bb9;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
--     }
-- 
--     bb8: {
--         _3 = const false;                // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
--         goto -> bb9;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
--     }
-- 
--     bb9: {
--         switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
--     }
-- 
--     bb10: {
-+         StorageLive(_9);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
-+         _9 = move _4;                    // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
-+         _3 = Ne(_9, const false);        // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
-+         StorageDead(_9);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
-+         StorageLive(_10);                // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
-+         _10 = move _3;                   // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
-          StorageDead(_4);                 // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
-          StorageDead(_3);                 // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
--         _1 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
--         goto -> bb12;                    // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
--     }
-- 
--     bb11: {
--         StorageDead(_4);                 // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
--         StorageDead(_3);                 // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
--         _1 = const false;                // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
--         goto -> bb12;                    // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
--     }
-- 
--     bb12: {
-+         _1 = Ne(_10, const false);       // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
-+         StorageDead(_10);                // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
-          StorageDead(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:+11:6: +11:7
-          _0 = _1;                         // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8
-          StorageDead(_1);                 // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2
-          return;                          // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff
deleted file mode 100644 (file)
index b8c7722..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-- // MIR for `match_nested_if` before MatchBranchSimplification
-+ // MIR for `match_nested_if` after MatchBranchSimplification
-  
-  fn match_nested_if() -> bool {
-      let mut _0: bool;                    // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29
-      let _1: bool;                        // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
-      let mut _2: ();                      // in scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
-      let mut _3: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
-      let mut _4: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
-      let mut _5: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
-      let mut _6: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-+     let mut _7: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-+     let mut _8: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
-+     let mut _9: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
-+     let mut _10: bool;                   // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
-      scope 1 {
-          debug val => _1;                 // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
-      }
-  
-      bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
-          StorageLive(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
-          Deinit(_2);                      // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
-          StorageLive(_3);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
-          StorageLive(_4);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
-          StorageLive(_5);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
-          StorageLive(_6);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-          _6 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
--         switchInt(move _6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
--     }
-- 
--     bb1: {
--         _5 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:31: +2:35
--         goto -> bb3;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
--     }
-- 
--     bb2: {
--         _5 = const false;                // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
--         goto -> bb3;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
--     }
-- 
--     bb3: {
-+         StorageLive(_7);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-+         _7 = move _6;                    // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-+         _5 = Ne(_7, const false);        // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
-+         StorageDead(_7);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-          StorageDead(_6);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
--         switchInt(move _5) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
--     }
-- 
--     bb4: {
--         _4 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:55: +2:59
--         goto -> bb6;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
--     }
-- 
--     bb5: {
--         _4 = const false;                // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
--         goto -> bb6;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
--     }
-- 
--     bb6: {
-+         StorageLive(_8);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
-+         _8 = move _5;                    // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
-+         _4 = Ne(_8, const false);        // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
-+         StorageDead(_8);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
-          StorageDead(_5);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:75: +2:76
--         switchInt(move _4) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
--     }
-- 
--     bb7: {
--         _3 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+3:13: +3:17
--         goto -> bb9;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
--     }
-- 
--     bb8: {
--         _3 = const false;                // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
--         goto -> bb9;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
--     }
-- 
--     bb9: {
--         switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
--     }
-- 
--     bb10: {
-+         StorageLive(_9);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
-+         _9 = move _4;                    // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
-+         _3 = Ne(_9, const false);        // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
-+         StorageDead(_9);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
-+         StorageLive(_10);                // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
-+         _10 = move _3;                   // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
-          StorageDead(_4);                 // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
-          StorageDead(_3);                 // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
--         _1 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
--         goto -> bb12;                    // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
--     }
-- 
--     bb11: {
--         StorageDead(_4);                 // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
--         StorageDead(_3);                 // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
--         _1 = const false;                // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
--         goto -> bb12;                    // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
--     }
-- 
--     bb12: {
-+         _1 = Ne(_10, const false);       // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
-+         StorageDead(_10);                // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
-          StorageDead(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:+11:6: +11:7
-          _0 = _1;                         // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8
-          StorageDead(_1);                 // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2
-          return;                          // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff
new file mode 100644 (file)
index 0000000..b8c7722
--- /dev/null
@@ -0,0 +1,113 @@
+- // MIR for `match_nested_if` before MatchBranchSimplification
++ // MIR for `match_nested_if` after MatchBranchSimplification
+  
+  fn match_nested_if() -> bool {
+      let mut _0: bool;                    // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29
+      let _1: bool;                        // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+      let mut _2: ();                      // in scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
+      let mut _3: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+      let mut _4: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+      let mut _5: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+      let mut _6: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++     let mut _7: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++     let mut _8: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
++     let mut _9: bool;                    // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
++     let mut _10: bool;                   // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+      scope 1 {
+          debug val => _1;                 // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+          StorageLive(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
+          Deinit(_2);                      // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
+          StorageLive(_3);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+          StorageLive(_4);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+          StorageLive(_5);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+          StorageLive(_6);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+          _6 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+-         switchInt(move _6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+-     }
+- 
+-     bb1: {
+-         _5 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:31: +2:35
+-         goto -> bb3;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+-     }
+- 
+-     bb2: {
+-         _5 = const false;                // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
+-         goto -> bb3;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+-     }
+- 
+-     bb3: {
++         StorageLive(_7);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++         _7 = move _6;                    // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++         _5 = Ne(_7, const false);        // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
++         StorageDead(_7);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+          StorageDead(_6);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
+-         switchInt(move _5) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+-     }
+- 
+-     bb4: {
+-         _4 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:55: +2:59
+-         goto -> bb6;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+-     }
+- 
+-     bb5: {
+-         _4 = const false;                // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
+-         goto -> bb6;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+-     }
+- 
+-     bb6: {
++         StorageLive(_8);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
++         _8 = move _5;                    // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
++         _4 = Ne(_8, const false);        // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
++         StorageDead(_8);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+          StorageDead(_5);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:75: +2:76
+-         switchInt(move _4) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+-     }
+- 
+-     bb7: {
+-         _3 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+3:13: +3:17
+-         goto -> bb9;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+-     }
+- 
+-     bb8: {
+-         _3 = const false;                // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
+-         goto -> bb9;                     // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+-     }
+- 
+-     bb9: {
+-         switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+-     }
+- 
+-     bb10: {
++         StorageLive(_9);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
++         _9 = move _4;                    // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
++         _3 = Ne(_9, const false);        // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
++         StorageDead(_9);                 // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
++         StorageLive(_10);                // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
++         _10 = move _3;                   // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+          StorageDead(_4);                 // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
+          StorageDead(_3);                 // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
+-         _1 = const true;                 // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
+-         goto -> bb12;                    // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
+-     }
+- 
+-     bb11: {
+-         StorageDead(_4);                 // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
+-         StorageDead(_3);                 // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
+-         _1 = const false;                // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+-         goto -> bb12;                    // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+-     }
+- 
+-     bb12: {
++         _1 = Ne(_10, const false);       // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
++         StorageDead(_10);                // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+          StorageDead(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:+11:6: +11:7
+          _0 = _1;                         // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8
+          StorageDead(_1);                 // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2
+          return;                          // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2
+      }
+  }
+  
index c122b4c69d15a1a8f17411371eec649a526e8e05..a81d5f7b4e8bc7a529a69fb680b449b7f7fe67fa 100644 (file)
@@ -1,6 +1,6 @@
 // unit-test: MatchBranchSimplification
 
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 // 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
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff
deleted file mode 100644 (file)
index 1b4dddc..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-- // MIR for `exhaustive_match` before MatchBranchSimplification
-+ // MIR for `exhaustive_match` after MatchBranchSimplification
-  
-  fn exhaustive_match(_1: E) -> u8 {
-      debug e => _1;                       // in scope 0 at $DIR/matches_u8.rs:+0:25: +0:26
-      let mut _0: u8;                      // return place in scope 0 at $DIR/matches_u8.rs:+0:34: +0:36
-      let mut _2: isize;                   // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13
-  
-      bb0: {
-          _2 = discriminant(_1);           // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
-          switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
-      }
-  
-      bb1: {
-          _0 = const 1_u8;                 // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
-          goto -> 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/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff
deleted file mode 100644 (file)
index 1b4dddc..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-- // MIR for `exhaustive_match` before MatchBranchSimplification
-+ // MIR for `exhaustive_match` after MatchBranchSimplification
-  
-  fn exhaustive_match(_1: E) -> u8 {
-      debug e => _1;                       // in scope 0 at $DIR/matches_u8.rs:+0:25: +0:26
-      let mut _0: u8;                      // return place in scope 0 at $DIR/matches_u8.rs:+0:34: +0:36
-      let mut _2: isize;                   // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13
-  
-      bb0: {
-          _2 = discriminant(_1);           // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
-          switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
-      }
-  
-      bb1: {
-          _0 = const 1_u8;                 // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
-          goto -> 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/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff
new file mode 100644 (file)
index 0000000..1b4dddc
--- /dev/null
@@ -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_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
+      }
+  
+      bb1: {
+          _0 = const 1_u8;                 // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+          goto -> 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/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff
deleted file mode 100644 (file)
index 6e73485..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-- // MIR for `exhaustive_match_i8` before MatchBranchSimplification
-+ // MIR for `exhaustive_match_i8` after MatchBranchSimplification
-  
-  fn exhaustive_match_i8(_1: E) -> i8 {
-      debug e => _1;                       // in scope 0 at $DIR/matches_u8.rs:+0:28: +0:29
-      let mut _0: i8;                      // return place in scope 0 at $DIR/matches_u8.rs:+0:37: +0:39
-      let mut _2: isize;                   // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13
-  
-      bb0: {
-          _2 = discriminant(_1);           // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
-          switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
-      }
-  
-      bb1: {
-          _0 = const 1_i8;                 // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
-          goto -> 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/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff
deleted file mode 100644 (file)
index 6e73485..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-- // MIR for `exhaustive_match_i8` before MatchBranchSimplification
-+ // MIR for `exhaustive_match_i8` after MatchBranchSimplification
-  
-  fn exhaustive_match_i8(_1: E) -> i8 {
-      debug e => _1;                       // in scope 0 at $DIR/matches_u8.rs:+0:28: +0:29
-      let mut _0: i8;                      // return place in scope 0 at $DIR/matches_u8.rs:+0:37: +0:39
-      let mut _2: isize;                   // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13
-  
-      bb0: {
-          _2 = discriminant(_1);           // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
-          switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
-      }
-  
-      bb1: {
-          _0 = const 1_i8;                 // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
-          goto -> 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/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff
new file mode 100644 (file)
index 0000000..6e73485
--- /dev/null
@@ -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_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
+      }
+  
+      bb1: {
+          _0 = const 1_i8;                 // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+          goto -> 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
+      }
+  }
+  
index 2c748b02a8b76711fc937d7447016410a440644d..422c3a95e8efa3cd894bb7a2dbc1e5036d806ce5 100644 (file)
@@ -1,6 +1,6 @@
 // unit-test: MatchBranchSimplification
 
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 // EMIT_MIR matches_u8.exhaustive_match.MatchBranchSimplification.diff
 // EMIT_MIR matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff
 
index 6c2e265d5146920aff554c383da16631591ac1e7..cb65242609086e0ef04ca11b20eb2b74e0fd7e35 100644 (file)
@@ -1,6 +1,6 @@
 // ignore-wasm32-bare compiled with panic=abort by default
 
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 // EMIT_MIR packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir
 fn main() {
     let mut x = Packed(Aligned(Droppy(0)));
diff --git a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir
deleted file mode 100644 (file)
index f9ed103..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-// MIR for `main` after SimplifyCfg-elaborate-drops
-
-fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +0:11
-    let mut _1: Packed;                  // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
-    let mut _2: Aligned;                 // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
-    let mut _3: Droppy;                  // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
-    let mut _4: Aligned;                 // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
-    let mut _5: Droppy;                  // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
-    let mut _6: Aligned;                 // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
-    scope 1 {
-        debug x => _1;                   // in scope 1 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
-    }
-
-    bb0: {
-        StorageLive(_1);                 // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
-        StorageLive(_2);                 // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
-        StorageLive(_3);                 // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
-        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/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir
deleted file mode 100644 (file)
index f9ed103..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-// MIR for `main` after SimplifyCfg-elaborate-drops
-
-fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +0:11
-    let mut _1: Packed;                  // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
-    let mut _2: Aligned;                 // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
-    let mut _3: Droppy;                  // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
-    let mut _4: Aligned;                 // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
-    let mut _5: Droppy;                  // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
-    let mut _6: Aligned;                 // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
-    scope 1 {
-        debug x => _1;                   // in scope 1 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
-    }
-
-    bb0: {
-        StorageLive(_1);                 // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
-        StorageLive(_2);                 // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
-        StorageLive(_3);                 // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
-        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/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir
new file mode 100644 (file)
index 0000000..f9ed103
--- /dev/null
@@ -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/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff b/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff
deleted file mode 100644 (file)
index 28536dc..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-- // MIR for `identity` before ConstProp
-+ // MIR for `identity` after ConstProp
-  
-  fn identity(_1: Result<i32, i32>) -> Result<i32, i32> {
-      debug x => _1;                       // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14
-      let mut _0: std::result::Result<i32, i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53
-      let mut _2: i32;                     // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-      let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-      let mut _4: std::result::Result<i32, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
-      let mut _5: isize;                   // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-      let _6: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-      let mut _7: !;                       // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-      let mut _8: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-      let _9: i32;                         // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-      scope 1 {
-          debug residual => _6;            // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10
-          scope 2 {
-              scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10
-                  debug residual => _8;    // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-                  let _16: i32;            // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-                  let mut _17: i32;        // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-                  let mut _18: i32;        // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-                  scope 9 {
-                      debug e => _16;      // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-                      scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL
-                          debug t => _18;  // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-                      }
-                  }
-              }
-          }
-      }
-      scope 3 {
-          debug val => _9;                 // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          scope 4 {
-          }
-      }
-      scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10
-          debug self => _4;                // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          let mut _10: isize;              // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          let _11: i32;                    // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          let mut _12: i32;                // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          let _13: i32;                    // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          let mut _14: std::result::Result<std::convert::Infallible, i32>; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          let mut _15: i32;                // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          scope 6 {
-              debug v => _11;              // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
-          }
-          scope 7 {
-              debug e => _13;              // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-          }
-      }
-  
-      bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          StorageLive(_3);                 // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          StorageLive(_4);                 // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
-          _4 = _1;                         // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
-          _10 = discriminant(_4);          // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-      }
-  
-      bb1: {
-          StorageLive(_9);                 // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          _9 = ((_3 as Continue).0: i32);  // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          _2 = _9;                         // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          StorageDead(_9);                 // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-          Deinit(_0);                      // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
-          ((_0 as Ok).0: i32) = move _2;   // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
-          discriminant(_0) = 0;            // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
-          StorageDead(_2);                 // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
-          StorageDead(_3);                 // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
-          return;                          // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
-      }
-  
-      bb2: {
-          unreachable;                     // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-      }
-  
-      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
-      }
-  
-      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
-          StorageDead(_4);                 // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
--         _5 = discriminant(_3);           // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
--         switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-+         _5 = const 1_isize;              // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-+         switchInt(const 1_isize) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-      }
-  
-      bb5: {
-          unreachable;                     // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-      }
-  
-      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
-          StorageDead(_4);                 // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
--         _5 = discriminant(_3);           // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
--         switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-+         _5 = const 0_isize;              // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-+         switchInt(const 0_isize) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-      }
-  }
-  
diff --git a/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir b/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir
deleted file mode 100644 (file)
index df20f0e..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-// MIR for `identity` after PreCodegen
-
-fn identity(_1: Result<i32, i32>) -> Result<i32, i32> {
-    debug x => _1;                       // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14
-    let mut _0: std::result::Result<i32, i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53
-    let mut _2: i32;                     // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-    let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-    let mut _4: std::result::Result<i32, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
-    let _5: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-    let mut _6: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-    let _7: i32;                         // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-    scope 1 {
-        debug residual => _5;            // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10
-        scope 2 {
-            scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10
-                debug residual => _6;    // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-                let _14: i32;            // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-                let mut _15: i32;        // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-                let mut _16: i32;        // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-                scope 9 {
-                    debug e => _14;      // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-                    scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL
-                        debug t => _16;  // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-                    }
-                }
-            }
-        }
-    }
-    scope 3 {
-        debug val => _7;                 // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10
-        scope 4 {
-        }
-    }
-    scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10
-        debug self => _4;                // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        let mut _8: isize;               // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        let _9: i32;                     // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        let mut _10: i32;                // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        let _11: i32;                    // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        let mut _12: std::result::Result<std::convert::Infallible, i32>; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        let mut _13: i32;                // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        scope 6 {
-            debug v => _9;               // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
-        }
-        scope 7 {
-            debug e => _11;              // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        }
-    }
-
-    bb0: {
-        StorageLive(_2);                 // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-        StorageLive(_3);                 // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-        StorageLive(_4);                 // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
-        _4 = _1;                         // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
-        _8 = discriminant(_4);           // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        switchInt(move _8) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-    }
-
-    bb1: {
-        StorageLive(_11);                // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        _11 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageLive(_12);                // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageLive(_13);                // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        _13 = move _11;                  // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        Deinit(_12);                     // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        ((_12 as Err).0: i32) = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        discriminant(_12) = 1;           // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageDead(_13);                // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        Deinit(_3);                      // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>) = move _12; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        discriminant(_3) = 1;            // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageDead(_12);                // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageDead(_11);                // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageDead(_4);                 // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-        StorageLive(_5);                 // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-        _5 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-        StorageLive(_6);                 // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
-        _6 = _5;                         // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
-        StorageLive(_14);                // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-        _14 = move ((_6 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageLive(_15);                // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageLive(_16);                // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-        _16 = move _14;                  // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-        _15 = move _16;                  // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-        StorageDead(_16);                // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-        Deinit(_0);                      // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-        ((_0 as Err).0: i32) = move _15; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-        discriminant(_0) = 1;            // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageDead(_15);                // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageDead(_14);                // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageDead(_6);                 // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
-        StorageDead(_5);                 // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-        StorageDead(_2);                 // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
-        StorageDead(_3);                 // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
-        return;                          // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
-    }
-
-    bb2: {
-        unreachable;                     // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-    }
-
-    bb3: {
-        StorageLive(_9);                 // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        _9 = move ((_4 as Ok).0: i32);   // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageLive(_10);                // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
-        _10 = move _9;                   // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
-        Deinit(_3);                      // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
-        ((_3 as Continue).0: i32) = move _10; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
-        discriminant(_3) = 0;            // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageDead(_10);                // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageDead(_9);                 // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-        StorageDead(_4);                 // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-        StorageLive(_7);                 // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-        _7 = ((_3 as Continue).0: i32);  // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-        _2 = _7;                         // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10
-        StorageDead(_7);                 // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-        Deinit(_0);                      // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
-        ((_0 as Ok).0: i32) = move _2;   // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
-        discriminant(_0) = 0;            // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
-        StorageDead(_2);                 // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
-        StorageDead(_3);                 // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
-        return;                          // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
-    }
-}
diff --git a/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff b/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff
deleted file mode 100644 (file)
index 2826916..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-- // MIR for `too_complex` before ConstProp
-+ // MIR for `too_complex` after ConstProp
-  
-  fn too_complex(_1: Result<i32, usize>) -> Option<i32> {
-      debug x => _1;                       // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17
-      let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53
-      let mut _2: std::ops::ControlFlow<usize, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-      let mut _3: isize;                   // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18
-      let _4: i32;                         // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
-      let mut _5: i32;                     // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45
-      let _6: usize;                       // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
-      let mut _7: usize;                   // in scope 0 at $DIR/separate_const_switch.rs:+8:42: +8:43
-      let mut _8: isize;                   // in scope 0 at $DIR/separate_const_switch.rs:+11:9: +11:33
-      let _9: i32;                         // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
-      let mut _10: i32;                    // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43
-      let _11: usize;                      // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
-      scope 1 {
-          debug v => _4;                   // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17
-      }
-      scope 2 {
-          debug r => _6;                   // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18
-      }
-      scope 3 {
-          debug v => _9;                   // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32
-      }
-      scope 4 {
-          debug r => _11;                  // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29
-      }
-  
-      bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-          _3 = discriminant(_1);           // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16
-          switchInt(move _3) -> [0_isize: bb3, 1_isize: 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
--         _8 = discriminant(_2);           // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
--         switchInt(move _8) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
-+         _8 = const 1_isize;              // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-+         switchInt(const 1_isize) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
-      }
-  
-      bb2: {
-          unreachable;                     // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16
-      }
-  
-      bb3: {
-          StorageLive(_4);                 // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
-          _4 = ((_1 as Ok).0: i32);        // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
-          StorageLive(_5);                 // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
-          _5 = _4;                         // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
-          Deinit(_2);                      // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
-          ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
-          discriminant(_2) = 0;            // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
-          StorageDead(_5);                 // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46
-          StorageDead(_4);                 // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
--         _8 = discriminant(_2);           // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
--         switchInt(move _8) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
-+         _8 = const 0_isize;              // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-+         switchInt(const 0_isize) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
-      }
-  
-      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 -> bb7;                     // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
-      }
-  
-      bb5: {
-          unreachable;                     // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-      }
-  
-      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 -> bb7;                     // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
-      }
-  
-      bb7: {
-          StorageDead(_2);                 // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2
-          return;                          // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir b/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir
deleted file mode 100644 (file)
index 0ee0706..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-// MIR for `too_complex` after PreCodegen
-
-fn too_complex(_1: Result<i32, usize>) -> Option<i32> {
-    debug x => _1;                       // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17
-    let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53
-    let mut _2: std::ops::ControlFlow<usize, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-    let mut _3: isize;                   // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18
-    let _4: i32;                         // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
-    let mut _5: i32;                     // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45
-    let _6: usize;                       // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
-    let _7: i32;                         // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
-    let mut _8: i32;                     // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43
-    let _9: usize;                       // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
-    scope 1 {
-        debug v => _4;                   // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17
-    }
-    scope 2 {
-        debug r => _6;                   // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18
-    }
-    scope 3 {
-        debug v => _7;                   // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32
-    }
-    scope 4 {
-        debug r => _9;                   // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29
-    }
-
-    bb0: {
-        StorageLive(_2);                 // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-        _3 = discriminant(_1);           // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16
-        switchInt(move _3) -> [0_isize: bb3, 1_isize: 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
-        StorageDead(_6);                 // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
-        StorageLive(_9);                 // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
-        Deinit(_0);                      // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
-        discriminant(_0) = 0;            // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
-        StorageDead(_9);                 // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
-        goto -> bb4;                     // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
-    }
-
-    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
-        StorageLive(_7);                 // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
-        _7 = ((_2 as Continue).0: i32);  // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
-        StorageLive(_8);                 // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
-        _8 = _7;                         // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
-        Deinit(_0);                      // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
-        ((_0 as Some).0: i32) = move _8; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
-        discriminant(_0) = 1;            // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
-        StorageDead(_8);                 // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44
-        StorageDead(_7);                 // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
-        goto -> bb4;                     // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
-    }
-
-    bb4: {
-        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
-    }
-}
index 44adc55b6f7feadd5418f31ad8b676a3f26b69b8..103033c4e2b861072f03d35aed92333f8cdbb274 100644 (file)
@@ -1,6 +1,6 @@
 // Test that we don't generate unnecessarily large MIR for very simple matches
 
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 // EMIT_MIR simple_match.match_bool.mir_map.0.mir
 fn match_bool(x: bool) -> usize {
     match x {
diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir
deleted file mode 100644 (file)
index 3bef6aa..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// MIR for `match_bool` 0 mir_map
-
-fn match_bool(_1: bool) -> usize {
-    debug x => _1;                       // in scope 0 at $DIR/simple-match.rs:+0:15: +0:16
-    let mut _0: usize;                   // return place in scope 0 at $DIR/simple-match.rs:+0:27: +0:32
-
-    bb0: {
-        FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple-match.rs:+1:11: +1:12
-        switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple-match.rs:+1:5: +1:12
-    }
-
-    bb1: {
-        falseEdge -> [real: bb3, imaginary: bb2]; // scope 0 at $DIR/simple-match.rs:+2:9: +2:13
-    }
-
-    bb2: {
-        _0 = const 20_usize;             // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
-        goto -> bb4;                     // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
-    }
-
-    bb3: {
-        _0 = const 10_usize;             // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
-        goto -> bb4;                     // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
-    }
-
-    bb4: {
-        return;                          // scope 0 at $DIR/simple-match.rs:+5:2: +5:2
-    }
-}
diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir
deleted file mode 100644 (file)
index 3bef6aa..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// MIR for `match_bool` 0 mir_map
-
-fn match_bool(_1: bool) -> usize {
-    debug x => _1;                       // in scope 0 at $DIR/simple-match.rs:+0:15: +0:16
-    let mut _0: usize;                   // return place in scope 0 at $DIR/simple-match.rs:+0:27: +0:32
-
-    bb0: {
-        FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple-match.rs:+1:11: +1:12
-        switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple-match.rs:+1:5: +1:12
-    }
-
-    bb1: {
-        falseEdge -> [real: bb3, imaginary: bb2]; // scope 0 at $DIR/simple-match.rs:+2:9: +2:13
-    }
-
-    bb2: {
-        _0 = const 20_usize;             // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
-        goto -> bb4;                     // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
-    }
-
-    bb3: {
-        _0 = const 10_usize;             // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
-        goto -> bb4;                     // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
-    }
-
-    bb4: {
-        return;                          // scope 0 at $DIR/simple-match.rs:+5:2: +5:2
-    }
-}
diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.mir
new file mode 100644 (file)
index 0000000..3bef6aa
--- /dev/null
@@ -0,0 +1,29 @@
+// MIR for `match_bool` 0 mir_map
+
+fn match_bool(_1: bool) -> usize {
+    debug x => _1;                       // in scope 0 at $DIR/simple-match.rs:+0:15: +0:16
+    let mut _0: usize;                   // return place in scope 0 at $DIR/simple-match.rs:+0:27: +0:32
+
+    bb0: {
+        FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple-match.rs:+1:11: +1:12
+        switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple-match.rs:+1:5: +1:12
+    }
+
+    bb1: {
+        falseEdge -> [real: bb3, imaginary: bb2]; // scope 0 at $DIR/simple-match.rs:+2:9: +2:13
+    }
+
+    bb2: {
+        _0 = const 20_usize;             // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
+        goto -> bb4;                     // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
+    }
+
+    bb3: {
+        _0 = const 10_usize;             // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
+        goto -> bb4;                     // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
+    }
+
+    bb4: {
+        return;                          // scope 0 at $DIR/simple-match.rs:+5:2: +5:2
+    }
+}
index 62a15df04b14429940d05a89f1711268caa43dc2..d09bd92c4e81d176328a1159f1c23aadd8c1e723 100644 (file)
@@ -11,5 +11,4 @@ fn main() {
     map(None);
 }
 
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
 // EMIT_MIR simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff
diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff
deleted file mode 100644 (file)
index 51d26b0..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-- // MIR for `map` before SimplifyLocals
-+ // MIR for `map` after SimplifyLocals
-  
-  fn map(_1: Option<Box<()>>) -> Option<Box<()>> {
-      debug x => _1;                       // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9
-      let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46
-      let mut _2: isize;                   // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13
-      let _3: std::boxed::Box<()>;         // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
-      let mut _4: std::boxed::Box<()>;     // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
--     let mut _5: bool;                    // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
--     let mut _6: isize;                   // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
--     let mut _7: isize;                   // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
-      scope 1 {
-          debug x => _3;                   // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
-      }
-  
-      bb0: {
--         _5 = const false;                // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
--         _5 = const true;                 // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
-          _2 = discriminant(_1);           // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
-          switchInt(move _2) -> [0_isize: bb3, 1_isize: 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/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff
deleted file mode 100644 (file)
index 51d26b0..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-- // MIR for `map` before SimplifyLocals
-+ // MIR for `map` after SimplifyLocals
-  
-  fn map(_1: Option<Box<()>>) -> Option<Box<()>> {
-      debug x => _1;                       // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9
-      let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46
-      let mut _2: isize;                   // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13
-      let _3: std::boxed::Box<()>;         // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
-      let mut _4: std::boxed::Box<()>;     // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
--     let mut _5: bool;                    // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
--     let mut _6: isize;                   // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
--     let mut _7: isize;                   // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
-      scope 1 {
-          debug x => _3;                   // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
-      }
-  
-      bb0: {
--         _5 = const false;                // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
--         _5 = const true;                 // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
-          _2 = discriminant(_1);           // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
-          switchInt(move _2) -> [0_isize: bb3, 1_isize: 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/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff
new file mode 100644 (file)
index 0000000..51d26b0
--- /dev/null
@@ -0,0 +1,52 @@
+- // MIR for `map` before SimplifyLocals
++ // MIR for `map` after SimplifyLocals
+  
+  fn map(_1: Option<Box<()>>) -> Option<Box<()>> {
+      debug x => _1;                       // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9
+      let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46
+      let mut _2: isize;                   // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13
+      let _3: std::boxed::Box<()>;         // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+      let mut _4: std::boxed::Box<()>;     // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
+-     let mut _5: bool;                    // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
+-     let mut _6: isize;                   // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
+-     let mut _7: isize;                   // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
+      scope 1 {
+          debug x => _3;                   // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+      }
+  
+      bb0: {
+-         _5 = const false;                // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
+-         _5 = const true;                 // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
+          _2 = discriminant(_1);           // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
+          switchInt(move _2) -> [0_isize: bb3, 1_isize: 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
+      }
+  }
+  
index 0fd32906db6be56536e6d51e65bf26864e4daf1d..344c1af2c91347c661ace0a5476d8dd05e5dd894 100644 (file)
@@ -1,6 +1,6 @@
 // compile-flags: -Zmir-opt-level=0
 
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 // EMIT_MIR core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
 fn main() {
     let _fn = std::ptr::drop_in_place::<[String]> as unsafe fn(_);
diff --git a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir
deleted file mode 100644 (file)
index b4b317e..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
-
-fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
-    let mut _0: ();                      // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _2: usize;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _3: usize;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _4: usize;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _5: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _6: bool;                    // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _7: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _8: bool;                    // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _9: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _10: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _11: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _12: bool;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _13: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _14: bool;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _15: *mut [std::string::String]; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-
-    bb0: {
-        goto -> bb15;                    // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb1: {
-        return;                          // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb2 (cleanup): {
-        resume;                          // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb3 (cleanup): {
-        _5 = &raw mut (*_1)[_4];         // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        drop((*_5)) -> bb4;              // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb4 (cleanup): {
-        _6 = Eq(_4, _3);                 // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        switchInt(move _6) -> [false: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb5: {
-        _7 = &raw mut (*_1)[_4];         // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        drop((*_7)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb6: {
-        _8 = Eq(_4, _3);                 // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        switchInt(move _8) -> [false: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb7: {
-        _4 = const 0_usize;              // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        goto -> bb6;                     // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb8: {
-        goto -> bb7;                     // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb9 (cleanup): {
-        _11 = _9;                        // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        drop((*_11)) -> bb10;            // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb10 (cleanup): {
-        _12 = Eq(_9, _10);               // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        switchInt(move _12) -> [false: bb9, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb11: {
-        _13 = _9;                        // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        drop((*_13)) -> [return: bb12, unwind: bb10]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb12: {
-        _14 = Eq(_9, _10);               // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        switchInt(move _14) -> [false: bb11, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb13: {
-        _15 = &raw mut (*_1);            // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _9 = move _15 as *mut std::string::String (Misc); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _10 = Offset(_9, move _3);       // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        goto -> bb12;                    // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb14: {
-        goto -> bb13;                    // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb15: {
-        _2 = SizeOf(std::string::String); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _3 = Len((*_1));                 // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        switchInt(move _2) -> [0_usize: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-}
diff --git a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir
deleted file mode 100644 (file)
index b4b317e..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
-
-fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
-    let mut _0: ();                      // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _2: usize;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _3: usize;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _4: usize;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _5: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _6: bool;                    // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _7: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _8: bool;                    // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _9: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _10: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _11: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _12: bool;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _13: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _14: bool;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _15: *mut [std::string::String]; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-
-    bb0: {
-        goto -> bb15;                    // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb1: {
-        return;                          // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb2 (cleanup): {
-        resume;                          // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb3 (cleanup): {
-        _5 = &raw mut (*_1)[_4];         // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        drop((*_5)) -> bb4;              // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb4 (cleanup): {
-        _6 = Eq(_4, _3);                 // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        switchInt(move _6) -> [false: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb5: {
-        _7 = &raw mut (*_1)[_4];         // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        drop((*_7)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb6: {
-        _8 = Eq(_4, _3);                 // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        switchInt(move _8) -> [false: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb7: {
-        _4 = const 0_usize;              // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        goto -> bb6;                     // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb8: {
-        goto -> bb7;                     // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb9 (cleanup): {
-        _11 = _9;                        // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        drop((*_11)) -> bb10;            // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb10 (cleanup): {
-        _12 = Eq(_9, _10);               // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        switchInt(move _12) -> [false: bb9, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb11: {
-        _13 = _9;                        // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        drop((*_13)) -> [return: bb12, unwind: bb10]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb12: {
-        _14 = Eq(_9, _10);               // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        switchInt(move _14) -> [false: bb11, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb13: {
-        _15 = &raw mut (*_1);            // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _9 = move _15 as *mut std::string::String (Misc); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _10 = Offset(_9, move _3);       // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        goto -> bb12;                    // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb14: {
-        goto -> bb13;                    // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb15: {
-        _2 = SizeOf(std::string::String); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _3 = Len((*_1));                 // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        switchInt(move _2) -> [0_usize: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-}
diff --git a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
new file mode 100644 (file)
index 0000000..b4b317e
--- /dev/null
@@ -0,0 +1,101 @@
+// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
+
+fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
+    let mut _0: ();                      // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _2: usize;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _3: usize;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _4: usize;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _5: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _6: bool;                    // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _7: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _8: bool;                    // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _9: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _10: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _11: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _12: bool;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _13: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _14: bool;                   // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _15: *mut [std::string::String]; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+
+    bb0: {
+        goto -> bb15;                    // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb1: {
+        return;                          // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb2 (cleanup): {
+        resume;                          // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb3 (cleanup): {
+        _5 = &raw mut (*_1)[_4];         // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        drop((*_5)) -> bb4;              // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb4 (cleanup): {
+        _6 = Eq(_4, _3);                 // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        switchInt(move _6) -> [false: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb5: {
+        _7 = &raw mut (*_1)[_4];         // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        drop((*_7)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb6: {
+        _8 = Eq(_4, _3);                 // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        switchInt(move _8) -> [false: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb7: {
+        _4 = const 0_usize;              // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        goto -> bb6;                     // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb8: {
+        goto -> bb7;                     // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb9 (cleanup): {
+        _11 = _9;                        // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        drop((*_11)) -> bb10;            // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb10 (cleanup): {
+        _12 = Eq(_9, _10);               // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        switchInt(move _12) -> [false: bb9, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb11: {
+        _13 = _9;                        // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        drop((*_13)) -> [return: bb12, unwind: bb10]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb12: {
+        _14 = Eq(_9, _10);               // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        switchInt(move _14) -> [false: bb11, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb13: {
+        _15 = &raw mut (*_1);            // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        _9 = move _15 as *mut std::string::String (Misc); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        _10 = Offset(_9, move _3);       // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        goto -> bb12;                    // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb14: {
+        goto -> bb13;                    // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb15: {
+        _2 = SizeOf(std::string::String); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        _3 = Len((*_1));                 // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        switchInt(move _2) -> [0_usize: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+}
index 670f61cd5ce3aff53a6a51ef1364b1e06bb94509..9ef3d86472db2158c11d09934758ae4b107ab321 100644 (file)
@@ -1,7 +1,7 @@
 // Test that we don't ICE when trying to dump MIR for unusual item types and
 // that we don't create filenames containing `<` and `>`
 // compile-flags: -Zmir-opt-level=0
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 
 struct A;
 
diff --git a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir
deleted file mode 100644 (file)
index a72e00e..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// MIR for `E::V::{constant#0}` 0 mir_map
-
-E::V::{constant#0}: isize = {
-    let mut _0: isize;                   // return place in scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
-
-    bb0: {
-        _0 = const 5_isize;              // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
-        return;                          // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
-    }
-}
diff --git a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir
deleted file mode 100644 (file)
index a72e00e..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// MIR for `E::V::{constant#0}` 0 mir_map
-
-E::V::{constant#0}: isize = {
-    let mut _0: isize;                   // return place in scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
-
-    bb0: {
-        _0 = const 5_isize;              // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
-        return;                          // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
-    }
-}
diff --git a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.mir
new file mode 100644 (file)
index 0000000..a72e00e
--- /dev/null
@@ -0,0 +1,10 @@
+// MIR for `E::V::{constant#0}` 0 mir_map
+
+E::V::{constant#0}: isize = {
+    let mut _0: isize;                   // return place in scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
+
+    bb0: {
+        _0 = const 5_isize;              // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
+        return;                          // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
+    }
+}
diff --git a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir
deleted file mode 100644 (file)
index 0686af4..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// MIR for `Test::X` 0 mir_map
-
-fn Test::X(_1: usize) -> Test {
-    let mut _0: Test;                    // return place in scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
-
-    bb0: {
-        Deinit(_0);                      // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
-        ((_0 as X).0: usize) = move _1;  // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
-        discriminant(_0) = 0;            // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
-        return;                          // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
-    }
-}
diff --git a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir
deleted file mode 100644 (file)
index 0686af4..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// MIR for `Test::X` 0 mir_map
-
-fn Test::X(_1: usize) -> Test {
-    let mut _0: Test;                    // return place in scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
-
-    bb0: {
-        Deinit(_0);                      // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
-        ((_0 as X).0: usize) = move _1;  // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
-        discriminant(_0) = 0;            // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
-        return;                          // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
-    }
-}
diff --git a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir
new file mode 100644 (file)
index 0000000..0686af4
--- /dev/null
@@ -0,0 +1,12 @@
+// MIR for `Test::X` 0 mir_map
+
+fn Test::X(_1: usize) -> Test {
+    let mut _0: Test;                    // return place in scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+
+    bb0: {
+        Deinit(_0);                      // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+        ((_0 as X).0: usize) = move _1;  // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+        discriminant(_0) = 0;            // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+        return;                          // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+    }
+}
diff --git a/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir
deleted file mode 100644 (file)
index 7ffd242..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
-
-fn std::ptr::drop_in_place(_1: *mut Vec<i32>) -> () {
-    let mut _0: ();                      // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _2: &mut std::vec::Vec<i32>; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _3: ();                      // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-
-    bb0: {
-        goto -> bb6;                     // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb1: {
-        return;                          // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb2 (cleanup): {
-        resume;                          // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb3: {
-        goto -> bb1;                     // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb4 (cleanup): {
-        drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> bb2; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb5: {
-        drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> [return: bb3, unwind: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb6: {
-        _2 = &mut (*_1);                 // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _3 = <Vec<i32> as Drop>::drop(move _2) -> [return: bb5, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-                                         // mir::Constant
-                                         // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-                                         // + literal: Const { ty: for<'r> fn(&'r mut Vec<i32>) {<Vec<i32> as Drop>::drop}, val: Value(<ZST>) }
-    }
-}
diff --git a/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir
deleted file mode 100644 (file)
index 7ffd242..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
-
-fn std::ptr::drop_in_place(_1: *mut Vec<i32>) -> () {
-    let mut _0: ();                      // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _2: &mut std::vec::Vec<i32>; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    let mut _3: ();                      // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-
-    bb0: {
-        goto -> bb6;                     // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb1: {
-        return;                          // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb2 (cleanup): {
-        resume;                          // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb3: {
-        goto -> bb1;                     // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb4 (cleanup): {
-        drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> bb2; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb5: {
-        drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> [return: bb3, unwind: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-    }
-
-    bb6: {
-        _2 = &mut (*_1);                 // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-        _3 = <Vec<i32> as Drop>::drop(move _2) -> [return: bb5, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-                                         // mir::Constant
-                                         // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-                                         // + literal: Const { ty: for<'r> fn(&'r mut Vec<i32>) {<Vec<i32> as Drop>::drop}, val: Value(<ZST>) }
-    }
-}
diff --git a/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir
new file mode 100644 (file)
index 0000000..7ffd242
--- /dev/null
@@ -0,0 +1,39 @@
+// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
+
+fn std::ptr::drop_in_place(_1: *mut Vec<i32>) -> () {
+    let mut _0: ();                      // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _2: &mut std::vec::Vec<i32>; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    let mut _3: ();                      // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+
+    bb0: {
+        goto -> bb6;                     // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb1: {
+        return;                          // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb2 (cleanup): {
+        resume;                          // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb3: {
+        goto -> bb1;                     // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb4 (cleanup): {
+        drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> bb2; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb5: {
+        drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> [return: bb3, unwind: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+    }
+
+    bb6: {
+        _2 = &mut (*_1);                 // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+        _3 = <Vec<i32> as Drop>::drop(move _2) -> [return: bb5, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
+                                         // mir::Constant
+                                         // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+                                         // + literal: Const { ty: for<'r> fn(&'r mut Vec<i32>) {<Vec<i32> as Drop>::drop}, val: Value(<ZST>) }
+    }
+}
diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir
deleted file mode 100644 (file)
index e2633f6..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// MIR for `<impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` 0 mir_map
-
-const <impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT: i32 = {
-    let mut _0: i32;                     // return place in scope 0 at $DIR/unusual-item-types.rs:+0:32: +0:35
-
-    bb0: {
-        _0 = const 2_i32;                // scope 0 at $DIR/unusual-item-types.rs:+0:38: +0:39
-        return;                          // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:39
-    }
-}
diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir
deleted file mode 100644 (file)
index e2633f6..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// MIR for `<impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` 0 mir_map
-
-const <impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT: i32 = {
-    let mut _0: i32;                     // return place in scope 0 at $DIR/unusual-item-types.rs:+0:32: +0:35
-
-    bb0: {
-        _0 = const 2_i32;                // scope 0 at $DIR/unusual-item-types.rs:+0:38: +0:39
-        return;                          // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:39
-    }
-}
diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir
new file mode 100644 (file)
index 0000000..e2633f6
--- /dev/null
@@ -0,0 +1,10 @@
+// MIR for `<impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` 0 mir_map
+
+const <impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT: i32 = {
+    let mut _0: i32;                     // return place in scope 0 at $DIR/unusual-item-types.rs:+0:32: +0:35
+
+    bb0: {
+        _0 = const 2_i32;                // scope 0 at $DIR/unusual-item-types.rs:+0:38: +0:39
+        return;                          // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:39
+    }
+}
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff
deleted file mode 100644 (file)
index eef7011..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-- // MIR for `change_loop_body` before ConstProp
-+ // MIR for `change_loop_body` after ConstProp
-  
-  fn change_loop_body() -> () {
-      let mut _0: ();                      // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27
-      let mut _1: i32;                     // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
-      let mut _2: ();                      // in scope 0 at $DIR/while_let_loops.rs:+0:1: +6:2
-      let mut _3: std::option::Option<u32>; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32
-      let mut _4: isize;                   // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25
-      let mut _5: !;                       // in scope 0 at $DIR/while_let_loops.rs:+2:33: +5:6
-      let mut _6: !;                       // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
-      let _7: ();                          // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
-      let mut _8: !;                       // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
-      scope 1 {
-          debug _x => _1;                  // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15
-          scope 2 {
-          }
-      }
-  
-      bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
-          _1 = const 0_i32;                // scope 0 at $DIR/while_let_loops.rs:+1:18: +1:19
-          StorageLive(_3);                 // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
-          Deinit(_3);                      // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
-          discriminant(_3) = 0;            // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
--         _4 = discriminant(_3);           // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
--         switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
-+         _4 = const 0_isize;              // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
-+         switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
-      }
-  
-      bb1: {
-          switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
-      }
-  
-      bb2: {
-          _1 = const 1_i32;                // scope 2 at $DIR/while_let_loops.rs:+3:9: +3:15
-          nop;                             // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
-          goto -> bb4;                     // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
-      }
-  
-      bb3: {
-          StorageLive(_7);                 // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6
-          nop;                             // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6
-          StorageDead(_7);                 // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6
-          goto -> bb4;                     // scope 1 at no-location
-      }
-  
-      bb4: {
-          StorageDead(_3);                 // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6
-          StorageDead(_1);                 // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2
-          return;                          // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff
deleted file mode 100644 (file)
index eef7011..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-- // MIR for `change_loop_body` before ConstProp
-+ // MIR for `change_loop_body` after ConstProp
-  
-  fn change_loop_body() -> () {
-      let mut _0: ();                      // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27
-      let mut _1: i32;                     // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
-      let mut _2: ();                      // in scope 0 at $DIR/while_let_loops.rs:+0:1: +6:2
-      let mut _3: std::option::Option<u32>; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32
-      let mut _4: isize;                   // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25
-      let mut _5: !;                       // in scope 0 at $DIR/while_let_loops.rs:+2:33: +5:6
-      let mut _6: !;                       // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
-      let _7: ();                          // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
-      let mut _8: !;                       // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
-      scope 1 {
-          debug _x => _1;                  // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15
-          scope 2 {
-          }
-      }
-  
-      bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
-          _1 = const 0_i32;                // scope 0 at $DIR/while_let_loops.rs:+1:18: +1:19
-          StorageLive(_3);                 // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
-          Deinit(_3);                      // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
-          discriminant(_3) = 0;            // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
--         _4 = discriminant(_3);           // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
--         switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
-+         _4 = const 0_isize;              // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
-+         switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
-      }
-  
-      bb1: {
-          switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
-      }
-  
-      bb2: {
-          _1 = const 1_i32;                // scope 2 at $DIR/while_let_loops.rs:+3:9: +3:15
-          nop;                             // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
-          goto -> bb4;                     // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
-      }
-  
-      bb3: {
-          StorageLive(_7);                 // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6
-          nop;                             // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6
-          StorageDead(_7);                 // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6
-          goto -> bb4;                     // scope 1 at no-location
-      }
-  
-      bb4: {
-          StorageDead(_3);                 // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6
-          StorageDead(_1);                 // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2
-          return;                          // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff
new file mode 100644 (file)
index 0000000..eef7011
--- /dev/null
@@ -0,0 +1,55 @@
+- // MIR for `change_loop_body` before ConstProp
++ // MIR for `change_loop_body` after ConstProp
+  
+  fn change_loop_body() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27
+      let mut _1: i32;                     // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
+      let mut _2: ();                      // in scope 0 at $DIR/while_let_loops.rs:+0:1: +6:2
+      let mut _3: std::option::Option<u32>; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32
+      let mut _4: isize;                   // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25
+      let mut _5: !;                       // in scope 0 at $DIR/while_let_loops.rs:+2:33: +5:6
+      let mut _6: !;                       // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
+      let _7: ();                          // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
+      let mut _8: !;                       // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
+      scope 1 {
+          debug _x => _1;                  // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15
+          scope 2 {
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
+          _1 = const 0_i32;                // scope 0 at $DIR/while_let_loops.rs:+1:18: +1:19
+          StorageLive(_3);                 // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
+          Deinit(_3);                      // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
+          discriminant(_3) = 0;            // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
+-         _4 = discriminant(_3);           // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
+-         switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
++         _4 = const 0_isize;              // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
++         switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
+      }
+  
+      bb1: {
+          switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
+      }
+  
+      bb2: {
+          _1 = const 1_i32;                // scope 2 at $DIR/while_let_loops.rs:+3:9: +3:15
+          nop;                             // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
+          goto -> bb4;                     // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
+      }
+  
+      bb3: {
+          StorageLive(_7);                 // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6
+          nop;                             // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6
+          StorageDead(_7);                 // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6
+          goto -> bb4;                     // scope 1 at no-location
+      }
+  
+      bb4: {
+          StorageDead(_3);                 // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6
+          StorageDead(_1);                 // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2
+          return;                          // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir
deleted file mode 100644 (file)
index 15b0aec..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// MIR for `change_loop_body` after PreCodegen
-
-fn change_loop_body() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27
-    let mut _1: i32;                     // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
-    scope 1 {
-        debug _x => _1;                  // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15
-        scope 2 {
-        }
-    }
-
-    bb0: {
-        StorageLive(_1);                 // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
-        StorageDead(_1);                 // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2
-        return;                          // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2
-    }
-}
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir
deleted file mode 100644 (file)
index 15b0aec..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// MIR for `change_loop_body` after PreCodegen
-
-fn change_loop_body() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27
-    let mut _1: i32;                     // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
-    scope 1 {
-        debug _x => _1;                  // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15
-        scope 2 {
-        }
-    }
-
-    bb0: {
-        StorageLive(_1);                 // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
-        StorageDead(_1);                 // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2
-        return;                          // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2
-    }
-}
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir
new file mode 100644 (file)
index 0000000..15b0aec
--- /dev/null
@@ -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
+    }
+}
index f320a218c852c345252882e6950dbf5cfb869a9b..fc56cd6985d69a901049bb0fa65f0e4faea8a840 100644 (file)
@@ -1,6 +1,5 @@
 // EMIT_MIR while_let_loops.change_loop_body.ConstProp.diff
 // EMIT_MIR while_let_loops.change_loop_body.PreCodegen.after.mir
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
 
 pub fn change_loop_body() {
     let mut _x = 0;
diff --git a/src/test/run-make/track-pgo-dep-info/Makefile b/src/test/run-make/track-pgo-dep-info/Makefile
new file mode 100644 (file)
index 0000000..60b59c0
--- /dev/null
@@ -0,0 +1,26 @@
+# needs-profiler-support
+# ignore-windows-gnu
+
+-include ../../run-make-fulldeps/tools.mk
+
+# FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC`
+# instead of hardcoding them everywhere they're needed.
+ifeq ($(IS_MUSL_HOST),1)
+ADDITIONAL_ARGS := $(RUSTFLAGS)
+endif
+
+all:
+       # Generate PGO profiles
+       $(BARE_RUSTC) $(ADDITIONAL_ARGS) -Cprofile-generate=$(TMPDIR)/profiles --out-dir $(TMPDIR) main.rs
+       $(TMPDIR)/main
+
+       # Merge profiles
+       "$(LLVM_BIN_DIR)/llvm-profdata" merge \
+               -o "$(TMPDIR)/merged.profdata" \
+               "$(TMPDIR)/profiles" || exit 1
+
+       # Use the profile
+       $(RUSTC) -Cprofile-use=$(TMPDIR)/merged.profdata --emit dep-info main.rs
+
+       # Check that profile file is in depinfo
+       $(CGREP) "merged.profdata" < $(TMPDIR)/main.d
diff --git a/src/test/run-make/track-pgo-dep-info/main.rs b/src/test/run-make/track-pgo-dep-info/main.rs
new file mode 100644 (file)
index 0000000..f328e4d
--- /dev/null
@@ -0,0 +1 @@
+fn main() {}
diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2015.stderr b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2015.stderr
new file mode 100644 (file)
index 0000000..fd2e454
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0277]: the trait bound `(): AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not satisfied
+  --> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:13
+   |
+LL | fn ice() -> impl AsRef<Fn(&())> {
+   |             ^^^^^^^^^^^^^^^^^^^ the trait `AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not implemented for `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr
new file mode 100644 (file)
index 0000000..c01c33a
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:24
+   |
+LL | fn ice() -> impl AsRef<Fn(&())> {
+   |                        ^^^^^^^
+   |
+help: add `dyn` keyword before this trait
+   |
+LL - fn ice() -> impl AsRef<Fn(&())> {
+LL + fn ice() -> impl AsRef<dyn Fn(&())> {
+   |
+
+error[E0277]: the trait bound `(): AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not satisfied
+  --> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:13
+   |
+LL | fn ice() -> impl AsRef<Fn(&())> {
+   |             ^^^^^^^^^^^^^^^^^^^ the trait `AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not implemented for `()`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0782.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs
new file mode 100644 (file)
index 0000000..856dc7a
--- /dev/null
@@ -0,0 +1,12 @@
+// revisions: edition2015 edition2021
+//[edition2021]edition:2021
+
+#![allow(warnings)]
+
+fn ice() -> impl AsRef<Fn(&())> {
+    //~^ ERROR: the trait bound `(): AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not satisfied [E0277]
+    //[edition2021]~| ERROR: trait objects must include the `dyn` keyword [E0782]
+    todo!()
+}
+
+fn main() {}
index 03aa37f52075f73b9a70fb8401136f06273e4363..02c5dd5bfb77198e526206170e5e915089f7d92c 100644 (file)
@@ -31,12 +31,16 @@ error[E0552]: unrecognized representation hint
    |
 LL |     #[repr(nothing)]
    |            ^^^^^^^
+   |
+   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
 error[E0552]: unrecognized representation hint
   --> $DIR/issue-43988.rs:18:12
    |
 LL |     #[repr(something_not_real)]
    |            ^^^^^^^^^^^^^^^^^^
+   |
+   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
 error[E0518]: attribute should be applied to function or closure
   --> $DIR/issue-43988.rs:30:5
diff --git a/src/test/ui/parser/do-not-suggest-semicolon-before-array.rs b/src/test/ui/parser/do-not-suggest-semicolon-before-array.rs
new file mode 100644 (file)
index 0000000..7ebf3f6
--- /dev/null
@@ -0,0 +1,8 @@
+fn foo() {}
+
+fn bar() -> [u8; 2] {
+    foo()
+    [1, 3) //~ ERROR expected one of `.`, `?`, `]`, or an operator, found `,`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/do-not-suggest-semicolon-before-array.stderr b/src/test/ui/parser/do-not-suggest-semicolon-before-array.stderr
new file mode 100644 (file)
index 0000000..a9dd526
--- /dev/null
@@ -0,0 +1,10 @@
+error: expected one of `.`, `?`, `]`, or an operator, found `,`
+  --> $DIR/do-not-suggest-semicolon-before-array.rs:5:5
+   |
+LL |     [1, 3)
+   |     ^ ^ help: `]` may belong here
+   |     |
+   |     unclosed delimiter
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs b/src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs
new file mode 100644 (file)
index 0000000..d6f7981
--- /dev/null
@@ -0,0 +1,3 @@
+fn main() {
+    let _x = vec[1, 2, 3]; //~ ERROR expected one of `.`, `?`, `]`, or an operator
+}
diff --git a/src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr b/src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr
new file mode 100644 (file)
index 0000000..2fe6a28
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected one of `.`, `?`, `]`, or an operator, found `,`
+  --> $DIR/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs:2:19
+   |
+LL |     let _x = vec[1, 2, 3];
+   |                   ^ expected one of `.`, `?`, `]`, or an operator
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/do-not-suggest-suggest-semicolon-before-array.rs b/src/test/ui/parser/do-not-suggest-suggest-semicolon-before-array.rs
deleted file mode 100644 (file)
index 7ebf3f6..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-fn foo() {}
-
-fn bar() -> [u8; 2] {
-    foo()
-    [1, 3) //~ ERROR expected one of `.`, `?`, `]`, or an operator, found `,`
-}
-
-fn main() {}
diff --git a/src/test/ui/parser/do-not-suggest-suggest-semicolon-before-array.stderr b/src/test/ui/parser/do-not-suggest-suggest-semicolon-before-array.stderr
deleted file mode 100644 (file)
index d6e8db8..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-error: expected one of `.`, `?`, `]`, or an operator, found `,`
-  --> $DIR/do-not-suggest-suggest-semicolon-before-array.rs:5:5
-   |
-LL |     [1, 3)
-   |     ^ ^ help: `]` may belong here
-   |     |
-   |     unclosed delimiter
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/parser/suggest-semicolon-before-array.fixed b/src/test/ui/parser/suggest-semicolon-before-array.fixed
new file mode 100644 (file)
index 0000000..a06b58b
--- /dev/null
@@ -0,0 +1,11 @@
+// run-rustfix
+#![allow(dead_code)]
+
+fn foo() {}
+
+fn bar() -> [u8; 2] {
+    foo();
+    [1, 3] //~ ERROR expected `;`, found `[`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/suggest-semicolon-before-array.rs b/src/test/ui/parser/suggest-semicolon-before-array.rs
new file mode 100644 (file)
index 0000000..f601ca2
--- /dev/null
@@ -0,0 +1,11 @@
+// run-rustfix
+#![allow(dead_code)]
+
+fn foo() {}
+
+fn bar() -> [u8; 2] {
+    foo()
+    [1, 3] //~ ERROR expected `;`, found `[`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/suggest-semicolon-before-array.stderr b/src/test/ui/parser/suggest-semicolon-before-array.stderr
new file mode 100644 (file)
index 0000000..8a33321
--- /dev/null
@@ -0,0 +1,13 @@
+error: expected `;`, found `[`
+  --> $DIR/suggest-semicolon-before-array.rs:8:5
+   |
+LL |     [1, 3]
+   |     ^
+   |
+help: consider adding `;` here
+   |
+LL |     foo();
+   |          +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/suggest-suggest-semicolon-before-array.fixed b/src/test/ui/parser/suggest-suggest-semicolon-before-array.fixed
deleted file mode 100644 (file)
index a06b58b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// run-rustfix
-#![allow(dead_code)]
-
-fn foo() {}
-
-fn bar() -> [u8; 2] {
-    foo();
-    [1, 3] //~ ERROR expected `;`, found `[`
-}
-
-fn main() {}
diff --git a/src/test/ui/parser/suggest-suggest-semicolon-before-array.rs b/src/test/ui/parser/suggest-suggest-semicolon-before-array.rs
deleted file mode 100644 (file)
index f601ca2..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// run-rustfix
-#![allow(dead_code)]
-
-fn foo() {}
-
-fn bar() -> [u8; 2] {
-    foo()
-    [1, 3] //~ ERROR expected `;`, found `[`
-}
-
-fn main() {}
diff --git a/src/test/ui/parser/suggest-suggest-semicolon-before-array.stderr b/src/test/ui/parser/suggest-suggest-semicolon-before-array.stderr
deleted file mode 100644 (file)
index bf86b43..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-error: expected `;`, found `[`
-  --> $DIR/suggest-suggest-semicolon-before-array.rs:8:5
-   |
-LL |     [1, 3]
-   |     ^
-   |
-help: consider adding `;` here
-   |
-LL |     foo();
-   |          +
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/repr/invalid_repr_list_help.rs b/src/test/ui/repr/invalid_repr_list_help.rs
new file mode 100644 (file)
index 0000000..c320984
--- /dev/null
@@ -0,0 +1,17 @@
+#![crate_type = "lib"]
+
+#[repr(uwu)] //~ERROR: unrecognized representation hint
+pub struct OwO;
+
+#[repr(uwu = "a")] //~ERROR: unrecognized representation hint
+pub struct OwO2(i32);
+
+#[repr(uwu(4))] //~ERROR: unrecognized representation hint
+pub struct OwO3 {
+    x: i32,
+}
+
+#[repr(uwu, u8)] //~ERROR: unrecognized representation hint
+pub enum OwO4 {
+    UwU = 1,
+}
diff --git a/src/test/ui/repr/invalid_repr_list_help.stderr b/src/test/ui/repr/invalid_repr_list_help.stderr
new file mode 100644 (file)
index 0000000..2acd56d
--- /dev/null
@@ -0,0 +1,35 @@
+error[E0552]: unrecognized representation hint
+  --> $DIR/invalid_repr_list_help.rs:3:8
+   |
+LL | #[repr(uwu)]
+   |        ^^^
+   |
+   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+
+error[E0552]: unrecognized representation hint
+  --> $DIR/invalid_repr_list_help.rs:6:8
+   |
+LL | #[repr(uwu = "a")]
+   |        ^^^^^^^^^
+   |
+   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+
+error[E0552]: unrecognized representation hint
+  --> $DIR/invalid_repr_list_help.rs:9:8
+   |
+LL | #[repr(uwu(4))]
+   |        ^^^^^^
+   |
+   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+
+error[E0552]: unrecognized representation hint
+  --> $DIR/invalid_repr_list_help.rs:14:8
+   |
+LL | #[repr(uwu, u8)]
+   |        ^^^
+   |
+   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0552`.
index ae509aab1525f68d2598e5d903ec3f085789166f..d1ab7fb67962ea83c19d93360024b334b704cbaf 100644 (file)
@@ -1175,7 +1175,7 @@ fn replace_types<'tcx>(
         if replaced.insert(param_ty.index) {
             for projection_predicate in projection_predicates {
                 if projection_predicate.projection_ty.self_ty() == param_ty.to_ty(cx.tcx)
-                    && let ty::Term::Ty(term_ty) = projection_predicate.term
+                    && let Some(term_ty) = projection_predicate.term.ty()
                     && let ty::Param(term_param_ty) = term_ty.kind()
                 {
                     let item_def_id = projection_predicate.projection_ty.item_def_id;
index fc9ba15d82a40e4e00f59c35ef8c378c43e28847..48a9d6e7c329e806ec571ebde331b7e0dbc63c0d 100644 (file)
@@ -3304,9 +3304,9 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::Impl
                 // one of the associated types must be Self
                 for &(predicate, _span) in cx.tcx.explicit_item_bounds(def_id) {
                     if let ty::PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
-                        let assoc_ty = match projection_predicate.term {
-                            ty::Term::Ty(ty) => ty,
-                            ty::Term::Const(_c) => continue,
+                        let assoc_ty = match projection_predicate.term.unpack() {
+                            ty::TermKind::Ty(ty) => ty,
+                            ty::TermKind::Const(_c) => continue,
                         };
                         // walk the associated type and check for Self
                         if let Some(self_adt) = self_ty.ty_adt_def() {
index 9dceb9af2f2234b09673affa472dce6887b57bdf..85da97a39f9a1539435c7f4d202b2dd5eb06fda9 100644 (file)
@@ -274,7 +274,7 @@ fn check_other_call_arg<'tcx>(
                         .subst_and_normalize_erasing_regions(call_substs, cx.param_env, projection_predicate.term);
                 implements_trait(cx, receiver_ty, deref_trait_id, &[])
                     && get_associated_type(cx, receiver_ty, deref_trait_id, "Target")
-                        .map_or(false, |ty| ty::Term::Ty(ty) == normalized_ty)
+                        .map_or(false, |ty| ty::TermKind::Ty(ty) == normalized_ty.unpack())
             } else {
                 false
             }
index 74c222bbcbeb99e6bda141ed4af1033c47915b3a..b22a9c817460db7761586f8899b839affd5be31d 100644 (file)
@@ -7,7 +7,7 @@
 use rustc_hir::def_id::DefId;
 use rustc_middle::mir::{
     Body, CastKind, NullOp, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
-    TerminatorKind,
+    TerminatorKind, NonDivergingIntrinsic
 };
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
@@ -212,11 +212,18 @@ fn check_statement<'tcx>(
             check_place(tcx, **place, span, body)
         },
 
-        StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { dst, src, count }) => {
+        StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => {
+            check_operand(tcx, op, span, body)
+        },
+
+        StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(
+            rustc_middle::mir::CopyNonOverlapping { dst, src, count },
+        )) => {
             check_operand(tcx, dst, span, body)?;
             check_operand(tcx, src, span, body)?;
             check_operand(tcx, count, span, body)
         },
+
         // These are all NOPs
         StatementKind::StorageLive(_)
         | StatementKind::StorageDead(_)
index dba35d2be72f4b78343d1a0f0b4737306f310672..ef3f649e49607a1fad64eb0a5139110df3efa2a7 160000 (submodule)
@@ -1 +1 @@
-Subproject commit dba35d2be72f4b78343d1a0f0b4737306f310672
+Subproject commit ef3f649e49607a1fad64eb0a5139110df3efa2a7
index a70252fa65a5d41dc9a26355ca5849c32a59474b..1563ee0b143851435a28597c8c088621e5c4a59b 100644 (file)
@@ -6,15 +6,15 @@ on:
   pull_request:
   push:
     branches:
-    - auto
-    - try
+      - auto
+      - try
 
 env:
   CARGO_INCREMENTAL: 0
   CARGO_NET_RETRY: 10
   CI: 1
   RUST_BACKTRACE: short
-  RUSTFLAGS: "-D warnings -W unreachable-pub -W rust-2021-compatibility"
+  RUSTFLAGS: "-D warnings -W unreachable-pub -W bare-trait-objects"
   RUSTUP_MAX_RETRIES: 10
 
 jobs:
@@ -31,25 +31,25 @@ jobs:
         os: [ubuntu-latest, windows-latest, macos-latest]
 
     steps:
-    - name: Checkout repository
-      uses: actions/checkout@v3
-      with:
-        ref: ${{ github.event.pull_request.head.sha }}
-        fetch-depth: 20
+      - name: Checkout repository
+        uses: actions/checkout@v3
+        with:
+          ref: ${{ github.event.pull_request.head.sha }}
+          fetch-depth: 20
 
-    - name: Install Rust toolchain
-      run: |
-        rustup update --no-self-update stable
-        rustup component add rustfmt rust-src
+      - name: Install Rust toolchain
+        run: |
+          rustup update --no-self-update stable
+          rustup component add rustfmt rust-src
 
-    - name: Cache Dependencies
-      uses: Swatinem/rust-cache@ce325b60658c1b38465c06cc965b79baf32c1e72
+      - name: Cache Dependencies
+        uses: Swatinem/rust-cache@ce325b60658c1b38465c06cc965b79baf32c1e72
 
-    - name: Compile
-      run: cargo test --no-run --locked
+      - name: Compile
+        run: cargo test --no-run --locked
 
-    - name: Test
-      run: cargo test -- --nocapture --quiet
+      - name: Test
+        run: cargo test -- --nocapture --quiet
 
   # Weird targets to catch non-portable code
   rust-cross:
@@ -64,25 +64,25 @@ jobs:
       targets_ide: "wasm32-unknown-unknown"
 
     steps:
-    - name: Checkout repository
-      uses: actions/checkout@v3
-
-    - name: Install Rust toolchain
-      run: |
-        rustup update --no-self-update stable
-        rustup target add ${{ env.targets }} ${{ env.targets_ide }}
-
-    - name: Cache Dependencies
-      uses: Swatinem/rust-cache@ce325b60658c1b38465c06cc965b79baf32c1e72
-
-    - name: Check
-      run: |
-        for target in ${{ env.targets }}; do
-          cargo check --target=$target --all-targets
-        done
-        for target in ${{ env.targets_ide }}; do
-          cargo check -p ide --target=$target --all-targets
-        done
+      - name: Checkout repository
+        uses: actions/checkout@v3
+
+      - name: Install Rust toolchain
+        run: |
+          rustup update --no-self-update stable
+          rustup target add ${{ env.targets }} ${{ env.targets_ide }}
+
+      - name: Cache Dependencies
+        uses: Swatinem/rust-cache@ce325b60658c1b38465c06cc965b79baf32c1e72
+
+      - name: Check
+        run: |
+          for target in ${{ env.targets }}; do
+            cargo check --target=$target --all-targets
+          done
+          for target in ${{ env.targets_ide }}; do
+            cargo check -p ide --target=$target --all-targets
+          done
 
   typescript:
     if: github.repository == 'rust-lang/rust-analyzer'
@@ -95,47 +95,47 @@ jobs:
     runs-on: ${{ matrix.os }}
 
     steps:
-    - name: Checkout repository
-      uses: actions/checkout@v3
-
-    - name: Install Nodejs
-      uses: actions/setup-node@v1
-      with:
-        node-version: 16.x
-
-    - name: Install xvfb
-      if: matrix.os == 'ubuntu-latest'
-      run: sudo apt-get install -y xvfb
-
-    - run: npm ci
-      working-directory: ./editors/code
-
-#    - run: npm audit || { sleep 10 && npm audit; } || { sleep 30 && npm audit; }
-#      if: runner.os == 'Linux'
-#      working-directory: ./editors/code
-
-    - run: npm run lint
-      working-directory: ./editors/code
-
-    - name: Run VS Code tests (Linux)
-      if: matrix.os == 'ubuntu-latest'
-      env:
-        VSCODE_CLI: 1
-      run: xvfb-run npm test
-      working-directory: ./editors/code
-
-    - name: Run VS Code tests (Windows)
-      if: matrix.os == 'windows-latest'
-      env:
-        VSCODE_CLI: 1
-      run: npm test
-      working-directory: ./editors/code
-
-    - run: npm run pretest
-      working-directory: ./editors/code
-
-    - run: npm run package --scripts-prepend-node-path
-      working-directory: ./editors/code
+      - name: Checkout repository
+        uses: actions/checkout@v3
+
+      - name: Install Nodejs
+        uses: actions/setup-node@v1
+        with:
+          node-version: 16.x
+
+      - name: Install xvfb
+        if: matrix.os == 'ubuntu-latest'
+        run: sudo apt-get install -y xvfb
+
+      - run: npm ci
+        working-directory: ./editors/code
+
+      #    - run: npm audit || { sleep 10 && npm audit; } || { sleep 30 && npm audit; }
+      #      if: runner.os == 'Linux'
+      #      working-directory: ./editors/code
+
+      - run: npm run lint
+        working-directory: ./editors/code
+
+      - name: Run VS Code tests (Linux)
+        if: matrix.os == 'ubuntu-latest'
+        env:
+          VSCODE_CLI: 1
+        run: xvfb-run npm test
+        working-directory: ./editors/code
+
+      - name: Run VS Code tests (Windows)
+        if: matrix.os == 'windows-latest'
+        env:
+          VSCODE_CLI: 1
+        run: npm test
+        working-directory: ./editors/code
+
+      - run: npm run pretest
+        working-directory: ./editors/code
+
+      - run: npm run package --scripts-prepend-node-path
+        working-directory: ./editors/code
 
   end-success:
     name: bors build finished
index b2e5db6f689b518e5b6cfdfbe11a7b79294bdbb1..303a10615bb7b7e33e5beb616a27059321cfff58 100644 (file)
@@ -248,7 +248,7 @@ jobs:
         if: github.ref == 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
         working-directory: ./editors/code
         # token from https://dev.azure.com/rust-analyzer/
-        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
+        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix || true
 
       - name: Publish Extension (Code Marketplace, nightly)
         if: github.ref != 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
@@ -258,4 +258,4 @@ jobs:
       - name: Publish Extension (OpenVSX, nightly)
         if: github.ref != 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
         working-directory: ./editors/code
-        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
+        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix || true
index 1d818d96267c177223985d6588e138556227e9c2..22f5fb9926638e0f7ea9413563fbcec4a372483f 100644 (file)
@@ -250,6 +250,10 @@ pub struct Body {
 
 pub type LabelPtr = AstPtr<ast::Label>;
 pub type LabelSource = InFile<LabelPtr>;
+
+pub type FieldPtr = AstPtr<ast::RecordExprField>;
+pub type FieldSource = InFile<FieldPtr>;
+
 /// An item body together with the mapping from syntax nodes to HIR expression
 /// IDs. This is needed to go from e.g. a position in a file to the HIR
 /// expression containing it; but for type inference etc., we want to operate on
@@ -264,18 +268,18 @@ pub struct Body {
 #[derive(Default, Debug, Eq, PartialEq)]
 pub struct BodySourceMap {
     expr_map: FxHashMap<ExprSource, ExprId>,
-    expr_map_back: ArenaMap<ExprId, Result<ExprSource, SyntheticSyntax>>,
+    expr_map_back: ArenaMap<ExprId, ExprSource>,
 
     pat_map: FxHashMap<PatSource, PatId>,
-    pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>,
+    pat_map_back: ArenaMap<PatId, PatSource>,
 
     label_map: FxHashMap<LabelSource, LabelId>,
     label_map_back: ArenaMap<LabelId, LabelSource>,
 
     /// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
     /// Instead, we use id of expression (`92`) to identify the field.
-    field_map: FxHashMap<InFile<AstPtr<ast::RecordExprField>>, ExprId>,
-    field_map_back: FxHashMap<ExprId, InFile<AstPtr<ast::RecordExprField>>>,
+    field_map: FxHashMap<FieldSource, ExprId>,
+    field_map_back: FxHashMap<ExprId, FieldSource>,
 
     expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>,
 
@@ -420,7 +424,7 @@ fn index(&self, label: LabelId) -> &Label {
 // Perhaps `expr_syntax` and `expr_id`?
 impl BodySourceMap {
     pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> {
-        self.expr_map_back[expr].clone()
+        self.expr_map_back.get(expr).cloned().ok_or(SyntheticSyntax)
     }
 
     pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option<ExprId> {
@@ -434,7 +438,7 @@ pub fn node_macro_file(&self, node: InFile<&ast::MacroCall>) -> Option<HirFileId
     }
 
     pub fn pat_syntax(&self, pat: PatId) -> Result<PatSource, SyntheticSyntax> {
-        self.pat_map_back[pat].clone()
+        self.pat_map_back.get(pat).cloned().ok_or(SyntheticSyntax)
     }
 
     pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> {
@@ -456,9 +460,10 @@ pub fn node_label(&self, node: InFile<&ast::Label>) -> Option<LabelId> {
         self.label_map.get(&src).cloned()
     }
 
-    pub fn field_syntax(&self, expr: ExprId) -> InFile<AstPtr<ast::RecordExprField>> {
+    pub fn field_syntax(&self, expr: ExprId) -> FieldSource {
         self.field_map_back[&expr].clone()
     }
+
     pub fn node_field(&self, node: InFile<&ast::RecordExprField>) -> Option<ExprId> {
         let src = node.map(AstPtr::new);
         self.field_map.get(&src).cloned()
index f6ec8bf7e9e0b4475302dfb6ed17b3c0e8c44d88..3b3297f7811c07628ba30e2382531672f2c89c39 100644 (file)
@@ -24,7 +24,7 @@
 
 use crate::{
     adt::StructKind,
-    body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax},
+    body::{Body, BodySourceMap, Expander, ExprPtr, LabelPtr, LabelSource, PatPtr},
     body::{BodyDiagnostic, ExprSource, PatSource},
     builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
     db::DefDatabase,
@@ -150,21 +150,21 @@ fn ctx(&self) -> LowerCtx<'_> {
         LowerCtx::new(self.db, self.expander.current_file_id)
     }
 
-    fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId {
+    fn alloc_expr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId {
         let src = self.expander.to_source(ptr);
-        let id = self.make_expr(expr, Ok(src.clone()));
+        let id = self.make_expr(expr, src.clone());
         self.source_map.expr_map.insert(src, id);
         id
     }
     // desugared exprs don't have ptr, that's wrong and should be fixed
     // somehow.
     fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId {
-        self.make_expr(expr, Err(SyntheticSyntax))
+        self.body.exprs.alloc(expr)
     }
     fn missing_expr(&mut self) -> ExprId {
         self.alloc_expr_desugared(Expr::Missing)
     }
-    fn make_expr(&mut self, expr: Expr, src: Result<ExprSource, SyntheticSyntax>) -> ExprId {
+    fn make_expr(&mut self, expr: Expr, src: ExprSource) -> ExprId {
         let id = self.body.exprs.alloc(expr);
         self.source_map.expr_map_back.insert(id, src);
         id
@@ -172,20 +172,20 @@ fn make_expr(&mut self, expr: Expr, src: Result<ExprSource, SyntheticSyntax>) ->
 
     fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId {
         let src = self.expander.to_source(ptr);
-        let id = self.make_pat(pat, Ok(src.clone()));
+        let id = self.make_pat(pat, src.clone());
         self.source_map.pat_map.insert(src, id);
         id
     }
     fn missing_pat(&mut self) -> PatId {
-        self.make_pat(Pat::Missing, Err(SyntheticSyntax))
+        self.body.pats.alloc(Pat::Missing)
     }
-    fn make_pat(&mut self, pat: Pat, src: Result<PatSource, SyntheticSyntax>) -> PatId {
+    fn make_pat(&mut self, pat: Pat, src: PatSource) -> PatId {
         let id = self.body.pats.alloc(pat);
         self.source_map.pat_map_back.insert(id, src);
         id
     }
 
-    fn alloc_label(&mut self, label: Label, ptr: AstPtr<ast::Label>) -> LabelId {
+    fn alloc_label(&mut self, label: Label, ptr: LabelPtr) -> LabelId {
         let src = self.expander.to_source(ptr);
         let id = self.make_label(label, src.clone());
         self.source_map.label_map.insert(src, id);
@@ -550,20 +550,6 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
                     None => self.alloc_expr(Expr::Missing, syntax_ptr),
                 }
             }
-            ast::Expr::MacroStmts(e) => {
-                let statements: Box<[_]> =
-                    e.statements().filter_map(|s| self.collect_stmt(s)).collect();
-                let tail = e.expr().map(|e| self.collect_expr(e));
-
-                if e.syntax().children().next().is_none() {
-                    // HACK: make sure that macros that expand to nothing aren't treated as a `()`
-                    // expression when used in block tail position.
-                    cov_mark::hit!(empty_macro_in_trailing_position_is_removed);
-                    return None;
-                }
-
-                self.alloc_expr(Expr::MacroStmts { tail, statements }, syntax_ptr)
-            }
             ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
         })
     }
@@ -640,11 +626,46 @@ fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId {
         }
     }
 
-    fn collect_stmt(&mut self, s: ast::Stmt) -> Option<Statement> {
+    fn collect_macro_as_stmt(
+        &mut self,
+        statements: &mut Vec<Statement>,
+        mac: ast::MacroExpr,
+    ) -> Option<ExprId> {
+        let mac_call = mac.macro_call()?;
+        let syntax_ptr = AstPtr::new(&ast::Expr::from(mac));
+        let macro_ptr = AstPtr::new(&mac_call);
+        let expansion = self.collect_macro_call(
+            mac_call,
+            macro_ptr,
+            false,
+            |this, expansion: Option<ast::MacroStmts>| match expansion {
+                Some(expansion) => {
+                    expansion.statements().for_each(|stmt| this.collect_stmt(statements, stmt));
+                    expansion.expr().and_then(|expr| match expr {
+                        ast::Expr::MacroExpr(mac) => this.collect_macro_as_stmt(statements, mac),
+                        expr => Some(this.collect_expr(expr)),
+                    })
+                }
+                None => None,
+            },
+        );
+        match expansion {
+            Some(tail) => {
+                // Make the macro-call point to its expanded expression so we can query
+                // semantics on syntax pointers to the macro
+                let src = self.expander.to_source(syntax_ptr);
+                self.source_map.expr_map.insert(src, tail);
+                Some(tail)
+            }
+            None => None,
+        }
+    }
+
+    fn collect_stmt(&mut self, statements: &mut Vec<Statement>, s: ast::Stmt) {
         match s {
             ast::Stmt::LetStmt(stmt) => {
                 if self.check_cfg(&stmt).is_none() {
-                    return None;
+                    return;
                 }
                 let pat = self.collect_pat_opt(stmt.pat());
                 let type_ref =
@@ -654,61 +675,26 @@ fn collect_stmt(&mut self, s: ast::Stmt) -> Option<Statement> {
                     .let_else()
                     .and_then(|let_else| let_else.block_expr())
                     .map(|block| self.collect_block(block));
-                Some(Statement::Let { pat, type_ref, initializer, else_branch })
+                statements.push(Statement::Let { pat, type_ref, initializer, else_branch });
             }
             ast::Stmt::ExprStmt(stmt) => {
                 let expr = stmt.expr();
-                if let Some(expr) = &expr {
-                    if self.check_cfg(expr).is_none() {
-                        return None;
-                    }
+                match &expr {
+                    Some(expr) if self.check_cfg(expr).is_none() => return,
+                    _ => (),
                 }
                 let has_semi = stmt.semicolon_token().is_some();
                 // Note that macro could be expanded to multiple statements
-                if let Some(expr @ ast::Expr::MacroExpr(mac)) = &expr {
-                    let mac_call = mac.macro_call()?;
-                    let syntax_ptr = AstPtr::new(expr);
-                    let macro_ptr = AstPtr::new(&mac_call);
-                    let stmt = self.collect_macro_call(
-                        mac_call,
-                        macro_ptr,
-                        false,
-                        |this, expansion: Option<ast::MacroStmts>| match expansion {
-                            Some(expansion) => {
-                                let statements = expansion
-                                    .statements()
-                                    .filter_map(|stmt| this.collect_stmt(stmt))
-                                    .collect();
-                                let tail = expansion.expr().map(|expr| this.collect_expr(expr));
-
-                                let mac_stmts = this.alloc_expr(
-                                    Expr::MacroStmts { tail, statements },
-                                    AstPtr::new(&ast::Expr::MacroStmts(expansion)),
-                                );
-
-                                Some(mac_stmts)
-                            }
-                            None => None,
-                        },
-                    );
-
-                    let expr = match stmt {
-                        Some(expr) => {
-                            // Make the macro-call point to its expanded expression so we can query
-                            // semantics on syntax pointers to the macro
-                            let src = self.expander.to_source(syntax_ptr);
-                            self.source_map.expr_map.insert(src, expr);
-                            expr
-                        }
-                        None => self.alloc_expr(Expr::Missing, syntax_ptr),
-                    };
-                    Some(Statement::Expr { expr, has_semi })
+                if let Some(ast::Expr::MacroExpr(mac)) = expr {
+                    if let Some(expr) = self.collect_macro_as_stmt(statements, mac) {
+                        statements.push(Statement::Expr { expr, has_semi })
+                    }
                 } else {
                     let expr = self.collect_expr_opt(expr);
-                    Some(Statement::Expr { expr, has_semi })
+                    statements.push(Statement::Expr { expr, has_semi });
                 }
             }
-            ast::Stmt::Item(_item) => None,
+            ast::Stmt::Item(_item) => (),
         }
     }
 
@@ -729,9 +715,12 @@ fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId {
         let prev_def_map = mem::replace(&mut self.expander.def_map, def_map);
         let prev_local_module = mem::replace(&mut self.expander.module, module);
 
-        let mut statements: Vec<_> =
-            block.statements().filter_map(|s| self.collect_stmt(s)).collect();
-        let tail = block.tail_expr().and_then(|e| self.maybe_collect_expr(e));
+        let mut statements = Vec::new();
+        block.statements().for_each(|s| self.collect_stmt(&mut statements, s));
+        let tail = block.tail_expr().and_then(|e| match e {
+            ast::Expr::MacroExpr(mac) => self.collect_macro_as_stmt(&mut statements, mac),
+            expr => self.maybe_collect_expr(expr),
+        });
         let tail = tail.or_else(|| {
             let stmt = statements.pop()?;
             if let Statement::Expr { expr, has_semi: false } = stmt {
index ddd476efe5c4d764dabd4ff597e732d902fb3dec..f2fed954444e2ca80b04a41a7bafa488f87905e4 100644 (file)
@@ -422,19 +422,6 @@ fn print_expr(&mut self, expr: ExprId) {
                 }
                 w!(self, "}}");
             }
-            Expr::MacroStmts { statements, tail } => {
-                w!(self, "{{ // macro statements");
-                self.indented(|p| {
-                    for stmt in statements.iter() {
-                        p.print_stmt(stmt);
-                    }
-                    if let Some(tail) = tail {
-                        p.print_expr(*tail);
-                    }
-                });
-                self.newline();
-                w!(self, "}}");
-            }
         }
     }
 
index f4c390dce26e0520168594430508281406137c3f..45f64ebb06007b7c5cf1a414d02930d5a12b203a 100644 (file)
@@ -47,16 +47,9 @@ pub struct ScopeData {
 impl ExprScopes {
     pub(crate) fn expr_scopes_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<ExprScopes> {
         let body = db.body(def);
-        Arc::new(ExprScopes::new(&*body))
-    }
-
-    fn new(body: &Body) -> ExprScopes {
-        let mut scopes =
-            ExprScopes { scopes: Arena::default(), scope_by_expr: FxHashMap::default() };
-        let mut root = scopes.root_scope();
-        scopes.add_params_bindings(body, root, &body.params);
-        compute_expr_scopes(body.body_expr, body, &mut scopes, &mut root);
-        scopes
+        let mut scopes = ExprScopes::new(&*body);
+        scopes.shrink_to_fit();
+        Arc::new(scopes)
     }
 
     pub fn entries(&self, scope: ScopeId) -> &[ScopeEntry] {
@@ -89,6 +82,17 @@ pub fn scope_for(&self, expr: ExprId) -> Option<ScopeId> {
     pub fn scope_by_expr(&self) -> &FxHashMap<ExprId, ScopeId> {
         &self.scope_by_expr
     }
+}
+
+impl ExprScopes {
+    fn new(body: &Body) -> ExprScopes {
+        let mut scopes =
+            ExprScopes { scopes: Arena::default(), scope_by_expr: FxHashMap::default() };
+        let mut root = scopes.root_scope();
+        scopes.add_params_bindings(body, root, &body.params);
+        compute_expr_scopes(body.body_expr, body, &mut scopes, &mut root);
+        scopes
+    }
 
     fn root_scope(&mut self) -> ScopeId {
         self.scopes.alloc(ScopeData { parent: None, block: None, label: None, entries: vec![] })
@@ -138,6 +142,13 @@ fn add_params_bindings(&mut self, body: &Body, scope: ScopeId, params: &[PatId])
     fn set_scope(&mut self, node: ExprId, scope: ScopeId) {
         self.scope_by_expr.insert(node, scope);
     }
+
+    fn shrink_to_fit(&mut self) {
+        let ExprScopes { scopes, scope_by_expr } = self;
+        scopes.shrink_to_fit();
+        scopes.values_mut().for_each(|it| it.entries.shrink_to_fit());
+        scope_by_expr.shrink_to_fit();
+    }
 }
 
 fn compute_block_scopes(
@@ -176,9 +187,6 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope
 
     scopes.set_scope(expr, *scope);
     match &body[expr] {
-        Expr::MacroStmts { statements, tail } => {
-            compute_block_scopes(statements, *tail, body, scopes, scope);
-        }
         Expr::Block { statements, tail, id, label } => {
             let mut scope = scopes.new_block_scope(*scope, *id, make_label(label));
             // Overwrite the old scope for the block expr, so that every block scope can be found
index 4381b43c258bfe90a9387e10f7608981090105f8..419d3feec3b6c2240c8be326edb0ad24a402c9eb 100644 (file)
@@ -206,10 +206,6 @@ pub enum Expr {
     Unsafe {
         body: ExprId,
     },
-    MacroStmts {
-        statements: Box<[Statement]>,
-        tail: Option<ExprId>,
-    },
     Array(Array),
     Literal(Literal),
     Underscore,
@@ -263,7 +259,7 @@ pub fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) {
             Expr::Let { expr, .. } => {
                 f(*expr);
             }
-            Expr::MacroStmts { tail, statements } | Expr::Block { statements, tail, .. } => {
+            Expr::Block { statements, tail, .. } => {
                 for stmt in statements.iter() {
                     match stmt {
                         Statement::Let { initializer, .. } => {
index 6eb530ecc54209d5e2f37ea98a8012c09ac3e87a..9b4ce9f97c86ff4b708e8c124ac71f07b385463e 100644 (file)
@@ -64,7 +64,7 @@
 use itertools::Itertools;
 use la_arena::Arena;
 use profile::Count;
-use rustc_hash::FxHashMap;
+use rustc_hash::{FxHashMap, FxHashSet};
 use stdx::format_to;
 use syntax::{ast, SmolStr};
 
@@ -98,7 +98,11 @@ pub struct DefMap {
     /// The prelude module for this crate. This either comes from an import
     /// marked with the `prelude_import` attribute, or (in the normal case) from
     /// a dependency (`std` or `core`).
+    /// The prelude is empty for non-block DefMaps (unless `#[prelude_import]` was used,
+    /// but that attribute is nightly and when used in a block, it affects resolution globally
+    /// so we aren't handling this correctly anyways).
     prelude: Option<ModuleId>,
+    /// The extern prelude is only populated for non-block DefMaps
     extern_prelude: FxHashMap<Name, ModuleId>,
 
     /// Side table for resolving derive helpers.
@@ -114,6 +118,8 @@ pub struct DefMap {
     registered_attrs: Vec<SmolStr>,
     /// Custom tool modules registered with `#![register_tool]`.
     registered_tools: Vec<SmolStr>,
+    /// Unstable features of Rust enabled with `#![feature(A, B)]`.
+    unstable_features: FxHashSet<SmolStr>,
 
     edition: Edition,
     recursion_limit: Option<u32>,
@@ -284,6 +290,7 @@ fn empty(krate: CrateId, edition: Edition, module_data: ModuleData) -> DefMap {
             modules,
             registered_attrs: Vec::new(),
             registered_tools: Vec::new(),
+            unstable_features: FxHashSet::default(),
             diagnostics: Vec::new(),
         }
     }
@@ -314,6 +321,10 @@ pub fn registered_attrs(&self) -> &[SmolStr] {
         &self.registered_attrs
     }
 
+    pub fn is_unstable_feature_enabled(&self, feature: &str) -> bool {
+        self.unstable_features.contains(feature)
+    }
+
     pub fn root(&self) -> LocalModuleId {
         self.root
     }
@@ -479,6 +490,7 @@ fn shrink_to_fit(&mut self) {
             registered_tools,
             fn_proc_macro_mapping,
             derive_helpers_in_scope,
+            unstable_features,
             proc_macro_loading_error: _,
             block: _,
             edition: _,
@@ -496,6 +508,7 @@ fn shrink_to_fit(&mut self) {
         registered_tools.shrink_to_fit();
         fn_proc_macro_mapping.shrink_to_fit();
         derive_helpers_in_scope.shrink_to_fit();
+        unstable_features.shrink_to_fit();
         for (_, module) in modules.iter_mut() {
             module.children.shrink_to_fit();
             module.scope.shrink_to_fit();
index 8a6bb929c3df7bd660e2fcd5995b8e38b61bcfc0..495bbe4579f00780774fc970110130f7fdd0ddb3 100644 (file)
@@ -294,6 +294,17 @@ fn seed_with_top_level(&mut self) {
                     continue;
                 }
 
+                if *attr_name == hir_expand::name![feature] {
+                    let features =
+                        attr.parse_path_comma_token_tree().into_iter().flatten().filter_map(
+                            |feat| match feat.segments() {
+                                [name] => Some(name.to_smol_str()),
+                                _ => None,
+                            },
+                        );
+                    self.def_map.unstable_features.extend(features);
+                }
+
                 let attr_is_register_like = *attr_name == hir_expand::name![register_attr]
                     || *attr_name == hir_expand::name![register_tool];
                 if !attr_is_register_like {
@@ -501,10 +512,9 @@ fn inject_prelude(&mut self, crate_attrs: &Attrs) {
             Edition::Edition2021 => name![rust_2021],
         };
 
-        let path_kind = if self.def_map.edition == Edition::Edition2015 {
-            PathKind::Plain
-        } else {
-            PathKind::Abs
+        let path_kind = match self.def_map.edition {
+            Edition::Edition2015 => PathKind::Plain,
+            _ => PathKind::Abs,
         };
         let path =
             ModPath::from_segments(path_kind, [krate.clone(), name![prelude], edition].into_iter());
@@ -524,7 +534,6 @@ fn inject_prelude(&mut self, crate_attrs: &Attrs) {
             match per_ns.types {
                 Some((ModuleDefId::ModuleId(m), _)) => {
                     self.def_map.prelude = Some(m);
-                    return;
                 }
                 types => {
                     tracing::debug!(
@@ -839,7 +848,10 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) {
                 tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
 
                 // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
-                if import.is_extern_crate && module_id == self.def_map.root {
+                if import.is_extern_crate
+                    && self.def_map.block.is_none()
+                    && module_id == self.def_map.root
+                {
                     if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name)
                     {
                         self.def_map.extern_prelude.insert(name.clone(), def);
index 99f7f1b549e2c91f0c09e3af97a6be772f0c1b61..ca7bcc814e8f8e41e4ced5c765e48f22af51a505 100644 (file)
@@ -65,6 +65,7 @@ pub(super) fn resolve_declaration(
         name: &Name,
         attr_path: Option<&SmolStr>,
     ) -> Result<(FileId, bool, ModDir), Box<[String]>> {
+        let name = name.unescaped();
         let orig_file_id = file_id.original_file(db.upcast());
 
         let mut candidate_files = ArrayVec::<_, 2>::new();
@@ -73,12 +74,10 @@ pub(super) fn resolve_declaration(
                 candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner))
             }
             None if file_id.is_include_macro(db.upcast()) => {
-                let name = name.unescaped();
                 candidate_files.push(format!("{}.rs", name));
                 candidate_files.push(format!("{}/mod.rs", name));
             }
             None => {
-                let name = name.unescaped();
                 candidate_files.push(format!("{}{}.rs", self.dir_path.0, name));
                 candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name));
             }
index 3fa585574deec5076c4ca53f0afd3be52747310e..ba3bf8b5a5cfa54075da94a07765c26f98fb2a7b 100644 (file)
@@ -127,7 +127,15 @@ fn module_resolution_works_for_raw_modules() {
 use self::r#async::Bar;
 
 //- /async.rs
+mod foo;
+mod r#async;
 pub struct Bar;
+
+//- /async/foo.rs
+pub struct Foo;
+
+//- /async/async.rs
+pub struct Baz;
 "#,
         expect![[r#"
             crate
@@ -136,6 +144,14 @@ fn module_resolution_works_for_raw_modules() {
 
             crate::r#async
             Bar: t v
+            foo: t
+            r#async: t
+
+            crate::r#async::foo
+            Foo: t v
+
+            crate::r#async::r#async
+            Baz: t v
         "#]],
     );
 }
index 3163fa0f93fa573c0e2215f2ccaf5f1627340b38..8aa5973cac57baae18937f13d92a45f2d83242f2 100644 (file)
@@ -31,12 +31,10 @@ pub struct Resolver {
     ///
     /// When using, you generally want to process the scopes in reverse order,
     /// there's `scopes` *method* for that.
-    ///
-    /// Invariant: There exists at least one Scope::ModuleScope at the start of the vec.
     scopes: Vec<Scope>,
+    module_scope: ModuleItemMap,
 }
 
-// FIXME how to store these best
 #[derive(Debug, Clone)]
 struct ModuleItemMap {
     def_map: Arc<DefMap>,
@@ -53,7 +51,7 @@ struct ExprScope {
 #[derive(Debug, Clone)]
 enum Scope {
     /// All the items and imported names of a module
-    ModuleScope(ModuleItemMap),
+    BlockScope(ModuleItemMap),
     /// Brings the generic parameters of an item into scope
     GenericParams { def: GenericDefId, params: Interned<GenericParams> },
     /// Brings `Self` in `impl` block into scope
@@ -127,24 +125,6 @@ pub fn resolve_known_enum(&self, db: &dyn DefDatabase, path: &ModPath) -> Option
         }
     }
 
-    fn scopes(&self) -> impl Iterator<Item = &Scope> {
-        self.scopes.iter().rev()
-    }
-
-    fn resolve_module_path(
-        &self,
-        db: &dyn DefDatabase,
-        path: &ModPath,
-        shadow: BuiltinShadowMode,
-    ) -> PerNs {
-        let (item_map, module) = self.module_scope();
-        let (module_res, segment_index) = item_map.resolve_path(db, module, path, shadow);
-        if segment_index.is_some() {
-            return PerNs::none();
-        }
-        module_res
-    }
-
     pub fn resolve_module_path_in_items(&self, db: &dyn DefDatabase, path: &ModPath) -> PerNs {
         self.resolve_module_path(db, path, BuiltinShadowMode::Module)
     }
@@ -155,7 +135,7 @@ pub fn resolve_module_path_in_trait_assoc_items(
         db: &dyn DefDatabase,
         path: &ModPath,
     ) -> Option<PerNs> {
-        let (item_map, module) = self.module_scope();
+        let (item_map, module) = self.item_scope();
         let (module_res, idx) = item_map.resolve_path(db, module, path, BuiltinShadowMode::Module);
         match module_res.take_types()? {
             ModuleDefId::TraitId(it) => {
@@ -183,37 +163,38 @@ pub fn resolve_path_in_type_ns(
     ) -> Option<(TypeNs, Option<usize>)> {
         let first_name = path.segments().first()?;
         let skip_to_mod = path.kind != PathKind::Plain;
+        if skip_to_mod {
+            return self.module_scope.resolve_path_in_type_ns(db, path);
+        }
+
+        let remaining_idx = || if path.segments().len() == 1 { None } else { Some(1) };
+
         for scope in self.scopes() {
             match scope {
                 Scope::ExprScope(_) => continue,
-                Scope::GenericParams { .. } | Scope::ImplDefScope(_) if skip_to_mod => continue,
-
                 Scope::GenericParams { params, def } => {
                     if let Some(id) = params.find_type_by_name(first_name, *def) {
-                        let idx = if path.segments().len() == 1 { None } else { Some(1) };
-                        return Some((TypeNs::GenericParam(id), idx));
+                        return Some((TypeNs::GenericParam(id), remaining_idx()));
                     }
                 }
-                Scope::ImplDefScope(impl_) => {
+                &Scope::ImplDefScope(impl_) => {
                     if first_name == &name![Self] {
-                        let idx = if path.segments().len() == 1 { None } else { Some(1) };
-                        return Some((TypeNs::SelfType(*impl_), idx));
+                        return Some((TypeNs::SelfType(impl_), remaining_idx()));
                     }
                 }
-                Scope::AdtScope(adt) => {
+                &Scope::AdtScope(adt) => {
                     if first_name == &name![Self] {
-                        let idx = if path.segments().len() == 1 { None } else { Some(1) };
-                        return Some((TypeNs::AdtSelfType(*adt), idx));
+                        return Some((TypeNs::AdtSelfType(adt), remaining_idx()));
                     }
                 }
-                Scope::ModuleScope(m) => {
+                Scope::BlockScope(m) => {
                     if let Some(res) = m.resolve_path_in_type_ns(db, path) {
                         return Some(res);
                     }
                 }
             }
         }
-        None
+        self.module_scope.resolve_path_in_type_ns(db, path)
     }
 
     pub fn resolve_path_in_type_ns_fully(
@@ -235,7 +216,7 @@ pub fn resolve_visibility(
     ) -> Option<Visibility> {
         match visibility {
             RawVisibility::Module(_) => {
-                let (item_map, module) = self.module_scope();
+                let (item_map, module) = self.item_scope();
                 item_map.resolve_visibility(db, module, visibility)
             }
             RawVisibility::Public => Some(Visibility::Public),
@@ -251,18 +232,14 @@ pub fn resolve_path_in_value_ns(
         let tmp = name![self];
         let first_name = if path.is_self() { &tmp } else { path.segments().first()? };
         let skip_to_mod = path.kind != PathKind::Plain && !path.is_self();
+        if skip_to_mod {
+            return self.module_scope.resolve_path_in_value_ns(db, path);
+        }
+
         for scope in self.scopes() {
             match scope {
-                Scope::AdtScope(_)
-                | Scope::ExprScope(_)
-                | Scope::GenericParams { .. }
-                | Scope::ImplDefScope(_)
-                    if skip_to_mod =>
-                {
-                    continue
-                }
-
-                Scope::ExprScope(scope) if n_segments <= 1 => {
+                Scope::ExprScope(_) if n_segments > 1 => continue,
+                Scope::ExprScope(scope) => {
                     let entry = scope
                         .expr_scopes
                         .entries(scope.scope_id)
@@ -273,44 +250,39 @@ pub fn resolve_path_in_value_ns(
                         return Some(ResolveValueResult::ValueNs(ValueNs::LocalBinding(e.pat())));
                     }
                 }
-                Scope::ExprScope(_) => continue,
-
                 Scope::GenericParams { params, def } if n_segments > 1 => {
                     if let Some(id) = params.find_type_by_name(first_name, *def) {
                         let ty = TypeNs::GenericParam(id);
                         return Some(ResolveValueResult::Partial(ty, 1));
                     }
                 }
-                Scope::GenericParams { params, def } if n_segments == 1 => {
+                Scope::GenericParams { .. } if n_segments != 1 => continue,
+                Scope::GenericParams { params, def } => {
                     if let Some(id) = params.find_const_by_name(first_name, *def) {
                         let val = ValueNs::GenericParam(id);
                         return Some(ResolveValueResult::ValueNs(val));
                     }
                 }
-                Scope::GenericParams { .. } => continue,
 
-                Scope::ImplDefScope(impl_) => {
+                &Scope::ImplDefScope(impl_) => {
                     if first_name == &name![Self] {
-                        if n_segments > 1 {
-                            let ty = TypeNs::SelfType(*impl_);
-                            return Some(ResolveValueResult::Partial(ty, 1));
+                        return Some(if n_segments > 1 {
+                            ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1)
                         } else {
-                            return Some(ResolveValueResult::ValueNs(ValueNs::ImplSelf(*impl_)));
-                        }
+                            ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_))
+                        });
                     }
                 }
+                // bare `Self` doesn't work in the value namespace in a struct/enum definition
+                Scope::AdtScope(_) if n_segments == 1 => continue,
                 Scope::AdtScope(adt) => {
-                    if n_segments == 1 {
-                        // bare `Self` doesn't work in the value namespace in a struct/enum definition
-                        continue;
-                    }
                     if first_name == &name![Self] {
                         let ty = TypeNs::AdtSelfType(*adt);
                         return Some(ResolveValueResult::Partial(ty, 1));
                     }
                 }
 
-                Scope::ModuleScope(m) => {
+                Scope::BlockScope(m) => {
                     if let Some(def) = m.resolve_path_in_value_ns(db, path) {
                         return Some(def);
                     }
@@ -318,15 +290,16 @@ pub fn resolve_path_in_value_ns(
             }
         }
 
+        if let res @ Some(_) = self.module_scope.resolve_path_in_value_ns(db, path) {
+            return res;
+        }
+
         // If a path of the shape `u16::from_le_bytes` failed to resolve at all, then we fall back
         // to resolving to the primitive type, to allow this to still work in the presence of
         // `use core::u16;`.
         if path.kind == PathKind::Plain && path.segments().len() > 1 {
-            match BuiltinType::by_name(&path.segments()[0]) {
-                Some(builtin) => {
-                    return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1));
-                }
-                None => {}
+            if let Some(builtin) = BuiltinType::by_name(&path.segments()[0]) {
+                return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1));
             }
         }
 
@@ -345,7 +318,7 @@ pub fn resolve_path_in_value_ns_fully(
     }
 
     pub fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<MacroId> {
-        let (item_map, module) = self.module_scope();
+        let (item_map, module) = self.item_scope();
         item_map.resolve_path(db, module, path, BuiltinShadowMode::Other).0.take_macros()
     }
 
@@ -395,30 +368,43 @@ pub fn names_in_scope(
         for scope in self.scopes() {
             scope.process_names(&mut res, db);
         }
+        let ModuleItemMap { ref def_map, module_id } = self.module_scope;
+        // FIXME: should we provide `self` here?
+        // f(
+        //     Name::self_param(),
+        //     PerNs::types(Resolution::Def {
+        //         def: m.module.into(),
+        //     }),
+        // );
+        def_map[module_id].scope.entries().for_each(|(name, def)| {
+            res.add_per_ns(name, def);
+        });
+        def_map[module_id].scope.legacy_macros().for_each(|(name, macs)| {
+            macs.iter().for_each(|&mac| {
+                res.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(MacroId::from(mac))));
+            })
+        });
+        def_map.extern_prelude().for_each(|(name, &def)| {
+            res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def)));
+        });
+        BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
+            res.add_per_ns(name, def);
+        });
+        if let Some(prelude) = def_map.prelude() {
+            let prelude_def_map = prelude.def_map(db);
+            for (name, def) in prelude_def_map[prelude.local_id].scope.entries() {
+                res.add_per_ns(name, def)
+            }
+        }
         res.map
     }
 
     pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
         let mut traits = FxHashSet::default();
+
         for scope in self.scopes() {
             match scope {
-                Scope::ModuleScope(m) => {
-                    if let Some(prelude) = m.def_map.prelude() {
-                        let prelude_def_map = prelude.def_map(db);
-                        traits.extend(prelude_def_map[prelude.local_id].scope.traits());
-                    }
-                    traits.extend(m.def_map[m.module_id].scope.traits());
-
-                    // Add all traits that are in scope because of the containing DefMaps
-                    m.def_map.with_ancestor_maps(db, m.module_id, &mut |def_map, module| {
-                        if let Some(prelude) = def_map.prelude() {
-                            let prelude_def_map = prelude.def_map(db);
-                            traits.extend(prelude_def_map[prelude.local_id].scope.traits());
-                        }
-                        traits.extend(def_map[module].scope.traits());
-                        None::<()>
-                    });
-                }
+                Scope::BlockScope(m) => traits.extend(m.def_map[m.module_id].scope.traits()),
                 &Scope::ImplDefScope(impl_) => {
                     if let Some(target_trait) = &db.impl_data(impl_).target_trait {
                         if let Some(TypeNs::TraitId(trait_)) =
@@ -431,35 +417,28 @@ pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
                 _ => (),
             }
         }
-        traits
-    }
 
-    fn module_scope(&self) -> (&DefMap, LocalModuleId) {
-        self.scopes()
-            .find_map(|scope| match scope {
-                Scope::ModuleScope(m) => Some((&*m.def_map, m.module_id)),
-                _ => None,
-            })
-            .expect("module scope invariant violated")
+        // Fill in the prelude traits
+        if let Some(prelude) = self.module_scope.def_map.prelude() {
+            let prelude_def_map = prelude.def_map(db);
+            traits.extend(prelude_def_map[prelude.local_id].scope.traits());
+        }
+        // Fill in module visible traits
+        traits.extend(self.module_scope.def_map[self.module_scope.module_id].scope.traits());
+        traits
     }
 
     pub fn module(&self) -> ModuleId {
-        let (def_map, local_id) = self.module_scope();
+        let (def_map, local_id) = self.item_scope();
         def_map.module_id(local_id)
     }
 
     pub fn krate(&self) -> CrateId {
-        self.def_map().krate()
+        self.module_scope.def_map.krate()
     }
 
     pub fn def_map(&self) -> &DefMap {
-        self.scopes
-            .get(0)
-            .and_then(|scope| match scope {
-                Scope::ModuleScope(m) => Some(&m.def_map),
-                _ => None,
-            })
-            .expect("module scope invariant violated")
+        self.item_scope().0
     }
 
     pub fn where_predicates_in_scope(
@@ -488,6 +467,36 @@ pub fn body_owner(&self) -> Option<DefWithBodyId> {
     }
 }
 
+impl Resolver {
+    fn scopes(&self) -> impl Iterator<Item = &Scope> {
+        self.scopes.iter().rev()
+    }
+
+    fn resolve_module_path(
+        &self,
+        db: &dyn DefDatabase,
+        path: &ModPath,
+        shadow: BuiltinShadowMode,
+    ) -> PerNs {
+        let (item_map, module) = self.item_scope();
+        let (module_res, segment_index) = item_map.resolve_path(db, module, path, shadow);
+        if segment_index.is_some() {
+            return PerNs::none();
+        }
+        module_res
+    }
+
+    /// The innermost block scope that contains items or the module scope that contains this resolver.
+    fn item_scope(&self) -> (&DefMap, LocalModuleId) {
+        self.scopes()
+            .find_map(|scope| match scope {
+                Scope::BlockScope(m) => Some((&*m.def_map, m.module_id)),
+                _ => None,
+            })
+            .unwrap_or((&self.module_scope.def_map, self.module_scope.module_id))
+    }
+}
+
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub enum ScopeDef {
     ModuleDef(ModuleDefId),
@@ -502,14 +511,7 @@ pub enum ScopeDef {
 impl Scope {
     fn process_names(&self, acc: &mut ScopeNames, db: &dyn DefDatabase) {
         match self {
-            Scope::ModuleScope(m) => {
-                // FIXME: should we provide `self` here?
-                // f(
-                //     Name::self_param(),
-                //     PerNs::types(Resolution::Def {
-                //         def: m.module.into(),
-                //     }),
-                // );
+            Scope::BlockScope(m) => {
                 m.def_map[m.module_id].scope.entries().for_each(|(name, def)| {
                     acc.add_per_ns(name, def);
                 });
@@ -521,18 +523,6 @@ fn process_names(&self, acc: &mut ScopeNames, db: &dyn DefDatabase) {
                         );
                     })
                 });
-                m.def_map.extern_prelude().for_each(|(name, &def)| {
-                    acc.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def)));
-                });
-                BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
-                    acc.add_per_ns(name, def);
-                });
-                if let Some(prelude) = m.def_map.prelude() {
-                    let prelude_def_map = prelude.def_map(db);
-                    for (name, def) in prelude_def_map[prelude.local_id].scope.entries() {
-                        acc.add_per_ns(name, def)
-                    }
-                }
             }
             Scope::GenericParams { params, def: parent } => {
                 let parent = *parent;
@@ -596,7 +586,7 @@ pub fn resolver_for_scope(
         if let Some(block) = scopes.block(scope) {
             if let Some(def_map) = db.block_def_map(block) {
                 let root = def_map.root();
-                r = r.push_module_scope(def_map, root);
+                r = r.push_block_scope(def_map, root);
                 // FIXME: This adds as many module scopes as there are blocks, but resolving in each
                 // already traverses all parents, so this is O(n²). I think we could only store the
                 // innermost module scope instead?
@@ -623,8 +613,8 @@ fn push_impl_def_scope(self, impl_def: ImplId) -> Resolver {
         self.push_scope(Scope::ImplDefScope(impl_def))
     }
 
-    fn push_module_scope(self, def_map: Arc<DefMap>, module_id: LocalModuleId) -> Resolver {
-        self.push_scope(Scope::ModuleScope(ModuleItemMap { def_map, module_id }))
+    fn push_block_scope(self, def_map: Arc<DefMap>, module_id: LocalModuleId) -> Resolver {
+        self.push_scope(Scope::BlockScope(ModuleItemMap { def_map, module_id }))
     }
 
     fn push_expr_scope(
@@ -768,14 +758,19 @@ pub trait HasResolver: Copy {
 impl HasResolver for ModuleId {
     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
         let mut def_map = self.def_map(db);
-        let mut modules: SmallVec<[_; 2]> = smallvec![(def_map.clone(), self.local_id)];
+        let mut modules: SmallVec<[_; 1]> = smallvec![];
+        let mut module_id = self.local_id;
         while let Some(parent) = def_map.parent() {
+            modules.push((def_map, module_id));
             def_map = parent.def_map(db);
-            modules.push((def_map.clone(), parent.local_id));
+            module_id = parent.local_id;
         }
-        let mut resolver = Resolver { scopes: Vec::with_capacity(modules.len()) };
+        let mut resolver = Resolver {
+            scopes: Vec::with_capacity(modules.len()),
+            module_scope: ModuleItemMap { def_map, module_id },
+        };
         for (def_map, module) in modules.into_iter().rev() {
-            resolver = resolver.push_module_scope(def_map, module);
+            resolver = resolver.push_block_scope(def_map, module);
         }
         resolver
     }
index d753d88470c442cb3c372494c2fc38720eb91573..fc128102f225a18cc066193e649e843dd2147906 100644 (file)
@@ -969,7 +969,7 @@ pub fn from_call_site(call: &ast::MacroCall) -> ExpandTo {
         if parent.kind() == MACRO_EXPR
             && parent
                 .parent()
-                .map_or(true, |p| matches!(p.kind(), EXPR_STMT | STMT_LIST | MACRO_STMTS))
+                .map_or(false, |p| matches!(p.kind(), EXPR_STMT | STMT_LIST | MACRO_STMTS))
         {
             return ExpandTo::Statements;
         }
index 2b859f775095beb0e005fb1657e59d001e933408..4ce21a57967c72048f59b5db4517c544d075b528 100644 (file)
@@ -336,6 +336,7 @@ macro_rules! known_names {
         test,
         test_case,
         recursion_limit,
+        feature,
         // Safe intrinsics
         abort,
         add_with_overflow,
index b6f226dbfd20d238ff19338a20d07eab5a3b7008..344036dd8139d28d433c745b6121ab8c85e9865f 100644 (file)
@@ -104,8 +104,7 @@ pub(crate) fn deref(table: &mut InferenceTable<'_>, ty: Ty) -> Option<Ty> {
 
 fn builtin_deref(ty: &Ty) -> Option<&Ty> {
     match ty.kind(Interner) {
-        TyKind::Ref(.., ty) => Some(ty),
-        TyKind::Raw(.., ty) => Some(ty),
+        TyKind::Ref(.., ty) | TyKind::Raw(.., ty) => Some(ty),
         _ => None,
     }
 }
index 642e03edd230636ca3911a0e0eee44dc8989a41e..c8df4c796efca045f974d21e3b21a8a67e23bf28 100644 (file)
@@ -159,12 +159,7 @@ fn validate_match(
         }
 
         let pattern_arena = Arena::new();
-        let cx = MatchCheckCtx {
-            module: self.owner.module(db.upcast()),
-            body: self.owner,
-            db,
-            pattern_arena: &pattern_arena,
-        };
+        let cx = MatchCheckCtx::new(self.owner.module(db.upcast()), self.owner, db, &pattern_arena);
 
         let mut m_arms = Vec::with_capacity(arms.len());
         let mut has_lowering_errors = false;
index bbbe539c13fbe2c94b1bb05c5c5ed3e9928398da..47d60fc41e700bc2962665e48ab04f6720b3884d 100644 (file)
 use smallvec::{smallvec, SmallVec};
 use stdx::never;
 
-use crate::{infer::normalize, AdtId, Interner, Scalar, Ty, TyExt, TyKind};
+use crate::{
+    infer::normalize, inhabitedness::is_enum_variant_uninhabited_from, AdtId, Interner, Scalar, Ty,
+    TyExt, TyKind,
+};
 
 use super::{
     is_box,
@@ -557,8 +560,8 @@ pub(super) fn new(pcx: PatCtxt<'_, '_>) -> Self {
             TyKind::Scalar(Scalar::Bool) => smallvec![make_range(0, 1, Scalar::Bool)],
             // TyKind::Array(..) if ... => unhandled(),
             TyKind::Array(..) | TyKind::Slice(..) => unhandled(),
-            &TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ..) => {
-                let enum_data = cx.db.enum_data(enum_id);
+            TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), subst) => {
+                let enum_data = cx.db.enum_data(*enum_id);
 
                 // If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an
                 // additional "unknown" constructor.
@@ -591,14 +594,15 @@ pub(super) fn new(pcx: PatCtxt<'_, '_>) -> Self {
                 let mut ctors: SmallVec<[_; 1]> = enum_data
                     .variants
                     .iter()
-                    .filter(|&(_, _v)| {
+                    .map(|(local_id, _)| EnumVariantId { parent: *enum_id, local_id })
+                    .filter(|&variant| {
                         // If `exhaustive_patterns` is enabled, we exclude variants known to be
                         // uninhabited.
                         let is_uninhabited = is_exhaustive_pat_feature
-                            && unimplemented!("after MatchCheckCtx.feature_exhaustive_patterns()");
+                            && is_enum_variant_uninhabited_from(variant, subst, cx.module, cx.db);
                         !is_uninhabited
                     })
-                    .map(|(local_id, _)| Variant(EnumVariantId { parent: enum_id, local_id }))
+                    .map(Variant)
                     .collect();
 
                 if is_secretly_empty || is_declared_nonexhaustive {
index 1221327b9510a9791984da46e12ab43d5ee142b9..c4d709a975b0299a7a0a0374b83d9e12824a8236 100644 (file)
 use smallvec::{smallvec, SmallVec};
 use typed_arena::Arena;
 
-use crate::{db::HirDatabase, Ty, TyExt};
+use crate::{db::HirDatabase, inhabitedness::is_ty_uninhabited_from, Ty, TyExt};
 
 use super::deconstruct_pat::{Constructor, DeconstructedPat, Fields, SplitWildcard};
 
@@ -289,13 +289,27 @@ pub(crate) struct MatchCheckCtx<'a, 'p> {
     pub(crate) db: &'a dyn HirDatabase,
     /// Lowered patterns from arms plus generated by the check.
     pub(crate) pattern_arena: &'p Arena<DeconstructedPat<'p>>,
+    exhaustive_patterns: bool,
 }
 
 impl<'a, 'p> MatchCheckCtx<'a, 'p> {
-    pub(super) fn is_uninhabited(&self, _ty: &Ty) -> bool {
-        // FIXME(iDawer) implement exhaustive_patterns feature. More info in:
-        // Tracking issue for RFC 1872: exhaustive_patterns feature https://github.com/rust-lang/rust/issues/51085
-        false
+    pub(crate) fn new(
+        module: ModuleId,
+        body: DefWithBodyId,
+        db: &'a dyn HirDatabase,
+        pattern_arena: &'p Arena<DeconstructedPat<'p>>,
+    ) -> Self {
+        let def_map = db.crate_def_map(module.krate());
+        let exhaustive_patterns = def_map.is_unstable_feature_enabled("exhaustive_patterns");
+        Self { module, body, db, pattern_arena, exhaustive_patterns }
+    }
+
+    pub(super) fn is_uninhabited(&self, ty: &Ty) -> bool {
+        if self.feature_exhaustive_patterns() {
+            is_ty_uninhabited_from(ty, self.module, self.db)
+        } else {
+            false
+        }
     }
 
     /// Returns whether the given type is an enum from another crate declared `#[non_exhaustive]`.
@@ -311,10 +325,9 @@ pub(super) fn is_foreign_non_exhaustive_enum(&self, ty: &Ty) -> bool {
         }
     }
 
-    // Rust feature described as "Allows exhaustive pattern matching on types that contain uninhabited types."
+    // Rust's unstable feature described as "Allows exhaustive pattern matching on types that contain uninhabited types."
     pub(super) fn feature_exhaustive_patterns(&self) -> bool {
-        // FIXME see MatchCheckCtx::is_uninhabited
-        false
+        self.exhaustive_patterns
     }
 }
 
index 5df48e5fdcbaf40502d0aa11f3b9bd666132b771..10ffde87eef1491b4c6777db2c19309ff6f36f4e 100644 (file)
@@ -182,7 +182,7 @@ fn map<U>(self, f: impl FnOnce(T) -> U) -> InferOk<U> {
 #[derive(Debug, PartialEq, Eq, Clone)]
 pub enum InferenceDiagnostic {
     NoSuchField { expr: ExprId },
-    BreakOutsideOfLoop { expr: ExprId },
+    BreakOutsideOfLoop { expr: ExprId, is_break: bool },
     MismatchedArgCount { call_expr: ExprId, expected: usize, found: usize },
 }
 
@@ -418,18 +418,45 @@ pub(crate) struct InferenceContext<'a> {
 
 #[derive(Clone, Debug)]
 struct BreakableContext {
+    /// Whether this context contains at least one break expression.
     may_break: bool,
+    /// The coercion target of the context.
     coerce: CoerceMany,
+    /// The optional label of the context.
     label: Option<name::Name>,
+    kind: BreakableKind,
+}
+
+#[derive(Clone, Debug)]
+enum BreakableKind {
+    Block,
+    Loop,
+    /// A border is something like an async block, closure etc. Anything that prevents
+    /// breaking/continuing through
+    Border,
 }
 
 fn find_breakable<'c>(
     ctxs: &'c mut [BreakableContext],
     label: Option<&name::Name>,
+) -> Option<&'c mut BreakableContext> {
+    let mut ctxs = ctxs
+        .iter_mut()
+        .rev()
+        .take_while(|it| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));
+    match label {
+        Some(_) => ctxs.find(|ctx| ctx.label.as_ref() == label),
+        None => ctxs.find(|ctx| matches!(ctx.kind, BreakableKind::Loop)),
+    }
+}
+
+fn find_continuable<'c>(
+    ctxs: &'c mut [BreakableContext],
+    label: Option<&name::Name>,
 ) -> Option<&'c mut BreakableContext> {
     match label {
-        Some(_) => ctxs.iter_mut().rev().find(|ctx| ctx.label.as_ref() == label),
-        None => ctxs.last_mut(),
+        Some(_) => find_breakable(ctxs, label).filter(|it| matches!(it.kind, BreakableKind::Loop)),
+        None => find_breakable(ctxs, label),
     }
 }
 
index 2a13106390d9f7f90773d1377bdc8b24351ca393..2d04a864a2cfd98455a5d198edaec33cc8303f0b 100644 (file)
@@ -10,7 +10,7 @@
     cast::Cast, fold::Shift, DebruijnIndex, GenericArgData, Mutability, TyVariableKind,
 };
 use hir_def::{
-    expr::{ArithOp, Array, BinaryOp, CmpOp, Expr, ExprId, Literal, Statement, UnaryOp},
+    expr::{ArithOp, Array, BinaryOp, CmpOp, Expr, ExprId, LabelId, Literal, Statement, UnaryOp},
     generics::TypeOrConstParamData,
     path::{GenericArg, GenericArgs},
     resolver::resolver_for_expr,
@@ -23,7 +23,7 @@
 use crate::{
     autoderef::{self, Autoderef},
     consteval,
-    infer::coerce::CoerceMany,
+    infer::{coerce::CoerceMany, find_continuable, BreakableKind},
     lower::{
         const_or_path_to_chalk, generic_arg_to_chalk, lower_to_chalk_mutability, ParamLoweringMode,
     },
@@ -120,32 +120,37 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                 let ty = match label {
                     Some(_) => {
                         let break_ty = self.table.new_type_var();
-                        self.breakables.push(BreakableContext {
-                            may_break: false,
-                            coerce: CoerceMany::new(break_ty.clone()),
-                            label: label.map(|label| self.body[label].name.clone()),
-                        });
-                        let ty = self.infer_block(
-                            tgt_expr,
-                            statements,
-                            *tail,
-                            &Expectation::has_type(break_ty),
+                        let (breaks, ty) = self.with_breakable_ctx(
+                            BreakableKind::Block,
+                            break_ty.clone(),
+                            *label,
+                            |this| {
+                                this.infer_block(
+                                    tgt_expr,
+                                    statements,
+                                    *tail,
+                                    &Expectation::has_type(break_ty),
+                                )
+                            },
                         );
-                        let ctxt = self.breakables.pop().expect("breakable stack broken");
-                        if ctxt.may_break {
-                            ctxt.coerce.complete()
-                        } else {
-                            ty
-                        }
+                        breaks.unwrap_or(ty)
                     }
                     None => self.infer_block(tgt_expr, statements, *tail, expected),
                 };
                 self.resolver = old_resolver;
                 ty
             }
-            Expr::Unsafe { body } | Expr::Const { body } => self.infer_expr(*body, expected),
+            Expr::Unsafe { body } => self.infer_expr(*body, expected),
+            Expr::Const { body } => {
+                self.with_breakable_ctx(BreakableKind::Border, self.err_ty(), None, |this| {
+                    this.infer_expr(*body, expected)
+                })
+                .1
+            }
             Expr::TryBlock { body } => {
-                let _inner = self.infer_expr(*body, expected);
+                self.with_breakable_ctx(BreakableKind::Border, self.err_ty(), None, |this| {
+                    let _inner = this.infer_expr(*body, expected);
+                });
                 // FIXME should be std::result::Result<{inner}, _>
                 self.err_ty()
             }
@@ -154,7 +159,10 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                 let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
                 let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty.clone());
 
-                let inner_ty = self.infer_expr_coerce(*body, &Expectation::has_type(ret_ty));
+                let (_, inner_ty) =
+                    self.with_breakable_ctx(BreakableKind::Border, self.err_ty(), None, |this| {
+                        this.infer_expr_coerce(*body, &Expectation::has_type(ret_ty))
+                    });
 
                 self.diverges = prev_diverges;
                 self.return_ty = prev_ret_ty;
@@ -166,54 +174,44 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                 TyKind::OpaqueType(opaque_ty_id, Substitution::from1(Interner, inner_ty))
                     .intern(Interner)
             }
-            Expr::Loop { body, label } => {
-                self.breakables.push(BreakableContext {
-                    may_break: false,
-                    coerce: CoerceMany::new(self.table.new_type_var()),
-                    label: label.map(|label| self.body[label].name.clone()),
-                });
-                self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
-
-                let ctxt = self.breakables.pop().expect("breakable stack broken");
+            &Expr::Loop { body, label } => {
+                let ty = self.table.new_type_var();
+                let (breaks, ()) =
+                    self.with_breakable_ctx(BreakableKind::Loop, ty, label, |this| {
+                        this.infer_expr(body, &Expectation::has_type(TyBuilder::unit()));
+                    });
 
-                if ctxt.may_break {
-                    self.diverges = Diverges::Maybe;
-                    ctxt.coerce.complete()
-                } else {
-                    TyKind::Never.intern(Interner)
+                match breaks {
+                    Some(breaks) => {
+                        self.diverges = Diverges::Maybe;
+                        breaks
+                    }
+                    None => TyKind::Never.intern(Interner),
                 }
             }
-            Expr::While { condition, body, label } => {
-                self.breakables.push(BreakableContext {
-                    may_break: false,
-                    coerce: CoerceMany::new(self.err_ty()),
-                    label: label.map(|label| self.body[label].name.clone()),
+            &Expr::While { condition, body, label } => {
+                self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {
+                    this.infer_expr(
+                        condition,
+                        &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
+                    );
+                    this.infer_expr(body, &Expectation::has_type(TyBuilder::unit()));
                 });
-                self.infer_expr(
-                    *condition,
-                    &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
-                );
-                self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
-                let _ctxt = self.breakables.pop().expect("breakable stack broken");
+
                 // the body may not run, so it diverging doesn't mean we diverge
                 self.diverges = Diverges::Maybe;
                 TyBuilder::unit()
             }
-            Expr::For { iterable, body, pat, label } => {
-                let iterable_ty = self.infer_expr(*iterable, &Expectation::none());
-
-                self.breakables.push(BreakableContext {
-                    may_break: false,
-                    coerce: CoerceMany::new(self.err_ty()),
-                    label: label.map(|label| self.body[label].name.clone()),
-                });
+            &Expr::For { iterable, body, pat, label } => {
+                let iterable_ty = self.infer_expr(iterable, &Expectation::none());
                 let pat_ty =
                     self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item());
 
-                self.infer_pat(*pat, &pat_ty, BindingMode::default());
+                self.infer_pat(pat, &pat_ty, BindingMode::default());
+                self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {
+                    this.infer_expr(body, &Expectation::has_type(TyBuilder::unit()));
+                });
 
-                self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
-                let _ctxt = self.breakables.pop().expect("breakable stack broken");
                 // the body may not run, so it diverging doesn't mean we diverge
                 self.diverges = Diverges::Maybe;
                 TyBuilder::unit()
@@ -269,7 +267,9 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                 let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
                 let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty.clone());
 
-                self.infer_expr_coerce(*body, &Expectation::has_type(ret_ty));
+                self.with_breakable_ctx(BreakableKind::Border, self.err_ty(), None, |this| {
+                    this.infer_expr_coerce(*body, &Expectation::has_type(ret_ty));
+                });
 
                 self.diverges = prev_diverges;
                 self.return_ty = prev_ret_ty;
@@ -372,37 +372,45 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
                 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or_else(|| self.err_ty())
             }
-            Expr::Continue { .. } => TyKind::Never.intern(Interner),
-            Expr::Break { expr, label } => {
-                let mut coerce = match find_breakable(&mut self.breakables, label.as_ref()) {
-                    Some(ctxt) => {
-                        // avoiding the borrowck
-                        mem::replace(
-                            &mut ctxt.coerce,
-                            CoerceMany::new(self.result.standard_types.unknown.clone()),
-                        )
-                    }
-                    None => CoerceMany::new(self.result.standard_types.unknown.clone()),
+            Expr::Continue { label } => {
+                if let None = find_continuable(&mut self.breakables, label.as_ref()) {
+                    self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
+                        expr: tgt_expr,
+                        is_break: false,
+                    });
                 };
-
+                TyKind::Never.intern(Interner)
+            }
+            Expr::Break { expr, label } => {
                 let val_ty = if let Some(expr) = *expr {
                     self.infer_expr(expr, &Expectation::none())
                 } else {
                     TyBuilder::unit()
                 };
 
-                // FIXME: create a synthetic `()` during lowering so we have something to refer to here?
-                coerce.coerce(self, *expr, &val_ty);
+                match find_breakable(&mut self.breakables, label.as_ref()) {
+                    Some(ctxt) => {
+                        // avoiding the borrowck
+                        let mut coerce = mem::replace(
+                            &mut ctxt.coerce,
+                            CoerceMany::new(self.result.standard_types.unknown.clone()),
+                        );
 
-                if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) {
-                    ctxt.coerce = coerce;
-                    ctxt.may_break = true;
-                } else {
-                    self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
-                        expr: tgt_expr,
-                    });
-                };
+                        // FIXME: create a synthetic `()` during lowering so we have something to refer to here?
+                        coerce.coerce(self, *expr, &val_ty);
 
+                        let ctxt = find_breakable(&mut self.breakables, label.as_ref())
+                            .expect("breakable stack changed during coercion");
+                        ctxt.coerce = coerce;
+                        ctxt.may_break = true;
+                    }
+                    None => {
+                        self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
+                            expr: tgt_expr,
+                            is_break: true,
+                        });
+                    }
+                }
                 TyKind::Never.intern(Interner)
             }
             Expr::Return { expr } => {
@@ -794,9 +802,6 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                     None => self.table.new_float_var(),
                 },
             },
-            Expr::MacroStmts { tail, statements } => {
-                self.infer_block(tgt_expr, statements, *tail, expected)
-            }
             Expr::Underscore => {
                 // Underscore expressions may only appear in assignee expressions,
                 // which are handled by `infer_assignee_expr()`, so any underscore
@@ -1475,4 +1480,20 @@ fn builtin_binary_op_rhs_expectation(&mut self, op: BinaryOp, lhs_ty: Ty) -> Opt
             },
         })
     }
+
+    fn with_breakable_ctx<T>(
+        &mut self,
+        kind: BreakableKind,
+        ty: Ty,
+        label: Option<LabelId>,
+        cb: impl FnOnce(&mut Self) -> T,
+    ) -> (Option<Ty>, T) {
+        self.breakables.push({
+            let label = label.map(|label| self.body[label].name.clone());
+            BreakableContext { kind, may_break: false, coerce: CoerceMany::new(ty), label }
+        });
+        let res = cb(self);
+        let ctx = self.breakables.pop().expect("breakable stack broken");
+        (ctx.may_break.then(|| ctx.coerce.complete()), res)
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs
new file mode 100644 (file)
index 0000000..0c54719
--- /dev/null
@@ -0,0 +1,173 @@
+//! Type inhabitedness logic.
+use std::ops::ControlFlow::{self, Break, Continue};
+
+use chalk_ir::{
+    visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
+    DebruijnIndex,
+};
+use hir_def::{
+    adt::VariantData, attr::Attrs, type_ref::ConstScalar, visibility::Visibility, AdtId,
+    EnumVariantId, HasModule, Lookup, ModuleId, VariantId,
+};
+
+use crate::{
+    db::HirDatabase, Binders, ConcreteConst, Const, ConstValue, Interner, Substitution, Ty, TyKind,
+};
+
+/// Checks whether a type is visibly uninhabited from a particular module.
+pub(crate) fn is_ty_uninhabited_from(ty: &Ty, target_mod: ModuleId, db: &dyn HirDatabase) -> bool {
+    let mut uninhabited_from = UninhabitedFrom { target_mod, db };
+    let inhabitedness = ty.visit_with(&mut uninhabited_from, DebruijnIndex::INNERMOST);
+    inhabitedness == BREAK_VISIBLY_UNINHABITED
+}
+
+/// Checks whether a variant is visibly uninhabited from a particular module.
+pub(crate) fn is_enum_variant_uninhabited_from(
+    variant: EnumVariantId,
+    subst: &Substitution,
+    target_mod: ModuleId,
+    db: &dyn HirDatabase,
+) -> bool {
+    let enum_data = db.enum_data(variant.parent);
+    let vars_attrs = db.variants_attrs(variant.parent);
+    let is_local = variant.parent.lookup(db.upcast()).container.krate() == target_mod.krate();
+
+    let mut uninhabited_from = UninhabitedFrom { target_mod, db };
+    let inhabitedness = uninhabited_from.visit_variant(
+        variant.into(),
+        &enum_data.variants[variant.local_id].variant_data,
+        subst,
+        &vars_attrs[variant.local_id],
+        is_local,
+    );
+    inhabitedness == BREAK_VISIBLY_UNINHABITED
+}
+
+struct UninhabitedFrom<'a> {
+    target_mod: ModuleId,
+    db: &'a dyn HirDatabase,
+}
+
+const CONTINUE_OPAQUELY_INHABITED: ControlFlow<VisiblyUninhabited> = Continue(());
+const BREAK_VISIBLY_UNINHABITED: ControlFlow<VisiblyUninhabited> = Break(VisiblyUninhabited);
+#[derive(PartialEq, Eq)]
+struct VisiblyUninhabited;
+
+impl TypeVisitor<Interner> for UninhabitedFrom<'_> {
+    type BreakTy = VisiblyUninhabited;
+
+    fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = VisiblyUninhabited> {
+        self
+    }
+
+    fn visit_ty(
+        &mut self,
+        ty: &Ty,
+        outer_binder: DebruijnIndex,
+    ) -> ControlFlow<VisiblyUninhabited> {
+        match ty.kind(Interner) {
+            TyKind::Adt(adt, subst) => self.visit_adt(adt.0, subst),
+            TyKind::Never => BREAK_VISIBLY_UNINHABITED,
+            TyKind::Tuple(..) => ty.super_visit_with(self, outer_binder),
+            TyKind::Array(item_ty, len) => match try_usize_const(len) {
+                Some(0) | None => CONTINUE_OPAQUELY_INHABITED,
+                Some(1..) => item_ty.super_visit_with(self, outer_binder),
+            },
+
+            TyKind::Ref(..) | _ => CONTINUE_OPAQUELY_INHABITED,
+        }
+    }
+
+    fn interner(&self) -> Interner {
+        Interner
+    }
+}
+
+impl UninhabitedFrom<'_> {
+    fn visit_adt(&mut self, adt: AdtId, subst: &Substitution) -> ControlFlow<VisiblyUninhabited> {
+        let attrs = self.db.attrs(adt.into());
+        let adt_non_exhaustive = attrs.by_key("non_exhaustive").exists();
+        let is_local = adt.module(self.db.upcast()).krate() == self.target_mod.krate();
+        if adt_non_exhaustive && !is_local {
+            return CONTINUE_OPAQUELY_INHABITED;
+        }
+
+        // An ADT is uninhabited iff all its variants uninhabited.
+        match adt {
+            // rustc: For now, `union`s are never considered uninhabited.
+            AdtId::UnionId(_) => CONTINUE_OPAQUELY_INHABITED,
+            AdtId::StructId(s) => {
+                let struct_data = self.db.struct_data(s);
+                self.visit_variant(s.into(), &struct_data.variant_data, subst, &attrs, is_local)
+            }
+            AdtId::EnumId(e) => {
+                let vars_attrs = self.db.variants_attrs(e);
+                let enum_data = self.db.enum_data(e);
+
+                for (local_id, enum_var) in enum_data.variants.iter() {
+                    let variant_inhabitedness = self.visit_variant(
+                        EnumVariantId { parent: e, local_id }.into(),
+                        &enum_var.variant_data,
+                        subst,
+                        &vars_attrs[local_id],
+                        is_local,
+                    );
+                    match variant_inhabitedness {
+                        Break(VisiblyUninhabited) => continue,
+                        Continue(()) => return CONTINUE_OPAQUELY_INHABITED,
+                    }
+                }
+                BREAK_VISIBLY_UNINHABITED
+            }
+        }
+    }
+
+    fn visit_variant(
+        &mut self,
+        variant: VariantId,
+        variant_data: &VariantData,
+        subst: &Substitution,
+        attrs: &Attrs,
+        is_local: bool,
+    ) -> ControlFlow<VisiblyUninhabited> {
+        let non_exhaustive_field_list = attrs.by_key("non_exhaustive").exists();
+        if non_exhaustive_field_list && !is_local {
+            return CONTINUE_OPAQUELY_INHABITED;
+        }
+
+        let is_enum = matches!(variant, VariantId::EnumVariantId(..));
+        let field_tys = self.db.field_types(variant);
+        let field_vis = self.db.field_visibilities(variant);
+
+        for (fid, _) in variant_data.fields().iter() {
+            self.visit_field(field_vis[fid], &field_tys[fid], subst, is_enum)?;
+        }
+        CONTINUE_OPAQUELY_INHABITED
+    }
+
+    fn visit_field(
+        &mut self,
+        vis: Visibility,
+        ty: &Binders<Ty>,
+        subst: &Substitution,
+        is_enum: bool,
+    ) -> ControlFlow<VisiblyUninhabited> {
+        if is_enum || vis.is_visible_from(self.db.upcast(), self.target_mod) {
+            let ty = ty.clone().substitute(Interner, subst);
+            ty.visit_with(self, DebruijnIndex::INNERMOST)
+        } else {
+            CONTINUE_OPAQUELY_INHABITED
+        }
+    }
+}
+
+fn try_usize_const(c: &Const) -> Option<u128> {
+    let data = &c.data(Interner);
+    if data.ty.kind(Interner) != &TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize)) {
+        return None;
+    }
+    match data.value {
+        ConstValue::Concrete(ConcreteConst { interned: ConstScalar::UInt(value) }) => Some(value),
+        _ => None,
+    }
+}
index 5a5d610e360ffba3d4318288faa1b4422987a929..a82a331d4b8750e99c5fb8f69b6b04cf8007e96e 100644 (file)
@@ -14,6 +14,7 @@ macro_rules! eprintln {
 mod chalk_ext;
 pub mod consteval;
 mod infer;
+mod inhabitedness;
 mod interner;
 mod lower;
 mod mapping;
index 3f6d0844e9c1f27afc10ece6dde6b3414c169937..4a37a7945330cc2a216a3eb6582ca7bbd0db0287 100644 (file)
@@ -1,8 +1,8 @@
 //! Methods for lowering the HIR to types. There are two main cases here:
 //!
 //!  - Lowering a type reference like `&usize` or `Option<foo::bar::Baz>` to a
-//!    type: The entry point for this is `Ty::from_hir`.
-//!  - Building the type for an item: This happens through the `type_for_def` query.
+//!    type: The entry point for this is `TyLoweringContext::lower_ty`.
+//!  - Building the type for an item: This happens through the `ty` query.
 //!
 //! This usually involves resolving names, collecting generic arguments etc.
 use std::{
@@ -47,7 +47,7 @@
     consteval::{intern_const_scalar, path_to_const, unknown_const, unknown_const_as_generic},
     db::HirDatabase,
     make_binders,
-    mapping::ToChalk,
+    mapping::{from_chalk_trait_id, ToChalk},
     static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
     utils::Generics,
     utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics},
@@ -332,7 +332,10 @@ pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
             TypeRef::Macro(macro_call) => {
                 let (mut expander, recursion_start) = {
                     match RefMut::filter_map(self.expander.borrow_mut(), Option::as_mut) {
+                        // There already is an expander here, this means we are already recursing
                         Ok(expander) => (expander, false),
+                        // No expander was created yet, so we are at the start of the expansion recursion
+                        // and therefore have to create an expander.
                         Err(expander) => (
                             RefMut::map(expander, |it| {
                                 it.insert(Expander::new(
@@ -362,9 +365,14 @@ pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
                                 .exit(self.db.upcast(), mark);
                             Some(ty)
                         }
-                        _ => None,
+                        _ => {
+                            drop(expander);
+                            None
+                        }
                     }
                 };
+
+                // drop the expander, resetting it to pre-recursion state
                 if recursion_start {
                     *self.expander.borrow_mut() = None;
                 }
@@ -974,13 +982,44 @@ fn assoc_type_bindings_from_type_bound(
     fn lower_dyn_trait(&self, bounds: &[Interned<TypeBound>]) -> Ty {
         let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
         let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
-            QuantifiedWhereClauses::from_iter(
+            let bounds =
+                bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false));
+
+            let mut auto_traits = SmallVec::<[_; 8]>::new();
+            let mut regular_traits = SmallVec::<[_; 2]>::new();
+            let mut other_bounds = SmallVec::<[_; 8]>::new();
+            for bound in bounds {
+                if let Some(id) = bound.trait_id() {
+                    if ctx.db.trait_data(from_chalk_trait_id(id)).is_auto {
+                        auto_traits.push(bound);
+                    } else {
+                        regular_traits.push(bound);
+                    }
+                } else {
+                    other_bounds.push(bound);
+                }
+            }
+
+            if regular_traits.len() > 1 {
+                return None;
+            }
+
+            auto_traits.sort_unstable_by_key(|b| b.trait_id().unwrap());
+            auto_traits.dedup();
+
+            Some(QuantifiedWhereClauses::from_iter(
                 Interner,
-                bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
-            )
+                regular_traits.into_iter().chain(other_bounds).chain(auto_traits),
+            ))
         });
-        let bounds = crate::make_single_type_binders(bounds);
-        TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
+
+        if let Some(bounds) = bounds {
+            let bounds = crate::make_single_type_binders(bounds);
+            TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
+        } else {
+            // FIXME: report error (additional non-auto traits)
+            TyKind::Error.intern(Interner)
+        }
     }
 
     fn lower_impl_trait(
index a1ab6060e790c0cdb4a9a02ffcd33e7b66d2aa0e..b3adafaafd38de8ea411754aa963079da3f3a309 100644 (file)
@@ -193,8 +193,6 @@ fn spam() {
             !0..6 '1isize': isize
             !0..6 '1isize': isize
             !0..6 '1isize': isize
-            !0..6 '1isize': isize
-            !0..6 '1isize': isize
             39..442 '{     ...!(); }': ()
             73..94 'spam!(...am!())': {unknown}
             100..119 'for _ ...!() {}': ()
@@ -276,8 +274,6 @@ fn spam() {
             !0..6 '1isize': isize
             !0..6 '1isize': isize
             !0..6 '1isize': isize
-            !0..6 '1isize': isize
-            !0..6 '1isize': isize
             53..456 '{     ...!(); }': ()
             87..108 'spam!(...am!())': {unknown}
             114..133 'for _ ...!() {}': ()
@@ -312,7 +308,6 @@ fn foo() {
         }
         "#,
         expect![[r#"
-            !0..8 'leta=();': ()
             !3..4 'a': ()
             !5..7 '()': ()
             57..84 '{     ...); } }': ()
@@ -321,7 +316,7 @@ fn foo() {
 }
 
 #[test]
-fn recurisve_macro_expanded_in_stmts() {
+fn recursive_macro_expanded_in_stmts() {
     check_infer(
         r#"
         macro_rules! ng {
@@ -340,11 +335,6 @@ fn foo() {
         }
         "#,
         expect![[r#"
-            !0..7 'leta=3;': ()
-            !0..13 'ng!{[leta=3]}': ()
-            !0..13 'ng!{[leta=]3}': ()
-            !0..13 'ng!{[leta]=3}': ()
-            !0..13 'ng!{[let]a=3}': ()
             !3..4 'a': i32
             !5..6 '3': i32
             196..237 '{     ...= a; }': ()
@@ -369,8 +359,6 @@ fn foo() {
         "#,
         expect![[r#"
             !0..1 '1': i32
-            !0..7 'mac!($)': ()
-            !0..26 'macro_...>{1};}': ()
             107..143 '{     ...!(); }': ()
             129..130 'a': i32
         "#]],
index c7895db1afbf5e523a3e6c9a03f09df74cd0aa73..23e51a9c16a5600138e3e519e2ae952c4a68c95e 100644 (file)
@@ -573,7 +573,6 @@ fn main() {
         }
         "#,
         expect![[r#"
-            !0..16 'let_a=...t_b=1;': ()
             !3..5 '_a': i32
             !6..7 '1': i32
             !11..13 '_b': i32
@@ -1679,7 +1678,6 @@ fn main() {
 
 #[test]
 fn trailing_empty_macro() {
-    cov_mark::check!(empty_macro_in_trailing_position_is_removed);
     check_no_mismatches(
         r#"
 macro_rules! m2 {
index 5b08f552109efe4a533c134e15046079056636ad..4ea103e5d9ec3cf1bc5fc85e4ff0866b18388826 100644 (file)
@@ -2549,7 +2549,6 @@ impl B for Astruct {}
         expect![[r#"
             569..573 'self': Box<[T], A>
             602..634 '{     ...     }': Vec<T, A>
-            612..628 'unimpl...ted!()': Vec<T, A>
             648..761 '{     ...t]); }': ()
             658..661 'vec': Vec<i32, Global>
             664..679 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global>
@@ -3070,3 +3069,17 @@ fn main() {
         "#,
     );
 }
+
+#[test]
+fn nested_break() {
+    check_no_mismatches(
+        r#"
+fn func() {
+    let int = loop {
+        break 0;
+        break (break 0);
+    };
+}
+    "#,
+    );
+}
index 0f37970e2b38d7fe678e101b19873789b2fbdd7e..e67c27aa2db97fb4cff6fd19475fa448aa422cc9 100644 (file)
@@ -3833,3 +3833,95 @@ fn test() {
 "#,
     )
 }
+
+#[test]
+fn dyn_multiple_auto_traits_in_different_order() {
+    check_no_mismatches(
+        r#"
+auto trait Send {}
+auto trait Sync {}
+
+fn f(t: &(dyn Sync + Send)) {}
+fn g(t: &(dyn Send + Sync)) {
+    f(t);
+}
+        "#,
+    );
+
+    check_no_mismatches(
+        r#"
+auto trait Send {}
+auto trait Sync {}
+trait T {}
+
+fn f(t: &(dyn T + Send + Sync)) {}
+fn g(t: &(dyn Sync + T + Send)) {
+    f(t);
+}
+        "#,
+    );
+
+    check_infer_with_mismatches(
+        r#"
+auto trait Send {}
+auto trait Sync {}
+trait T1 {}
+trait T2 {}
+
+fn f(t: &(dyn T1 + T2 + Send + Sync)) {}
+fn g(t: &(dyn Sync + T2 + T1 + Send)) {
+    f(t);
+}
+        "#,
+        expect![[r#"
+            68..69 't': &{unknown}
+            101..103 '{}': ()
+            109..110 't': &{unknown}
+            142..155 '{     f(t); }': ()
+            148..149 'f': fn f(&{unknown})
+            148..152 'f(t)': ()
+            150..151 't': &{unknown}
+        "#]],
+    );
+
+    check_no_mismatches(
+        r#"
+auto trait Send {}
+auto trait Sync {}
+trait T {
+    type Proj: Send + Sync;
+}
+
+fn f(t: &(dyn T<Proj = ()>  + Send + Sync)) {}
+fn g(t: &(dyn Sync + T<Proj = ()> + Send)) {
+    f(t);
+}
+        "#,
+    );
+}
+
+#[test]
+fn dyn_duplicate_auto_trait() {
+    check_no_mismatches(
+        r#"
+auto trait Send {}
+
+fn f(t: &(dyn Send + Send)) {}
+fn g(t: &(dyn Send)) {
+    f(t);
+}
+        "#,
+    );
+
+    check_no_mismatches(
+        r#"
+auto trait Send {}
+trait T {}
+
+fn f(t: &(dyn T + Send + Send)) {}
+fn g(t: &(dyn T + Send)) {
+    f(t);
+}
+        "#,
+    );
+}
index 50374f4b3fe47ebdd8e6907c26430a013b185687..5edc16d8bce9060262914d14060b4bfd1cb3e6d2 100644 (file)
@@ -124,6 +124,7 @@ pub struct NoSuchField {
 #[derive(Debug)]
 pub struct BreakOutsideOfLoop {
     pub expr: InFile<AstPtr<ast::Expr>>,
+    pub is_break: bool,
 }
 
 #[derive(Debug)]
index 6dccf2ed20b8e8e6dc00534678e42e7a558de526..e4bb63a864719956e4b31b76e8994852f3b3ca55 100644 (file)
@@ -1216,11 +1216,11 @@ pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>) {
                     let field = source_map.field_syntax(*expr);
                     acc.push(NoSuchField { field }.into())
                 }
-                hir_ty::InferenceDiagnostic::BreakOutsideOfLoop { expr } => {
+                &hir_ty::InferenceDiagnostic::BreakOutsideOfLoop { expr, is_break } => {
                     let expr = source_map
-                        .expr_syntax(*expr)
+                        .expr_syntax(expr)
                         .expect("break outside of loop in synthetic syntax");
-                    acc.push(BreakOutsideOfLoop { expr }.into())
+                    acc.push(BreakOutsideOfLoop { expr, is_break }.into())
                 }
                 hir_ty::InferenceDiagnostic::MismatchedArgCount { call_expr, expected, found } => {
                     match source_map.expr_syntax(*call_expr) {
index bd35af06e23eb0ccbbd29146b61ca99394db1bfa..342912b678a1db836de2a77eb92f674fbc7246cd 100644 (file)
@@ -140,11 +140,19 @@ fn expand_expr(
     ) -> Option<InFile<ast::Expr>> {
         let macro_file = self.body_source_map()?.node_macro_file(expr.as_ref())?;
         let expanded = db.parse_or_expand(macro_file)?;
-
-        let res = match ast::MacroCall::cast(expanded.clone()) {
-            Some(call) => self.expand_expr(db, InFile::new(macro_file, call))?,
-            _ => InFile::new(macro_file, ast::Expr::cast(expanded)?),
+        let res = if let Some(stmts) = ast::MacroStmts::cast(expanded.clone()) {
+            match stmts.expr()? {
+                ast::Expr::MacroExpr(mac) => {
+                    self.expand_expr(db, InFile::new(macro_file, mac.macro_call()?))?
+                }
+                expr => InFile::new(macro_file, expr),
+            }
+        } else if let Some(call) = ast::MacroCall::cast(expanded.clone()) {
+            self.expand_expr(db, InFile::new(macro_file, call))?
+        } else {
+            InFile::new(macro_file, ast::Expr::cast(expanded)?)
         };
+
         Some(res)
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs
new file mode 100644 (file)
index 0000000..54a7f48
--- /dev/null
@@ -0,0 +1,294 @@
+use syntax::ast::{self, AstNode};
+
+use crate::{AssistContext, AssistId, AssistKind, Assists};
+
+// Assist: convert_two_arm_bool_match_to_matches_macro
+//
+// Convert 2-arm match that evaluates to a boolean into the equivalent matches! invocation.
+//
+// ```
+// fn main() {
+//     match scrutinee$0 {
+//         Some(val) if val.cond() => true,
+//         _ => false,
+//     }
+// }
+// ```
+// ->
+// ```
+// fn main() {
+//     matches!(scrutinee, Some(val) if val.cond())
+// }
+// ```
+pub(crate) fn convert_two_arm_bool_match_to_matches_macro(
+    acc: &mut Assists,
+    ctx: &AssistContext<'_>,
+) -> Option<()> {
+    let match_expr = ctx.find_node_at_offset::<ast::MatchExpr>()?;
+    let match_arm_list = match_expr.match_arm_list()?;
+    let mut arms = match_arm_list.arms();
+    let first_arm = arms.next()?;
+    let second_arm = arms.next()?;
+    if arms.next().is_some() {
+        cov_mark::hit!(non_two_arm_match);
+        return None;
+    }
+    let first_arm_expr = first_arm.expr();
+    let second_arm_expr = second_arm.expr();
+
+    let invert_matches = if is_bool_literal_expr(&first_arm_expr, true)
+        && is_bool_literal_expr(&second_arm_expr, false)
+    {
+        false
+    } else if is_bool_literal_expr(&first_arm_expr, false)
+        && is_bool_literal_expr(&second_arm_expr, true)
+    {
+        true
+    } else {
+        cov_mark::hit!(non_invert_bool_literal_arms);
+        return None;
+    };
+
+    let target_range = ctx.sema.original_range(match_expr.syntax()).range;
+    let expr = match_expr.expr()?;
+
+    acc.add(
+        AssistId("convert_two_arm_bool_match_to_matches_macro", AssistKind::RefactorRewrite),
+        "Convert to matches!",
+        target_range,
+        |builder| {
+            let mut arm_str = String::new();
+            if let Some(ref pat) = first_arm.pat() {
+                arm_str += &pat.to_string();
+            }
+            if let Some(ref guard) = first_arm.guard() {
+                arm_str += &format!(" {}", &guard.to_string());
+            }
+            if invert_matches {
+                builder.replace(target_range, format!("!matches!({}, {})", expr, arm_str));
+            } else {
+                builder.replace(target_range, format!("matches!({}, {})", expr, arm_str));
+            }
+        },
+    )
+}
+
+fn is_bool_literal_expr(expr: &Option<ast::Expr>, expect_bool: bool) -> bool {
+    if let Some(ast::Expr::Literal(lit)) = expr {
+        if let ast::LiteralKind::Bool(b) = lit.kind() {
+            return b == expect_bool;
+        }
+    }
+
+    return false;
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
+
+    use super::convert_two_arm_bool_match_to_matches_macro;
+
+    #[test]
+    fn not_applicable_outside_of_range_left() {
+        check_assist_not_applicable(
+            convert_two_arm_bool_match_to_matches_macro,
+            r#"
+fn foo(a: Option<u32>) -> bool {
+    $0 match a {
+        Some(_val) => true,
+        _ => false
+    }
+}
+        "#,
+        );
+    }
+
+    #[test]
+    fn not_applicable_non_two_arm_match() {
+        cov_mark::check!(non_two_arm_match);
+        check_assist_not_applicable(
+            convert_two_arm_bool_match_to_matches_macro,
+            r#"
+fn foo(a: Option<u32>) -> bool {
+    match a$0 {
+        Some(3) => true,
+        Some(4) => true,
+        _ => false
+    }
+}
+        "#,
+        );
+    }
+
+    #[test]
+    fn not_applicable_non_bool_literal_arms() {
+        cov_mark::check!(non_invert_bool_literal_arms);
+        check_assist_not_applicable(
+            convert_two_arm_bool_match_to_matches_macro,
+            r#"
+fn foo(a: Option<u32>) -> bool {
+    match a$0 {
+        Some(val) => val == 3,
+        _ => false
+    }
+}
+        "#,
+        );
+    }
+    #[test]
+    fn not_applicable_both_false_arms() {
+        cov_mark::check!(non_invert_bool_literal_arms);
+        check_assist_not_applicable(
+            convert_two_arm_bool_match_to_matches_macro,
+            r#"
+fn foo(a: Option<u32>) -> bool {
+    match a$0 {
+        Some(val) => false,
+        _ => false
+    }
+}
+        "#,
+        );
+    }
+
+    #[test]
+    fn not_applicable_both_true_arms() {
+        cov_mark::check!(non_invert_bool_literal_arms);
+        check_assist_not_applicable(
+            convert_two_arm_bool_match_to_matches_macro,
+            r#"
+fn foo(a: Option<u32>) -> bool {
+    match a$0 {
+        Some(val) => true,
+        _ => true
+    }
+}
+        "#,
+        );
+    }
+
+    #[test]
+    fn convert_simple_case() {
+        check_assist(
+            convert_two_arm_bool_match_to_matches_macro,
+            r#"
+fn foo(a: Option<u32>) -> bool {
+    match a$0 {
+        Some(_val) => true,
+        _ => false
+    }
+}
+"#,
+            r#"
+fn foo(a: Option<u32>) -> bool {
+    matches!(a, Some(_val))
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn convert_simple_invert_case() {
+        check_assist(
+            convert_two_arm_bool_match_to_matches_macro,
+            r#"
+fn foo(a: Option<u32>) -> bool {
+    match a$0 {
+        Some(_val) => false,
+        _ => true
+    }
+}
+"#,
+            r#"
+fn foo(a: Option<u32>) -> bool {
+    !matches!(a, Some(_val))
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn convert_with_guard_case() {
+        check_assist(
+            convert_two_arm_bool_match_to_matches_macro,
+            r#"
+fn foo(a: Option<u32>) -> bool {
+    match a$0 {
+        Some(val) if val > 3 => true,
+        _ => false
+    }
+}
+"#,
+            r#"
+fn foo(a: Option<u32>) -> bool {
+    matches!(a, Some(val) if val > 3)
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn convert_enum_match_cases() {
+        check_assist(
+            convert_two_arm_bool_match_to_matches_macro,
+            r#"
+enum X { A, B }
+
+fn foo(a: X) -> bool {
+    match a$0 {
+        X::A => true,
+        _ => false
+    }
+}
+"#,
+            r#"
+enum X { A, B }
+
+fn foo(a: X) -> bool {
+    matches!(a, X::A)
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn convert_target_simple() {
+        check_assist_target(
+            convert_two_arm_bool_match_to_matches_macro,
+            r#"
+fn foo(a: Option<u32>) -> bool {
+    match a$0 {
+        Some(val) => true,
+        _ => false
+    }
+}
+"#,
+            r#"match a {
+        Some(val) => true,
+        _ => false
+    }"#,
+        );
+    }
+
+    #[test]
+    fn convert_target_complex() {
+        check_assist_target(
+            convert_two_arm_bool_match_to_matches_macro,
+            r#"
+enum E { X, Y }
+
+fn main() {
+    match E::X$0 {
+        E::X => true,
+        _ => false,
+    }
+}
+"#,
+            "match E::X {
+        E::X => true,
+        _ => false,
+    }",
+        );
+    }
+}
index dfb5652126467ee974ca77dc60820836d796f6f0..ddc2052e7aa240f92f32c3122423138edea0f4da 100644 (file)
@@ -101,21 +101,22 @@ pub(crate) fn extract_struct_from_enum_variant(
                 });
             }
 
-            let indent = enum_ast.indent_level();
             let generic_params = enum_ast
                 .generic_param_list()
                 .and_then(|known_generics| extract_generic_params(&known_generics, &field_list));
             let generics = generic_params.as_ref().map(|generics| generics.clone_for_update());
             let def =
                 create_struct_def(variant_name.clone(), &variant, &field_list, generics, &enum_ast);
+
+            let enum_ast = variant.parent_enum();
+            let indent = enum_ast.indent_level();
             def.reindent_to(indent);
 
-            let start_offset = &variant.parent_enum().syntax().clone();
-            ted::insert_all_raw(
-                ted::Position::before(start_offset),
+            ted::insert_all(
+                ted::Position::before(enum_ast.syntax()),
                 vec![
                     def.syntax().clone().into(),
-                    make::tokens::whitespace(&format!("\n\n{}", indent)).into(),
+                    make::tokens::whitespace(&format!("\n\n{indent}")).into(),
                 ],
             );
 
@@ -227,7 +228,7 @@ fn tag_generics_in_variant(ty: &ast::Type, generics: &mut [(ast::GenericParam, b
 }
 
 fn create_struct_def(
-    variant_name: ast::Name,
+    name: ast::Name,
     variant: &ast::Variant,
     field_list: &Either<ast::RecordFieldList, ast::TupleFieldList>,
     generics: Option<ast::GenericParamList>,
@@ -269,43 +270,27 @@ fn create_struct_def(
             field_list.into()
         }
     };
-
     field_list.reindent_to(IndentLevel::single());
 
-    let strukt = make::struct_(enum_vis, variant_name, generics, field_list).clone_for_update();
-
-    // FIXME: Consider making this an actual function somewhere (like in `AttrsOwnerEdit`) after some deliberation
-    let attrs_and_docs = |node: &SyntaxNode| {
-        let mut select_next_ws = false;
-        node.children_with_tokens().filter(move |child| {
-            let accept = match child.kind() {
-                ATTR | COMMENT => {
-                    select_next_ws = true;
-                    return true;
-                }
-                WHITESPACE if select_next_ws => true,
-                _ => false,
-            };
-            select_next_ws = false;
-
-            accept
-        })
-    };
+    let strukt = make::struct_(enum_vis, name, generics, field_list).clone_for_update();
 
-    // copy attributes & comments from variant
-    let variant_attrs = attrs_and_docs(variant.syntax())
-        .map(|tok| match tok.kind() {
-            WHITESPACE => make::tokens::single_newline().into(),
-            _ => tok,
-        })
-        .collect();
-    ted::insert_all(ted::Position::first_child_of(strukt.syntax()), variant_attrs);
+    // take comments from variant
+    ted::insert_all(
+        ted::Position::first_child_of(strukt.syntax()),
+        take_all_comments(variant.syntax()),
+    );
 
     // copy attributes from enum
     ted::insert_all(
         ted::Position::first_child_of(strukt.syntax()),
-        enum_.attrs().map(|it| it.syntax().clone_for_update().into()).collect(),
+        enum_
+            .attrs()
+            .flat_map(|it| {
+                vec![it.syntax().clone_for_update().into(), make::tokens::single_newline().into()]
+            })
+            .collect(),
     );
+
     strukt
 }
 
@@ -346,16 +331,48 @@ fn update_variant(variant: &ast::Variant, generics: Option<ast::GenericParamList
         })
         .unwrap_or_else(|| make::ty(&name.text()));
 
+    // change from a record to a tuple field list
     let tuple_field = make::tuple_field(None, ty);
-    let replacement = make::variant(
-        name,
-        Some(ast::FieldList::TupleFieldList(make::tuple_field_list(iter::once(tuple_field)))),
-    )
-    .clone_for_update();
-    ted::replace(variant.syntax(), replacement.syntax());
+    let field_list = make::tuple_field_list(iter::once(tuple_field)).clone_for_update();
+    ted::replace(variant.field_list()?.syntax(), field_list.syntax());
+
+    // remove any ws after the name
+    if let Some(ws) = name
+        .syntax()
+        .siblings_with_tokens(syntax::Direction::Next)
+        .find_map(|tok| tok.into_token().filter(|tok| tok.kind() == WHITESPACE))
+    {
+        ted::remove(SyntaxElement::Token(ws));
+    }
+
     Some(())
 }
 
+// Note: this also detaches whitespace after comments,
+// since `SyntaxNode::splice_children` (and by extension `ted::insert_all_raw`)
+// detaches nodes. If we only took the comments, we'd leave behind the old whitespace.
+fn take_all_comments(node: &SyntaxNode) -> Vec<SyntaxElement> {
+    let mut remove_next_ws = false;
+    node.children_with_tokens()
+        .filter_map(move |child| match child.kind() {
+            COMMENT => {
+                remove_next_ws = true;
+                child.detach();
+                Some(child)
+            }
+            WHITESPACE if remove_next_ws => {
+                remove_next_ws = false;
+                child.detach();
+                Some(make::tokens::single_newline().into())
+            }
+            _ => {
+                remove_next_ws = false;
+                None
+            }
+        })
+        .collect()
+}
+
 fn apply_references(
     insert_use_cfg: InsertUseConfig,
     segment: ast::PathSegment,
@@ -480,10 +497,14 @@ enum En<T> { Var(Var<T>) }"#,
     fn test_extract_struct_carries_over_attributes() {
         check_assist(
             extract_struct_from_enum_variant,
-            r#"#[derive(Debug)]
+            r#"
+#[derive(Debug)]
 #[derive(Clone)]
 enum Enum { Variant{ field: u32$0 } }"#,
-            r#"#[derive(Debug)]#[derive(Clone)] struct Variant{ field: u32 }
+            r#"
+#[derive(Debug)]
+#[derive(Clone)]
+struct Variant{ field: u32 }
 
 #[derive(Debug)]
 #[derive(Clone)]
@@ -614,7 +635,7 @@ enum A { One(One) }"#,
     }
 
     #[test]
-    fn test_extract_struct_keep_comments_and_attrs_on_variant_struct() {
+    fn test_extract_struct_move_struct_variant_comments() {
         check_assist(
             extract_struct_from_enum_variant,
             r#"
@@ -631,19 +652,19 @@ enum A {
 /* comment */
 // other
 /// comment
-#[attr]
 struct One{
     a: u32
 }
 
 enum A {
+    #[attr]
     One(One)
 }"#,
         );
     }
 
     #[test]
-    fn test_extract_struct_keep_comments_and_attrs_on_variant_tuple() {
+    fn test_extract_struct_move_tuple_variant_comments() {
         check_assist(
             extract_struct_from_enum_variant,
             r#"
@@ -658,10 +679,10 @@ enum A {
 /* comment */
 // other
 /// comment
-#[attr]
 struct One(u32, u32);
 
 enum A {
+    #[attr]
     One(One)
 }"#,
         );
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs
new file mode 100644 (file)
index 0000000..7d91be6
--- /dev/null
@@ -0,0 +1,364 @@
+use ide_db::{
+    assists::{AssistId, AssistKind},
+    famous_defs::FamousDefs,
+};
+use syntax::{
+    ast::{self, make, Expr, HasArgList},
+    AstNode,
+};
+
+use crate::{AssistContext, Assists};
+
+// Assist: replace_or_with_or_else
+//
+// Replace `unwrap_or` with `unwrap_or_else` and `ok_or` with `ok_or_else`.
+//
+// ```
+// # //- minicore:option
+// fn foo() {
+//     let a = Some(1);
+//     a.unwra$0p_or(2);
+// }
+// ```
+// ->
+// ```
+// fn foo() {
+//     let a = Some(1);
+//     a.unwrap_or_else(|| 2);
+// }
+// ```
+pub(crate) fn replace_or_with_or_else(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+    let call: ast::MethodCallExpr = ctx.find_node_at_offset()?;
+
+    let kind = is_option_or_result(call.receiver()?, ctx)?;
+
+    let (name, arg_list) = (call.name_ref()?, call.arg_list()?);
+
+    let mut map_or = false;
+
+    let replace = match &*name.text() {
+        "unwrap_or" => "unwrap_or_else".to_string(),
+        "or" => "or_else".to_string(),
+        "ok_or" if kind == Kind::Option => "ok_or_else".to_string(),
+        "map_or" => {
+            map_or = true;
+            "map_or_else".to_string()
+        }
+        _ => return None,
+    };
+
+    let arg = match arg_list.args().collect::<Vec<_>>().as_slice() {
+        [] => make::arg_list(Vec::new()),
+        [first] => {
+            let param = into_closure(first);
+            make::arg_list(vec![param])
+        }
+        [first, second] if map_or => {
+            let param = into_closure(first);
+            make::arg_list(vec![param, second.clone()])
+        }
+        _ => return None,
+    };
+
+    acc.add(
+        AssistId("replace_or_with_or_else", AssistKind::RefactorRewrite),
+        format!("Replace {} with {}", name.text(), replace),
+        call.syntax().text_range(),
+        |builder| {
+            builder.replace(name.syntax().text_range(), replace);
+            builder.replace_ast(arg_list, arg)
+        },
+    )
+}
+
+fn into_closure(param: &Expr) -> Expr {
+    (|| {
+        if let ast::Expr::CallExpr(call) = param {
+            if call.arg_list()?.args().count() == 0 {
+                Some(call.expr()?.clone())
+            } else {
+                None
+            }
+        } else {
+            None
+        }
+    })()
+    .unwrap_or_else(|| make::expr_closure(None, param.clone()))
+}
+
+// Assist: replace_or_else_with_or
+//
+// Replace `unwrap_or_else` with `unwrap_or` and `ok_or_else` with `ok_or`.
+//
+// ```
+// # //- minicore:option
+// fn foo() {
+//     let a = Some(1);
+//     a.unwra$0p_or_else(|| 2);
+// }
+// ```
+// ->
+// ```
+// fn foo() {
+//     let a = Some(1);
+//     a.unwrap_or(2);
+// }
+// ```
+pub(crate) fn replace_or_else_with_or(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+    let call: ast::MethodCallExpr = ctx.find_node_at_offset()?;
+
+    let kind = is_option_or_result(call.receiver()?, ctx)?;
+
+    let (name, arg_list) = (call.name_ref()?, call.arg_list()?);
+
+    let mut map_or = false;
+    let replace = match &*name.text() {
+        "unwrap_or_else" => "unwrap_or".to_string(),
+        "or_else" => "or".to_string(),
+        "ok_or_else" if kind == Kind::Option => "ok_or".to_string(),
+        "map_or_else" => {
+            map_or = true;
+            "map_or".to_string()
+        }
+        _ => return None,
+    };
+
+    let arg = match arg_list.args().collect::<Vec<_>>().as_slice() {
+        [] => make::arg_list(Vec::new()),
+        [first] => {
+            let param = into_call(first);
+            make::arg_list(vec![param])
+        }
+        [first, second] if map_or => {
+            let param = into_call(first);
+            make::arg_list(vec![param, second.clone()])
+        }
+        _ => return None,
+    };
+
+    acc.add(
+        AssistId("replace_or_else_with_or", AssistKind::RefactorRewrite),
+        format!("Replace {} with {}", name.text(), replace),
+        call.syntax().text_range(),
+        |builder| {
+            builder.replace(name.syntax().text_range(), replace);
+            builder.replace_ast(arg_list, arg)
+        },
+    )
+}
+
+fn into_call(param: &Expr) -> Expr {
+    (|| {
+        if let ast::Expr::ClosureExpr(closure) = param {
+            if closure.param_list()?.params().count() == 0 {
+                Some(closure.body()?.clone())
+            } else {
+                None
+            }
+        } else {
+            None
+        }
+    })()
+    .unwrap_or_else(|| make::expr_call(param.clone(), make::arg_list(Vec::new())))
+}
+
+#[derive(PartialEq, Eq)]
+enum Kind {
+    Option,
+    Result,
+}
+
+fn is_option_or_result(receiver: Expr, ctx: &AssistContext<'_>) -> Option<Kind> {
+    let ty = ctx.sema.type_of_expr(&receiver)?.adjusted().as_adt()?.as_enum()?;
+    let option_enum =
+        FamousDefs(&ctx.sema, ctx.sema.scope(receiver.syntax())?.krate()).core_option_Option();
+
+    if let Some(option_enum) = option_enum {
+        if ty == option_enum {
+            return Some(Kind::Option);
+        }
+    }
+
+    let result_enum =
+        FamousDefs(&ctx.sema, ctx.sema.scope(receiver.syntax())?.krate()).core_result_Result();
+
+    if let Some(result_enum) = result_enum {
+        if ty == result_enum {
+            return Some(Kind::Result);
+        }
+    }
+
+    None
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::tests::{check_assist, check_assist_not_applicable};
+
+    use super::*;
+
+    #[test]
+    fn replace_or_with_or_else_simple() {
+        check_assist(
+            replace_or_with_or_else,
+            r#"
+//- minicore: option
+fn foo() {
+    let foo = Some(1);
+    return foo.unwrap_$0or(2);
+}
+"#,
+            r#"
+fn foo() {
+    let foo = Some(1);
+    return foo.unwrap_or_else(|| 2);
+}
+"#,
+        )
+    }
+
+    #[test]
+    fn replace_or_with_or_else_call() {
+        check_assist(
+            replace_or_with_or_else,
+            r#"
+//- minicore: option
+fn foo() {
+    let foo = Some(1);
+    return foo.unwrap_$0or(x());
+}
+"#,
+            r#"
+fn foo() {
+    let foo = Some(1);
+    return foo.unwrap_or_else(x);
+}
+"#,
+        )
+    }
+
+    #[test]
+    fn replace_or_with_or_else_block() {
+        check_assist(
+            replace_or_with_or_else,
+            r#"
+//- minicore: option
+fn foo() {
+    let foo = Some(1);
+    return foo.unwrap_$0or({
+        let mut x = bar();
+        for i in 0..10 {
+            x += i;
+        }
+        x
+    });
+}
+"#,
+            r#"
+fn foo() {
+    let foo = Some(1);
+    return foo.unwrap_or_else(|| {
+        let mut x = bar();
+        for i in 0..10 {
+            x += i;
+        }
+        x
+    });
+}
+"#,
+        )
+    }
+
+    #[test]
+    fn replace_or_else_with_or_simple() {
+        check_assist(
+            replace_or_else_with_or,
+            r#"
+//- minicore: option
+fn foo() {
+    let foo = Some(1);
+    return foo.unwrap_$0or_else(|| 2);
+}
+"#,
+            r#"
+fn foo() {
+    let foo = Some(1);
+    return foo.unwrap_or(2);
+}
+"#,
+        )
+    }
+
+    #[test]
+    fn replace_or_else_with_or_call() {
+        check_assist(
+            replace_or_else_with_or,
+            r#"
+//- minicore: option
+fn foo() {
+    let foo = Some(1);
+    return foo.unwrap_$0or_else(x);
+}
+"#,
+            r#"
+fn foo() {
+    let foo = Some(1);
+    return foo.unwrap_or(x());
+}
+"#,
+        )
+    }
+
+    #[test]
+    fn replace_or_else_with_or_result() {
+        check_assist(
+            replace_or_else_with_or,
+            r#"
+//- minicore: result
+fn foo() {
+    let foo = Ok(1);
+    return foo.unwrap_$0or_else(x);
+}
+"#,
+            r#"
+fn foo() {
+    let foo = Ok(1);
+    return foo.unwrap_or(x());
+}
+"#,
+        )
+    }
+
+    #[test]
+    fn replace_or_else_with_or_map() {
+        check_assist(
+            replace_or_else_with_or,
+            r#"
+//- minicore: result
+fn foo() {
+    let foo = Ok("foo");
+    return foo.map$0_or_else(|| 42, |v| v.len());
+}
+"#,
+            r#"
+fn foo() {
+    let foo = Ok("foo");
+    return foo.map_or(42, |v| v.len());
+}
+"#,
+        )
+    }
+
+    #[test]
+    fn replace_or_else_with_or_not_applicable() {
+        check_assist_not_applicable(
+            replace_or_else_with_or,
+            r#"
+fn foo() {
+    let foo = Ok(1);
+    return foo.unwrap_$0or_else(x);
+}
+"#,
+        )
+    }
+}
index 5242f3b5100cfa9357d322ac8f2cc647def5385f..521447c26dfbed01d20ac10592fd127a286f16ec 100644 (file)
@@ -1,5 +1,6 @@
+use hir::HirDisplay;
 use syntax::{
-    ast::{Expr, GenericArg},
+    ast::{Expr, GenericArg, GenericArgList},
     ast::{LetStmt, Type::InferType},
     AstNode, TextRange,
 };
@@ -34,21 +35,7 @@ pub(crate) fn replace_turbofish_with_explicit_type(
 
     let initializer = let_stmt.initializer()?;
 
-    let generic_args = match &initializer {
-        Expr::MethodCallExpr(ce) => ce.generic_arg_list()?,
-        Expr::CallExpr(ce) => {
-            if let Expr::PathExpr(pe) = ce.expr()? {
-                pe.path()?.segment()?.generic_arg_list()?
-            } else {
-                cov_mark::hit!(not_applicable_if_non_path_function_call);
-                return None;
-            }
-        }
-        _ => {
-            cov_mark::hit!(not_applicable_if_non_function_call_initializer);
-            return None;
-        }
-    };
+    let generic_args = generic_arg_list(&initializer)?;
 
     // Find range of ::<_>
     let colon2 = generic_args.coloncolon_token()?;
@@ -65,7 +52,16 @@ pub(crate) fn replace_turbofish_with_explicit_type(
 
     // An improvement would be to check that this is correctly part of the return value of the
     // function call, or sub in the actual return type.
-    let turbofish_type = &turbofish_args[0];
+    let returned_type = match ctx.sema.type_of_expr(&initializer) {
+        Some(returned_type) if !returned_type.original.contains_unknown() => {
+            let module = ctx.sema.scope(let_stmt.syntax())?.module();
+            returned_type.original.display_source_code(ctx.db(), module.into()).ok()?
+        }
+        _ => {
+            cov_mark::hit!(fallback_to_turbofish_type_if_type_info_not_available);
+            turbofish_args[0].to_string()
+        }
+    };
 
     let initializer_start = initializer.syntax().text_range().start();
     if ctx.offset() > turbofish_range.end() || ctx.offset() < initializer_start {
@@ -83,7 +79,7 @@ pub(crate) fn replace_turbofish_with_explicit_type(
             "Replace turbofish with explicit type",
             TextRange::new(initializer_start, turbofish_range.end()),
             |builder| {
-                builder.insert(ident_range.end(), format!(": {}", turbofish_type));
+                builder.insert(ident_range.end(), format!(": {}", returned_type));
                 builder.delete(turbofish_range);
             },
         );
@@ -98,7 +94,7 @@ pub(crate) fn replace_turbofish_with_explicit_type(
             "Replace `_` with turbofish type",
             turbofish_range,
             |builder| {
-                builder.replace(underscore_range, turbofish_type.to_string());
+                builder.replace(underscore_range, returned_type);
                 builder.delete(turbofish_range);
             },
         );
@@ -107,6 +103,26 @@ pub(crate) fn replace_turbofish_with_explicit_type(
     None
 }
 
+fn generic_arg_list(expr: &Expr) -> Option<GenericArgList> {
+    match expr {
+        Expr::MethodCallExpr(expr) => expr.generic_arg_list(),
+        Expr::CallExpr(expr) => {
+            if let Expr::PathExpr(pe) = expr.expr()? {
+                pe.path()?.segment()?.generic_arg_list()
+            } else {
+                cov_mark::hit!(not_applicable_if_non_path_function_call);
+                return None;
+            }
+        }
+        Expr::AwaitExpr(expr) => generic_arg_list(&expr.expr()?),
+        Expr::TryExpr(expr) => generic_arg_list(&expr.expr()?),
+        _ => {
+            cov_mark::hit!(not_applicable_if_non_function_call_initializer);
+            None
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -115,6 +131,7 @@ mod tests {
 
     #[test]
     fn replaces_turbofish_for_vec_string() {
+        cov_mark::check!(fallback_to_turbofish_type_if_type_info_not_available);
         check_assist(
             replace_turbofish_with_explicit_type,
             r#"
@@ -135,6 +152,7 @@ fn main() {
     #[test]
     fn replaces_method_calls() {
         // foo.make() is a method call which uses a different expr in the let initializer
+        cov_mark::check!(fallback_to_turbofish_type_if_type_info_not_available);
         check_assist(
             replace_turbofish_with_explicit_type,
             r#"
@@ -237,6 +255,110 @@ fn make<T>() -> T {}
 fn main() {
     let a = make$0::<Vec<String>, i32>();
 }
+"#,
+        );
+    }
+
+    #[test]
+    fn replaces_turbofish_for_known_type() {
+        check_assist(
+            replace_turbofish_with_explicit_type,
+            r#"
+fn make<T>() -> T {}
+fn main() {
+    let a = make$0::<i32>();
+}
+"#,
+            r#"
+fn make<T>() -> T {}
+fn main() {
+    let a: i32 = make();
+}
+"#,
+        );
+        check_assist(
+            replace_turbofish_with_explicit_type,
+            r#"
+//- minicore: option
+fn make<T>() -> T {}
+fn main() {
+    let a = make$0::<Option<bool>>();
+}
+"#,
+            r#"
+fn make<T>() -> T {}
+fn main() {
+    let a: Option<bool> = make();
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn replaces_turbofish_not_same_type() {
+        check_assist(
+            replace_turbofish_with_explicit_type,
+            r#"
+//- minicore: option
+fn make<T>() -> Option<T> {}
+fn main() {
+    let a = make$0::<u128>();
+}
+"#,
+            r#"
+fn make<T>() -> Option<T> {}
+fn main() {
+    let a: Option<u128> = make();
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn replaces_turbofish_for_type_with_defaulted_generic_param() {
+        check_assist(
+            replace_turbofish_with_explicit_type,
+            r#"
+struct HasDefault<T, U = i32>(T, U);
+fn make<T>() -> HasDefault<T> {}
+fn main() {
+    let a = make$0::<bool>();
+}
+"#,
+            r#"
+struct HasDefault<T, U = i32>(T, U);
+fn make<T>() -> HasDefault<T> {}
+fn main() {
+    let a: HasDefault<bool> = make();
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn replaces_turbofish_try_await() {
+        check_assist(
+            replace_turbofish_with_explicit_type,
+            r#"
+//- minicore: option, future
+struct Fut<T>(T);
+impl<T> core::future::Future for Fut<T> {
+    type Output = Option<T>;
+}
+fn make<T>() -> Fut<T> {}
+fn main() {
+    let a = make$0::<bool>().await?;
+}
+"#,
+            r#"
+struct Fut<T>(T);
+impl<T> core::future::Future for Fut<T> {
+    type Output = Option<T>;
+}
+fn make<T>() -> Fut<T> {}
+fn main() {
+    let a: bool = make().await?;
+}
 "#,
         );
     }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs
new file mode 100644 (file)
index 0000000..9565f0e
--- /dev/null
@@ -0,0 +1,293 @@
+use syntax::{
+    algo::neighbor,
+    ast::{self, edit::IndentLevel, make, AstNode},
+    ted::{self, Position},
+    Direction, SyntaxKind, T,
+};
+
+use crate::{AssistContext, AssistId, AssistKind, Assists};
+
+// Assist: unmerge_match_arm
+//
+// Splits the current match with a `|` pattern into two arms with identical bodies.
+//
+// ```
+// enum Action { Move { distance: u32 }, Stop }
+//
+// fn handle(action: Action) {
+//     match action {
+//         Action::Move(..) $0| Action::Stop => foo(),
+//     }
+// }
+// ```
+// ->
+// ```
+// enum Action { Move { distance: u32 }, Stop }
+//
+// fn handle(action: Action) {
+//     match action {
+//         Action::Move(..) => foo(),
+//         Action::Stop => foo(),
+//     }
+// }
+// ```
+pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+    let pipe_token = ctx.find_token_syntax_at_offset(T![|])?;
+    let or_pat = ast::OrPat::cast(pipe_token.parent()?)?.clone_for_update();
+    let match_arm = ast::MatchArm::cast(or_pat.syntax().parent()?)?;
+    let match_arm_body = match_arm.expr()?;
+
+    // We don't need to check for leading pipe because it is directly under `MatchArm`
+    // without `OrPat`.
+
+    let new_parent = match_arm.syntax().parent()?;
+    let old_parent_range = new_parent.text_range();
+
+    acc.add(
+        AssistId("unmerge_match_arm", AssistKind::RefactorRewrite),
+        "Unmerge match arm",
+        pipe_token.text_range(),
+        |edit| {
+            let pats_after = pipe_token
+                .siblings_with_tokens(Direction::Next)
+                .filter_map(|it| ast::Pat::cast(it.into_node()?));
+            // FIXME: We should add a leading pipe if the original arm has one.
+            let new_match_arm = make::match_arm(
+                pats_after,
+                match_arm.guard().and_then(|guard| guard.condition()),
+                match_arm_body,
+            )
+            .clone_for_update();
+
+            let mut pipe_index = pipe_token.index();
+            if pipe_token
+                .prev_sibling_or_token()
+                .map_or(false, |it| it.kind() == SyntaxKind::WHITESPACE)
+            {
+                pipe_index -= 1;
+            }
+            or_pat.syntax().splice_children(
+                pipe_index..or_pat.syntax().children_with_tokens().count(),
+                Vec::new(),
+            );
+
+            let mut insert_after_old_arm = Vec::new();
+
+            // A comma can be:
+            //  - After the arm. In this case we always want to insert a comma after the newly
+            //    inserted arm.
+            //  - Missing after the arm, with no arms after. In this case we want to insert a
+            //    comma before the newly inserted arm. It can not be necessary if there arm
+            //    body is a block, but we don't bother to check that.
+            //  - Missing after the arm with arms after, if the arm body is a block. In this case
+            //    we don't want to insert a comma at all.
+            let has_comma_after =
+                std::iter::successors(match_arm.syntax().last_child_or_token(), |it| {
+                    it.prev_sibling_or_token()
+                })
+                .map(|it| it.kind())
+                .skip_while(|it| it.is_trivia())
+                .next()
+                    == Some(T![,]);
+            let has_arms_after = neighbor(&match_arm, Direction::Next).is_some();
+            if !has_comma_after && !has_arms_after {
+                insert_after_old_arm.push(make::token(T![,]).into());
+            }
+
+            let indent = IndentLevel::from_node(match_arm.syntax());
+            insert_after_old_arm.push(make::tokens::whitespace(&format!("\n{indent}")).into());
+
+            insert_after_old_arm.push(new_match_arm.syntax().clone().into());
+
+            ted::insert_all_raw(Position::after(match_arm.syntax()), insert_after_old_arm);
+
+            if has_comma_after {
+                ted::insert_raw(
+                    Position::last_child_of(new_match_arm.syntax()),
+                    make::token(T![,]),
+                );
+            }
+
+            edit.replace(old_parent_range, new_parent.to_string());
+        },
+    )
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::tests::{check_assist, check_assist_not_applicable};
+
+    use super::*;
+
+    #[test]
+    fn unmerge_match_arm_single_pipe() {
+        check_assist(
+            unmerge_match_arm,
+            r#"
+#[derive(Debug)]
+enum X { A, B, C }
+
+fn main() {
+    let x = X::A;
+    let y = match x {
+        X::A $0| X::B => { 1i32 }
+        X::C => { 2i32 }
+    };
+}
+"#,
+            r#"
+#[derive(Debug)]
+enum X { A, B, C }
+
+fn main() {
+    let x = X::A;
+    let y = match x {
+        X::A => { 1i32 }
+        X::B => { 1i32 }
+        X::C => { 2i32 }
+    };
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn unmerge_match_arm_guard() {
+        check_assist(
+            unmerge_match_arm,
+            r#"
+#[derive(Debug)]
+enum X { A, B, C }
+
+fn main() {
+    let x = X::A;
+    let y = match x {
+        X::A $0| X::B if true => { 1i32 }
+        _ => { 2i32 }
+    };
+}
+"#,
+            r#"
+#[derive(Debug)]
+enum X { A, B, C }
+
+fn main() {
+    let x = X::A;
+    let y = match x {
+        X::A if true => { 1i32 }
+        X::B if true => { 1i32 }
+        _ => { 2i32 }
+    };
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn unmerge_match_arm_leading_pipe() {
+        check_assist_not_applicable(
+            unmerge_match_arm,
+            r#"
+
+fn main() {
+    let y = match 0 {
+        |$0 0 => { 1i32 }
+        1 => { 2i32 }
+    };
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn unmerge_match_arm_multiple_pipes() {
+        check_assist(
+            unmerge_match_arm,
+            r#"
+#[derive(Debug)]
+enum X { A, B, C, D, E }
+
+fn main() {
+    let x = X::A;
+    let y = match x {
+        X::A | X::B |$0 X::C | X::D => 1i32,
+        X::E => 2i32,
+    };
+}
+"#,
+            r#"
+#[derive(Debug)]
+enum X { A, B, C, D, E }
+
+fn main() {
+    let x = X::A;
+    let y = match x {
+        X::A | X::B => 1i32,
+        X::C | X::D => 1i32,
+        X::E => 2i32,
+    };
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn unmerge_match_arm_inserts_comma_if_required() {
+        check_assist(
+            unmerge_match_arm,
+            r#"
+#[derive(Debug)]
+enum X { A, B }
+
+fn main() {
+    let x = X::A;
+    let y = match x {
+        X::A $0| X::B => 1i32
+    };
+}
+"#,
+            r#"
+#[derive(Debug)]
+enum X { A, B }
+
+fn main() {
+    let x = X::A;
+    let y = match x {
+        X::A => 1i32,
+        X::B => 1i32
+    };
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn unmerge_match_arm_inserts_comma_if_had_after() {
+        check_assist(
+            unmerge_match_arm,
+            r#"
+#[derive(Debug)]
+enum X { A, B }
+
+fn main() {
+    let x = X::A;
+    match x {
+        X::A $0| X::B => {},
+    }
+}
+"#,
+            r#"
+#[derive(Debug)]
+enum X { A, B }
+
+fn main() {
+    let x = X::A;
+    match x {
+        X::A => {},
+        X::B => {},
+    }
+}
+"#,
+        );
+    }
+}
index 7fb35143fa2ff1303459cedde3579f16221d7fa7..e52544db5f530ff969735c4a25b305c64c5491ae 100644 (file)
@@ -122,6 +122,7 @@ mod handlers {
     mod convert_let_else_to_match;
     mod convert_tuple_struct_to_named_struct;
     mod convert_to_guarded_return;
+    mod convert_two_arm_bool_match_to_matches_macro;
     mod convert_while_to_loop;
     mod destructure_tuple_binding;
     mod expand_glob_import;
@@ -179,12 +180,14 @@ mod handlers {
     mod replace_try_expr_with_match;
     mod replace_derive_with_manual_impl;
     mod replace_if_let_with_match;
+    mod replace_or_with_or_else;
     mod introduce_named_generic;
     mod replace_let_with_if_let;
     mod replace_qualified_name_with_use;
     mod replace_string_with_char;
     mod replace_turbofish_with_explicit_type;
     mod split_import;
+    mod unmerge_match_arm;
     mod sort_items;
     mod toggle_ignore;
     mod unmerge_use;
@@ -215,6 +218,7 @@ pub(crate) fn all() -> &'static [Handler] {
             convert_let_else_to_match::convert_let_else_to_match,
             convert_to_guarded_return::convert_to_guarded_return,
             convert_tuple_struct_to_named_struct::convert_tuple_struct_to_named_struct,
+            convert_two_arm_bool_match_to_matches_macro::convert_two_arm_bool_match_to_matches_macro,
             convert_while_to_loop::convert_while_to_loop,
             destructure_tuple_binding::destructure_tuple_binding,
             expand_glob_import::expand_glob_import,
@@ -273,11 +277,14 @@ pub(crate) fn all() -> &'static [Handler] {
             replace_if_let_with_match::replace_if_let_with_match,
             replace_if_let_with_match::replace_match_with_if_let,
             replace_let_with_if_let::replace_let_with_if_let,
+            replace_or_with_or_else::replace_or_else_with_or,
+            replace_or_with_or_else::replace_or_with_or_else,
             replace_turbofish_with_explicit_type::replace_turbofish_with_explicit_type,
             replace_qualified_name_with_use::replace_qualified_name_with_use,
             sort_items::sort_items,
             split_import::split_import,
             toggle_ignore::toggle_ignore,
+            unmerge_match_arm::unmerge_match_arm,
             unmerge_use::unmerge_use,
             unnecessary_async::unnecessary_async,
             unwrap_block::unwrap_block,
index 22319f36134fb6b6d0ee259ae1f2245754d36917..a8c8622c1c1d89cdcab5caf4d489f96f454112f2 100644 (file)
@@ -472,6 +472,26 @@ pub fn y(&self) -> f32 {
     )
 }
 
+#[test]
+fn doctest_convert_two_arm_bool_match_to_matches_macro() {
+    check_doc_test(
+        "convert_two_arm_bool_match_to_matches_macro",
+        r#####"
+fn main() {
+    match scrutinee$0 {
+        Some(val) if val.cond() => true,
+        _ => false,
+    }
+}
+"#####,
+        r#####"
+fn main() {
+    matches!(scrutinee, Some(val) if val.cond())
+}
+"#####,
+    )
+}
+
 #[test]
 fn doctest_convert_while_to_loop() {
     check_doc_test(
@@ -2009,6 +2029,46 @@ fn handle(action: Action) {
     )
 }
 
+#[test]
+fn doctest_replace_or_else_with_or() {
+    check_doc_test(
+        "replace_or_else_with_or",
+        r#####"
+//- minicore:option
+fn foo() {
+    let a = Some(1);
+    a.unwra$0p_or_else(|| 2);
+}
+"#####,
+        r#####"
+fn foo() {
+    let a = Some(1);
+    a.unwrap_or(2);
+}
+"#####,
+    )
+}
+
+#[test]
+fn doctest_replace_or_with_or_else() {
+    check_doc_test(
+        "replace_or_with_or_else",
+        r#####"
+//- minicore:option
+fn foo() {
+    let a = Some(1);
+    a.unwra$0p_or(2);
+}
+"#####,
+        r#####"
+fn foo() {
+    let a = Some(1);
+    a.unwrap_or_else(|| 2);
+}
+"#####,
+    )
+}
+
 #[test]
 fn doctest_replace_qualified_name_with_use() {
     check_doc_test(
@@ -2207,6 +2267,32 @@ fn arithmetics {
     )
 }
 
+#[test]
+fn doctest_unmerge_match_arm() {
+    check_doc_test(
+        "unmerge_match_arm",
+        r#####"
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+    match action {
+        Action::Move(..) $0| Action::Stop => foo(),
+    }
+}
+"#####,
+        r#####"
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+    match action {
+        Action::Move(..) => foo(),
+        Action::Stop => foo(),
+    }
+}
+"#####,
+    )
+}
+
 #[test]
 fn doctest_unmerge_use() {
     check_doc_test(
index 4d66af9e8d5b8b0933b785d685d55114caf91bfe..588b52cc1ee3a72090d66899fdf89756ad6c48f3 100644 (file)
@@ -282,14 +282,26 @@ pub(crate) fn complete_expr_path(
                         }
                     }
 
-                    if let Some(ty) = innermost_ret_ty {
+                    if let Some(ret_ty) = innermost_ret_ty {
                         add_keyword(
                             "return",
-                            match (in_block_expr, ty.is_unit()) {
-                                (true, true) => "return ;",
-                                (true, false) => "return;",
-                                (false, true) => "return $0",
-                                (false, false) => "return",
+                            match (ret_ty.is_unit(), in_block_expr) {
+                                (true, true) => {
+                                    cov_mark::hit!(return_unit_block);
+                                    "return;"
+                                }
+                                (true, false) => {
+                                    cov_mark::hit!(return_unit_no_block);
+                                    "return"
+                                }
+                                (false, true) => {
+                                    cov_mark::hit!(return_value_block);
+                                    "return $0;"
+                                }
+                                (false, false) => {
+                                    cov_mark::hit!(return_value_no_block);
+                                    "return $0"
+                                }
                             },
                         );
                     }
index 925081ebf66025552c5a5a1e03bbbf0c2e058176..38e24ebc732d497aa4250f6fe23d06a2c2614f61 100644 (file)
@@ -1,7 +1,7 @@
 //! Completion tests for expressions.
 use expect_test::{expect, Expect};
 
-use crate::tests::{completion_list, BASE_ITEMS_FIXTURE};
+use crate::tests::{check_edit, completion_list, BASE_ITEMS_FIXTURE};
 
 fn check(ra_fixture: &str, expect: Expect) {
     let actual = completion_list(&format!("{}{}", BASE_ITEMS_FIXTURE, ra_fixture));
@@ -670,3 +670,39 @@ fn test() fn() -> Zulu
         "#]],
     );
 }
+
+#[test]
+fn return_unit_block() {
+    cov_mark::check!(return_unit_block);
+    check_edit("return", r#"fn f() { if true { $0 } }"#, r#"fn f() { if true { return; } }"#);
+}
+
+#[test]
+fn return_unit_no_block() {
+    cov_mark::check!(return_unit_no_block);
+    check_edit(
+        "return",
+        r#"fn f() { match () { () => $0 } }"#,
+        r#"fn f() { match () { () => return } }"#,
+    );
+}
+
+#[test]
+fn return_value_block() {
+    cov_mark::check!(return_value_block);
+    check_edit(
+        "return",
+        r#"fn f() -> i32 { if true { $0 } }"#,
+        r#"fn f() -> i32 { if true { return $0; } }"#,
+    );
+}
+
+#[test]
+fn return_value_no_block() {
+    cov_mark::check!(return_value_no_block);
+    check_edit(
+        "return",
+        r#"fn f() -> i32 { match () { () => $0 } }"#,
+        r#"fn f() -> i32 { match () { () => return $0 } }"#,
+    );
+}
index 84bde4d44dbb34dda5249336ec315966d1f0c881..b890e2b58df8f2688923c1262665e7361a747881 100644 (file)
@@ -315,7 +315,6 @@ pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) {
         | ast::Expr::IndexExpr(_)
         | ast::Expr::Literal(_)
         | ast::Expr::MacroExpr(_)
-        | ast::Expr::MacroStmts(_)
         | ast::Expr::MethodCallExpr(_)
         | ast::Expr::ParenExpr(_)
         | ast::Expr::PathExpr(_)
index d12594a4ce5c5f77c0f101870c890214ef50731d..0c92e706b3916f65c73df4b6e3945b4e6501a052 100644 (file)
@@ -7,9 +7,10 @@ pub(crate) fn break_outside_of_loop(
     ctx: &DiagnosticsContext<'_>,
     d: &hir::BreakOutsideOfLoop,
 ) -> Diagnostic {
+    let construct = if d.is_break { "break" } else { "continue" };
     Diagnostic::new(
         "break-outside-of-loop",
-        "break outside of loop",
+        format!("{construct} outside of loop"),
         ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range,
     )
 }
@@ -19,11 +20,122 @@ mod tests {
     use crate::tests::check_diagnostics;
 
     #[test]
-    fn break_outside_of_loop() {
+    fn outside_of_loop() {
         check_diagnostics(
             r#"
-fn foo() { break; }
-         //^^^^^ error: break outside of loop
+fn foo() {
+    break;
+  //^^^^^ error: break outside of loop
+    break 'a;
+  //^^^^^^^^ error: break outside of loop
+    continue;
+  //^^^^^^^^ error: continue outside of loop
+    continue 'a;
+  //^^^^^^^^^^^ error: continue outside of loop
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn try_blocks_are_borders() {
+        check_diagnostics(
+            r#"
+fn foo() {
+    'a: loop {
+        try {
+                break;
+              //^^^^^ error: break outside of loop
+                break 'a;
+              //^^^^^^^^ error: break outside of loop
+                continue;
+              //^^^^^^^^ error: continue outside of loop
+                continue 'a;
+              //^^^^^^^^^^^ error: continue outside of loop
+        };
+    }
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn async_blocks_are_borders() {
+        check_diagnostics(
+            r#"
+fn foo() {
+    'a: loop {
+        try {
+                break;
+              //^^^^^ error: break outside of loop
+                break 'a;
+              //^^^^^^^^ error: break outside of loop
+                continue;
+              //^^^^^^^^ error: continue outside of loop
+                continue 'a;
+              //^^^^^^^^^^^ error: continue outside of loop
+        };
+    }
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn closures_are_borders() {
+        check_diagnostics(
+            r#"
+fn foo() {
+    'a: loop {
+        try {
+                break;
+              //^^^^^ error: break outside of loop
+                break 'a;
+              //^^^^^^^^ error: break outside of loop
+                continue;
+              //^^^^^^^^ error: continue outside of loop
+                continue 'a;
+              //^^^^^^^^^^^ error: continue outside of loop
+        };
+    }
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn blocks_pass_through() {
+        check_diagnostics(
+            r#"
+fn foo() {
+    'a: loop {
+        {
+            break;
+            break 'a;
+            continue;
+            continue 'a;
+        }
+    }
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn label_blocks() {
+        check_diagnostics(
+            r#"
+fn foo() {
+    'a: {
+        break;
+      //^^^^^ error: break outside of loop
+        break 'a;
+        continue;
+      //^^^^^^^^ error: continue outside of loop
+        continue 'a;
+      //^^^^^^^^^^^ error: continue outside of loop
+    }
+}
 "#,
         );
     }
index 5fcaf405b14b94887cc6e81c1dd05db061eac143..c24430ce604692de844a2cc86cea6e0e2bc24abe 100644 (file)
@@ -947,6 +947,50 @@ fn f() {
         );
     }
 
+    mod rust_unstable {
+        use super::*;
+
+        #[test]
+        fn rfc_1872_exhaustive_patterns() {
+            check_diagnostics_no_bails(
+                r"
+//- minicore: option, result
+#![feature(exhaustive_patterns)]
+enum Void {}
+fn test() {
+    match None::<!> { None => () }
+    match Result::<u8, !>::Ok(2) { Ok(_) => () }
+    match Result::<u8, Void>::Ok(2) { Ok(_) => () }
+    match (2, loop {}) {}
+    match Result::<!, !>::Ok(loop {}) {}
+    match (&loop {}) {} // https://github.com/rust-lang/rust/issues/50642#issuecomment-388234919
+    //    ^^^^^^^^^^ error: missing match arm: type `&!` is non-empty
+}",
+            );
+        }
+
+        #[test]
+        fn rfc_1872_private_uninhabitedness() {
+            check_diagnostics_no_bails(
+                r"
+//- minicore: option
+//- /lib.rs crate:lib
+#![feature(exhaustive_patterns)]
+pub struct PrivatelyUninhabited { private_field: Void }
+enum Void {}
+fn test_local(x: Option<PrivatelyUninhabited>) {
+    match x {}
+} //      ^ error: missing match arm: `None` not covered
+//- /main.rs crate:main deps:lib
+#![feature(exhaustive_patterns)]
+fn test(x: Option<lib::PrivatelyUninhabited>) {
+    match x {}
+    //    ^ error: missing match arm: `None` and `Some(_)` not covered
+}",
+            );
+        }
+    }
+
     mod false_negatives {
         //! The implementation of match checking here is a work in progress. As we roll this out, we
         //! prefer false negatives to false positives (ideally there would be no false positives). This
index ed19784d1fa49d11355835d94be8b83983f75792..e9034daefa8d46c1dea2afce1e07683f52f82f66 100644 (file)
@@ -1910,7 +1910,7 @@ pub fn new() -> Self { Vec {} }
 pub struct Box<T> {}
 
 trait Display {}
-trait Sync {}
+auto trait Sync {}
 
 fn main() {
     // The block expression wrapping disables the constructor hint hiding logic
index 8de5d33a1936d42479470854e39bee711f1916a2..5dc9c6c82a14e06f0dda759607d69f9431713d07 100644 (file)
@@ -118,6 +118,11 @@ fn opt_path_type_args(p: &mut Parser<'_>, mode: Mode) {
     match mode {
         Mode::Use => {}
         Mode::Type => {
+            // test typepathfn_with_coloncolon
+            // type F = Start::(Middle) -> (Middle)::End;
+            if p.at(T![::]) && p.nth_at(2, T!['(']) {
+                p.bump(T![::]);
+            }
             // test path_fn_trait_args
             // type F = Box<Fn(i32) -> ()>;
             if p.at(T!['(']) {
index 628fa745e752d678d625ef5489173918529b265b..c84f45f1f8e4ec0f059a484354a45fc042fb2e0a 100644 (file)
@@ -262,33 +262,117 @@ pub enum SyntaxKind {
 use self::SyntaxKind::*;
 impl SyntaxKind {
     pub fn is_keyword(self) -> bool {
-        match self {
-            AS_KW | ASYNC_KW | AWAIT_KW | BOX_KW | BREAK_KW | CONST_KW | CONTINUE_KW | CRATE_KW
-            | DYN_KW | ELSE_KW | ENUM_KW | EXTERN_KW | FALSE_KW | FN_KW | FOR_KW | IF_KW
-            | IMPL_KW | IN_KW | LET_KW | LOOP_KW | MACRO_KW | MATCH_KW | MOD_KW | MOVE_KW
-            | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | SELF_TYPE_KW | STATIC_KW
-            | STRUCT_KW | SUPER_KW | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW
-            | WHERE_KW | WHILE_KW | YIELD_KW | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW
-            | RAW_KW | MACRO_RULES_KW => true,
-            _ => false,
-        }
+        matches!(
+            self,
+            AS_KW
+                | ASYNC_KW
+                | AWAIT_KW
+                | BOX_KW
+                | BREAK_KW
+                | CONST_KW
+                | CONTINUE_KW
+                | CRATE_KW
+                | DYN_KW
+                | ELSE_KW
+                | ENUM_KW
+                | EXTERN_KW
+                | FALSE_KW
+                | FN_KW
+                | FOR_KW
+                | IF_KW
+                | IMPL_KW
+                | IN_KW
+                | LET_KW
+                | LOOP_KW
+                | MACRO_KW
+                | MATCH_KW
+                | MOD_KW
+                | MOVE_KW
+                | MUT_KW
+                | PUB_KW
+                | REF_KW
+                | RETURN_KW
+                | SELF_KW
+                | SELF_TYPE_KW
+                | STATIC_KW
+                | STRUCT_KW
+                | SUPER_KW
+                | TRAIT_KW
+                | TRUE_KW
+                | TRY_KW
+                | TYPE_KW
+                | UNSAFE_KW
+                | USE_KW
+                | WHERE_KW
+                | WHILE_KW
+                | YIELD_KW
+                | AUTO_KW
+                | DEFAULT_KW
+                | EXISTENTIAL_KW
+                | UNION_KW
+                | RAW_KW
+                | MACRO_RULES_KW
+        )
     }
     pub fn is_punct(self) -> bool {
-        match self {
-            SEMICOLON | COMMA | L_PAREN | R_PAREN | L_CURLY | R_CURLY | L_BRACK | R_BRACK
-            | L_ANGLE | R_ANGLE | AT | POUND | TILDE | QUESTION | DOLLAR | AMP | PIPE | PLUS
-            | STAR | SLASH | CARET | PERCENT | UNDERSCORE | DOT | DOT2 | DOT3 | DOT2EQ | COLON
-            | COLON2 | EQ | EQ2 | FAT_ARROW | BANG | NEQ | MINUS | THIN_ARROW | LTEQ | GTEQ
-            | PLUSEQ | MINUSEQ | PIPEEQ | AMPEQ | CARETEQ | SLASHEQ | STAREQ | PERCENTEQ | AMP2
-            | PIPE2 | SHL | SHR | SHLEQ | SHREQ => true,
-            _ => false,
-        }
+        matches!(
+            self,
+            SEMICOLON
+                | COMMA
+                | L_PAREN
+                | R_PAREN
+                | L_CURLY
+                | R_CURLY
+                | L_BRACK
+                | R_BRACK
+                | L_ANGLE
+                | R_ANGLE
+                | AT
+                | POUND
+                | TILDE
+                | QUESTION
+                | DOLLAR
+                | AMP
+                | PIPE
+                | PLUS
+                | STAR
+                | SLASH
+                | CARET
+                | PERCENT
+                | UNDERSCORE
+                | DOT
+                | DOT2
+                | DOT3
+                | DOT2EQ
+                | COLON
+                | COLON2
+                | EQ
+                | EQ2
+                | FAT_ARROW
+                | BANG
+                | NEQ
+                | MINUS
+                | THIN_ARROW
+                | LTEQ
+                | GTEQ
+                | PLUSEQ
+                | MINUSEQ
+                | PIPEEQ
+                | AMPEQ
+                | CARETEQ
+                | SLASHEQ
+                | STAREQ
+                | PERCENTEQ
+                | AMP2
+                | PIPE2
+                | SHL
+                | SHR
+                | SHLEQ
+                | SHREQ
+        )
     }
     pub fn is_literal(self) -> bool {
-        match self {
-            INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE | STRING | BYTE_STRING => true,
-            _ => false,
-        }
+        matches!(self, INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE | STRING | BYTE_STRING)
     }
     pub fn from_keyword(ident: &str) -> Option<SyntaxKind> {
         let kw = match ident {
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rast
new file mode 100644 (file)
index 0000000..b47a5a5
--- /dev/null
@@ -0,0 +1,43 @@
+SOURCE_FILE
+  TYPE_ALIAS
+    TYPE_KW "type"
+    WHITESPACE " "
+    NAME
+      IDENT "F"
+    WHITESPACE " "
+    EQ "="
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "Start"
+            COLON2 "::"
+            PARAM_LIST
+              L_PAREN "("
+              PARAM
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Middle"
+              R_PAREN ")"
+            WHITESPACE " "
+            RET_TYPE
+              THIN_ARROW "->"
+              WHITESPACE " "
+              PAREN_TYPE
+                L_PAREN "("
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Middle"
+                R_PAREN ")"
+        COLON2 "::"
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "End"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rs
new file mode 100644 (file)
index 0000000..8efd93a
--- /dev/null
@@ -0,0 +1 @@
+type F = Start::(Middle) -> (Middle)::End;
index 706e1742dffde38a695d9119413849ad8fb497ac..92df4d70fd9024edc3865ddd935ae62bee437389 100644 (file)
@@ -116,6 +116,7 @@ pub(crate) struct GlobalStateSnapshot {
     pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
     vfs: Arc<RwLock<(vfs::Vfs, NoHashHashMap<FileId, LineEndings>)>>,
     pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
+    pub(crate) proc_macros_loaded: bool,
 }
 
 impl std::panic::UnwindSafe for GlobalStateSnapshot {}
@@ -256,6 +257,7 @@ pub(crate) fn snapshot(&self) -> GlobalStateSnapshot {
             check_fixes: Arc::clone(&self.diagnostics.check_fixes),
             mem_docs: self.mem_docs.clone(),
             semantic_tokens_cache: Arc::clone(&self.semantic_tokens_cache),
+            proc_macros_loaded: !self.fetch_build_data_queue.last_op_result().0.is_empty(),
         }
     }
 
index d89f0f5a3cf456d24c7889deec9355b3098e7a34..d9b669afbe81cd3be1baea15b57d53788b842a9c 100644 (file)
@@ -1504,7 +1504,11 @@ pub(crate) fn handle_semantic_tokens_full(
     let text = snap.analysis.file_text(file_id)?;
     let line_index = snap.file_line_index(file_id)?;
 
-    let highlights = snap.analysis.highlight(snap.config.highlighting_config(), file_id)?;
+    let mut highlight_config = snap.config.highlighting_config();
+    // Avoid flashing a bunch of unresolved references when the proc-macro servers haven't been spawned yet.
+    highlight_config.syntactic_name_ref_highlighting = !snap.proc_macros_loaded;
+
+    let highlights = snap.analysis.highlight(highlight_config, file_id)?;
     let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights);
 
     // Unconditionally cache the tokens
@@ -1523,7 +1527,11 @@ pub(crate) fn handle_semantic_tokens_full_delta(
     let text = snap.analysis.file_text(file_id)?;
     let line_index = snap.file_line_index(file_id)?;
 
-    let highlights = snap.analysis.highlight(snap.config.highlighting_config(), file_id)?;
+    let mut highlight_config = snap.config.highlighting_config();
+    // Avoid flashing a bunch of unresolved references when the proc-macro servers haven't been spawned yet.
+    highlight_config.syntactic_name_ref_highlighting = !snap.proc_macros_loaded;
+
+    let highlights = snap.analysis.highlight(highlight_config, file_id)?;
     let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights);
 
     let mut cache = snap.semantic_tokens_cache.lock();
index ceb2a6d703d959ad819f422ae27d0e807f1d25d9..f23bbca6387659aa24d32e97036154883bea9a33 100644 (file)
@@ -347,8 +347,8 @@ fn eq_ignore_build_data<'a>(
                             error
                         })
                     })
-                    .collect();
-            }
+                    .collect()
+            };
         }
 
         let watch = match files_config.watcher {
index 62aa47839942a42b596723d7da9b241f128afc58..894795435451c8e2691fe805253987719cd80313 100644 (file)
@@ -343,7 +343,6 @@ Expr =
 | Literal
 | LoopExpr
 | MacroExpr
-| MacroStmts
 | MatchExpr
 | MethodCallExpr
 | ParenExpr
index 63309a155219e55ebec99bcfd3b416ede648df38..449402e5f5b30af4f6e69e3b26c27aa234a2b93c 100644 (file)
@@ -1526,7 +1526,6 @@ pub enum Expr {
     Literal(Literal),
     LoopExpr(LoopExpr),
     MacroExpr(MacroExpr),
-    MacroStmts(MacroStmts),
     MatchExpr(MatchExpr),
     MethodCallExpr(MethodCallExpr),
     ParenExpr(ParenExpr),
@@ -3169,10 +3168,7 @@ fn from(node: ConstArg) -> GenericArg { GenericArg::ConstArg(node) }
 }
 impl AstNode for GenericArg {
     fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            TYPE_ARG | ASSOC_TYPE_ARG | LIFETIME_ARG | CONST_ARG => true,
-            _ => false,
-        }
+        matches!(kind, TYPE_ARG | ASSOC_TYPE_ARG | LIFETIME_ARG | CONST_ARG)
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
@@ -3237,12 +3233,23 @@ fn from(node: TupleType) -> Type { Type::TupleType(node) }
 }
 impl AstNode for Type {
     fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            ARRAY_TYPE | DYN_TRAIT_TYPE | FN_PTR_TYPE | FOR_TYPE | IMPL_TRAIT_TYPE | INFER_TYPE
-            | MACRO_TYPE | NEVER_TYPE | PAREN_TYPE | PATH_TYPE | PTR_TYPE | REF_TYPE
-            | SLICE_TYPE | TUPLE_TYPE => true,
-            _ => false,
-        }
+        matches!(
+            kind,
+            ARRAY_TYPE
+                | DYN_TRAIT_TYPE
+                | FN_PTR_TYPE
+                | FOR_TYPE
+                | IMPL_TRAIT_TYPE
+                | INFER_TYPE
+                | MACRO_TYPE
+                | NEVER_TYPE
+                | PAREN_TYPE
+                | PATH_TYPE
+                | PTR_TYPE
+                | REF_TYPE
+                | SLICE_TYPE
+                | TUPLE_TYPE
+        )
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
@@ -3334,9 +3341,6 @@ fn from(node: LoopExpr) -> Expr { Expr::LoopExpr(node) }
 impl From<MacroExpr> for Expr {
     fn from(node: MacroExpr) -> Expr { Expr::MacroExpr(node) }
 }
-impl From<MacroStmts> for Expr {
-    fn from(node: MacroStmts) -> Expr { Expr::MacroStmts(node) }
-}
 impl From<MatchExpr> for Expr {
     fn from(node: MatchExpr) -> Expr { Expr::MatchExpr(node) }
 }
@@ -3384,15 +3388,41 @@ fn from(node: UnderscoreExpr) -> Expr { Expr::UnderscoreExpr(node) }
 }
 impl AstNode for Expr {
     fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            ARRAY_EXPR | AWAIT_EXPR | BIN_EXPR | BLOCK_EXPR | BOX_EXPR | BREAK_EXPR | CALL_EXPR
-            | CAST_EXPR | CLOSURE_EXPR | CONTINUE_EXPR | FIELD_EXPR | FOR_EXPR | IF_EXPR
-            | INDEX_EXPR | LITERAL | LOOP_EXPR | MACRO_EXPR | MACRO_STMTS | MATCH_EXPR
-            | METHOD_CALL_EXPR | PAREN_EXPR | PATH_EXPR | PREFIX_EXPR | RANGE_EXPR
-            | RECORD_EXPR | REF_EXPR | RETURN_EXPR | TRY_EXPR | TUPLE_EXPR | WHILE_EXPR
-            | YIELD_EXPR | LET_EXPR | UNDERSCORE_EXPR => true,
-            _ => false,
-        }
+        matches!(
+            kind,
+            ARRAY_EXPR
+                | AWAIT_EXPR
+                | BIN_EXPR
+                | BLOCK_EXPR
+                | BOX_EXPR
+                | BREAK_EXPR
+                | CALL_EXPR
+                | CAST_EXPR
+                | CLOSURE_EXPR
+                | CONTINUE_EXPR
+                | FIELD_EXPR
+                | FOR_EXPR
+                | IF_EXPR
+                | INDEX_EXPR
+                | LITERAL
+                | LOOP_EXPR
+                | MACRO_EXPR
+                | MATCH_EXPR
+                | METHOD_CALL_EXPR
+                | PAREN_EXPR
+                | PATH_EXPR
+                | PREFIX_EXPR
+                | RANGE_EXPR
+                | RECORD_EXPR
+                | REF_EXPR
+                | RETURN_EXPR
+                | TRY_EXPR
+                | TUPLE_EXPR
+                | WHILE_EXPR
+                | YIELD_EXPR
+                | LET_EXPR
+                | UNDERSCORE_EXPR
+        )
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
@@ -3413,7 +3443,6 @@ fn cast(syntax: SyntaxNode) -> Option<Self> {
             LITERAL => Expr::Literal(Literal { syntax }),
             LOOP_EXPR => Expr::LoopExpr(LoopExpr { syntax }),
             MACRO_EXPR => Expr::MacroExpr(MacroExpr { syntax }),
-            MACRO_STMTS => Expr::MacroStmts(MacroStmts { syntax }),
             MATCH_EXPR => Expr::MatchExpr(MatchExpr { syntax }),
             METHOD_CALL_EXPR => Expr::MethodCallExpr(MethodCallExpr { syntax }),
             PAREN_EXPR => Expr::ParenExpr(ParenExpr { syntax }),
@@ -3452,7 +3481,6 @@ fn syntax(&self) -> &SyntaxNode {
             Expr::Literal(it) => &it.syntax,
             Expr::LoopExpr(it) => &it.syntax,
             Expr::MacroExpr(it) => &it.syntax,
-            Expr::MacroStmts(it) => &it.syntax,
             Expr::MatchExpr(it) => &it.syntax,
             Expr::MethodCallExpr(it) => &it.syntax,
             Expr::ParenExpr(it) => &it.syntax,
@@ -3521,11 +3549,25 @@ fn from(node: Use) -> Item { Item::Use(node) }
 }
 impl AstNode for Item {
     fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MACRO_RULES
-            | MACRO_DEF | MODULE | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true,
-            _ => false,
-        }
+        matches!(
+            kind,
+            CONST
+                | ENUM
+                | EXTERN_BLOCK
+                | EXTERN_CRATE
+                | FN
+                | IMPL
+                | MACRO_CALL
+                | MACRO_RULES
+                | MACRO_DEF
+                | MODULE
+                | STATIC
+                | STRUCT
+                | TRAIT
+                | TYPE_ALIAS
+                | UNION
+                | USE
+        )
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
@@ -3629,12 +3671,25 @@ fn from(node: ConstBlockPat) -> Pat { Pat::ConstBlockPat(node) }
 }
 impl AstNode for Pat {
     fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            IDENT_PAT | BOX_PAT | REST_PAT | LITERAL_PAT | MACRO_PAT | OR_PAT | PAREN_PAT
-            | PATH_PAT | WILDCARD_PAT | RANGE_PAT | RECORD_PAT | REF_PAT | SLICE_PAT
-            | TUPLE_PAT | TUPLE_STRUCT_PAT | CONST_BLOCK_PAT => true,
-            _ => false,
-        }
+        matches!(
+            kind,
+            IDENT_PAT
+                | BOX_PAT
+                | REST_PAT
+                | LITERAL_PAT
+                | MACRO_PAT
+                | OR_PAT
+                | PAREN_PAT
+                | PATH_PAT
+                | WILDCARD_PAT
+                | RANGE_PAT
+                | RECORD_PAT
+                | REF_PAT
+                | SLICE_PAT
+                | TUPLE_PAT
+                | TUPLE_STRUCT_PAT
+                | CONST_BLOCK_PAT
+        )
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
@@ -3686,12 +3741,7 @@ impl From<TupleFieldList> for FieldList {
     fn from(node: TupleFieldList) -> FieldList { FieldList::TupleFieldList(node) }
 }
 impl AstNode for FieldList {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            RECORD_FIELD_LIST | TUPLE_FIELD_LIST => true,
-            _ => false,
-        }
-    }
+    fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, RECORD_FIELD_LIST | TUPLE_FIELD_LIST) }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
             RECORD_FIELD_LIST => FieldList::RecordFieldList(RecordFieldList { syntax }),
@@ -3717,12 +3767,7 @@ impl From<Union> for Adt {
     fn from(node: Union) -> Adt { Adt::Union(node) }
 }
 impl AstNode for Adt {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            ENUM | STRUCT | UNION => true,
-            _ => false,
-        }
-    }
+    fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, ENUM | STRUCT | UNION) }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
             ENUM => Adt::Enum(Enum { syntax }),
@@ -3753,12 +3798,7 @@ impl From<TypeAlias> for AssocItem {
     fn from(node: TypeAlias) -> AssocItem { AssocItem::TypeAlias(node) }
 }
 impl AstNode for AssocItem {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            CONST | FN | MACRO_CALL | TYPE_ALIAS => true,
-            _ => false,
-        }
-    }
+    fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, CONST | FN | MACRO_CALL | TYPE_ALIAS) }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
             CONST => AssocItem::Const(Const { syntax }),
@@ -3791,12 +3831,7 @@ impl From<TypeAlias> for ExternItem {
     fn from(node: TypeAlias) -> ExternItem { ExternItem::TypeAlias(node) }
 }
 impl AstNode for ExternItem {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            FN | MACRO_CALL | STATIC | TYPE_ALIAS => true,
-            _ => false,
-        }
-    }
+    fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, FN | MACRO_CALL | STATIC | TYPE_ALIAS) }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
             FN => ExternItem::Fn(Fn { syntax }),
@@ -3827,10 +3862,7 @@ fn from(node: TypeParam) -> GenericParam { GenericParam::TypeParam(node) }
 }
 impl AstNode for GenericParam {
     fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            CONST_PARAM | LIFETIME_PARAM | TYPE_PARAM => true,
-            _ => false,
-        }
+        matches!(kind, CONST_PARAM | LIFETIME_PARAM | TYPE_PARAM)
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
@@ -3856,12 +3888,7 @@ pub fn new<T: ast::HasArgList>(node: T) -> AnyHasArgList {
     }
 }
 impl AstNode for AnyHasArgList {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            CALL_EXPR | METHOD_CALL_EXPR => true,
-            _ => false,
-        }
-    }
+    fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, CALL_EXPR | METHOD_CALL_EXPR) }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         Self::can_cast(syntax.kind()).then(|| AnyHasArgList { syntax })
     }
@@ -3875,76 +3902,76 @@ pub fn new<T: ast::HasAttrs>(node: T) -> AnyHasAttrs {
 }
 impl AstNode for AnyHasAttrs {
     fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
+        matches!(
+            kind,
             MACRO_CALL
-            | SOURCE_FILE
-            | CONST
-            | ENUM
-            | EXTERN_BLOCK
-            | EXTERN_CRATE
-            | FN
-            | IMPL
-            | MACRO_RULES
-            | MACRO_DEF
-            | MODULE
-            | STATIC
-            | STRUCT
-            | TRAIT
-            | TYPE_ALIAS
-            | UNION
-            | USE
-            | ITEM_LIST
-            | BLOCK_EXPR
-            | SELF_PARAM
-            | PARAM
-            | RECORD_FIELD
-            | TUPLE_FIELD
-            | VARIANT
-            | ASSOC_ITEM_LIST
-            | EXTERN_ITEM_LIST
-            | CONST_PARAM
-            | LIFETIME_PARAM
-            | TYPE_PARAM
-            | LET_STMT
-            | ARRAY_EXPR
-            | AWAIT_EXPR
-            | BIN_EXPR
-            | BOX_EXPR
-            | BREAK_EXPR
-            | CALL_EXPR
-            | CAST_EXPR
-            | CLOSURE_EXPR
-            | CONTINUE_EXPR
-            | FIELD_EXPR
-            | FOR_EXPR
-            | IF_EXPR
-            | INDEX_EXPR
-            | LITERAL
-            | LOOP_EXPR
-            | MATCH_EXPR
-            | METHOD_CALL_EXPR
-            | PAREN_EXPR
-            | PATH_EXPR
-            | PREFIX_EXPR
-            | RANGE_EXPR
-            | REF_EXPR
-            | RETURN_EXPR
-            | TRY_EXPR
-            | TUPLE_EXPR
-            | WHILE_EXPR
-            | YIELD_EXPR
-            | LET_EXPR
-            | UNDERSCORE_EXPR
-            | STMT_LIST
-            | RECORD_EXPR_FIELD_LIST
-            | RECORD_EXPR_FIELD
-            | MATCH_ARM_LIST
-            | MATCH_ARM
-            | IDENT_PAT
-            | REST_PAT
-            | RECORD_PAT_FIELD => true,
-            _ => false,
-        }
+                | SOURCE_FILE
+                | CONST
+                | ENUM
+                | EXTERN_BLOCK
+                | EXTERN_CRATE
+                | FN
+                | IMPL
+                | MACRO_RULES
+                | MACRO_DEF
+                | MODULE
+                | STATIC
+                | STRUCT
+                | TRAIT
+                | TYPE_ALIAS
+                | UNION
+                | USE
+                | ITEM_LIST
+                | BLOCK_EXPR
+                | SELF_PARAM
+                | PARAM
+                | RECORD_FIELD
+                | TUPLE_FIELD
+                | VARIANT
+                | ASSOC_ITEM_LIST
+                | EXTERN_ITEM_LIST
+                | CONST_PARAM
+                | LIFETIME_PARAM
+                | TYPE_PARAM
+                | LET_STMT
+                | ARRAY_EXPR
+                | AWAIT_EXPR
+                | BIN_EXPR
+                | BOX_EXPR
+                | BREAK_EXPR
+                | CALL_EXPR
+                | CAST_EXPR
+                | CLOSURE_EXPR
+                | CONTINUE_EXPR
+                | FIELD_EXPR
+                | FOR_EXPR
+                | IF_EXPR
+                | INDEX_EXPR
+                | LITERAL
+                | LOOP_EXPR
+                | MATCH_EXPR
+                | METHOD_CALL_EXPR
+                | PAREN_EXPR
+                | PATH_EXPR
+                | PREFIX_EXPR
+                | RANGE_EXPR
+                | REF_EXPR
+                | RETURN_EXPR
+                | TRY_EXPR
+                | TUPLE_EXPR
+                | WHILE_EXPR
+                | YIELD_EXPR
+                | LET_EXPR
+                | UNDERSCORE_EXPR
+                | STMT_LIST
+                | RECORD_EXPR_FIELD_LIST
+                | RECORD_EXPR_FIELD
+                | MATCH_ARM_LIST
+                | MATCH_ARM
+                | IDENT_PAT
+                | REST_PAT
+                | RECORD_PAT_FIELD
+        )
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         Self::can_cast(syntax.kind()).then(|| AnyHasAttrs { syntax })
@@ -3959,12 +3986,29 @@ pub fn new<T: ast::HasDocComments>(node: T) -> AnyHasDocComments {
 }
 impl AstNode for AnyHasDocComments {
     fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            MACRO_CALL | SOURCE_FILE | CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL
-            | MACRO_RULES | MACRO_DEF | MODULE | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION
-            | USE | RECORD_FIELD | TUPLE_FIELD | VARIANT => true,
-            _ => false,
-        }
+        matches!(
+            kind,
+            MACRO_CALL
+                | SOURCE_FILE
+                | CONST
+                | ENUM
+                | EXTERN_BLOCK
+                | EXTERN_CRATE
+                | FN
+                | IMPL
+                | MACRO_RULES
+                | MACRO_DEF
+                | MODULE
+                | STATIC
+                | STRUCT
+                | TRAIT
+                | TYPE_ALIAS
+                | UNION
+                | USE
+                | RECORD_FIELD
+                | TUPLE_FIELD
+                | VARIANT
+        )
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         Self::can_cast(syntax.kind()).then(|| AnyHasDocComments { syntax })
@@ -3979,10 +4023,7 @@ pub fn new<T: ast::HasGenericParams>(node: T) -> AnyHasGenericParams {
 }
 impl AstNode for AnyHasGenericParams {
     fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            ENUM | FN | IMPL | STRUCT | TRAIT | TYPE_ALIAS | UNION => true,
-            _ => false,
-        }
+        matches!(kind, ENUM | FN | IMPL | STRUCT | TRAIT | TYPE_ALIAS | UNION)
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         Self::can_cast(syntax.kind()).then(|| AnyHasGenericParams { syntax })
@@ -3996,12 +4037,7 @@ pub fn new<T: ast::HasLoopBody>(node: T) -> AnyHasLoopBody {
     }
 }
 impl AstNode for AnyHasLoopBody {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            FOR_EXPR | LOOP_EXPR | WHILE_EXPR => true,
-            _ => false,
-        }
-    }
+    fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, FOR_EXPR | LOOP_EXPR | WHILE_EXPR) }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         Self::can_cast(syntax.kind()).then(|| AnyHasLoopBody { syntax })
     }
@@ -4014,12 +4050,7 @@ pub fn new<T: ast::HasModuleItem>(node: T) -> AnyHasModuleItem {
     }
 }
 impl AstNode for AnyHasModuleItem {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            MACRO_ITEMS | SOURCE_FILE | ITEM_LIST => true,
-            _ => false,
-        }
-    }
+    fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, MACRO_ITEMS | SOURCE_FILE | ITEM_LIST) }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         Self::can_cast(syntax.kind()).then(|| AnyHasModuleItem { syntax })
     }
@@ -4033,12 +4064,27 @@ pub fn new<T: ast::HasName>(node: T) -> AnyHasName {
 }
 impl AstNode for AnyHasName {
     fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            CONST | ENUM | FN | MACRO_RULES | MACRO_DEF | MODULE | STATIC | STRUCT | TRAIT
-            | TYPE_ALIAS | UNION | RENAME | SELF_PARAM | RECORD_FIELD | VARIANT | CONST_PARAM
-            | TYPE_PARAM | IDENT_PAT => true,
-            _ => false,
-        }
+        matches!(
+            kind,
+            CONST
+                | ENUM
+                | FN
+                | MACRO_RULES
+                | MACRO_DEF
+                | MODULE
+                | STATIC
+                | STRUCT
+                | TRAIT
+                | TYPE_ALIAS
+                | UNION
+                | RENAME
+                | SELF_PARAM
+                | RECORD_FIELD
+                | VARIANT
+                | CONST_PARAM
+                | TYPE_PARAM
+                | IDENT_PAT
+        )
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         Self::can_cast(syntax.kind()).then(|| AnyHasName { syntax })
@@ -4053,10 +4099,10 @@ pub fn new<T: ast::HasTypeBounds>(node: T) -> AnyHasTypeBounds {
 }
 impl AstNode for AnyHasTypeBounds {
     fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            ASSOC_TYPE_ARG | TRAIT | TYPE_ALIAS | LIFETIME_PARAM | TYPE_PARAM | WHERE_PRED => true,
-            _ => false,
-        }
+        matches!(
+            kind,
+            ASSOC_TYPE_ARG | TRAIT | TYPE_ALIAS | LIFETIME_PARAM | TYPE_PARAM | WHERE_PRED
+        )
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         Self::can_cast(syntax.kind()).then(|| AnyHasTypeBounds { syntax })
@@ -4071,13 +4117,26 @@ pub fn new<T: ast::HasVisibility>(node: T) -> AnyHasVisibility {
 }
 impl AstNode for AnyHasVisibility {
     fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            CONST | ENUM | EXTERN_CRATE | FN | IMPL | MACRO_RULES | MACRO_DEF | MODULE | STATIC
-            | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE | RECORD_FIELD | TUPLE_FIELD | VARIANT => {
-                true
-            }
-            _ => false,
-        }
+        matches!(
+            kind,
+            CONST
+                | ENUM
+                | EXTERN_CRATE
+                | FN
+                | IMPL
+                | MACRO_RULES
+                | MACRO_DEF
+                | MODULE
+                | STATIC
+                | STRUCT
+                | TRAIT
+                | TYPE_ALIAS
+                | UNION
+                | USE
+                | RECORD_FIELD
+                | TUPLE_FIELD
+                | VARIANT
+        )
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         Self::can_cast(syntax.kind()).then(|| AnyHasVisibility { syntax })
index 037de876d45c94f16955502621129bc2872b2b85..83f8bbac5880bfd5fa542f03e90af2110039d169 100644 (file)
@@ -25,7 +25,7 @@ pub fn simple_ident_pat(name: ast::Name) -> ast::IdentPat {
         return from_text(&name.text());
 
         fn from_text(text: &str) -> ast::IdentPat {
-            ast_from_text(&format!("fn f({}: ())", text))
+            ast_from_text(&format!("fn f({text}: ())"))
         }
     }
     pub fn ident_path(ident: &str) -> ast::Path {
@@ -60,10 +60,10 @@ pub fn expr_todo() -> ast::Expr {
         expr_from_text("todo!()")
     }
     pub fn expr_ty_default(ty: &ast::Type) -> ast::Expr {
-        expr_from_text(&format!("{}::default()", ty))
+        expr_from_text(&format!("{ty}::default()"))
     }
     pub fn expr_ty_new(ty: &ast::Type) -> ast::Expr {
-        expr_from_text(&format!("{}::new()", ty))
+        expr_from_text(&format!("{ty}::new()"))
     }
 
     pub fn zero_number() -> ast::Expr {
@@ -92,18 +92,20 @@ pub fn ty_bool() -> ast::Type {
         ty_path(ident_path("bool"))
     }
     pub fn ty_option(t: ast::Type) -> ast::Type {
-        ty_from_text(&format!("Option<{}>", t))
+        ty_from_text(&format!("Option<{t}>"))
     }
     pub fn ty_result(t: ast::Type, e: ast::Type) -> ast::Type {
-        ty_from_text(&format!("Result<{}, {}>", t, e))
+        ty_from_text(&format!("Result<{t}, {e}>"))
     }
 }
 
-pub fn name(text: &str) -> ast::Name {
-    ast_from_text(&format!("mod {}{};", raw_ident_esc(text), text))
+pub fn name(name: &str) -> ast::Name {
+    let raw_escape = raw_ident_esc(name);
+    ast_from_text(&format!("mod {raw_escape}{name};"))
 }
-pub fn name_ref(text: &str) -> ast::NameRef {
-    ast_from_text(&format!("fn f() {{ {}{}; }}", raw_ident_esc(text), text))
+pub fn name_ref(name_ref: &str) -> ast::NameRef {
+    let raw_escape = raw_ident_esc(name_ref);
+    ast_from_text(&format!("fn f() {{ {raw_escape}{name_ref}; }}"))
 }
 fn raw_ident_esc(ident: &str) -> &'static str {
     let is_keyword = parser::SyntaxKind::from_keyword(ident).is_some();
@@ -118,10 +120,10 @@ pub fn lifetime(text: &str) -> ast::Lifetime {
     let mut text = text;
     let tmp;
     if never!(!text.starts_with('\'')) {
-        tmp = format!("'{}", text);
+        tmp = format!("'{text}");
         text = &tmp;
     }
-    ast_from_text(&format!("fn f<{}>() {{ }}", text))
+    ast_from_text(&format!("fn f<{text}>() {{ }}"))
 }
 
 // FIXME: replace stringly-typed constructor with a family of typed ctors, a-la
@@ -142,16 +144,16 @@ pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type {
         contents.push(',');
     }
 
-    ty_from_text(&format!("({})", contents))
+    ty_from_text(&format!("({contents})"))
 }
 pub fn ty_ref(target: ast::Type, exclusive: bool) -> ast::Type {
-    ty_from_text(&if exclusive { format!("&mut {}", target) } else { format!("&{}", target) })
+    ty_from_text(&if exclusive { format!("&mut {target}") } else { format!("&{target}") })
 }
 pub fn ty_path(path: ast::Path) -> ast::Type {
     ty_from_text(&path.to_string())
 }
 fn ty_from_text(text: &str) -> ast::Type {
-    ast_from_text(&format!("type _T = {};", text))
+    ast_from_text(&format!("type _T = {text};"))
 }
 
 pub fn assoc_item_list() -> ast::AssocItemList {
@@ -171,7 +173,7 @@ pub fn impl_(
         Some(params) => params.to_string(),
         None => String::new(),
     };
-    ast_from_text(&format!("impl{} {}{} {{}}", params, ty, ty_params))
+    ast_from_text(&format!("impl{params} {ty}{ty_params} {{}}"))
 }
 
 pub fn impl_trait(
@@ -180,7 +182,7 @@ pub fn impl_trait(
     ty_params: Option<ast::GenericParamList>,
 ) -> ast::Impl {
     let ty_params = ty_params.map_or_else(String::new, |params| params.to_string());
-    ast_from_text(&format!("impl{2} {} for {}{2} {{}}", trait_, ty, ty_params))
+    ast_from_text(&format!("impl{ty_params} {trait_} for {ty}{ty_params} {{}}"))
 }
 
 pub(crate) fn generic_arg_list() -> ast::GenericArgList {
@@ -188,13 +190,13 @@ pub(crate) fn generic_arg_list() -> ast::GenericArgList {
 }
 
 pub fn path_segment(name_ref: ast::NameRef) -> ast::PathSegment {
-    ast_from_text(&format!("type __ = {};", name_ref))
+    ast_from_text(&format!("type __ = {name_ref};"))
 }
 
 pub fn path_segment_ty(type_ref: ast::Type, trait_ref: Option<ast::PathType>) -> ast::PathSegment {
     let text = match trait_ref {
-        Some(trait_ref) => format!("fn f(x: <{} as {}>) {{}}", type_ref, trait_ref),
-        None => format!("fn f(x: <{}>) {{}}", type_ref),
+        Some(trait_ref) => format!("fn f(x: <{type_ref} as {trait_ref}>) {{}}"),
+        None => format!("fn f(x: <{type_ref}>) {{}}"),
     };
     ast_from_text(&text)
 }
@@ -212,15 +214,15 @@ pub fn path_segment_crate() -> ast::PathSegment {
 }
 
 pub fn path_unqualified(segment: ast::PathSegment) -> ast::Path {
-    ast_from_text(&format!("type __ = {};", segment))
+    ast_from_text(&format!("type __ = {segment};"))
 }
 
 pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path {
-    ast_from_text(&format!("{}::{}", qual, segment))
+    ast_from_text(&format!("{qual}::{segment}"))
 }
 // FIXME: path concatenation operation doesn't make sense as AST op.
 pub fn path_concat(first: ast::Path, second: ast::Path) -> ast::Path {
-    ast_from_text(&format!("type __ = {}::{};", first, second))
+    ast_from_text(&format!("type __ = {first}::{second};"))
 }
 
 pub fn path_from_segments(
@@ -229,20 +231,20 @@ pub fn path_from_segments(
 ) -> ast::Path {
     let segments = segments.into_iter().map(|it| it.syntax().clone()).join("::");
     ast_from_text(&if is_abs {
-        format!("fn f(x: ::{}) {{}}", segments)
+        format!("fn f(x: ::{segments}) {{}}")
     } else {
-        format!("fn f(x: {}) {{}}", segments)
+        format!("fn f(x: {segments}) {{}}")
     })
 }
 
 pub fn join_paths(paths: impl IntoIterator<Item = ast::Path>) -> ast::Path {
     let paths = paths.into_iter().map(|it| it.syntax().clone()).join("::");
-    ast_from_text(&format!("type __ = {};", paths))
+    ast_from_text(&format!("type __ = {paths};"))
 }
 
 // FIXME: should not be pub
 pub fn path_from_text(text: &str) -> ast::Path {
-    ast_from_text(&format!("fn main() {{ let test = {}; }}", text))
+    ast_from_text(&format!("fn main() {{ let test = {text}; }}"))
 }
 
 pub fn use_tree_glob() -> ast::UseTree {
@@ -257,50 +259,50 @@ pub fn use_tree(
     let mut buf = "use ".to_string();
     buf += &path.syntax().to_string();
     if let Some(use_tree_list) = use_tree_list {
-        format_to!(buf, "::{}", use_tree_list);
+        format_to!(buf, "::{use_tree_list}");
     }
     if add_star {
         buf += "::*";
     }
 
     if let Some(alias) = alias {
-        format_to!(buf, " {}", alias);
+        format_to!(buf, " {alias}");
     }
     ast_from_text(&buf)
 }
 
 pub fn use_tree_list(use_trees: impl IntoIterator<Item = ast::UseTree>) -> ast::UseTreeList {
     let use_trees = use_trees.into_iter().map(|it| it.syntax().clone()).join(", ");
-    ast_from_text(&format!("use {{{}}};", use_trees))
+    ast_from_text(&format!("use {{{use_trees}}};"))
 }
 
 pub fn use_(visibility: Option<ast::Visibility>, use_tree: ast::UseTree) -> ast::Use {
     let visibility = match visibility {
         None => String::new(),
-        Some(it) => format!("{} ", it),
+        Some(it) => format!("{it} "),
     };
-    ast_from_text(&format!("{}use {};", visibility, use_tree))
+    ast_from_text(&format!("{visibility}use {use_tree};"))
 }
 
 pub fn record_expr(path: ast::Path, fields: ast::RecordExprFieldList) -> ast::RecordExpr {
-    ast_from_text(&format!("fn f() {{ {} {} }}", path, fields))
+    ast_from_text(&format!("fn f() {{ {path} {fields} }}"))
 }
 
 pub fn record_expr_field_list(
     fields: impl IntoIterator<Item = ast::RecordExprField>,
 ) -> ast::RecordExprFieldList {
     let fields = fields.into_iter().join(", ");
-    ast_from_text(&format!("fn f() {{ S {{ {} }} }}", fields))
+    ast_from_text(&format!("fn f() {{ S {{ {fields} }} }}"))
 }
 
 pub fn record_expr_field(name: ast::NameRef, expr: Option<ast::Expr>) -> ast::RecordExprField {
     return match expr {
-        Some(expr) => from_text(&format!("{}: {}", name, expr)),
+        Some(expr) => from_text(&format!("{name}: {expr}")),
         None => from_text(&name.to_string()),
     };
 
     fn from_text(text: &str) -> ast::RecordExprField {
-        ast_from_text(&format!("fn f() {{ S {{ {}, }} }}", text))
+        ast_from_text(&format!("fn f() {{ S {{ {text}, }} }}"))
     }
 }
 
@@ -311,9 +313,9 @@ pub fn record_field(
 ) -> ast::RecordField {
     let visibility = match visibility {
         None => String::new(),
-        Some(it) => format!("{} ", it),
+        Some(it) => format!("{it} "),
     };
-    ast_from_text(&format!("struct S {{ {}{}: {}, }}", visibility, name, ty))
+    ast_from_text(&format!("struct S {{ {visibility}{name}: {ty}, }}"))
 }
 
 // TODO
@@ -323,13 +325,13 @@ pub fn block_expr(
 ) -> ast::BlockExpr {
     let mut buf = "{\n".to_string();
     for stmt in stmts.into_iter() {
-        format_to!(buf, "    {}\n", stmt);
+        format_to!(buf, "    {stmt}\n");
     }
     if let Some(tail_expr) = tail_expr {
-        format_to!(buf, "    {}\n", tail_expr);
+        format_to!(buf, "    {tail_expr}\n");
     }
     buf += "}";
-    ast_from_text(&format!("fn f() {}", buf))
+    ast_from_text(&format!("fn f() {buf}"))
 }
 
 /// Ideally this function wouldn't exist since it involves manual indenting.
@@ -343,18 +345,18 @@ pub fn hacky_block_expr_with_comments(
     let mut buf = "{\n".to_string();
     for node_or_token in elements.into_iter() {
         match node_or_token {
-            rowan::NodeOrToken::Node(n) => format_to!(buf, "    {}\n", n),
+            rowan::NodeOrToken::Node(n) => format_to!(buf, "    {n}\n"),
             rowan::NodeOrToken::Token(t) if t.kind() == SyntaxKind::COMMENT => {
-                format_to!(buf, "    {}\n", t)
+                format_to!(buf, "    {t}\n")
             }
             _ => (),
         }
     }
     if let Some(tail_expr) = tail_expr {
-        format_to!(buf, "    {}\n", tail_expr);
+        format_to!(buf, "    {tail_expr}\n");
     }
     buf += "}";
-    ast_from_text(&format!("fn f() {}", buf))
+    ast_from_text(&format!("fn f() {buf}"))
 }
 
 pub fn expr_unit() -> ast::Expr {
@@ -362,7 +364,7 @@ pub fn expr_unit() -> ast::Expr {
 }
 pub fn expr_literal(text: &str) -> ast::Literal {
     assert_eq!(text.trim(), text);
-    ast_from_text(&format!("fn f() {{ let _ = {}; }}", text))
+    ast_from_text(&format!("fn f() {{ let _ = {text}; }}"))
 }
 
 pub fn expr_empty_block() -> ast::Expr {
@@ -373,41 +375,41 @@ pub fn expr_path(path: ast::Path) -> ast::Expr {
 }
 pub fn expr_continue(label: Option<ast::Lifetime>) -> ast::Expr {
     match label {
-        Some(label) => expr_from_text(&format!("continue {}", label)),
+        Some(label) => expr_from_text(&format!("continue {label}")),
         None => expr_from_text("continue"),
     }
 }
 // Consider `op: SyntaxKind` instead for nicer syntax at the call-site?
 pub fn expr_bin_op(lhs: ast::Expr, op: ast::BinaryOp, rhs: ast::Expr) -> ast::Expr {
-    expr_from_text(&format!("{} {} {}", lhs, op, rhs))
+    expr_from_text(&format!("{lhs} {op} {rhs}"))
 }
 pub fn expr_break(label: Option<ast::Lifetime>, expr: Option<ast::Expr>) -> ast::Expr {
     let mut s = String::from("break");
 
     if let Some(label) = label {
-        format_to!(s, " {}", label);
+        format_to!(s, " {label}");
     }
 
     if let Some(expr) = expr {
-        format_to!(s, " {}", expr);
+        format_to!(s, " {expr}");
     }
 
     expr_from_text(&s)
 }
 pub fn expr_return(expr: Option<ast::Expr>) -> ast::Expr {
     match expr {
-        Some(expr) => expr_from_text(&format!("return {}", expr)),
+        Some(expr) => expr_from_text(&format!("return {expr}")),
         None => expr_from_text("return"),
     }
 }
 pub fn expr_try(expr: ast::Expr) -> ast::Expr {
-    expr_from_text(&format!("{}?", expr))
+    expr_from_text(&format!("{expr}?"))
 }
 pub fn expr_await(expr: ast::Expr) -> ast::Expr {
-    expr_from_text(&format!("{}.await", expr))
+    expr_from_text(&format!("{expr}.await"))
 }
 pub fn expr_match(expr: ast::Expr, match_arm_list: ast::MatchArmList) -> ast::Expr {
-    expr_from_text(&format!("match {} {}", expr, match_arm_list))
+    expr_from_text(&format!("match {expr} {match_arm_list}"))
 }
 pub fn expr_if(
     condition: ast::Expr,
@@ -415,66 +417,67 @@ pub fn expr_if(
     else_branch: Option<ast::ElseBranch>,
 ) -> ast::Expr {
     let else_branch = match else_branch {
-        Some(ast::ElseBranch::Block(block)) => format!("else {}", block),
-        Some(ast::ElseBranch::IfExpr(if_expr)) => format!("else {}", if_expr),
+        Some(ast::ElseBranch::Block(block)) => format!("else {block}"),
+        Some(ast::ElseBranch::IfExpr(if_expr)) => format!("else {if_expr}"),
         None => String::new(),
     };
-    expr_from_text(&format!("if {} {} {}", condition, then_branch, else_branch))
+    expr_from_text(&format!("if {condition} {then_branch} {else_branch}"))
 }
 pub fn expr_for_loop(pat: ast::Pat, expr: ast::Expr, block: ast::BlockExpr) -> ast::Expr {
-    expr_from_text(&format!("for {} in {} {}", pat, expr, block))
+    expr_from_text(&format!("for {pat} in {expr} {block}"))
 }
 
 pub fn expr_loop(block: ast::BlockExpr) -> ast::Expr {
-    expr_from_text(&format!("loop {}", block))
+    expr_from_text(&format!("loop {block}"))
 }
 
 pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::Expr {
     let token = token(op);
-    expr_from_text(&format!("{}{}", token, expr))
+    expr_from_text(&format!("{token}{expr}"))
 }
 pub fn expr_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
-    expr_from_text(&format!("{}{}", f, arg_list))
+    expr_from_text(&format!("{f}{arg_list}"))
 }
 pub fn expr_method_call(
     receiver: ast::Expr,
     method: ast::NameRef,
     arg_list: ast::ArgList,
 ) -> ast::Expr {
-    expr_from_text(&format!("{}.{}{}", receiver, method, arg_list))
+    expr_from_text(&format!("{receiver}.{method}{arg_list}"))
 }
 pub fn expr_macro_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
-    expr_from_text(&format!("{}!{}", f, arg_list))
+    expr_from_text(&format!("{f}!{arg_list}"))
 }
 pub fn expr_ref(expr: ast::Expr, exclusive: bool) -> ast::Expr {
-    expr_from_text(&if exclusive { format!("&mut {}", expr) } else { format!("&{}", expr) })
+    expr_from_text(&if exclusive { format!("&mut {expr}") } else { format!("&{expr}") })
 }
 pub fn expr_closure(pats: impl IntoIterator<Item = ast::Param>, expr: ast::Expr) -> ast::Expr {
     let params = pats.into_iter().join(", ");
-    expr_from_text(&format!("|{}| {}", params, expr))
+    expr_from_text(&format!("|{params}| {expr}"))
 }
 pub fn expr_field(receiver: ast::Expr, field: &str) -> ast::Expr {
-    expr_from_text(&format!("{}.{}", receiver, field))
+    expr_from_text(&format!("{receiver}.{field}"))
 }
 pub fn expr_paren(expr: ast::Expr) -> ast::Expr {
-    expr_from_text(&format!("({})", expr))
+    expr_from_text(&format!("({expr})"))
 }
 pub fn expr_tuple(elements: impl IntoIterator<Item = ast::Expr>) -> ast::Expr {
     let expr = elements.into_iter().format(", ");
-    expr_from_text(&format!("({})", expr))
+    expr_from_text(&format!("({expr})"))
 }
 pub fn expr_assignment(lhs: ast::Expr, rhs: ast::Expr) -> ast::Expr {
-    expr_from_text(&format!("{} = {}", lhs, rhs))
+    expr_from_text(&format!("{lhs} = {rhs}"))
 }
 fn expr_from_text(text: &str) -> ast::Expr {
-    ast_from_text(&format!("const C: () = {};", text))
+    ast_from_text(&format!("const C: () = {text};"))
 }
 pub fn expr_let(pattern: ast::Pat, expr: ast::Expr) -> ast::LetExpr {
-    ast_from_text(&format!("const _: () = while let {} = {} {{}};", pattern, expr))
+    ast_from_text(&format!("const _: () = while let {pattern} = {expr} {{}};"))
 }
 
 pub fn arg_list(args: impl IntoIterator<Item = ast::Expr>) -> ast::ArgList {
-    ast_from_text(&format!("fn main() {{ ()({}) }}", args.into_iter().format(", ")))
+    let args = args.into_iter().format(", ");
+    ast_from_text(&format!("fn main() {{ ()({args}) }}"))
 }
 
 pub fn ident_pat(ref_: bool, mut_: bool, name: ast::Name) -> ast::IdentPat {
@@ -485,7 +488,7 @@ pub fn ident_pat(ref_: bool, mut_: bool, name: ast::Name) -> ast::IdentPat {
     if mut_ {
         s.push_str("mut ");
     }
-    format_to!(s, "{}", name);
+    format_to!(s, "{name}");
     s.push_str(": ())");
     ast_from_text(&s)
 }
@@ -494,7 +497,7 @@ pub fn wildcard_pat() -> ast::WildcardPat {
     return from_text("_");
 
     fn from_text(text: &str) -> ast::WildcardPat {
-        ast_from_text(&format!("fn f({}: ())", text))
+        ast_from_text(&format!("fn f({text}: ())"))
     }
 }
 
@@ -502,7 +505,7 @@ pub fn literal_pat(lit: &str) -> ast::LiteralPat {
     return from_text(lit);
 
     fn from_text(text: &str) -> ast::LiteralPat {
-        ast_from_text(&format!("fn f() {{ match x {{ {} => {{}} }} }}", text))
+        ast_from_text(&format!("fn f() {{ match x {{ {text} => {{}} }} }}"))
     }
 }
 
@@ -515,10 +518,10 @@ pub fn tuple_pat(pats: impl IntoIterator<Item = ast::Pat>) -> ast::TuplePat {
     if count == 1 {
         pats_str.push(',');
     }
-    return from_text(&format!("({})", pats_str));
+    return from_text(&format!("({pats_str})"));
 
     fn from_text(text: &str) -> ast::TuplePat {
-        ast_from_text(&format!("fn f({}: ())", text))
+        ast_from_text(&format!("fn f({text}: ())"))
     }
 }
 
@@ -527,46 +530,46 @@ pub fn tuple_struct_pat(
     pats: impl IntoIterator<Item = ast::Pat>,
 ) -> ast::TupleStructPat {
     let pats_str = pats.into_iter().join(", ");
-    return from_text(&format!("{}({})", path, pats_str));
+    return from_text(&format!("{path}({pats_str})"));
 
     fn from_text(text: &str) -> ast::TupleStructPat {
-        ast_from_text(&format!("fn f({}: ())", text))
+        ast_from_text(&format!("fn f({text}: ())"))
     }
 }
 
 pub fn record_pat(path: ast::Path, pats: impl IntoIterator<Item = ast::Pat>) -> ast::RecordPat {
     let pats_str = pats.into_iter().join(", ");
-    return from_text(&format!("{} {{ {} }}", path, pats_str));
+    return from_text(&format!("{path} {{ {pats_str} }}"));
 
     fn from_text(text: &str) -> ast::RecordPat {
-        ast_from_text(&format!("fn f({}: ())", text))
+        ast_from_text(&format!("fn f({text}: ())"))
     }
 }
 
 pub fn record_pat_with_fields(path: ast::Path, fields: ast::RecordPatFieldList) -> ast::RecordPat {
-    ast_from_text(&format!("fn f({} {}: ()))", path, fields))
+    ast_from_text(&format!("fn f({path} {fields}: ()))"))
 }
 
 pub fn record_pat_field_list(
     fields: impl IntoIterator<Item = ast::RecordPatField>,
 ) -> ast::RecordPatFieldList {
     let fields = fields.into_iter().join(", ");
-    ast_from_text(&format!("fn f(S {{ {} }}: ()))", fields))
+    ast_from_text(&format!("fn f(S {{ {fields} }}: ()))"))
 }
 
 pub fn record_pat_field(name_ref: ast::NameRef, pat: ast::Pat) -> ast::RecordPatField {
-    ast_from_text(&format!("fn f(S {{ {}: {} }}: ()))", name_ref, pat))
+    ast_from_text(&format!("fn f(S {{ {name_ref}: {pat} }}: ()))"))
 }
 
 pub fn record_pat_field_shorthand(name_ref: ast::NameRef) -> ast::RecordPatField {
-    ast_from_text(&format!("fn f(S {{ {} }}: ()))", name_ref))
+    ast_from_text(&format!("fn f(S {{ {name_ref} }}: ()))"))
 }
 
 /// Returns a `BindPat` if the path has just one segment, a `PathPat` otherwise.
 pub fn path_pat(path: ast::Path) -> ast::Pat {
     return from_text(&path.to_string());
     fn from_text(text: &str) -> ast::Pat {
-        ast_from_text(&format!("fn f({}: ())", text))
+        ast_from_text(&format!("fn f({text}: ())"))
     }
 }
 
@@ -577,12 +580,12 @@ pub fn match_arm(
 ) -> ast::MatchArm {
     let pats_str = pats.into_iter().join(" | ");
     return match guard {
-        Some(guard) => from_text(&format!("{} if {} => {}", pats_str, guard, expr)),
-        None => from_text(&format!("{} => {}", pats_str, expr)),
+        Some(guard) => from_text(&format!("{pats_str} if {guard} => {expr}")),
+        None => from_text(&format!("{pats_str} => {expr}")),
     };
 
     fn from_text(text: &str) -> ast::MatchArm {
-        ast_from_text(&format!("fn f() {{ match () {{{}}} }}", text))
+        ast_from_text(&format!("fn f() {{ match () {{{text}}} }}"))
     }
 }
 
@@ -592,10 +595,10 @@ pub fn match_arm_with_guard(
     expr: ast::Expr,
 ) -> ast::MatchArm {
     let pats_str = pats.into_iter().join(" | ");
-    return from_text(&format!("{} if {} => {}", pats_str, guard, expr));
+    return from_text(&format!("{pats_str} if {guard} => {expr}"));
 
     fn from_text(text: &str) -> ast::MatchArm {
-        ast_from_text(&format!("fn f() {{ match () {{{}}} }}", text))
+        ast_from_text(&format!("fn f() {{ match () {{{text}}} }}"))
     }
 }
 
@@ -605,13 +608,14 @@ pub fn match_arm_list(arms: impl IntoIterator<Item = ast::MatchArm>) -> ast::Mat
         .map(|arm| {
             let needs_comma = arm.expr().map_or(true, |it| !it.is_block_like());
             let comma = if needs_comma { "," } else { "" };
-            format!("    {}{}\n", arm.syntax(), comma)
+            let arm = arm.syntax();
+            format!("    {arm}{comma}\n")
         })
         .collect::<String>();
     return from_text(&arms_str);
 
     fn from_text(text: &str) -> ast::MatchArmList {
-        ast_from_text(&format!("fn f() {{ match () {{\n{}}} }}", text))
+        ast_from_text(&format!("fn f() {{ match () {{\n{text}}} }}"))
     }
 }
 
@@ -620,10 +624,10 @@ pub fn where_pred(
     bounds: impl IntoIterator<Item = ast::TypeBound>,
 ) -> ast::WherePred {
     let bounds = bounds.into_iter().join(" + ");
-    return from_text(&format!("{}: {}", path, bounds));
+    return from_text(&format!("{path}: {bounds}"));
 
     fn from_text(text: &str) -> ast::WherePred {
-        ast_from_text(&format!("fn f() where {} {{ }}", text))
+        ast_from_text(&format!("fn f() where {text} {{ }}"))
     }
 }
 
@@ -632,7 +636,7 @@ pub fn where_clause(preds: impl IntoIterator<Item = ast::WherePred>) -> ast::Whe
     return from_text(preds.as_str());
 
     fn from_text(text: &str) -> ast::WhereClause {
-        ast_from_text(&format!("fn f() where {} {{ }}", text))
+        ast_from_text(&format!("fn f() where {text} {{ }}"))
     }
 }
 
@@ -642,19 +646,19 @@ pub fn let_stmt(
     initializer: Option<ast::Expr>,
 ) -> ast::LetStmt {
     let mut text = String::new();
-    format_to!(text, "let {}", pattern);
+    format_to!(text, "let {pattern}");
     if let Some(ty) = ty {
-        format_to!(text, ": {}", ty);
+        format_to!(text, ": {ty}");
     }
     match initializer {
-        Some(it) => format_to!(text, " = {};", it),
+        Some(it) => format_to!(text, " = {it};"),
         None => format_to!(text, ";"),
     };
-    ast_from_text(&format!("fn f() {{ {} }}", text))
+    ast_from_text(&format!("fn f() {{ {text} }}"))
 }
 pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt {
     let semi = if expr.is_block_like() { "" } else { ";" };
-    ast_from_text(&format!("fn f() {{ {}{} (); }}", expr, semi))
+    ast_from_text(&format!("fn f() {{ {expr}{semi} (); }}"))
 }
 
 pub fn item_const(
@@ -665,13 +669,13 @@ pub fn item_const(
 ) -> ast::Const {
     let visibility = match visibility {
         None => String::new(),
-        Some(it) => format!("{} ", it),
+        Some(it) => format!("{it} "),
     };
-    ast_from_text(&format!("{} const {}: {} = {};", visibility, name, ty, expr))
+    ast_from_text(&format!("{visibility} const {name}: {ty} = {expr};"))
 }
 
 pub fn param(pat: ast::Pat, ty: ast::Type) -> ast::Param {
-    ast_from_text(&format!("fn f({}: {}) {{ }}", pat, ty))
+    ast_from_text(&format!("fn f({pat}: {ty}) {{ }}"))
 }
 
 pub fn self_param() -> ast::SelfParam {
@@ -679,7 +683,7 @@ pub fn self_param() -> ast::SelfParam {
 }
 
 pub fn ret_type(ty: ast::Type) -> ast::RetType {
-    ast_from_text(&format!("fn f() -> {} {{ }}", ty))
+    ast_from_text(&format!("fn f() -> {ty} {{ }}"))
 }
 
 pub fn param_list(
@@ -688,30 +692,30 @@ pub fn param_list(
 ) -> ast::ParamList {
     let args = pats.into_iter().join(", ");
     let list = match self_param {
-        Some(self_param) if args.is_empty() => format!("fn f({}) {{ }}", self_param),
-        Some(self_param) => format!("fn f({}, {}) {{ }}", self_param, args),
-        None => format!("fn f({}) {{ }}", args),
+        Some(self_param) if args.is_empty() => format!("fn f({self_param}) {{ }}"),
+        Some(self_param) => format!("fn f({self_param}, {args}) {{ }}"),
+        None => format!("fn f({args}) {{ }}"),
     };
     ast_from_text(&list)
 }
 
 pub fn type_param(name: ast::Name, ty: Option<ast::TypeBoundList>) -> ast::TypeParam {
     let bound = match ty {
-        Some(it) => format!(": {}", it),
+        Some(it) => format!(": {it}"),
         None => String::new(),
     };
-    ast_from_text(&format!("fn f<{}{}>() {{ }}", name, bound))
+    ast_from_text(&format!("fn f<{name}{bound}>() {{ }}"))
 }
 
 pub fn lifetime_param(lifetime: ast::Lifetime) -> ast::LifetimeParam {
-    ast_from_text(&format!("fn f<{}>() {{ }}", lifetime))
+    ast_from_text(&format!("fn f<{lifetime}>() {{ }}"))
 }
 
 pub fn generic_param_list(
     pats: impl IntoIterator<Item = ast::GenericParam>,
 ) -> ast::GenericParamList {
     let args = pats.into_iter().join(", ");
-    ast_from_text(&format!("fn f<{}>() {{ }}", args))
+    ast_from_text(&format!("fn f<{args}>() {{ }}"))
 }
 
 pub fn visibility_pub_crate() -> ast::Visibility {
@@ -724,33 +728,33 @@ pub fn visibility_pub() -> ast::Visibility {
 
 pub fn tuple_field_list(fields: impl IntoIterator<Item = ast::TupleField>) -> ast::TupleFieldList {
     let fields = fields.into_iter().join(", ");
-    ast_from_text(&format!("struct f({});", fields))
+    ast_from_text(&format!("struct f({fields});"))
 }
 
 pub fn record_field_list(
     fields: impl IntoIterator<Item = ast::RecordField>,
 ) -> ast::RecordFieldList {
     let fields = fields.into_iter().join(", ");
-    ast_from_text(&format!("struct f {{ {} }}", fields))
+    ast_from_text(&format!("struct f {{ {fields} }}"))
 }
 
 pub fn tuple_field(visibility: Option<ast::Visibility>, ty: ast::Type) -> ast::TupleField {
     let visibility = match visibility {
         None => String::new(),
-        Some(it) => format!("{} ", it),
+        Some(it) => format!("{it} "),
     };
-    ast_from_text(&format!("struct f({}{});", visibility, ty))
+    ast_from_text(&format!("struct f({visibility}{ty});"))
 }
 
 pub fn variant(name: ast::Name, field_list: Option<ast::FieldList>) -> ast::Variant {
     let field_list = match field_list {
         None => String::new(),
         Some(it) => match it {
-            ast::FieldList::RecordFieldList(record) => format!(" {}", record),
-            ast::FieldList::TupleFieldList(tuple) => format!("{}", tuple),
+            ast::FieldList::RecordFieldList(record) => format!(" {record}"),
+            ast::FieldList::TupleFieldList(tuple) => format!("{tuple}"),
         },
     };
-    ast_from_text(&format!("enum f {{ {}{} }}", name, field_list))
+    ast_from_text(&format!("enum f {{ {name}{field_list} }}"))
 }
 
 pub fn fn_(
@@ -763,23 +767,22 @@ pub fn fn_(
     is_async: bool,
 ) -> ast::Fn {
     let type_params = match type_params {
-        Some(type_params) => format!("{}", type_params),
+        Some(type_params) => format!("{type_params}"),
         None => "".into(),
     };
     let ret_type = match ret_type {
-        Some(ret_type) => format!("{} ", ret_type),
+        Some(ret_type) => format!("{ret_type} "),
         None => "".into(),
     };
     let visibility = match visibility {
         None => String::new(),
-        Some(it) => format!("{} ", it),
+        Some(it) => format!("{it} "),
     };
 
     let async_literal = if is_async { "async " } else { "" };
 
     ast_from_text(&format!(
-        "{}{}fn {}{}{} {}{}",
-        visibility, async_literal, fn_name, type_params, params, ret_type, body
+        "{visibility}{async_literal}fn {fn_name}{type_params}{params} {ret_type}{body}",
     ))
 }
 
@@ -793,13 +796,10 @@ pub fn struct_(
     let type_params = generic_param_list.map_or_else(String::new, |it| it.to_string());
     let visibility = match visibility {
         None => String::new(),
-        Some(it) => format!("{} ", it),
+        Some(it) => format!("{it} "),
     };
 
-    ast_from_text(&format!(
-        "{}struct {}{}{}{}",
-        visibility, strukt_name, type_params, field_list, semicolon
-    ))
+    ast_from_text(&format!("{visibility}struct {strukt_name}{type_params}{field_list}{semicolon}",))
 }
 
 #[track_caller]
@@ -808,7 +808,8 @@ fn ast_from_text<N: AstNode>(text: &str) -> N {
     let node = match parse.tree().syntax().descendants().find_map(N::cast) {
         Some(it) => it,
         None => {
-            panic!("Failed to make ast node `{}` from text {}", std::any::type_name::<N>(), text)
+            let node = std::any::type_name::<N>();
+            panic!("Failed to make ast node `{node}` from text {text}")
         }
     };
     let node = node.clone_subtree();
@@ -824,7 +825,7 @@ pub fn token(kind: SyntaxKind) -> SyntaxToken {
         .descendants_with_tokens()
         .filter_map(|it| it.into_token())
         .find(|it| it.kind() == kind)
-        .unwrap_or_else(|| panic!("unhandled token: {:?}", kind))
+        .unwrap_or_else(|| panic!("unhandled token: {kind:?}"))
 }
 
 pub mod tokens {
@@ -863,7 +864,7 @@ pub fn doc_comment(text: &str) -> SyntaxToken {
 
     pub fn literal(text: &str) -> SyntaxToken {
         assert_eq!(text.trim(), text);
-        let lit: ast::Literal = super::ast_from_text(&format!("fn f() {{ let _ = {}; }}", text));
+        let lit: ast::Literal = super::ast_from_text(&format!("fn f() {{ let _ = {text}; }}"));
         lit.syntax().first_child_or_token().unwrap().into_token().unwrap()
     }
 
index 28976d837b88a142e44d26c06a11d2108606d24c..ba72e64425b23c095063a54e3aa7cf1edef2e618 100644 (file)
@@ -322,7 +322,7 @@ pub fn suffix(&self) -> Option<&str> {
 
     pub fn float_value(&self) -> Option<f64> {
         let (_, text, _) = self.split_into_parts();
-        text.parse::<f64>().ok()
+        text.replace('_', "").parse::<f64>().ok()
     }
 }
 
@@ -361,7 +361,7 @@ pub fn suffix(&self) -> Option<&str> {
 
     pub fn value(&self) -> Option<f64> {
         let (text, _) = self.split_into_parts();
-        text.parse::<f64>().ok()
+        text.replace('_', "").parse::<f64>().ok()
     }
 }
 
@@ -397,6 +397,15 @@ fn check_int_suffix<'a>(lit: &str, expected: impl Into<Option<&'a str>>) {
         assert_eq!(IntNumber { syntax: make::tokens::literal(lit) }.suffix(), expected.into());
     }
 
+    fn check_float_value(lit: &str, expected: impl Into<Option<f64>> + Copy) {
+        assert_eq!(FloatNumber { syntax: make::tokens::literal(lit) }.value(), expected.into());
+        assert_eq!(IntNumber { syntax: make::tokens::literal(lit) }.float_value(), expected.into());
+    }
+
+    fn check_int_value(lit: &str, expected: impl Into<Option<u128>>) {
+        assert_eq!(IntNumber { syntax: make::tokens::literal(lit) }.value(), expected.into());
+    }
+
     #[test]
     fn test_float_number_suffix() {
         check_float_suffix("123.0", None);
@@ -437,6 +446,14 @@ fn test_string_escape() {
         check_string_value(r"\nfoobar", "\nfoobar");
         check_string_value(r"C:\\Windows\\System32\\", "C:\\Windows\\System32\\");
     }
+
+    #[test]
+    fn test_value_underscores() {
+        check_float_value("3.141592653589793_f64", 3.141592653589793_f64);
+        check_float_value("1__0.__0__f32", 10.0);
+        check_int_value("0b__1_0_", 2);
+        check_int_value("1_1_1_1_1_1", 111111);
+    }
 }
 
 impl ast::Char {
index 6d2766225103f7b0aa2406a99939031a973b7274..70b54843dbaab5d6f328d18546e8cac979fd25f6 100644 (file)
@@ -169,10 +169,7 @@ fn syntax(&self) -> &SyntaxNode { &self.syntax }
                 quote! {
                     impl AstNode for #name {
                         fn can_cast(kind: SyntaxKind) -> bool {
-                            match kind {
-                                #(#kinds)|* => true,
-                                _ => false,
-                            }
+                            matches!(kind, #(#kinds)|*)
                         }
                         fn cast(syntax: SyntaxNode) -> Option<Self> {
                             let res = match syntax.kind() {
@@ -253,10 +250,7 @@ pub fn new<T: ast::#trait_name>(node: T) -> #name {
                     }
                     impl AstNode for #name {
                         fn can_cast(kind: SyntaxKind) -> bool {
-                            match kind {
-                                #(#kinds)|* => true,
-                                _ => false,
-                            }
+                            matches!(kind, #(#kinds)|*)
                         }
                         fn cast(syntax: SyntaxNode) -> Option<Self> {
                             Self::can_cast(syntax.kind()).then(|| #name { syntax })
@@ -410,24 +404,17 @@ pub enum SyntaxKind {
 
         impl SyntaxKind {
             pub fn is_keyword(self) -> bool {
-                match self {
-                    #(#all_keywords)|* => true,
-                    _ => false,
-                }
+                matches!(self, #(#all_keywords)|*)
             }
 
             pub fn is_punct(self) -> bool {
-                match self {
-                    #(#punctuation)|* => true,
-                    _ => false,
-                }
+
+                matches!(self, #(#punctuation)|*)
+
             }
 
             pub fn is_literal(self) -> bool {
-                match self {
-                    #(#literals)|* => true,
-                    _ => false,
-                }
+                matches!(self, #(#literals)|*)
             }
 
             pub fn from_keyword(ident: &str) -> Option<SyntaxKind> {
index 50e8d06b66049795bedc69b320bad4be62d7a811..ccaaf3991769ec737833da7eb0bec769d36a501a 100644 (file)
@@ -322,6 +322,43 @@ pub fn iter_mut(
             .map(|(idx, value)| (Idx::from_raw(RawIdx(idx as u32)), value))
     }
 
+    /// Returns an iterator over the arena’s values.
+    ///
+    /// ```
+    /// let mut arena = la_arena::Arena::new();
+    /// let idx1 = arena.alloc(20);
+    /// let idx2 = arena.alloc(40);
+    /// let idx3 = arena.alloc(60);
+    ///
+    /// let mut iterator = arena.values();
+    /// assert_eq!(iterator.next(), Some(&20));
+    /// assert_eq!(iterator.next(), Some(&40));
+    /// assert_eq!(iterator.next(), Some(&60));
+    /// ```
+    pub fn values(&mut self) -> impl Iterator<Item = &T> + ExactSizeIterator + DoubleEndedIterator {
+        self.data.iter()
+    }
+
+    /// Returns an iterator over the arena’s mutable values.
+    ///
+    /// ```
+    /// let mut arena = la_arena::Arena::new();
+    /// let idx1 = arena.alloc(20);
+    ///
+    /// assert_eq!(arena[idx1], 20);
+    ///
+    /// let mut iterator = arena.values_mut();
+    /// *iterator.next().unwrap() = 10;
+    /// drop(iterator);
+    ///
+    /// assert_eq!(arena[idx1], 10);
+    /// ```
+    pub fn values_mut(
+        &mut self,
+    ) -> impl Iterator<Item = &mut T> + ExactSizeIterator + DoubleEndedIterator {
+        self.data.iter_mut()
+    }
+
     /// Reallocates the arena to make it take up as little space as possible.
     pub fn shrink_to_fit(&mut self) {
         self.data.shrink_to_fit();