Skip to content

Commit

Permalink
Rollup merge of #99954 - dingxiangfei2009:break-out-let-else-higher-u…
Browse files Browse the repository at this point in the history
…p, r=oli-obk

let-else: break out to one scope higher for let-else

```@est31``` This PR follows up with #99518 which is to break out to the last remainder scope. It breaks to the out-most `region_scope` of the block if the first statement is a `let-else`.
  • Loading branch information
JohnTitor authored Aug 24, 2022
2 parents f4550a6 + 8467a7b commit b3f1783
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
21 changes: 19 additions & 2 deletions compiler/rustc_mir_build/src/build/block.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::build::matches::ArmHasGuard;
use crate::build::ForGuard::OutsideGuard;
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
use rustc_middle::middle::region::Scope;
use rustc_middle::thir::*;
use rustc_middle::{mir::*, ty};
use rustc_span::Span;
Expand Down Expand Up @@ -34,10 +35,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&stmts,
expr,
safety_mode,
region_scope,
))
})
} else {
this.ast_block_stmts(destination, block, span, &stmts, expr, safety_mode)
this.ast_block_stmts(
destination,
block,
span,
&stmts,
expr,
safety_mode,
region_scope,
)
}
})
})
Expand All @@ -51,6 +61,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
stmts: &[StmtId],
expr: Option<&Expr<'tcx>>,
safety_mode: BlockSafety,
region_scope: Scope,
) -> BlockAnd<()> {
let this = self;

Expand All @@ -73,6 +84,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let mut let_scope_stack = Vec::with_capacity(8);
let outer_source_scope = this.source_scope;
let outer_in_scope_unsafe = this.in_scope_unsafe;
// This scope information is kept for breaking out of the parent remainder scope in case
// one let-else pattern matching fails.
// By doing so, we can be sure that even temporaries that receive extended lifetime
// assignments are dropped, too.
let mut last_remainder_scope = region_scope;
this.update_source_scope_for_safety_mode(span, safety_mode);

let source_info = this.source_info(span);
Expand Down Expand Up @@ -132,7 +148,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
initializer_span,
else_block,
visibility_scope,
*remainder_scope,
last_remainder_scope,
remainder_span,
pattern,
)
Expand Down Expand Up @@ -178,6 +194,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
if let Some(source_scope) = visibility_scope {
this.source_scope = source_scope;
}
last_remainder_scope = *remainder_scope;
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/let-else/let-else-temporary-lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ fn main() {
};
}
}
{
fn must_pass() {
let rc = Rc::new(());
let &None = &Some(Rc::clone(&rc)) else {
Rc::try_unwrap(rc).unwrap();
return;
};
unreachable!();
}
must_pass();
}
{
// test let-else drops temps before else block
// NOTE: this test has to be the last block in the `main`
Expand Down

0 comments on commit b3f1783

Please sign in to comment.