Rollup merge of #99954 - dingxiangfei2009:break-out-let-else-higher-up, 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`.
This commit is contained in:
commit
b3f178350a
2 changed files with 30 additions and 2 deletions
|
@ -1,6 +1,7 @@
|
||||||
use crate::build::matches::ArmHasGuard;
|
use crate::build::matches::ArmHasGuard;
|
||||||
use crate::build::ForGuard::OutsideGuard;
|
use crate::build::ForGuard::OutsideGuard;
|
||||||
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
||||||
|
use rustc_middle::middle::region::Scope;
|
||||||
use rustc_middle::thir::*;
|
use rustc_middle::thir::*;
|
||||||
use rustc_middle::{mir::*, ty};
|
use rustc_middle::{mir::*, ty};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -34,10 +35,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
&stmts,
|
&stmts,
|
||||||
expr,
|
expr,
|
||||||
safety_mode,
|
safety_mode,
|
||||||
|
region_scope,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
} else {
|
} 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,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -51,6 +61,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
stmts: &[StmtId],
|
stmts: &[StmtId],
|
||||||
expr: Option<&Expr<'tcx>>,
|
expr: Option<&Expr<'tcx>>,
|
||||||
safety_mode: BlockSafety,
|
safety_mode: BlockSafety,
|
||||||
|
region_scope: Scope,
|
||||||
) -> BlockAnd<()> {
|
) -> BlockAnd<()> {
|
||||||
let this = self;
|
let this = self;
|
||||||
|
|
||||||
|
@ -73,6 +84,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let mut let_scope_stack = Vec::with_capacity(8);
|
let mut let_scope_stack = Vec::with_capacity(8);
|
||||||
let outer_source_scope = this.source_scope;
|
let outer_source_scope = this.source_scope;
|
||||||
let outer_in_scope_unsafe = this.in_scope_unsafe;
|
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);
|
this.update_source_scope_for_safety_mode(span, safety_mode);
|
||||||
|
|
||||||
let source_info = this.source_info(span);
|
let source_info = this.source_info(span);
|
||||||
|
@ -132,7 +148,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
initializer_span,
|
initializer_span,
|
||||||
else_block,
|
else_block,
|
||||||
visibility_scope,
|
visibility_scope,
|
||||||
*remainder_scope,
|
last_remainder_scope,
|
||||||
remainder_span,
|
remainder_span,
|
||||||
pattern,
|
pattern,
|
||||||
)
|
)
|
||||||
|
@ -178,6 +194,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
if let Some(source_scope) = visibility_scope {
|
if let Some(source_scope) = visibility_scope {
|
||||||
this.source_scope = source_scope;
|
this.source_scope = source_scope;
|
||||||
}
|
}
|
||||||
|
last_remainder_scope = *remainder_scope;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
// test let-else drops temps before else block
|
||||||
// NOTE: this test has to be the last block in the `main`
|
// NOTE: this test has to be the last block in the `main`
|
||||||
|
|
Loading…
Add table
Reference in a new issue