11use clippy_utils:: diagnostics:: { span_lint, span_lint_and_help, span_lint_and_sugg} ;
22use clippy_utils:: source:: { snippet, snippet_with_applicability} ;
3- use clippy_utils:: ty:: { get_associated_type , implements_trait , is_type_diagnostic_item} ;
3+ use clippy_utils:: ty:: is_type_diagnostic_item;
44use clippy_utils:: { get_parent_expr, is_lint_allowed, match_function_call, method_calls, paths} ;
55use clippy_utils:: { peel_blocks, SpanlessEq } ;
66use if_chain:: if_chain;
77use rustc_errors:: Applicability ;
8+ use rustc_hir:: def_id:: DefId ;
89use rustc_hir:: { BinOpKind , BorrowKind , Expr , ExprKind , LangItem , QPath } ;
910use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
1011use rustc_middle:: lint:: in_external_macro;
11- use rustc_middle:: ty:: { self , Ty } ;
12+ use rustc_middle:: ty;
1213use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
1314use rustc_span:: source_map:: Spanned ;
1415use rustc_span:: sym;
@@ -476,13 +477,16 @@ declare_lint_pass!(TrimSplitWhitespace => [TRIM_SPLIT_WHITESPACE]);
476477
477478impl < ' tcx > LateLintPass < ' tcx > for TrimSplitWhitespace {
478479 fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & Expr < ' _ > ) {
480+ let tyckres = cx. typeck_results ( ) ;
479481 if_chain ! {
480- if let ExprKind :: MethodCall ( path, [ recv ] , split_ws_span) = expr. kind;
482+ if let ExprKind :: MethodCall ( path, [ split_recv ] , split_ws_span) = expr. kind;
481483 if path. ident. name == sym!( split_whitespace) ;
482- if let ExprKind :: MethodCall ( path, [ recv] , trim_span) = recv. kind;
484+ if let Some ( split_ws_def_id) = tyckres. type_dependent_def_id( expr. hir_id) ;
485+ if cx. tcx. is_diagnostic_item( sym:: str_split_whitespace, split_ws_def_id) ;
486+ if let ExprKind :: MethodCall ( path, [ _trim_recv] , trim_span) = split_recv. kind;
483487 if let trim_fn_name @ ( "trim" | "trim_start" | "trim_end" ) = path. ident. name. as_str( ) ;
484- let recv_ty = cx . typeck_results ( ) . expr_ty ( recv ) . peel_refs ( ) ;
485- if recv_ty . is_str ( ) || implements_deref_str ( cx, recv_ty ) ;
488+ if let Some ( trim_def_id ) = tyckres . type_dependent_def_id ( split_recv . hir_id ) ;
489+ if is_one_of_trim_diagnostic_items ( cx, trim_def_id ) ;
486490 then {
487491 span_lint_and_sugg(
488492 cx,
@@ -498,17 +502,8 @@ impl<'tcx> LateLintPass<'tcx> for TrimSplitWhitespace {
498502 }
499503}
500504
501- /// does ty implement Deref<Target=str>?
502- fn implements_deref_str < ' t > ( cx : & LateContext < ' t > , ty : Ty < ' t > ) -> bool {
503- if_chain ! {
504- if let Some ( deref_trait_id) = cx. tcx. get_diagnostic_item( sym:: Deref ) ;
505- if implements_trait( cx, ty, deref_trait_id, & [ ] ) ;
506- if let Some ( target) = get_associated_type( cx, ty, deref_trait_id, "Target" ) ;
507- then {
508- target. is_str( )
509- }
510- else {
511- false
512- }
513- }
505+ fn is_one_of_trim_diagnostic_items ( cx : & LateContext < ' _ > , trim_def_id : DefId ) -> bool {
506+ cx. tcx . is_diagnostic_item ( sym:: str_trim, trim_def_id)
507+ || cx. tcx . is_diagnostic_item ( sym:: str_trim_start, trim_def_id)
508+ || cx. tcx . is_diagnostic_item ( sym:: str_trim_end, trim_def_id)
514509}
0 commit comments