// 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,
) => {
// 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 {
}
}
+ 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
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();