Rm diagnostic item, use lang item

This commit is contained in:
Deadbeef 2022-07-05 16:56:16 +00:00
parent 11d632f7b1
commit a09423f8c8
26 changed files with 95 additions and 91 deletions

View file

@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
if format_args.format_string.parts == [kw::Empty]; if format_args.format_string.parts == [kw::Empty];
if arg.format.is_default(); if arg.format.is_default();
if match cx.typeck_results().expr_ty(value).peel_refs().kind() { if match cx.typeck_results().expr_ty(value).peel_refs().kind() {
ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(sym::String, adt.did()), ty::Adt(adt, _) => Some(adt.did()) == cx.tcx.lang_items().string(),
ty::Str => true, ty::Str => true,
_ => false, _ => false,
}; };

View file

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_lang_item;
use clippy_utils::{match_def_path, paths, peel_hir_expr_refs}; use clippy_utils::{match_def_path, paths, peel_hir_expr_refs};
use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym; use rustc_span::sym;
@ -41,7 +41,7 @@ declare_clippy_lint! {
declare_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]); declare_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]);
fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), sym::String) is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String)
} }
fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
if let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id { if let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id {

View file

@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_integer_literal; use clippy_utils::is_integer_literal;
use clippy_utils::sugg::Sugg; use clippy_utils::sugg::Sugg;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{def, Expr, ExprKind, PrimTy, QPath, TyKind}; use rustc_hir::{def, Expr, ExprKind, LangItem, PrimTy, QPath, TyKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Ty; use rustc_middle::ty::Ty;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -98,5 +98,5 @@ impl<'tcx> LateLintPass<'tcx> for FromStrRadix10 {
/// Checks if a Ty is `String` or `&str` /// Checks if a Ty is `String` or `&str`
fn is_ty_stringish(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { fn is_ty_stringish(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
is_type_diagnostic_item(cx, ty, sym::String) || is_type_diagnostic_item(cx, ty, sym::str) is_type_lang_item(cx, ty, LangItem::String) || is_type_diagnostic_item(cx, ty, sym::str)
} }

View file

@ -1,8 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; use clippy_utils::ty::{implements_trait, is_type_lang_item};
use clippy_utils::{return_ty, trait_ref_of_method}; use clippy_utils::{return_ty, trait_ref_of_method};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind}; use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym; use rustc_span::sym;
@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
if impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. })); if impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }));
// Check if return type is String // Check if return type is String
if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id()), sym::String); if is_type_lang_item(cx, return_ty(cx, impl_item.hir_id()), LangItem::String);
// Filters instances of to_string which are required by a trait // Filters instances of to_string which are required by a trait
if trait_ref_of_method(cx, impl_item.owner_id.def_id).is_none(); if trait_ref_of_method(cx, impl_item.owner_id.def_id).is_none();

