@@ -2,17 +2,16 @@ use super::REDUNDANT_PATTERN_MATCHING;
2
2
use clippy_utils:: diagnostics:: span_lint_and_then;
3
3
use clippy_utils:: source:: snippet;
4
4
use clippy_utils:: sugg:: Sugg ;
5
- use clippy_utils:: ty:: { implements_trait , is_type_diagnostic_item , is_type_lang_item , match_type } ;
5
+ use clippy_utils:: ty:: needs_ordered_drop ;
6
6
use clippy_utils:: { higher, match_def_path} ;
7
7
use clippy_utils:: { is_lang_ctor, is_trait_method, paths} ;
8
8
use if_chain:: if_chain;
9
9
use rustc_ast:: ast:: LitKind ;
10
- use rustc_data_structures:: fx:: FxHashSet ;
11
10
use rustc_errors:: Applicability ;
12
11
use rustc_hir:: LangItem :: { OptionNone , PollPending } ;
13
12
use rustc_hir:: {
14
13
intravisit:: { walk_expr, Visitor } ,
15
- Arm , Block , Expr , ExprKind , LangItem , Node , Pat , PatKind , QPath , UnOp ,
14
+ Arm , Block , Expr , ExprKind , Node , Pat , PatKind , QPath , UnOp ,
16
15
} ;
17
16
use rustc_lint:: LateContext ;
18
17
use rustc_middle:: ty:: { self , subst:: GenericArgKind , DefIdTree , Ty } ;
@@ -32,59 +31,6 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
32
31
}
33
32
}
34
33
35
- /// Checks if the drop order for a type matters. Some std types implement drop solely to
36
- /// deallocate memory. For these types, and composites containing them, changing the drop order
37
- /// won't result in any observable side effects.
38
- fn type_needs_ordered_drop < ' tcx > ( cx : & LateContext < ' tcx > , ty : Ty < ' tcx > ) -> bool {
39
- type_needs_ordered_drop_inner ( cx, ty, & mut FxHashSet :: default ( ) )
40
- }
41
-
42
- fn type_needs_ordered_drop_inner < ' tcx > ( cx : & LateContext < ' tcx > , ty : Ty < ' tcx > , seen : & mut FxHashSet < Ty < ' tcx > > ) -> bool {
43
- if !seen. insert ( ty) {
44
- return false ;
45
- }
46
- if !ty. needs_drop ( cx. tcx , cx. param_env ) {
47
- false
48
- } else if !cx
49
- . tcx
50
- . lang_items ( )
51
- . drop_trait ( )
52
- . map_or ( false , |id| implements_trait ( cx, ty, id, & [ ] ) )
53
- {
54
- // This type doesn't implement drop, so no side effects here.
55
- // Check if any component type has any.
56
- match ty. kind ( ) {
57
- ty:: Tuple ( fields) => fields. iter ( ) . any ( |ty| type_needs_ordered_drop_inner ( cx, ty, seen) ) ,
58
- ty:: Array ( ty, _) => type_needs_ordered_drop_inner ( cx, * ty, seen) ,
59
- ty:: Adt ( adt, subs) => adt
60
- . all_fields ( )
61
- . map ( |f| f. ty ( cx. tcx , subs) )
62
- . any ( |ty| type_needs_ordered_drop_inner ( cx, ty, seen) ) ,
63
- _ => true ,
64
- }
65
- }
66
- // Check for std types which implement drop, but only for memory allocation.
67
- else if is_type_diagnostic_item ( cx, ty, sym:: Vec )
68
- || is_type_lang_item ( cx, ty, LangItem :: OwnedBox )
69
- || is_type_diagnostic_item ( cx, ty, sym:: Rc )
70
- || is_type_diagnostic_item ( cx, ty, sym:: Arc )
71
- || is_type_diagnostic_item ( cx, ty, sym:: cstring_type)
72
- || is_type_diagnostic_item ( cx, ty, sym:: BTreeMap )
73
- || is_type_diagnostic_item ( cx, ty, sym:: LinkedList )
74
- || match_type ( cx, ty, & paths:: WEAK_RC )
75
- || match_type ( cx, ty, & paths:: WEAK_ARC )
76
- {
77
- // Check all of the generic arguments.
78
- if let ty:: Adt ( _, subs) = ty. kind ( ) {
79
- subs. types ( ) . any ( |ty| type_needs_ordered_drop_inner ( cx, ty, seen) )
80
- } else {
81
- true
82
- }
83
- } else {
84
- true
85
- }
86
- }
87
-
88
34
// Extract the generic arguments out of a type
89
35
fn try_get_generic_ty ( ty : Ty < ' _ > , index : usize ) -> Option < Ty < ' _ > > {
90
36
if_chain ! {
@@ -115,7 +61,7 @@ fn temporaries_need_ordered_drop<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<
115
61
// e.g. In `(String::new(), 0).1` the string is a temporary value.
116
62
ExprKind :: AddrOf ( _, _, expr) | ExprKind :: Field ( expr, _) => {
117
63
if !matches ! ( expr. kind, ExprKind :: Path ( _) ) {
118
- if type_needs_ordered_drop ( self . cx , self . cx . typeck_results ( ) . expr_ty ( expr) ) {
64
+ if needs_ordered_drop ( self . cx , self . cx . typeck_results ( ) . expr_ty ( expr) ) {
119
65
self . res = true ;
120
66
} else {
121
67
self . visit_expr ( expr) ;
@@ -126,7 +72,7 @@ fn temporaries_need_ordered_drop<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<
126
72
// e.g. In `(vec![0])[0]` the vector is a temporary value.
127
73
ExprKind :: Index ( base, index) => {
128
74
if !matches ! ( base. kind, ExprKind :: Path ( _) ) {
129
- if type_needs_ordered_drop ( self . cx , self . cx . typeck_results ( ) . expr_ty ( base) ) {
75
+ if needs_ordered_drop ( self . cx , self . cx . typeck_results ( ) . expr_ty ( base) ) {
130
76
self . res = true ;
131
77
} else {
132
78
self . visit_expr ( base) ;
@@ -143,7 +89,7 @@ fn temporaries_need_ordered_drop<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<
143
89
. typeck_results ( )
144
90
. type_dependent_def_id ( expr. hir_id )
145
91
. map_or ( false , |id| self . cx . tcx . fn_sig ( id) . skip_binder ( ) . inputs ( ) [ 0 ] . is_ref ( ) ) ;
146
- if self_by_ref && type_needs_ordered_drop ( self . cx , self . cx . typeck_results ( ) . expr_ty ( self_arg) ) {
92
+ if self_by_ref && needs_ordered_drop ( self . cx , self . cx . typeck_results ( ) . expr_ty ( self_arg) ) {
147
93
self . res = true ;
148
94
} else {
149
95
self . visit_expr ( self_arg) ;
@@ -243,7 +189,7 @@ fn find_sugg_for_if_let<'tcx>(
243
189
// scrutinee would be, so they have to be considered as well.
244
190
// e.g. in `if let Some(x) = foo.lock().unwrap().baz.as_ref() { .. }` the lock will be held
245
191
// for the duration if body.
246
- let needs_drop = type_needs_ordered_drop ( cx, check_ty) || temporaries_need_ordered_drop ( cx, let_expr) ;
192
+ let needs_drop = needs_ordered_drop ( cx, check_ty) || temporaries_need_ordered_drop ( cx, let_expr) ;
247
193
248
194
// check that `while_let_on_iterator` lint does not trigger
249
195
if_chain ! {
0 commit comments