11use clippy_utils:: diagnostics:: span_lint;
2- use clippy_utils:: ty:: is_type_diagnostic_item;
2+ use clippy_utils:: ty:: { is_type_diagnostic_item, is_type_lang_item } ;
33use clippy_utils:: visitors:: for_each_expr_with_closures;
44use clippy_utils:: { get_enclosing_block, get_parent_node, path_to_local_id} ;
55use core:: ops:: ControlFlow ;
6- use rustc_hir:: { Block , ExprKind , HirId , Local , Node , PatKind } ;
6+ use rustc_hir:: { Block , ExprKind , HirId , LangItem , Local , Node , PatKind } ;
77use rustc_lint:: { LateContext , LateLintPass } ;
88use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
99use rustc_span:: symbol:: sym;
@@ -44,24 +44,23 @@ declare_clippy_lint! {
4444}
4545declare_lint_pass ! ( CollectionIsNeverRead => [ COLLECTION_IS_NEVER_READ ] ) ;
4646
47- static COLLECTIONS : [ Symbol ; 10 ] = [
47+ // Add `String` here when it is added to diagnostic items
48+ static COLLECTIONS : [ Symbol ; 9 ] = [
4849 sym:: BTreeMap ,
4950 sym:: BTreeSet ,
5051 sym:: BinaryHeap ,
5152 sym:: HashMap ,
5253 sym:: HashSet ,
5354 sym:: LinkedList ,
5455 sym:: Option ,
55- sym:: String ,
5656 sym:: Vec ,
5757 sym:: VecDeque ,
5858] ;
5959
6060impl < ' tcx > LateLintPass < ' tcx > for CollectionIsNeverRead {
6161 fn check_local ( & mut self , cx : & LateContext < ' tcx > , local : & ' tcx Local < ' tcx > ) {
6262 // Look for local variables whose type is a container. Search surrounding bock for read access.
63- let ty = cx. typeck_results ( ) . pat_ty ( local. pat ) ;
64- if COLLECTIONS . iter ( ) . any ( |& sym| is_type_diagnostic_item ( cx, ty, sym) )
63+ if match_acceptable_type ( cx, local, & COLLECTIONS )
6564 && let PatKind :: Binding ( _, local_id, _, _) = local. pat . kind
6665 && let Some ( enclosing_block) = get_enclosing_block ( cx, local. hir_id )
6766 && has_no_read_access ( cx, local_id, enclosing_block)
@@ -71,6 +70,13 @@ impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead {
7170 }
7271}
7372
73+ fn match_acceptable_type ( cx : & LateContext < ' _ > , local : & Local < ' _ > , collections : & [ rustc_span:: Symbol ] ) -> bool {
74+ let ty = cx. typeck_results ( ) . pat_ty ( local. pat ) ;
75+ collections. iter ( ) . any ( |& sym| is_type_diagnostic_item ( cx, ty, sym) )
76+ // String type is a lang item but not a diagnostic item for now so we need a separate check
77+ || is_type_lang_item ( cx, ty, LangItem :: String )
78+ }
79+
7480fn has_no_read_access < ' tcx > ( cx : & LateContext < ' tcx > , id : HirId , block : & ' tcx Block < ' tcx > ) -> bool {
7581 let mut has_access = false ;
7682 let mut has_read_access = false ;
0 commit comments