@@ -16,7 +16,7 @@ use rustc_span::Span;
16
16
17
17
use super :: SIGNIFICANT_DROP_IN_SCRUTINEE ;
18
18
19
- pub ( super ) fn check < ' tcx > (
19
+ pub ( super ) fn check_match < ' tcx > (
20
20
cx : & LateContext < ' tcx > ,
21
21
expr : & ' tcx Expr < ' tcx > ,
22
22
scrutinee : & ' tcx Expr < ' _ > ,
@@ -27,7 +27,72 @@ pub(super) fn check<'tcx>(
27
27
return ;
28
28
}
29
29
30
- let ( suggestions, message) = has_significant_drop_in_scrutinee ( cx, scrutinee, source) ;
30
+ let scrutinee = match ( source, & scrutinee. kind ) {
31
+ ( MatchSource :: ForLoopDesugar , ExprKind :: Call ( _, [ e] ) ) => e,
32
+ _ => scrutinee,
33
+ } ;
34
+
35
+ let message = if source == MatchSource :: Normal {
36
+ "temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression"
37
+ } else {
38
+ "temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression"
39
+ } ;
40
+
41
+ let arms = arms. iter ( ) . map ( |arm| arm. body ) . collect :: < Vec < _ > > ( ) ;
42
+
43
+ check ( cx, expr, scrutinee, & arms, message) ;
44
+ }
45
+
46
+ pub ( super ) fn check_if_let < ' tcx > (
47
+ cx : & LateContext < ' tcx > ,
48
+ expr : & ' tcx Expr < ' tcx > ,
49
+ scrutinee : & ' tcx Expr < ' _ > ,
50
+ if_then : & ' tcx Expr < ' _ > ,
51
+ if_else : Option < & ' tcx Expr < ' _ > > ,
52
+ ) {
53
+ if is_lint_allowed ( cx, SIGNIFICANT_DROP_IN_SCRUTINEE , expr. hir_id ) {
54
+ return ;
55
+ }
56
+
57
+ let message =
58
+ "temporary with significant `Drop` in `if let` scrutinee will live until the end of the `if let` expression" ;
59
+
60
+ if let Some ( if_else) = if_else {
61
+ check ( cx, expr, scrutinee, & [ if_then, if_else] , message) ;
62
+ } else {
63
+ check ( cx, expr, scrutinee, & [ if_then] , message) ;
64
+ }
65
+ }
66
+
67
+ pub ( super ) fn check_while_let < ' tcx > (
68
+ cx : & LateContext < ' tcx > ,
69
+ expr : & ' tcx Expr < ' tcx > ,
70
+ scrutinee : & ' tcx Expr < ' _ > ,
71
+ body : & ' tcx Expr < ' _ > ,
72
+ ) {
73
+ if is_lint_allowed ( cx, SIGNIFICANT_DROP_IN_SCRUTINEE , expr. hir_id ) {
74
+ return ;
75
+ }
76
+
77
+ check (
78
+ cx,
79
+ expr,
80
+ scrutinee,
81
+ & [ body] ,
82
+ "temporary with significant `Drop` in `while let` scrutinee will live until the end of the `while let` expression" ,
83
+ ) ;
84
+ }
85
+
86
+ fn check < ' tcx > (
87
+ cx : & LateContext < ' tcx > ,
88
+ expr : & ' tcx Expr < ' tcx > ,
89
+ scrutinee : & ' tcx Expr < ' _ > ,
90
+ arms : & [ & ' tcx Expr < ' _ > ] ,
91
+ message : & ' static str ,
92
+ ) {
93
+ let mut helper = SigDropHelper :: new ( cx) ;
94
+ let suggestions = helper. find_sig_drop ( scrutinee) ;
95
+
31
96
for found in suggestions {
32
97
span_lint_and_then ( cx, SIGNIFICANT_DROP_IN_SCRUTINEE , found. found_span , message, |diag| {
33
98
set_diagnostic ( diag, cx, expr, found) ;
@@ -81,26 +146,6 @@ fn set_diagnostic<'tcx>(diag: &mut Diag<'_, ()>, cx: &LateContext<'tcx>, expr: &
81
146
) ;
82
147
}
83
148
84
- /// If the expression is an `ExprKind::Match`, check if the scrutinee has a significant drop that
85
- /// may have a surprising lifetime.
86
- fn has_significant_drop_in_scrutinee < ' tcx > (
87
- cx : & LateContext < ' tcx > ,
88
- scrutinee : & ' tcx Expr < ' tcx > ,
89
- source : MatchSource ,
90
- ) -> ( Vec < FoundSigDrop > , & ' static str ) {
91
- let mut helper = SigDropHelper :: new ( cx) ;
92
- let scrutinee = match ( source, & scrutinee. kind ) {
93
- ( MatchSource :: ForLoopDesugar , ExprKind :: Call ( _, [ e] ) ) => e,
94
- _ => scrutinee,
95
- } ;
96
- let message = if source == MatchSource :: Normal {
97
- "temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression"
98
- } else {
99
- "temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression"
100
- } ;
101
- ( helper. find_sig_drop ( scrutinee) , message)
102
- }
103
-
104
149
struct SigDropChecker < ' a , ' tcx > {
105
150
seen_types : FxHashSet < Ty < ' tcx > > ,
106
151
cx : & ' a LateContext < ' tcx > ,
@@ -430,10 +475,10 @@ impl<'a, 'tcx> ArmSigDropHelper<'a, 'tcx> {
430
475
}
431
476
}
432
477
433
- fn has_significant_drop_in_arms < ' tcx > ( cx : & LateContext < ' tcx > , arms : & ' tcx [ Arm < ' _ > ] ) -> FxHashSet < Span > {
478
+ fn has_significant_drop_in_arms < ' tcx > ( cx : & LateContext < ' tcx > , arms : & [ & ' tcx Expr < ' _ > ] ) -> FxHashSet < Span > {
434
479
let mut helper = ArmSigDropHelper :: new ( cx) ;
435
480
for arm in arms {
436
- helper. visit_expr ( arm. body ) ;
481
+ helper. visit_expr ( arm) ;
437
482
}
438
483
helper. found_sig_drop_spans
439
484
}
0 commit comments