Skip to content

Commit d1b5fa2

Browse files
authored
fix: correct suggestion for significant_drop_in_scrutinee in expressions (rust-lang#14019)
This PR fixes an issue with the `significant_drop_in_scrutinee`, where the lint generates invalid Rust syntax when suggesting fixes for match expressions that are part of larger expressions, such as in assignment contexts. For example: ```rust let mutex = Mutex::new(State {}); let _ = match mutex.lock().unwrap().foo() { true => 0, false => 1, }; ``` would suggest: ```rust let _ = let value = mutex.lock().unwrap().foo(); match value { ``` With this PR, it now suggests: ```rust let value = mutex.lock().unwrap().foo(); let _ = match value { ``` closes: rust-lang#13986 changelog: [`significant_drop_in_scrutinee`] Fix incorrect suggestion for `significant_drop_in_scrutinee` lint in expression context
2 parents 8f1b4bb + 23e602c commit d1b5fa2

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

clippy_lints/src/matches/significant_drop_in_scrutinee.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::ops::ControlFlow;
22

33
use crate::FxHashSet;
44
use clippy_utils::diagnostics::span_lint_and_then;
5-
use clippy_utils::source::{indent_of, snippet};
5+
use clippy_utils::source::{first_line_of_span, indent_of, snippet};
66
use clippy_utils::ty::{for_each_top_level_late_bound_region, is_copy};
77
use clippy_utils::{get_attr, is_lint_allowed};
88
use itertools::Itertools;
@@ -152,7 +152,7 @@ fn set_suggestion<'tcx>(diag: &mut Diag<'_, ()>, cx: &LateContext<'tcx>, expr: &
152152
diag.multipart_suggestion(
153153
suggestion_message,
154154
vec![
155-
(expr.span.shrink_to_lo(), replacement),
155+
(first_line_of_span(cx, expr.span).shrink_to_lo(), replacement),
156156
(found.found_span, scrutinee_replacement),
157157
],
158158
Applicability::MaybeIncorrect,

tests/ui/significant_drop_in_scrutinee.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,4 +850,18 @@ async fn should_not_trigger_lint_in_async_expansion(mutex: Mutex<i32>) -> i32 {
850850
}
851851
}
852852

853+
fn should_trigger_lint_in_match_expr() {
854+
let mutex = Mutex::new(State {});
855+
856+
// Should trigger lint because the lifetime of the temporary MutexGuard is surprising because it
857+
// is preserved until the end of the match, but there is no clear indication that this is the
858+
// case.
859+
let _ = match mutex.lock().unwrap().foo() {
860+
//~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
861+
//~| NOTE: this might lead to deadlocks or other unexpected behavior
862+
true => 0,
863+
false => 1,
864+
};
865+
}
866+
853867
fn main() {}

tests/ui/significant_drop_in_scrutinee.stderr

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,5 +584,21 @@ LL ~ let value = *foo_async(&mutex).await.unwrap();
584584
LL ~ match value {
585585
|
586586

587-
error: aborting due to 30 previous errors
587+
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
588+
--> tests/ui/significant_drop_in_scrutinee.rs:859:19
589+
|
590+
LL | let _ = match mutex.lock().unwrap().foo() {
591+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
592+
...
593+
LL | };
594+
| - temporary lives until here
595+
|
596+
= note: this might lead to deadlocks or other unexpected behavior
597+
help: try moving the temporary above the match
598+
|
599+
LL ~ let value = mutex.lock().unwrap().foo();
600+
LL ~ let _ = match value {
601+
|
602+
603+
error: aborting due to 31 previous errors
588604

0 commit comments

Comments
 (0)