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.
|
// scopes, meaning that temporaries cannot outlive them.
|
||||||
// This ensures fixed size stacks.
|
// This ensures fixed size stacks.
|
||||||
hir::ExprKind::Binary(
|
hir::ExprKind::Binary(
|
||||||
source_map::Spanned { node: outer @ hir::BinOpKind::And, .. },
|
source_map::Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
|
||||||
ref l,
|
|
||||||
ref r,
|
|
||||||
)
|
|
||||||
| hir::ExprKind::Binary(
|
|
||||||
source_map::Spanned { node: outer @ hir::BinOpKind::Or, .. },
|
|
||||||
ref l,
|
ref l,
|
||||||
ref r,
|
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.
|
// into a terminating scope if it is not a binop.
|
||||||
|
|
||||||
let terminate_lhs = match l.kind {
|
let terminate_lhs = match l.kind {
|
||||||
|
// let expressions can create temporaries that live on
|
||||||
hir::ExprKind::Let(_) => false,
|
hir::ExprKind::Let(_) => false,
|
||||||
hir::ExprKind::Binary(source_map::Spanned { node, .. }, ..)
|
// binops already drop their temporaries, so there is no
|
||||||
if node == outer =>
|
// need to put them into a terminating scope.
|
||||||
{
|
// This is purely an optimization to reduce the number of
|
||||||
false
|
// terminating scopes.
|
||||||
}
|
hir::ExprKind::Binary(
|
||||||
// If the LHS is not another binop itself of the same kind as
|
source_map::Spanned {
|
||||||
// the current binop, mark it as terminating.
|
node: hir::BinOpKind::And | hir::BinOpKind::Or, ..
|
||||||
|
},
|
||||||
|
..,
|
||||||
|
) => false,
|
||||||
|
// otherwise: mark it as terminating
|
||||||
_ => true,
|
_ => true,
|
||||||
};
|
};
|
||||||
if terminate_lhs {
|
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) {
|
fn let_chain(&self) {
|
||||||
// take the "then" branch
|
// take the "then" branch
|
||||||
if self.option_loud_drop(1).is_some() // 1
|
if self.option_loud_drop(1).is_some() // 1
|
||||||
|
@ -251,6 +265,11 @@ fn main() {
|
||||||
collector.or_chain();
|
collector.or_chain();
|
||||||
collector.assert_sorted();
|
collector.assert_sorted();
|
||||||
|
|
||||||
|
println!("-- mixed and/or chain --");
|
||||||
|
let collector = DropOrderCollector::default();
|
||||||
|
collector.mixed_and_or_chain();
|
||||||
|
collector.assert_sorted();
|
||||||
|
|
||||||
println!("-- if let --");
|
println!("-- if let --");
|
||||||
let collector = DropOrderCollector::default();
|
let collector = DropOrderCollector::default();
|
||||||
collector.if_let();
|
collector.if_let();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue