]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/methods/unnecessary_join.rs
Rm diagnostic item, use lang item
[rust.git] / clippy_lints / src / methods / unnecessary_join.rs
1 use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item};
2 use rustc_ast::ast::LitKind;
3 use rustc_errors::Applicability;
4 use rustc_hir::{Expr, ExprKind, LangItem};
5 use rustc_lint::LateContext;
6 use rustc_middle::ty::{Ref, Slice};
7 use rustc_span::Span;
8
9 use super::UNNECESSARY_JOIN;
10
11 pub(super) fn check<'tcx>(
12     cx: &LateContext<'tcx>,
13     expr: &'tcx Expr<'tcx>,
14     join_self_arg: &'tcx Expr<'tcx>,
15     join_arg: &'tcx Expr<'tcx>,
16     span: Span,
17 ) {
18     let applicability = Applicability::MachineApplicable;
19     let collect_output_adjusted_type = cx.typeck_results().expr_ty_adjusted(join_self_arg);
20     if_chain! {
21         // the turbofish for collect is ::<Vec<String>>
22         if let Ref(_, ref_type, _) = collect_output_adjusted_type.kind();
23         if let Slice(slice) = ref_type.kind();
24         if is_type_lang_item(cx, *slice, LangItem::String);
25         // the argument for join is ""
26         if let ExprKind::Lit(spanned) = &join_arg.kind;
27         if let LitKind::Str(symbol, _) = spanned.node;
28         if symbol.is_empty();
29         then {
30             span_lint_and_sugg(
31                 cx,
32                 UNNECESSARY_JOIN,
33                 span.with_hi(expr.span.hi()),
34                 r#"called `.collect<Vec<String>>().join("")` on an iterator"#,
35                 "try using",
36                 "collect::<String>()".to_owned(),
37                 applicability,
38             );
39         }
40     }
41 }