@@ -2,17 +2,16 @@ use super::REDUNDANT_PATTERN_MATCHING;
22use clippy_utils:: diagnostics:: span_lint_and_then;
33use clippy_utils:: source:: snippet;
44use 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 ;
66use clippy_utils:: { higher, match_def_path} ;
77use clippy_utils:: { is_lang_ctor, is_trait_method, paths} ;
88use if_chain:: if_chain;
99use rustc_ast:: ast:: LitKind ;
10- use rustc_data_structures:: fx:: FxHashSet ;
1110use rustc_errors:: Applicability ;
1211use rustc_hir:: LangItem :: { OptionNone , PollPending } ;
1312use rustc_hir:: {
1413 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 ,
1615} ;
1716use rustc_lint:: LateContext ;
1817use rustc_middle:: ty:: { self , subst:: GenericArgKind , DefIdTree , Ty } ;
@@ -32,59 +31,6 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
3231 }
3332}
3433
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-
8834// Extract the generic arguments out of a type
8935fn try_get_generic_ty ( ty : Ty < ' _ > , index : usize ) -> Option < Ty < ' _ > > {
9036 if_chain ! {
@@ -115,7 +61,7 @@ fn temporaries_need_ordered_drop<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<
11561 // e.g. In `(String::new(), 0).1` the string is a temporary value.
11662 ExprKind :: AddrOf ( _, _, expr) | ExprKind :: Field ( expr, _) => {
11763 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) ) {
11965 self . res = true ;
12066 } else {
12167 self . visit_expr ( expr) ;
@@ -126,7 +72,7 @@ fn temporaries_need_ordered_drop<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<
12672 // e.g. In `(vec![0])[0]` the vector is a temporary value.
12773 ExprKind :: Index ( base, index) => {
12874 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) ) {
13076 self . res = true ;
13177 } else {
13278 self . visit_expr ( base) ;
@@ -143,7 +89,7 @@ fn temporaries_need_ordered_drop<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<
14389 . typeck_results ( )
14490 . type_dependent_def_id ( expr. hir_id )
14591 . 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) ) {
14793 self . res = true ;
14894 } else {
14995 self . visit_expr ( self_arg) ;
@@ -243,7 +189,7 @@ fn find_sugg_for_if_let<'tcx>(
243189 // scrutinee would be, so they have to be considered as well.
244190 // e.g. in `if let Some(x) = foo.lock().unwrap().baz.as_ref() { .. }` the lock will be held
245191 // 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) ;
247193
248194 // check that `while_let_on_iterator` lint does not trigger
249195 if_chain ! {
0 commit comments