use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item}; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; use rustc_middle::ty::{Ref, Slice}; use rustc_span::{sym, Span}; use super::UNNECESSARY_JOIN; pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, join_self_arg: &'tcx Expr<'tcx>, join_arg: &'tcx Expr<'tcx>, span: Span, ) { let applicability = Applicability::MachineApplicable; let collect_output_adjusted_type = cx.typeck_results().expr_ty_adjusted(join_self_arg); if_chain! { // the turbofish for collect is ::> if let Ref(_, ref_type, _) = collect_output_adjusted_type.kind(); if let Slice(slice) = ref_type.kind(); if is_type_diagnostic_item(cx, *slice, sym::String); // the argument for join is "" if let ExprKind::Lit(spanned) = &join_arg.kind; if let LitKind::Str(symbol, _) = spanned.node; if symbol.is_empty(); then { span_lint_and_sugg( cx, UNNECESSARY_JOIN, span.with_hi(expr.span.hi()), r#"called `.collect>().join("")` on an iterator"#, "try using", "collect::()".to_owned(), applicability, ); } } }