diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs index 3e765173fb9..d43ad1b8c9c 100644 --- a/clippy_lints/src/matches/mod.rs +++ b/clippy_lints/src/matches/mod.rs @@ -963,7 +963,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches { return; } if matches!(source, MatchSource::Normal | MatchSource::ForLoopDesugar) { - significant_drop_in_scrutinee::check(cx, expr, ex, source); + significant_drop_in_scrutinee::check(cx, expr, ex, arms, source); } collapsible_match::check_match(cx, arms); diff --git a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index dcaf6f865de..59ca33cbcc7 100644 --- a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -4,7 +4,7 @@ use clippy_utils::get_attr; use clippy_utils::source::{indent_of, snippet}; use rustc_errors::{Applicability, Diagnostic}; use rustc_hir::intravisit::{walk_expr, Visitor}; -use rustc_hir::{Expr, ExprKind, MatchSource}; +use rustc_hir::{Arm, Expr, ExprKind, MatchSource}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{Ty, TypeAndMut}; @@ -16,12 +16,21 @@ pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, scrutinee: &'tcx Expr<'_>, + arms: &'tcx [Arm<'_>], source: MatchSource, ) { if let Some((suggestions, message)) = has_significant_drop_in_scrutinee(cx, scrutinee, source) { for found in suggestions { span_lint_and_then(cx, SIGNIFICANT_DROP_IN_SCRUTINEE, found.found_span, message, |diag| { set_diagnostic(diag, cx, expr, found); + let s = Span::new(expr.span.hi(), expr.span.hi(), expr.span.ctxt(), None); + diag.span_label(s, "original temporary lives until here"); + if let Some(spans) = has_significant_drop_in_arms(cx, arms) { + for span in spans { + diag.span_label(span, "significant drop in arm here"); + } + diag.note("this might lead to deadlocks or other unexpected behavior"); + } }); } } @@ -80,22 +89,77 @@ fn has_significant_drop_in_scrutinee<'tcx, 'a>( let mut helper = SigDropHelper::new(cx); helper.find_sig_drop(scrutinee).map(|drops| { let message = if source == MatchSource::Normal { - "temporary with significant drop in match scrutinee" + "temporary with drop impl with side effects in match scrutinee lives to end of block" } else { - "temporary with significant drop in for loop" + "temporary with drop impl with side effects in for loop condition lives to end of block" }; (drops, message) }) } +struct SigDropChecker<'a, 'tcx> { + seen_types: FxHashSet>, + cx: &'a LateContext<'tcx>, +} + +impl<'a, 'tcx> SigDropChecker<'a, 'tcx> { + fn new(cx: &'a LateContext<'tcx>) -> SigDropChecker<'a, 'tcx> { + SigDropChecker { + seen_types: FxHashSet::default(), + cx, + } + } + + fn get_type(&self, ex: &'tcx Expr<'_>) -> Ty<'tcx> { + self.cx.typeck_results().expr_ty(ex) + } + + fn has_seen_type(&mut self, ty: Ty<'tcx>) -> bool { + !self.seen_types.insert(ty) + } + + fn has_sig_drop_attr(&mut self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { + if let Some(adt) = ty.ty_adt_def() { + if get_attr(cx.sess(), cx.tcx.get_attrs_unchecked(adt.did()), "has_significant_drop").count() > 0 { + return true; + } + } + + match ty.kind() { + rustc_middle::ty::Adt(a, b) => { + for f in a.all_fields() { + let ty = f.ty(cx.tcx, b); + if !self.has_seen_type(ty) && self.has_sig_drop_attr(cx, ty) { + return true; + } + } + + for generic_arg in b.iter() { + if let GenericArgKind::Type(ty) = generic_arg.unpack() { + if self.has_sig_drop_attr(cx, ty) { + return true; + } + } + } + false + }, + rustc_middle::ty::Array(ty, _) + | rustc_middle::ty::RawPtr(TypeAndMut { ty, .. }) + | rustc_middle::ty::Ref(_, ty, _) + | rustc_middle::ty::Slice(ty) => self.has_sig_drop_attr(cx, *ty), + _ => false, + } + } +} + struct SigDropHelper<'a, 'tcx> { cx: &'a LateContext<'tcx>, is_chain_end: bool, - seen_types: FxHashSet>, has_significant_drop: bool, current_sig_drop: Option, sig_drop_spans: Option>, special_handling_for_binary_op: bool, + sig_drop_checker: SigDropChecker<'a, 'tcx>, } #[expect(clippy::enum_variant_names)] @@ -118,11 +182,11 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> { SigDropHelper { cx, is_chain_end: true, - seen_types: FxHashSet::default(), has_significant_drop: false, current_sig_drop: None, sig_drop_spans: None, special_handling_for_binary_op: false, + sig_drop_checker: SigDropChecker::new(cx), } } @@ -163,7 +227,7 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> { if self.current_sig_drop.is_some() { return; } - let ty = self.get_type(expr); + let ty = self.sig_drop_checker.get_type(expr); if ty.is_ref() { // We checked that the type was ref, so builtin_deref will return Some TypeAndMut, // but let's avoid any chance of an ICE @@ -187,14 +251,6 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> { } } - fn get_type(&self, ex: &'tcx Expr<'_>) -> Ty<'tcx> { - self.cx.typeck_results().expr_ty(ex) - } - - fn has_seen_type(&mut self, ty: Ty<'tcx>) -> bool { - !self.seen_types.insert(ty) - } - fn visit_exprs_for_binary_ops( &mut self, left: &'tcx Expr<'_>, @@ -214,44 +270,15 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> { self.special_handling_for_binary_op = false; } - - fn has_sig_drop_attr(&mut self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - if let Some(adt) = ty.ty_adt_def() { - if get_attr(cx.sess(), cx.tcx.get_attrs_unchecked(adt.did()), "has_significant_drop").count() > 0 { - return true; - } - } - - match ty.kind() { - rustc_middle::ty::Adt(a, b) => { - for f in a.all_fields() { - let ty = f.ty(cx.tcx, b); - if !self.has_seen_type(ty) && self.has_sig_drop_attr(cx, ty) { - return true; - } - } - - for generic_arg in b.iter() { - if let GenericArgKind::Type(ty) = generic_arg.unpack() { - if self.has_sig_drop_attr(cx, ty) { - return true; - } - } - } - false - }, - rustc_middle::ty::Array(ty, _) - | rustc_middle::ty::RawPtr(TypeAndMut { ty, .. }) - | rustc_middle::ty::Ref(_, ty, _) - | rustc_middle::ty::Slice(ty) => self.has_sig_drop_attr(cx, *ty), - _ => false, - } - } } impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> { fn visit_expr(&mut self, ex: &'tcx Expr<'_>) { - if !self.is_chain_end && self.has_sig_drop_attr(self.cx, self.get_type(ex)) { + if !self.is_chain_end + && self + .sig_drop_checker + .has_sig_drop_attr(self.cx, self.sig_drop_checker.get_type(ex)) + { self.has_significant_drop = true; return; } @@ -330,3 +357,40 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> { } } } + +struct ArmSigDropHelper<'a, 'tcx> { + sig_drop_checker: SigDropChecker<'a, 'tcx>, + found_sig_drop_spans: Option>, +} + +impl<'a, 'tcx> ArmSigDropHelper<'a, 'tcx> { + fn new(cx: &'a LateContext<'tcx>) -> ArmSigDropHelper<'a, 'tcx> { + ArmSigDropHelper { + sig_drop_checker: SigDropChecker::new(cx), + found_sig_drop_spans: None, + } + } +} + +fn has_significant_drop_in_arms<'tcx, 'a>(cx: &'a LateContext<'tcx>, arms: &'tcx [Arm<'_>]) -> Option> { + let mut helper = ArmSigDropHelper::new(cx); + for arm in arms { + helper.visit_expr(arm.body); + } + helper.found_sig_drop_spans +} + +impl<'a, 'tcx> Visitor<'tcx> for ArmSigDropHelper<'a, 'tcx> { + fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) { + if self + .sig_drop_checker + .has_sig_drop_attr(self.sig_drop_checker.cx, self.sig_drop_checker.get_type(ex)) + { + self.found_sig_drop_spans + .get_or_insert_with(FxHashSet::default) + .insert(ex.span); + return; + } + walk_expr(self, ex); + } +} diff --git a/tests/ui/significant_drop_in_scrutinee.rs b/tests/ui/significant_drop_in_scrutinee.rs index 4347610f393..dd64f240c4a 100644 --- a/tests/ui/significant_drop_in_scrutinee.rs +++ b/tests/ui/significant_drop_in_scrutinee.rs @@ -591,4 +591,20 @@ fn should_trigger_lint_for_read_write_lock_for_loop() { } } +fn do_bar(mutex: &Mutex) { + mutex.lock().unwrap().bar(); +} + +fn should_trigger_lint_without_significant_drop_in_arm() { + let mutex = Mutex::new(State {}); + + // Should trigger lint because the lifetime of the temporary MutexGuard is surprising because it + // is preserved until the end of the match, but there is no clear indication that this is the + // case. + match mutex.lock().unwrap().foo() { + true => do_bar(&mutex), + false => {}, + }; +} + fn main() {} diff --git a/tests/ui/significant_drop_in_scrutinee.stderr b/tests/ui/significant_drop_in_scrutinee.stderr index 303f3c1df03..472f998ebf2 100644 --- a/tests/ui/significant_drop_in_scrutinee.stderr +++ b/tests/ui/significant_drop_in_scrutinee.stderr @@ -1,45 +1,69 @@ -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:59:11 | LL | match mutex.lock().unwrap().foo() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | true => { +LL | mutex.lock().unwrap().bar(); + | --------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here | = note: `-D clippy::significant-drop-in-scrutinee` implied by `-D warnings` + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = mutex.lock().unwrap().foo(); LL ~ match value { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:132:11 | LL | match s.lock_m().get_the_value() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | println!("{}", s.lock_m().get_the_value()); + | ---------- significant drop in arm here +... +LL | } + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = s.lock_m().get_the_value(); LL ~ match value { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:153:11 | LL | match s.lock_m_m().get_the_value() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | println!("{}", s.lock_m().get_the_value()); + | ---------- significant drop in arm here +... +LL | } + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = s.lock_m_m().get_the_value(); LL ~ match value { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:201:11 | LL | match counter.temp_increment().len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | }; + | - original temporary lives until here | help: try moving the temporary above the match | @@ -47,127 +71,218 @@ LL ~ let value = counter.temp_increment().len(); LL ~ match value { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:224:16 | LL | match (mutex1.lock().unwrap().s.len(), true) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | mutex1.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = mutex1.lock().unwrap().s.len(); LL ~ match (value, true) { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:233:22 | LL | match (true, mutex1.lock().unwrap().s.len(), true) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | mutex1.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = mutex1.lock().unwrap().s.len(); LL ~ match (true, value, true) { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:243:16 | LL | match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | mutex1.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +LL | mutex2.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = mutex1.lock().unwrap().s.len(); LL ~ match (value, true, mutex2.lock().unwrap().s.len()) { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:243:54 | LL | match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | mutex1.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +LL | mutex2.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = mutex2.lock().unwrap().s.len(); LL ~ match (mutex1.lock().unwrap().s.len(), true, value) { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:254:15 | LL | match mutex3.lock().unwrap().s.as_str() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | mutex1.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +LL | mutex2.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here + | + = note: this might lead to deadlocks or other unexpected behavior -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:264:22 | LL | match (true, mutex3.lock().unwrap().s.as_str()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | mutex1.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +LL | mutex2.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here + | + = note: this might lead to deadlocks or other unexpected behavior -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:283:11 | LL | match mutex.lock().unwrap().s.len() > 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | true => { +LL | mutex.lock().unwrap().s.len(); + | --------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = mutex.lock().unwrap().s.len() > 1; LL ~ match value { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:290:11 | LL | match 1 < mutex.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | true => { +LL | mutex.lock().unwrap().s.len(); + | --------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = 1 < mutex.lock().unwrap().s.len(); LL ~ match value { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:308:11 | LL | match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | mutex1.lock().unwrap().s.len(), + | ---------------------- significant drop in arm here +LL | mutex2.lock().unwrap().s.len() + | ---------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len(); LL ~ match value { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:319:11 | LL | match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | mutex1.lock().unwrap().s.len(), + | ---------------------- significant drop in arm here +LL | mutex2.lock().unwrap().s.len() + | ---------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len(); LL ~ match value { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:354:11 | LL | match get_mutex_guard().s.len() > 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | true => { +LL | mutex1.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = get_mutex_guard().s.len() > 1; LL ~ match value { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:371:11 | LL | match match i { @@ -179,7 +294,14 @@ LL | | .s LL | | .len() LL | | > 1 | |___________^ +... +LL | mutex1.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = match i { @@ -190,7 +312,7 @@ LL + .s LL + .len() ... -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:397:11 | LL | match if i > 1 { @@ -202,7 +324,14 @@ LL | | mutex2.lock().unwrap() LL | | .len() LL | | > 1 | |___________^ +... +LL | mutex1.lock().unwrap().s.len(); + | ---------------------- significant drop in arm here +... +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ let value = if i > 1 { @@ -213,83 +342,145 @@ LL + } LL + .s ... -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:451:11 | LL | match s.lock().deref().deref() { | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | 0 | 1 => println!("Value was less than 2"), +LL | _ => println!("Value is {}", s.lock().deref()), + | ---------------- significant drop in arm here +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match and create a copy | LL ~ let value = *s.lock().deref().deref(); LL ~ match value { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:479:11 | LL | match s.lock().deref().deref() { | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | matcher => println!("Value is {}", s.lock().deref()), + | ---------------- significant drop in arm here +LL | _ => println!("Value was not a match"), +LL | }; + | - original temporary lives until here + | + = note: this might lead to deadlocks or other unexpected behavior -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:498:11 | LL | match mutex.lock().unwrap().i = i { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | _ => { +LL | println!("{}", mutex.lock().unwrap().i); + | --------------------- significant drop in arm here +LL | }, +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ mutex.lock().unwrap().i = i; LL ~ match () { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:504:11 | LL | match i = mutex.lock().unwrap().i { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | _ => { +LL | println!("{}", mutex.lock().unwrap().i); + | --------------------- significant drop in arm here +LL | }, +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ i = mutex.lock().unwrap().i; LL ~ match () { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:510:11 | LL | match mutex.lock().unwrap().i += 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | _ => { +LL | println!("{}", mutex.lock().unwrap().i); + | --------------------- significant drop in arm here +LL | }, +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ mutex.lock().unwrap().i += 1; LL ~ match () { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:516:11 | LL | match i += mutex.lock().unwrap().i { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | _ => { +LL | println!("{}", mutex.lock().unwrap().i); + | --------------------- significant drop in arm here +LL | }, +LL | }; + | - original temporary lives until here | + = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | LL ~ i += mutex.lock().unwrap().i; LL ~ match () { | -error: temporary with significant drop in match scrutinee +error: temporary with drop impl with side effects in match scrutinee lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:579:11 | LL | match rwlock.read().unwrap().to_number() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | }; + | - original temporary lives until here -error: temporary with significant drop in for loop +error: temporary with drop impl with side effects in for loop condition lives to end of block --> $DIR/significant_drop_in_scrutinee.rs:589:14 | LL | for s in rwlock.read().unwrap().iter() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | println!("{}", s); +LL | } + | - original temporary lives until here -error: aborting due to 25 previous errors +error: temporary with drop impl with side effects in match scrutinee lives to end of block + --> $DIR/significant_drop_in_scrutinee.rs:604:11 + | +LL | match mutex.lock().unwrap().foo() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | }; + | - original temporary lives until here + | +help: try moving the temporary above the match + | +LL ~ let value = mutex.lock().unwrap().foo(); +LL ~ match value { + | + +error: aborting due to 26 previous errors