Skip to content

Commit a59a2d3

Browse files
committed
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.
1 parent a2076dc commit a59a2d3

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

compiler/rustc_hir_analysis/src/check/region.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
241241
// scopes, meaning that temporaries cannot outlive them.
242242
// This ensures fixed size stacks.
243243
hir::ExprKind::Binary(
244-
source_map::Spanned { node: outer @ hir::BinOpKind::And, .. },
245-
ref l,
246-
ref r,
247-
)
248-
| hir::ExprKind::Binary(
249-
source_map::Spanned { node: outer @ hir::BinOpKind::Or, .. },
244+
source_map::Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
250245
ref l,
251246
ref r,
252247
) => {
@@ -268,14 +263,19 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
268263
// into a terminating scope if it is not a binop.
269264

270265
let terminate_lhs = match l.kind {
266+
// let expressions can create temporaries that live on
271267
hir::ExprKind::Let(_) => false,
272-
hir::ExprKind::Binary(source_map::Spanned { node, .. }, ..)
273-
if node == outer =>
274-
{
275-
false
276-
}
277-
// If the LHS is not another binop itself of the same kind as
278-
// the current binop, mark it as terminating.
268+
// binops already drop their temporaries, so there is no
269+
// need to put them into a terminating scope.
270+
// This is purely an optimization to reduce the number of
271+
// terminating scopes.
272+
hir::ExprKind::Binary(
273+
source_map::Spanned {
274+
node: hir::BinOpKind::And | hir::BinOpKind::Or, ..
275+
},
276+
..,
277+
) => false,
278+
// otherwise: mark it as terminating
279279
_ => true,
280280
};
281281
if terminate_lhs {

src/test/ui/drop/drop_order.rs

+19
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,20 @@ impl DropOrderCollector {
172172
}
173173
}
174174

175+
fn mixed_and_or_chain(&self) {
176+
// issue-103107
177+
if self.option_loud_drop(1).is_none() // 1
178+
|| self.option_loud_drop(2).is_none() // 2
179+
|| self.option_loud_drop(3).is_some() // 3
180+
&& self.option_loud_drop(4).is_some() // 4
181+
&& self.option_loud_drop(5).is_none() // 5
182+
|| self.option_loud_drop(6).is_none() // 6
183+
|| self.option_loud_drop(7).is_some() // 7
184+
{
185+
self.print(8); // 8
186+
}
187+
}
188+
175189
fn let_chain(&self) {
176190
// take the "then" branch
177191
if self.option_loud_drop(1).is_some() // 1
@@ -251,6 +265,11 @@ fn main() {
251265
collector.or_chain();
252266
collector.assert_sorted();
253267

268+
println!("-- mixed and/or chain --");
269+
let collector = DropOrderCollector::default();
270+
collector.mixed_and_or_chain();
271+
collector.assert_sorted();
272+
254273
println!("-- if let --");
255274
let collector = DropOrderCollector::default();
256275
collector.if_let();

0 commit comments

Comments
 (0)