about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-03-02 16:53:16 +0100
committerGitHub <noreply@github.com>2024-03-02 16:53:16 +0100
commit7bacfced9523407af772d9de5fc87435b90a5be5 (patch)
tree8980b7994723e57f97c5af018acf6195fd418852
parent5b66e008e09061c585079f11bfc8785fa3cfaa00 (diff)
parent972d8daf47d8a61e00304e1e362b32ca380ce947 (diff)
Rollup merge of #121892 - Zalathar:expr-kind-let, r=Nadrieril
The ordinary lowering of `thir::ExprKind::Let` is unreachable

After desugaring, `let` expressions should only appear inside `if` expressions or `match` guards, possibly nested within a let-chain. In both cases they are specifically handled by the lowerings of those expressions, so this case is currently unreachable.

---

Context: https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Lowering.20of.20.60thir.3A.3AExprKind.3A.3ALet.60.20is.20unreachable

My conclusions are partly based on the observation that stubbing out this match arm doesn't cause any test failures. So either this really is unreachable, or it can be reached in some obscure circumstances that our test suite doesn't cover.

If we end up needing this code (or something like it) for an implementation of https://github.com/rust-lang/rfcs/pull/3573, it should be easy enough to pull it back out of version control history.

I looked into having the `if`/`match` lowerings call back into `expr_into_dest`, but from what I can tell that won't work well, because there are extra scoping considerations that require some awareness of the enclosing if/match.

r? ```@Nadrieril```
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs38
1 files changed, 6 insertions, 32 deletions
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 2978491d646..f2cf6fe613c 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -109,38 +109,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 this.cfg.goto(else_blk, source_info, join_block);
                 join_block.unit()
             }
-            ExprKind::Let { expr, ref pat } => {
-                let scope = this.local_scope();
-                let (true_block, false_block) = this.in_if_then_scope(scope, expr_span, |this| {
-                    this.lower_let_expr(block, expr, pat, scope, None, expr_span, true)
-                });
-
-                this.cfg.push_assign_constant(
-                    true_block,
-                    source_info,
-                    destination,
-                    ConstOperand {
-                        span: expr_span,
-                        user_ty: None,
-                        const_: Const::from_bool(this.tcx, true),
-                    },
-                );
-
-                this.cfg.push_assign_constant(
-                    false_block,
-                    source_info,
-                    destination,
-                    ConstOperand {
-                        span: expr_span,
-                        user_ty: None,
-                        const_: Const::from_bool(this.tcx, false),
-                    },
-                );
-
-                let join_block = this.cfg.start_new_block();
-                this.cfg.goto(true_block, source_info, join_block);
-                this.cfg.goto(false_block, source_info, join_block);
-                join_block.unit()
+            ExprKind::Let { .. } => {
+                // After desugaring, `let` expressions should only appear inside `if`
+                // expressions or `match` guards, possibly nested within a let-chain.
+                // In both cases they are specifically handled by the lowerings of
+                // those expressions, so this case is currently unreachable.
+                span_bug!(expr_span, "unexpected let expression outside of if or match-guard");
             }
             ExprKind::NeverToAny { source } => {
                 let source_expr = &this.thir[source];