about summary refs log tree commit diff
path: root/compiler/rustc_mir_build/src/build
diff options
context:
space:
mode:
authorDing Xiang Fei <dingxiangfei2009@protonmail.ch>2022-09-13 21:01:48 +0800
committerDing Xiang Fei <dingxiangfei2009@protonmail.ch>2022-09-15 10:08:13 +0800
commitc7d1c9b66fdd1cbec64a7dc263557eee895b70ef (patch)
treed2d816e3ab1a646c5b885050d8369c5e54e3bdf6 /compiler/rustc_mir_build/src/build
parent635b57c2ede8eb311b418104f027ad4fae1ee548 (diff)
downloadrust-c7d1c9b66fdd1cbec64a7dc263557eee895b70ef.tar.gz
rust-c7d1c9b66fdd1cbec64a7dc263557eee895b70ef.zip
add explanatory note
Diffstat (limited to 'compiler/rustc_mir_build/src/build')
-rw-r--r--compiler/rustc_mir_build/src/build/block.rs15
1 files changed, 15 insertions, 0 deletions
diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs
index d611f02333f..8eabd925e45 100644
--- a/compiler/rustc_mir_build/src/build/block.rs
+++ b/compiler/rustc_mir_build/src/build/block.rs
@@ -117,6 +117,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     lint_level,
                     else_block: Some(else_block),
                 } => {
+                    // When lowering the statement `let <pat> = <expr> else { <else> };`,
+                    // the `<else>` block is nested in the parent scope enclosing this statment.
+                    // That scope is usually either the enclosing block scope,
+                    // or the remainder scope of the last statement.
+                    // This is to make sure that temporaries instantiated in `<expr>` are dropped
+                    // as well.
+                    // In addition, even though bindings in `<pat>` only come into scope if
+                    // the pattern matching passes, in the MIR building the storages for them
+                    // are declared as live any way.
+                    // This is similar to `let x;` statements without an initializer expression,
+                    // where the value of `x` in this example may or may be assigned,
+                    // because the storage for their values may not be live after all due to
+                    // failure in pattern matching.
+                    // For this reason, we declare those storages as live but we do not schedule
+                    // any drop yet- they are scheduled later after the pattern matching.
                     let ignores_expr_result = matches!(pattern.kind, PatKind::Wild);
                     this.block_context.push(BlockFrame::Statement { ignores_expr_result });