View file

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use clippy_utils::{get_parent_expr, match_def_path, paths, SpanlessEq}; use clippy_utils::{get_parent_expr, match_def_path, paths, SpanlessEq};
use clippy_utils::{meets_msrv, msrvs}; use clippy_utils::{meets_msrv, msrvs};
use rustc_errors::Applicability; use rustc_errors::Applicability;
@ -140,7 +140,7 @@ fn check_to_owned(
&& let Some(chars_expr_def_id) = cx.typeck_results().type_dependent_def_id(chars_expr.hir_id) && let Some(chars_expr_def_id) = cx.typeck_results().type_dependent_def_id(chars_expr.hir_id)
&& match_def_path(cx, chars_expr_def_id, &paths::STR_CHARS) && match_def_path(cx, chars_expr_def_id, &paths::STR_CHARS)
&& let ty = cx.typeck_results().expr_ty(str_expr).peel_refs() && let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()
&& is_type_diagnostic_item(cx, ty, sym::String) && is_type_lang_item(cx, ty, hir::LangItem::String)
&& SpanlessEq::new(cx).eq_expr(left_expr, str_expr) { && SpanlessEq::new(cx).eq_expr(left_expr, str_expr) {
suggest(cx, parent_expr, left_expr, filter_expr); suggest(cx, parent_expr, left_expr, filter_expr);
} }

View file

@ -44,7 +44,7 @@ impl LateLintPass<'_> for ManualStringNew {
let ty = cx.typeck_results().expr_ty(expr); let ty = cx.typeck_results().expr_ty(expr);
match ty.kind() { match ty.kind() {
ty::Adt(adt_def, _) if adt_def.is_struct() => { ty::Adt(adt_def, _) if adt_def.is_struct() => {
if !cx.tcx.is_diagnostic_item(sym::String, adt_def.did()) { if cx.tcx.lang_items().string() != Some(adt_def.did()) {
return; return;
} }
}, },

View file

@ -1,13 +1,13 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_lang_item;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{Arm, Expr, ExprKind, PatKind}; use rustc_hir::{Arm, Expr, ExprKind, LangItem, PatKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use rustc_span::{sym, Span}; use rustc_span::Span;
use super::MATCH_STR_CASE_MISMATCH; use super::MATCH_STR_CASE_MISMATCH;
@ -59,7 +59,7 @@ impl<'a, 'tcx> MatchExprVisitor<'a, 'tcx> {
if let Some(case_method) = get_case_method(segment_ident) { if let Some(case_method) = get_case_method(segment_ident) {
let ty = self.cx.typeck_results().expr_ty(receiver).peel_refs(); let ty = self.cx.typeck_results().expr_ty(receiver).peel_refs();
if is_type_diagnostic_item(self.cx, ty, sym::String) || ty.kind() == &ty::Str { if is_type_lang_item(self.cx, ty, LangItem::String) || ty.kind() == &ty::Str {
self.case_method = Some(case_method); self.case_method = Some(case_method);
return true; return true;
} }

View file

@ -1,11 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_lang_item;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_span::sym;
use super::BYTES_COUNT_TO_LEN; use super::BYTES_COUNT_TO_LEN;
@ -20,7 +19,7 @@ pub(super) fn check<'tcx>(
if let Some(impl_id) = cx.tcx.impl_of_method(bytes_id); if let Some(impl_id) = cx.tcx.impl_of_method(bytes_id);
if cx.tcx.type_of(impl_id).is_str(); if cx.tcx.type_of(impl_id).is_str();
let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs(); let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs();
if ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String); if ty.is_str() || is_type_lang_item(cx, ty, hir::LangItem::String);
then { then {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(

View file

@ -1,10 +1,9 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_lang_item;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::Expr; use rustc_hir::{Expr, LangItem};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_span::sym;
use super::BYTES_NTH; use super::BYTES_NTH;
@ -12,7 +11,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E
let ty = cx.typeck_results().expr_ty(recv).peel_refs(); let ty = cx.typeck_results().expr_ty(recv).peel_refs();
let caller_type = if ty.is_str() { let caller_type = if ty.is_str() {
"str" "str"
} else if is_type_diagnostic_item(cx, ty, sym::String) { } else if is_type_lang_item(cx, ty, LangItem::String) {
"String" "String"
} else { } else {
return; return;

View file

@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_lang_item;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind, LangItem};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_span::{source_map::Spanned, symbol::sym, Span}; use rustc_span::{source_map::Spanned, Span};
use super::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS; use super::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS;
@ -26,7 +26,7 @@ pub(super) fn check<'tcx>(
if ext_str.chars().skip(1).all(|c| c.is_uppercase() || c.is_ascii_digit()) if ext_str.chars().skip(1).all(|c| c.is_uppercase() || c.is_ascii_digit())
|| ext_str.chars().skip(1).all(|c| c.is_lowercase() || c.is_ascii_digit()); || ext_str.chars().skip(1).all(|c| c.is_lowercase() || c.is_ascii_digit());
let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs(); let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs();
if recv_ty.is_str() || is_type_diagnostic_item(cx, recv_ty, sym::String); if recv_ty.is_str() || is_type_lang_item(cx, recv_ty, LangItem::String);
then { then {
span_lint_and_help( span_lint_and_help(
cx, cx,

View file

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn}; use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn};
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::LateContext; use rustc_lint::LateContext;
@ -33,7 +33,7 @@ pub(super) fn check<'tcx>(
if (method_name.ident.name == sym::as_str || method_name.ident.name == sym::as_ref) && { if (method_name.ident.name == sym::as_str || method_name.ident.name == sym::as_ref) && {
let arg_type = cx.typeck_results().expr_ty(receiver); let arg_type = cx.typeck_results().expr_ty(receiver);
let base_type = arg_type.peel_refs(); let base_type = arg_type.peel_refs();
*base_type.kind() == ty::Str || is_type_diagnostic_item(cx, base_type, sym::String) *base_type.kind() == ty::Str || is_type_lang_item(cx, base_type, hir::LangItem::String)
} { } {
receiver receiver
} else { } else {
@ -50,7 +50,7 @@ pub(super) fn check<'tcx>(
// converted to string. // converted to string.
fn requires_to_string(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool { fn requires_to_string(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
let arg_ty = cx.typeck_results().expr_ty(arg); let arg_ty = cx.typeck_results().expr_ty(arg);
if is_type_diagnostic_item(cx, arg_ty, sym::String) { if is_type_lang_item(cx, arg_ty, hir::LangItem::String) {
return false; return false;
} }
if let ty::Ref(_, ty, ..) = arg_ty.kind() { if let ty::Ref(_, ty, ..) = arg_ty.kind() {

View file

@ -1,13 +1,13 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::{is_type_diagnostic_item, walk_ptrs_ty_depth}; use clippy_utils::ty::{is_type_lang_item, walk_ptrs_ty_depth};
use clippy_utils::{match_def_path, paths}; use clippy_utils::{match_def_path, paths};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{Symbol, sym};
use super::INEFFICIENT_TO_STRING; use super::INEFFICIENT_TO_STRING;
@ -60,7 +60,7 @@ fn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
return true; return true;
} }
if is_type_diagnostic_item(cx, ty, sym::String) { if is_type_lang_item(cx, ty, hir::LangItem::String) {
return true; return true;
} }

View file

@ -36,14 +36,14 @@ fn parse_repeat_arg(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<RepeatKind> {
} }
} else { } else {
let ty = cx.typeck_results().expr_ty(e); let ty = cx.typeck_results().expr_ty(e);
if is_type_diagnostic_item(cx, ty, sym::String) if is_type_lang_item(cx, ty, LangItem::String)
|| (is_type_lang_item(cx, ty, LangItem::OwnedBox) && get_ty_param(ty).map_or(false, Ty::is_str)) || (is_type_lang_item(cx, ty, LangItem::OwnedBox) && get_ty_param(ty).map_or(false, Ty::is_str))
|| (is_type_diagnostic_item(cx, ty, sym::Cow) && get_ty_param(ty).map_or(false, Ty::is_str)) || (is_type_diagnostic_item(cx, ty, sym::Cow) && get_ty_param(ty).map_or(false, Ty::is_str))
{ {
Some(RepeatKind::String) Some(RepeatKind::String)
} else { } else {
let ty = ty.peel_refs(); let ty = ty.peel_refs();
(ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String)).then_some(RepeatKind::String) (ty.is_str() || is_type_lang_item(cx, ty, LangItem::String)).then_some(RepeatKind::String)
} }
} }
} }
@ -58,7 +58,7 @@ pub(super) fn check(
if_chain! { if_chain! {
if let ExprKind::Call(repeat_fn, [repeat_arg]) = take_self_arg.kind; if let ExprKind::Call(repeat_fn, [repeat_arg]) = take_self_arg.kind;
if is_path_diagnostic_item(cx, repeat_fn, sym::iter_repeat); if is_path_diagnostic_item(cx, repeat_fn, sym::iter_repeat);
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(collect_expr), sym::String); if is_type_lang_item(cx, cx.typeck_results().expr_ty(collect_expr), LangItem::String);
if let Some(collect_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id); if let Some(collect_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id);
if let Some(take_id) = cx.typeck_results().type_dependent_def_id(take_expr.hir_id); if let Some(take_id) = cx.typeck_results().type_dependent_def_id(take_expr.hir_id);
if let Some(iter_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator); if let Some(iter_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator);

View file

@ -1,11 +1,10 @@
use clippy_utils::diagnostics::span_lint; use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_lang_item;
use clippy_utils::SpanlessEq; use clippy_utils::SpanlessEq;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::LitKind; use rustc_ast::LitKind;
use rustc_hir::ExprKind; use rustc_hir::{ExprKind, LangItem};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_span::sym;
use super::NO_EFFECT_REPLACE; use super::NO_EFFECT_REPLACE;
@ -16,7 +15,7 @@ pub(super) fn check<'tcx>(
arg2: &'tcx rustc_hir::Expr<'_>, arg2: &'tcx rustc_hir::Expr<'_>,
) { ) {
let ty = cx.typeck_results().expr_ty(expr).peel_refs(); let ty = cx.typeck_results().expr_ty(expr).peel_refs();
if !(ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String)) { if !(ty.is_str() || is_type_lang_item(cx, ty, LangItem::String)) {
return; return;
} }

View file

@ -1,11 +1,10 @@
use clippy_utils::consts::{constant_context, Constant}; use clippy_utils::consts::{constant_context, Constant};
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_lang_item;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::Expr; use rustc_hir::{Expr, LangItem};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_span::sym;
use super::REPEAT_ONCE; use super::REPEAT_ONCE;
@ -37,7 +36,7 @@ pub(super) fn check<'tcx>(
format!("{}.to_vec()", snippet(cx, recv.span, r#""...""#)), format!("{}.to_vec()", snippet(cx, recv.span, r#""...""#)),
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
} else if is_type_diagnostic_item(cx, ty, sym::String) { } else if is_type_lang_item(cx, ty, LangItem::String) {
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
REPEAT_ONCE, REPEAT_ONCE,

View file

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::sugg::deref_closure_args; use clippy_utils::sugg::deref_closure_args;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_lang_item;
use clippy_utils::{is_trait_method, strip_pat_refs}; use clippy_utils::{is_trait_method, strip_pat_refs};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
@ -105,7 +105,7 @@ pub(super) fn check<'tcx>(
else if search_method == "find" { else if search_method == "find" {
let is_string_or_str_slice = |e| { let is_string_or_str_slice = |e| {
let self_ty = cx.typeck_results().expr_ty(e).peel_refs(); let self_ty = cx.typeck_results().expr_ty(e).peel_refs();
if is_type_diagnostic_item(cx, self_ty, sym::String) { if is_type_lang_item(cx, self_ty, hir::LangItem::String) {
true true
} else { } else {
*self_ty.kind() == ty::Str *self_ty.kind() == ty::Str

View file

@ -1,18 +1,17 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::method_chain_args; use clippy_utils::method_chain_args;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_lang_item;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_span::symbol::sym;
use super::STRING_EXTEND_CHARS; use super::STRING_EXTEND_CHARS;
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) { pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs(); let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
if !is_type_diagnostic_item(cx, obj_ty, sym::String) { if !is_type_lang_item(cx, obj_ty, hir::LangItem::String) {
return; return;
} }
if let Some(arglists) = method_chain_args(arg, &["chars"]) { if let Some(arglists) = method_chain_args(arg, &["chars"]) {
@ -20,7 +19,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
let self_ty = cx.typeck_results().expr_ty(target).peel_refs(); let self_ty = cx.typeck_results().expr_ty(target).peel_refs();
let ref_str = if *self_ty.kind() == ty::Str { let ref_str = if *self_ty.kind() == ty::Str {
"" ""
} else if is_type_diagnostic_item(cx, self_ty, sym::String) { } else if is_type_lang_item(cx, self_ty, hir::LangItem::String) {
"&" "&"
} else { } else {
return; return;

View file

@ -1,10 +1,10 @@
use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item}; use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item};
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind, LangItem};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{Ref, Slice}; use rustc_middle::ty::{Ref, Slice};
use rustc_span::{sym, Span}; use rustc_span::Span;
use super::UNNECESSARY_JOIN; use super::UNNECESSARY_JOIN;
@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(
// the turbofish for collect is ::<Vec<String>> // the turbofish for collect is ::<Vec<String>>
if let Ref(_, ref_type, _) = collect_output_adjusted_type.kind(); if let Ref(_, ref_type, _) = collect_output_adjusted_type.kind();
if let Slice(slice) = ref_type.kind(); if let Slice(slice) = ref_type.kind();
if is_type_diagnostic_item(cx, *slice, sym::String); if is_type_lang_item(cx, *slice, LangItem::String);
// the argument for join is "" // the argument for join is ""
if let ExprKind::Lit(spanned) = &join_arg.kind; if let ExprKind::Lit(spanned) = &join_arg.kind;
if let LitKind::Str(symbol, _) = spanned.node; if let LitKind::Str(symbol, _) = spanned.node;

View file

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then}; use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
use clippy_utils::ptr::get_spans; use clippy_utils::ptr::get_spans;
use clippy_utils::source::{snippet, snippet_opt}; use clippy_utils::source::{snippet, snippet_opt};
use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item}; use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item};
use clippy_utils::{get_trait_def_id, is_self, paths}; use clippy_utils::{get_trait_def_id, is_self, paths};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::Attribute; use rustc_ast::ast::Attribute;
@ -11,7 +11,7 @@ use rustc_hir::intravisit::FnKind;
use rustc_hir::{ use rustc_hir::{
BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Mutability, Node, PatKind, QPath, TyKind, BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Mutability, Node, PatKind, QPath, TyKind,
}; };
use rustc_hir::{HirIdMap, HirIdSet}; use rustc_hir::{HirIdMap, HirIdSet, LangItem};
use rustc_hir_typeck::expr_use_visitor as euv; use rustc_hir_typeck::expr_use_visitor as euv;
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -249,7 +249,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
} }
} }
if is_type_diagnostic_item(cx, ty, sym::String) { if is_type_lang_item(cx, ty, LangItem::String) {
if let Some(clone_spans) = if let Some(clone_spans) =
get_spans(cx, Some(body.id()), idx, &[("clone", ".to_string()"), ("as_str", "")]) { get_spans(cx, Some(body.id()), idx, &[("clone", ".to_string()"), ("as_str", "")]) {
diag.span_suggestion( diag.span_suggestion(

View file

@ -450,7 +450,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
substs.type_at(0), substs.type_at(0),
), ),
), ),
Some(sym::String) => ( _ if Some(adt.did()) == cx.tcx.lang_items().string() => (
[("clone", ".to_owned()"), ("as_str", "")].as_slice(), [("clone", ".to_owned()"), ("as_str", "")].as_slice(),
DerefTy::Str, DerefTy::Str,
), ),

View file

@ -1,12 +1,12 @@
use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then}; use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
use clippy_utils::mir::{visit_local_usage, LocalUsage, PossibleBorrowerMap}; use clippy_utils::mir::{visit_local_usage, LocalUsage, PossibleBorrowerMap};
use clippy_utils::source::snippet_opt; use clippy_utils::source::snippet_opt;
use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, walk_ptrs_ty_depth}; use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, is_type_lang_item, walk_ptrs_ty_depth};
use clippy_utils::{fn_has_unsatisfiable_preds, match_def_path, paths}; use clippy_utils::{fn_has_unsatisfiable_preds, match_def_path, paths};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind; use rustc_hir::intravisit::FnKind;
use rustc_hir::{def_id, Body, FnDecl, HirId}; use rustc_hir::{def_id, Body, FnDecl, HirId, LangItem};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD) let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD)
|| match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD) || match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD)
|| (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD) || (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD)
&& is_type_diagnostic_item(cx, arg_ty, sym::String)); && is_type_lang_item(cx, arg_ty, LangItem::String));
let from_deref = !from_borrow let from_deref = !from_borrow
&& (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF) && (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF)

View file

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg}; use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg};
use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_lang_item;
use clippy_utils::{get_parent_expr, is_lint_allowed, match_function_call, method_calls, paths}; use clippy_utils::{get_parent_expr, is_lint_allowed, match_function_call, method_calls, paths};
use clippy_utils::{peel_blocks, SpanlessEq}; use clippy_utils::{peel_blocks, SpanlessEq};
use if_chain::if_chain; use if_chain::if_chain;
@ -190,7 +190,7 @@ impl<'tcx> LateLintPass<'tcx> for StringAdd {
}, },
ExprKind::Index(target, _idx) => { ExprKind::Index(target, _idx) => {
let e_ty = cx.typeck_results().expr_ty(target).peel_refs(); let e_ty = cx.typeck_results().expr_ty(target).peel_refs();
if matches!(e_ty.kind(), ty::Str) || is_type_diagnostic_item(cx, e_ty, sym::String) { if matches!(e_ty.kind(), ty::Str) || is_type_lang_item(cx, e_ty, LangItem::String) {
span_lint( span_lint(
cx, cx,
STRING_SLICE, STRING_SLICE,
@ -205,7 +205,7 @@ impl<'tcx> LateLintPass<'tcx> for StringAdd {
} }
fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), sym::String) is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String)
} }
fn is_add(cx: &LateContext<'_>, src: &Expr<'_>, target: &Expr<'_>) -> bool { fn is_add(cx: &LateContext<'_>, src: &Expr<'_>, target: &Expr<'_>) -> bool {
@ -446,7 +446,7 @@ impl<'tcx> LateLintPass<'tcx> for StringToString {
if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind; if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind;
if path.ident.name == sym::to_string; if path.ident.name == sym::to_string;
let ty = cx.typeck_results().expr_ty(self_arg); let ty = cx.typeck_results().expr_ty(self_arg);
if is_type_diagnostic_item(cx, ty, sym::String); if is_type_lang_item(cx, ty, LangItem::String);
then { then {
span_lint_and_help( span_lint_and_help(
cx, cx,

View file

@ -37,18 +37,19 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
fn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Symbol> { fn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Symbol> {
let param = qpath_generic_tys(qpath).next()?; let param = qpath_generic_tys(qpath).next()?;
let id = path_def_id(cx, param)?; let id = path_def_id(cx, param)?;
cx.tcx.get_diagnostic_name(id).filter(|&name| { cx.tcx
matches!( .get_diagnostic_name(id)
name, .filter(|&name| matches!(name, sym::HashMap | sym::Vec | sym::HashSet
sym::HashMap
| sym::String
| sym::Vec
| sym::HashSet
| sym::VecDeque | sym::VecDeque
| sym::LinkedList | sym::LinkedList
| sym::BTreeMap | sym::BTreeMap
| sym::BTreeSet | sym::BTreeSet
| sym::BinaryHeap | sym::BinaryHeap))
) .or_else(|| {
cx.tcx
.lang_items()
.string()
.filter(|did| id == *did)
.map(|_| sym::String)
}) })
} }

View file

@ -91,10 +91,10 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> { fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> {
let ty = qpath_generic_tys(qpath).next()?; let ty = qpath_generic_tys(qpath).next()?;
let id = path_def_id(cx, ty)?; let id = path_def_id(cx, ty)?;
let path = match cx.tcx.get_diagnostic_name(id)? { let path = match cx.tcx.get_diagnostic_name(id) {
sym::String => "str", Some(sym::OsString) => "std::ffi::OsStr",
sym::OsString => "std::ffi::OsStr", Some(sym::PathBuf) => "std::path::Path",
sym::PathBuf => "std::path::Path", _ if Some(id) == cx.tcx.lang_items().string() => "str",
_ => return None, _ => return None,
}; };
Some(path) Some(path)

View file

@ -1,13 +1,12 @@
use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item}; use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item};
use clippy_utils::{match_def_path, paths}; use clippy_utils::{match_def_path, paths};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability}; use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty; use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
@ -61,7 +60,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings {
if let LitKind::Str(symbol, _) = spanned.node; if let LitKind::Str(symbol, _) = spanned.node;
if symbol.is_empty(); if symbol.is_empty();
let inner_expr_type = cx.typeck_results().expr_ty(inner_expr); let inner_expr_type = cx.typeck_results().expr_ty(inner_expr);
if is_type_diagnostic_item(cx, inner_expr_type, sym::String); if is_type_lang_item(cx, inner_expr_type, LangItem::String);
then { then {
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,

View file

@ -434,6 +434,16 @@ pub fn is_expr_path_def_path(cx: &LateContext<'_>, expr: &Expr<'_>, segments: &[
path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, segments)) path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, segments))
} }
/// If `maybe_path` is a path node which resolves to an item, resolves it to a `DefId` and checks if
/// it matches the given lang item.
pub fn is_path_lang_item<'tcx>(
cx: &LateContext<'_>,
maybe_path: &impl MaybePath<'tcx>,
lang_item: LangItem,
) -> bool {
path_def_id(cx, maybe_path).map_or(false, |id| cx.tcx.lang_items().get(lang_item) == Some(id))
}
/// If `maybe_path` is a path node which resolves to an item, resolves it to a `DefId` and checks if /// If `maybe_path` is a path node which resolves to an item, resolves it to a `DefId` and checks if
/// it matches the given diagnostic item. /// it matches the given diagnostic item.
pub fn is_path_diagnostic_item<'tcx>( pub fn is_path_diagnostic_item<'tcx>(
@ -760,7 +770,6 @@ pub fn can_mut_borrow_both(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>) -
/// constructor from the std library /// constructor from the std library
fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<'_>) -> bool { fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<'_>) -> bool {
let std_types_symbols = &[ let std_types_symbols = &[
sym::String,
sym::Vec, sym::Vec,
sym::VecDeque, sym::VecDeque,
sym::LinkedList, sym::LinkedList,
@ -777,7 +786,7 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<
if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() { if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() {
return std_types_symbols return std_types_symbols
.iter() .iter()
.any(|&symbol| cx.tcx.is_diagnostic_item(symbol, adt.did())); .any(|&symbol| cx.tcx.is_diagnostic_item(symbol, adt.did()) || Some(adt.did()) == cx.tcx.lang_items().string());
} }
} }
} }
@ -834,7 +843,7 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: &
ExprKind::Lit(hir::Lit { ExprKind::Lit(hir::Lit {
node: LitKind::Str(ref sym, _), node: LitKind::Str(ref sym, _),
.. ..
}) => return sym.is_empty() && is_path_diagnostic_item(cx, ty, sym::String), }) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String),
ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec), ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec),
ExprKind::Repeat(_, ArrayLen::Body(len)) => { ExprKind::Repeat(_, ArrayLen::Body(len)) => {
if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(len.body).value.kind && if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(len.body).value.kind &&