Also avoid creating a terminating scope in mixed chains
This avoids creation of a terminating scope in chains that contain both && and ||, because also there we know that a terminating scope is not neccessary: all the chain members are already in such terminating scopes. Also add a mixed && / || test.
This commit is contained in:
parent
a2076dc0a6
commit
a59a2d3f6a
2 changed files with 32 additions and 13 deletions
|
@ -241,12 +241,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
|
|||
// scopes, meaning that temporaries cannot outlive them.
|
||||
// This ensures fixed size stacks.
|
||||
hir::ExprKind::Binary(
|
||||
source_map::Spanned { node: outer @ hir::BinOpKind::And, .. },
|
||||
ref l,
|
||||
ref r,
|
||||
)
|
||||
| hir::ExprKind::Binary(
|
||||
source_map::Spanned { node: outer @ hir::BinOpKind::Or, .. },
|
||||
source_map::Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
|
||||
ref l,
|
||||
ref r,
|
||||
) => {
|
||||
|
@ -268,14 +263,19 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
|
|||
// into a terminating scope if it is not a binop.
|
||||
|
||||
let terminate_lhs = match l.kind {
|
||||
// let expressions can create temporaries that live on
|
||||
hir::ExprKind::Let(_) => false,
|
||||
hir::ExprKind::Binary(source_map::Spanned { node, .. }, ..)
|
||||
if node == outer =>
|
||||
{
|
||||
false
|
||||
}
|
||||
// If the LHS is not another binop itself of the same kind as
|
||||
// the current binop, mark it as terminating.
|
||||
// binops already drop their temporaries, so there is no
|
||||
// need to put them into a terminating scope.
|
||||
// This is purely an optimization to reduce the number of
|
||||
// terminating scopes.
|
||||
hir::ExprKind::Binary(
|
||||
source_map::Spanned {
|
||||
node: hir::BinOpKind::And | hir::BinOpKind::Or, ..
|
||||
},
|
||||
..,
|
||||
) => false,
|
||||
// otherwise: mark it as terminating
|
||||
_ => true,
|
||||
};
|
||||
if terminate_lhs {
|
||||
|
|
|
@ -172,6 +172,20 @@ impl DropOrderCollector {
|
|||
}
|
||||
}
|
||||
|
||||
fn mixed_and_or_chain(&self) {
|
||||
// issue-103107
|
||||
if self.option_loud_drop(1).is_none() // 1
|
||||
|| self.option_loud_drop(2).is_none() // 2
|
||||
|| self.option_loud_drop(3).is_some() // 3
|
||||
&& self.option_loud_drop(4).is_some() // 4
|
||||
&& self.option_loud_drop(5).is_none() // 5
|
||||
|| self.option_loud_drop(6).is_none() // 6
|
||||
|| self.option_loud_drop(7).is_some() // 7
|
||||
{
|
||||
self.print(8); // 8
|
||||
}
|
||||
}
|
||||
|
||||
fn let_chain(&self) {
|
||||
// take the "then" branch
|
||||
if self.option_loud_drop(1).is_some() // 1
|
||||
|
@ -251,6 +265,11 @@ fn main() {
|
|||
collector.or_chain();
|
||||
collector.assert_sorted();
|
||||
|
||||
println!("-- mixed and/or chain --");
|
||||
let collector = DropOrderCollector::default();
|
||||
collector.mixed_and_or_chain();
|
||||
collector.assert_sorted();
|
||||
|
||||
println!("-- if let --");
|
||||
let collector = DropOrderCollector::default();
|
||||
collector.if_let();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue