Replace all item identification utils (#15682)
This introduces a new way of identifying items/paths using extension traits with a composable set of functions rather than unique functions for various combinations of starting points and target items. Altogether this is a set of five traits: * `MaybeTypeckRes`: Allows both `LateContext` and `TypeckResults` to be used for type-dependent lookup. The implementation here will avoid ICEs by returning `None` when debug assertions are disabled. With assertions this will assert that we don't silently lookup anything from a different body than the current one and that a definition actually exists. * `HasHirId`: Simply a convenience to allow not typing `.hir_id` at call sites. * `MaybeQPath`: This is the old `MaybePath`. Extension functions for type-dependent path lookups exist here. A lot of these functions aren't used in the current PR, but what they accomplish is done in various places I haven't cleaned up yet. * `MaybeResPath`: Like `MaybeQPath`, but only does non-type-dependent lookup (`QPath::Resolved`). * `MaybeDef`: Extension functions for identifying the current definition and accessing properties. Implemented for several types for convenience. `MaybeDef` is implemented for `Option` to allow chaining methods together. e.g. `cx.ty_based_def(e).opt_parent(cx).opt_impl_ty(cx).is_diag_item(..)` would chaining `and_then` or `if let` on every step. `MaybeQPath` and `MaybeResPath` are also implemented for `Option` for the same reason. `ty_based_def` is just a shorter name for `type_dependent_def`. I'm not really attached to it, but it's nice that it's a little shorter. changelog: none
This commit is contained in:
commit
ebbbbebf2d
282 changed files with 2051 additions and 1324 deletions
|
|
@ -759,8 +759,7 @@ for some users. Adding a configuration is done in the following steps:
|
|||
Here are some pointers to things you are likely going to need for every lint:
|
||||
|
||||
* [Clippy utils][utils] - Various helper functions. Maybe the function you need
|
||||
is already in here ([`is_type_diagnostic_item`], [`implements_trait`],
|
||||
[`snippet`], etc)
|
||||
is already in here ([`implements_trait`], [`snippet`], etc)
|
||||
* [Clippy diagnostics][diagnostics]
|
||||
* [Let chains][let-chains]
|
||||
* [`from_expansion`][from_expansion] and
|
||||
|
|
@ -790,7 +789,6 @@ get away with copying things from existing similar lints. If you are stuck,
|
|||
don't hesitate to ask on [Zulip] or in the issue/PR.
|
||||
|
||||
[utils]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/index.html
|
||||
[`is_type_diagnostic_item`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/ty/fn.is_type_diagnostic_item.html
|
||||
[`implements_trait`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/ty/fn.implements_trait.html
|
||||
[`snippet`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/source/fn.snippet.html
|
||||
[let-chains]: https://github.com/rust-lang/rust/pull/94927
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@ to check for. All of these methods only check for the base type, generic
|
|||
arguments have to be checked separately.
|
||||
|
||||
```rust
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
|
||||
use clippy_utils::paths;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_hir::LangItem;
|
||||
|
||||
|
|
@ -97,12 +97,12 @@ impl LateLintPass<'_> for MyStructLint {
|
|||
|
||||
// 1. Using diagnostic items
|
||||
// The last argument is the diagnostic item to check for
|
||||
if is_type_diagnostic_item(cx, ty, sym::Option) {
|
||||
if ty.is_diag_item(cx, sym::Option) {
|
||||
// The type is an `Option`
|
||||
}
|
||||
|
||||
// 2. Using lang items
|
||||
if is_type_lang_item(cx, ty, LangItem::RangeFull) {
|
||||
if ty.is_lang_item(cx, LangItem::RangeFull) {
|
||||
// The type is a full range like `.drain(..)`
|
||||
}
|
||||
|
||||
|
|
@ -124,26 +124,28 @@ diagnostic item, lang item or neither.
|
|||
|
||||
```rust
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use clippy_utils::is_trait_method;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
impl LateLintPass<'_> for MyStructLint {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
// 1. Using diagnostic items with the expression
|
||||
// we use `is_trait_method` function from Clippy's utils
|
||||
if is_trait_method(cx, expr, sym::Iterator) {
|
||||
// method call in `expr` belongs to `Iterator` trait
|
||||
|
||||
// 1. Get the `DefId` of the trait.
|
||||
// via lang items
|
||||
let trait_id = cx.tcx.lang_items().drop_trait();
|
||||
// via diagnostic items
|
||||
let trait_id = cx.tcx.get_diagnostic_item(sym::Eq);
|
||||
|
||||
// 2. Check for the trait implementation via the `implements_trait` util.
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
if trait_id.is_some_and(|id| implements_trait(cx, ty, id, &[])) {
|
||||
// `ty` implements the trait.
|
||||
}
|
||||
|
||||
// 2. Using lang items with the expression type
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
if cx.tcx.lang_items()
|
||||
// we are looking for the `DefId` of `Drop` trait in lang items
|
||||
.drop_trait()
|
||||
// then we use it with our type `ty` by calling `implements_trait` from Clippy's utils
|
||||
.is_some_and(|id| implements_trait(cx, ty, id, &[])) {
|
||||
// `expr` implements `Drop` trait
|
||||
}
|
||||
// 3. If the trait requires additional generic arguments
|
||||
let trait_id = cx.tcx.lang_items().eq_trait();
|
||||
if trait_id.is_some_and(|id| implements_trait(cx, ty, id, &[ty])) {
|
||||
// `ty` implements `PartialEq<Self>`
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -173,7 +175,7 @@ impl<'tcx> LateLintPass<'tcx> for MyTypeImpl {
|
|||
// We can also check it has a parameter `self`
|
||||
&& signature.decl.implicit_self.has_implicit_self()
|
||||
// We can go further and even check if its return type is `String`
|
||||
&& is_type_lang_item(cx, return_ty(cx, impl_item.hir_id), LangItem::String)
|
||||
&& return_ty(cx, impl_item.hir_id).is_lang_item(cx, LangItem::String)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ the [`ExprKind`] that we can access from `expr.kind`:
|
|||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_span::sym;
|
||||
use clippy_utils::is_trait_method;
|
||||
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for OurFancyMethodLint {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
|
||||
|
|
@ -28,7 +28,7 @@ impl<'tcx> LateLintPass<'tcx> for OurFancyMethodLint {
|
|||
// (It's necessary if we want to check that method is specifically belonging to a specific trait,
|
||||
// for example, a `map` method could belong to user-defined trait instead of to `Iterator`)
|
||||
// See the next section for more information.
|
||||
&& is_trait_method(cx, self_arg, sym::OurFancyTrait)
|
||||
&& cx.ty_based_def(self_arg).opt_parent(cx).is_diag_item(cx, sym::OurFancyTrait)
|
||||
{
|
||||
println!("`expr` is a method call for `our_fancy_method`");
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ Let us take a look at how we might check for the implementation of
|
|||
`our_fancy_method` on a type:
|
||||
|
||||
```rust
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::return_ty;
|
||||
use rustc_hir::{ImplItem, ImplItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -71,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for MyTypeImpl {
|
|||
// We can also check it has a parameter `self`
|
||||
&& signature.decl.implicit_self.has_implicit_self()
|
||||
// We can go even further and even check if its return type is `String`
|
||||
&& is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id), sym::String)
|
||||
&& return_ty(cx, impl_item.hir_id).is_diag_item(cx, sym::String)
|
||||
{
|
||||
println!("`our_fancy_method` is implemented!");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::is_from_proc_macro;
|
||||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use rustc_hir::{Expr, ExprKind, QPath};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
|
|
@ -46,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for ArcWithNonSendSync {
|
|||
&& let ExprKind::Path(QPath::TypeRelative(func_ty, func_name)) = func.kind
|
||||
&& func_name.ident.name == sym::new
|
||||
&& !expr.span.from_expansion()
|
||||
&& is_type_diagnostic_item(cx, cx.typeck_results().node_type(func_ty.hir_id), sym::Arc)
|
||||
&& cx.typeck_results().node_type(func_ty.hir_id).is_diag_item(cx, sym::Arc)
|
||||
&& let arg_ty = cx.typeck_results().expr_ty(arg)
|
||||
// make sure that the type is not and does not contain any type parameters
|
||||
&& arg_ty.walk().all(|arg| {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::macros::{PanicExpn, find_assert_args, root_macro_call_first_node};
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath};
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::ty::{has_debug_impl, is_copy, is_type_diagnostic_item};
|
||||
use clippy_utils::sym;
|
||||
use clippy_utils::ty::{has_debug_impl, is_copy};
|
||||
use clippy_utils::usage::local_used_after_expr;
|
||||
use clippy_utils::{path_res, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{Expr, ExprKind, Node};
|
||||
|
|
@ -55,13 +56,13 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
|
|||
&& let ExprKind::MethodCall(method_segment, recv, [], _) = condition.kind
|
||||
&& let result_type_with_refs = cx.typeck_results().expr_ty(recv)
|
||||
&& let result_type = result_type_with_refs.peel_refs()
|
||||
&& is_type_diagnostic_item(cx, result_type, sym::Result)
|
||||
&& result_type.is_diag_item(cx, sym::Result)
|
||||
&& let ty::Adt(_, args) = result_type.kind()
|
||||
{
|
||||
if !is_copy(cx, result_type) {
|
||||
if result_type_with_refs != result_type {
|
||||
return;
|
||||
} else if let Res::Local(binding_id) = path_res(cx, recv)
|
||||
} else if let Res::Local(binding_id) = *recv.basic_res()
|
||||
&& local_used_after_expr(cx, binding_id, recv)
|
||||
{
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ use clippy_config::Conf;
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::mir::{PossibleBorrowerMap, enclosing_mir};
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath};
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{is_diag_trait_item, is_in_test, last_path_segment, local_is_initialized, path_to_local, sym};
|
||||
use clippy_utils::{is_in_test, last_path_segment, local_is_initialized, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{self as hir, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -68,15 +69,15 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones {
|
|||
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
|
||||
if let ExprKind::Assign(lhs, rhs, _) = e.kind
|
||||
&& let typeck = cx.typeck_results()
|
||||
&& let (call_kind, fn_name, fn_id, fn_arg, fn_gen_args) = match rhs.kind {
|
||||
&& let (call_kind, fn_name, fn_def, fn_arg, fn_gen_args) = match rhs.kind {
|
||||
ExprKind::Call(f, [arg])
|
||||
if let ExprKind::Path(fn_path) = &f.kind
|
||||
&& let Some(id) = typeck.qpath_res(fn_path, f.hir_id).opt_def_id() =>
|
||||
&& let Some(def) = typeck.qpath_res(fn_path, f.hir_id).opt_def(cx) =>
|
||||
{
|
||||
(CallKind::Ufcs, last_path_segment(fn_path).ident.name, id, arg, typeck.node_args(f.hir_id))
|
||||
(CallKind::Ufcs, last_path_segment(fn_path).ident.name, def, arg, typeck.node_args(f.hir_id))
|
||||
},
|
||||
ExprKind::MethodCall(name, recv, [], _) if let Some(id) = typeck.type_dependent_def_id(rhs.hir_id) => {
|
||||
(CallKind::Method, name.ident.name, id, recv, typeck.node_args(rhs.hir_id))
|
||||
ExprKind::MethodCall(name, recv, [], _) if let Some(def) = typeck.type_dependent_def(rhs.hir_id) => {
|
||||
(CallKind::Method, name.ident.name, def, recv, typeck.node_args(rhs.hir_id))
|
||||
},
|
||||
_ => return,
|
||||
}
|
||||
|
|
@ -84,20 +85,20 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones {
|
|||
// Don't lint in macros.
|
||||
&& ctxt.is_root()
|
||||
&& let which_trait = match fn_name {
|
||||
sym::clone if is_diag_trait_item(cx, fn_id, sym::Clone) => CloneTrait::Clone,
|
||||
sym::clone if fn_def.assoc_fn_parent(cx).is_diag_item(cx, sym::Clone) => CloneTrait::Clone,
|
||||
sym::to_owned
|
||||
if is_diag_trait_item(cx, fn_id, sym::ToOwned)
|
||||
if fn_def.assoc_fn_parent(cx).is_diag_item(cx, sym::ToOwned)
|
||||
&& self.msrv.meets(cx, msrvs::CLONE_INTO) =>
|
||||
{
|
||||
CloneTrait::ToOwned
|
||||
},
|
||||
_ => return,
|
||||
}
|
||||
&& let Ok(Some(resolved_fn)) = Instance::try_resolve(cx.tcx, cx.typing_env(), fn_id, fn_gen_args)
|
||||
&& let Ok(Some(resolved_fn)) = Instance::try_resolve(cx.tcx, cx.typing_env(), fn_def.1, fn_gen_args)
|
||||
// TODO: This check currently bails if the local variable has no initializer.
|
||||
// That is overly conservative - the lint should fire even if there was no initializer,
|
||||
// but the variable has been initialized before `lhs` was evaluated.
|
||||
&& path_to_local(lhs).is_none_or(|lhs| local_is_initialized(cx, lhs))
|
||||
&& lhs.res_local_id().is_none_or(|lhs| local_is_initialized(cx, lhs))
|
||||
&& let Some(resolved_impl) = cx.tcx.impl_of_assoc(resolved_fn.def_id())
|
||||
// Derived forms don't implement `clone_from`/`clone_into`.
|
||||
// See https://github.com/rust-lang/rust/pull/98445#issuecomment-1190681305
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ use clippy_config::Conf;
|
|||
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
|
||||
use clippy_utils::higher::has_let_expr;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use clippy_utils::{eq_expr_value, sym};
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
|
|
@ -431,9 +432,7 @@ fn simplify_not(cx: &LateContext<'_>, curr_msrv: Msrv, expr: &Expr<'_>) -> Optio
|
|||
},
|
||||
ExprKind::MethodCall(path, receiver, args, _) => {
|
||||
let type_of_receiver = cx.typeck_results().expr_ty(receiver);
|
||||
if !is_type_diagnostic_item(cx, type_of_receiver, sym::Option)
|
||||
&& !is_type_diagnostic_item(cx, type_of_receiver, sym::Result)
|
||||
{
|
||||
if !type_of_receiver.is_diag_item(cx, sym::Option) && !type_of_receiver.is_diag_item(cx, sym::Result) {
|
||||
return None;
|
||||
}
|
||||
METHODS_WITH_NEGATION
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::is_default_equivalent;
|
||||
use clippy_utils::macros::macro_backtrace;
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath};
|
||||
use clippy_utils::ty::expr_sig;
|
||||
use clippy_utils::{is_default_equivalent, path_def_id};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};
|
||||
use rustc_hir::{AmbigArg, Block, Expr, ExprKind, HirId, LetStmt, Node, QPath, Ty, TyKind};
|
||||
use rustc_hir::{AmbigArg, Block, Expr, ExprKind, HirId, LangItem, LetStmt, Node, QPath, Ty, TyKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::{Span, sym};
|
||||
|
|
@ -44,7 +45,7 @@ impl LateLintPass<'_> for BoxDefault {
|
|||
// And that method is `new`
|
||||
&& seg.ident.name == sym::new
|
||||
// And the call is that of a `Box` method
|
||||
&& path_def_id(cx, ty).is_some_and(|id| Some(id) == cx.tcx.lang_items().owned_box())
|
||||
&& ty.basic_res().is_lang_item(cx, LangItem::OwnedBox)
|
||||
// And the single argument to the call is another function call
|
||||
// This is the `T::default()` (or default equivalent) of `Box::new(T::default())`
|
||||
&& let ExprKind::Call(arg_path, _) = arg.kind
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath};
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::{expr_or_init, is_path_diagnostic_item, std_or_core, sym};
|
||||
use clippy_utils::{expr_or_init, std_or_core, sym};
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, GenericArg, Mutability, QPath, Ty, TyKind};
|
||||
|
|
@ -53,7 +54,7 @@ fn is_expr_const_aligned(cx: &LateContext<'_>, expr: &Expr<'_>, to: &Ty<'_>) ->
|
|||
|
||||
fn is_align_of_call(cx: &LateContext<'_>, fun: &Expr<'_>, to: &Ty<'_>) -> bool {
|
||||
if let ExprKind::Path(QPath::Resolved(_, path)) = fun.kind
|
||||
&& is_path_diagnostic_item(cx, fun, sym::mem_align_of)
|
||||
&& fun.basic_res().is_diag_item(cx, sym::mem_align_of)
|
||||
&& let Some(args) = path.segments.last().and_then(|seg| seg.args)
|
||||
&& let [GenericArg::Type(generic_ty)] = args.args
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::numeric_literal::NumericLiteral;
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::{SpanRangeExt, snippet_opt};
|
||||
use clippy_utils::visitors::{Visitable, for_each_expr_without_closures};
|
||||
use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias, path_to_local};
|
||||
use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias};
|
||||
use rustc_ast::{LitFloatType, LitIntType, LitKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
|
|
@ -167,11 +168,11 @@ pub(super) fn check<'tcx>(
|
|||
sym::assert_ne_macro,
|
||||
sym::debug_assert_ne_macro,
|
||||
];
|
||||
matches!(expr.span.ctxt().outer_expn_data().macro_def_id, Some(def_id) if
|
||||
matches!(expr.span.ctxt().outer_expn_data().macro_def_id, Some(def_id) if
|
||||
cx.tcx.get_diagnostic_name(def_id).is_some_and(|sym| ALLOWED_MACROS.contains(&sym)))
|
||||
}
|
||||
|
||||
if let Some(id) = path_to_local(cast_expr)
|
||||
if let Some(id) = cast_expr.res_local_id()
|
||||
&& !cx.tcx.hir_span(id).eq_ctxt(cast_expr.span)
|
||||
{
|
||||
// Binding context is different than the identifiers context.
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::visitors::is_const_evaluatable;
|
||||
use clippy_utils::{is_in_const_context, is_mutable, is_trait_method};
|
||||
use clippy_utils::{is_in_const_context, is_mutable};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -73,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for ClonedRefToSliceRefs<'_> {
|
|||
|
||||
// check for clones
|
||||
&& let ExprKind::MethodCall(_, val, _, _) = item.kind
|
||||
&& is_trait_method(cx, item, sym::Clone)
|
||||
&& cx.ty_based_def(item).opt_parent(cx).is_diag_item(cx, sym::Clone)
|
||||
|
||||
// check for immutability or purity
|
||||
&& (!is_mutable(cx, val) || is_const_evaluatable(cx, val))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::{IntoSpan, SpanRangeExt};
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::visitors::for_each_expr_without_closures;
|
||||
use clippy_utils::{LimitStack, get_async_fn_body, sym};
|
||||
use core::ops::ControlFlow;
|
||||
|
|
@ -93,7 +93,7 @@ impl CognitiveComplexity {
|
|||
});
|
||||
|
||||
let ret_ty = cx.typeck_results().node_type(expr.hir_id);
|
||||
let ret_adjust = if is_type_diagnostic_item(cx, ret_ty, sym::Result) {
|
||||
let ret_adjust = if ret_ty.is_diag_item(cx, sym::Result) {
|
||||
returns
|
||||
} else {
|
||||
#[expect(clippy::integer_division)]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::ty::{get_type_diagnostic_name, is_type_lang_item};
|
||||
use clippy_utils::get_enclosing_block;
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath};
|
||||
use clippy_utils::visitors::{Visitable, for_each_expr};
|
||||
use clippy_utils::{get_enclosing_block, path_to_local_id};
|
||||
use core::ops::ControlFlow;
|
||||
use rustc_hir::{Body, ExprKind, HirId, LangItem, LetStmt, Node, PatKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -59,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead {
|
|||
fn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>) -> bool {
|
||||
let ty = cx.typeck_results().pat_ty(local.pat);
|
||||
matches!(
|
||||
get_type_diagnostic_name(cx, ty),
|
||||
ty.opt_diag_name(cx),
|
||||
Some(
|
||||
sym::BTreeMap
|
||||
| sym::BTreeSet
|
||||
|
|
@ -71,7 +71,7 @@ fn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>) -> bool {
|
|||
| sym::Vec
|
||||
| sym::VecDeque
|
||||
)
|
||||
) || is_type_lang_item(cx, ty, LangItem::String)
|
||||
) || ty.is_lang_item(cx, LangItem::String)
|
||||
}
|
||||
|
||||
fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirId, block: T) -> bool {
|
||||
|
|
@ -81,7 +81,7 @@ fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirI
|
|||
// Inspect all expressions and sub-expressions in the block.
|
||||
for_each_expr(cx, block, |expr| {
|
||||
// Ignore expressions that are not simply `id`.
|
||||
if !path_to_local_id(expr, id) {
|
||||
if expr.res_local_id() != Some(id) {
|
||||
return ControlFlow::Continue(());
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirI
|
|||
// id = ...; // Not reading `id`.
|
||||
if let Node::Expr(parent) = cx.tcx.parent_hir_node(expr.hir_id)
|
||||
&& let ExprKind::Assign(lhs, ..) = parent.kind
|
||||
&& path_to_local_id(lhs, id)
|
||||
&& lhs.res_local_id() == Some(id)
|
||||
{
|
||||
return ControlFlow::Continue(());
|
||||
}
|
||||
|
|
@ -107,7 +107,7 @@ fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirI
|
|||
// have side effects, so consider them a read.
|
||||
if let Node::Expr(parent) = cx.tcx.parent_hir_node(expr.hir_id)
|
||||
&& let ExprKind::MethodCall(_, receiver, args, _) = parent.kind
|
||||
&& path_to_local_id(receiver, id)
|
||||
&& receiver.res_local_id() == Some(id)
|
||||
&& let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id)
|
||||
&& !method_def_id.is_local()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
|
||||
use clippy_utils::sugg::has_enclosing_paren;
|
||||
use clippy_utils::ty::{adjust_derefs_manually_drop, implements_trait, is_manually_drop, peel_and_count_ty_refs};
|
||||
use clippy_utils::{
|
||||
DefinedTy, ExprUseNode, expr_use_ctxt, get_parent_expr, is_block_like, is_from_proc_macro, is_lint_allowed,
|
||||
path_to_local,
|
||||
};
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
|
|
@ -239,7 +239,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
if let Some(local) = path_to_local(expr) {
|
||||
if let Some(local) = expr.res_local_id() {
|
||||
self.check_local_usage(cx, expr, local);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use clippy_utils::path_res;
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{Impl, Item, ItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -199,7 +199,7 @@ impl<'tcx> LateLintPass<'tcx> for Derive {
|
|||
self_ty,
|
||||
..
|
||||
}) = item.kind
|
||||
&& let Res::Def(_, def_id) = path_res(cx, self_ty)
|
||||
&& let Res::Def(_, def_id) = *self_ty.basic_res()
|
||||
&& let Some(local_def_id) = def_id.as_local()
|
||||
{
|
||||
let adt_hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use super::{DocHeaders, MISSING_ERRORS_DOC, MISSING_PANICS_DOC, MISSING_SAFETY_DOC, UNNECESSARY_SAFETY_DOC};
|
||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_note};
|
||||
use clippy_utils::macros::{is_panic, root_macro_call_first_node};
|
||||
use clippy_utils::ty::{get_type_diagnostic_name, implements_trait_with_env, is_type_diagnostic_item};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::ty::implements_trait_with_env;
|
||||
use clippy_utils::visitors::for_each_expr;
|
||||
use clippy_utils::{fulfill_or_allowed, is_doc_hidden, is_inside_always_const_context, method_chain_args, return_ty};
|
||||
use rustc_hir::{BodyId, FnSig, OwnerId, Safety};
|
||||
|
|
@ -62,7 +63,7 @@ pub fn check(
|
|||
);
|
||||
}
|
||||
if !headers.errors {
|
||||
if is_type_diagnostic_item(cx, return_ty(cx, owner_id), sym::Result) {
|
||||
if return_ty(cx, owner_id).is_diag_item(cx, sym::Result) {
|
||||
span_lint(
|
||||
cx,
|
||||
MISSING_ERRORS_DOC,
|
||||
|
|
@ -83,7 +84,7 @@ pub fn check(
|
|||
&[],
|
||||
)
|
||||
&& let ty::Coroutine(_, subs) = ret_ty.kind()
|
||||
&& is_type_diagnostic_item(cx, subs.as_coroutine().return_ty(), sym::Result)
|
||||
&& subs.as_coroutine().return_ty().is_diag_item(cx, sym::Result)
|
||||
{
|
||||
span_lint(
|
||||
cx,
|
||||
|
|
@ -119,10 +120,7 @@ fn find_panic(cx: &LateContext<'_>, body_id: BodyId) -> Option<Span> {
|
|||
if let Some(arglists) =
|
||||
method_chain_args(expr, &[sym::unwrap]).or_else(|| method_chain_args(expr, &[sym::expect]))
|
||||
&& let receiver_ty = typeck.expr_ty(arglists[0].0).peel_refs()
|
||||
&& matches!(
|
||||
get_type_diagnostic_name(cx, receiver_ty),
|
||||
Some(sym::Option | sym::Result)
|
||||
)
|
||||
&& matches!(receiver_ty.opt_diag_name(cx), Some(sym::Option | sym::Result))
|
||||
&& !fulfill_or_allowed(cx, MISSING_PANICS_DOC, [expr.hir_id])
|
||||
&& panic_span.is_none()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::is_must_use_func_call;
|
||||
use clippy_utils::ty::{is_copy, is_must_use_ty, is_type_lang_item};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::ty::{is_copy, is_must_use_ty};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, LangItem, Node};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
|
@ -97,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
|
|||
sym::mem_forget if arg_ty.is_ref() => return,
|
||||
sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return,
|
||||
sym::mem_forget if is_copy => return,
|
||||
sym::mem_drop if is_type_lang_item(cx, arg_ty, LangItem::ManuallyDrop) => return,
|
||||
sym::mem_drop if arg_ty.is_lang_item(cx, LangItem::ManuallyDrop) => return,
|
||||
sym::mem_drop
|
||||
if !(arg_ty.needs_drop(cx.tcx, cx.typing_env())
|
||||
|| is_must_use_func_call(cx, arg)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use clippy_utils::diagnostics::{span_lint, span_lint_hir_and_then};
|
||||
use clippy_utils::path_res;
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::{Item, ItemKind};
|
||||
|
|
@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError {
|
|||
if let Some(trait_def_id) = imp.of_trait.and_then(|t| t.trait_ref.trait_def_id())
|
||||
&& let Some(error_def_id) = cx.tcx.get_diagnostic_item(sym::Error)
|
||||
&& error_def_id == trait_def_id
|
||||
&& let Some(def_id) = path_res(cx, imp.self_ty).opt_def_id().and_then(DefId::as_local)
|
||||
&& let Some(def_id) = imp.self_ty.basic_res().opt_def_id().and_then(DefId::as_local)
|
||||
&& let Some(ident) = cx.tcx.opt_item_ident(def_id.to_def_id())
|
||||
&& ident.name == sym::Error
|
||||
&& is_visible_outside_module(cx, def_id) =>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
use clippy_utils::diagnostics::span_lint_hir_and_then;
|
||||
use clippy_utils::higher::VecArgs;
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath};
|
||||
use clippy_utils::source::{snippet_opt, snippet_with_applicability};
|
||||
use clippy_utils::ty::get_type_diagnostic_name;
|
||||
use clippy_utils::usage::{local_used_after_expr, local_used_in};
|
||||
use clippy_utils::{
|
||||
get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate, path_to_local, path_to_local_id,
|
||||
};
|
||||
use clippy_utils::{get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate};
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
|
|
@ -144,7 +142,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
|
|||
{
|
||||
let callee_ty_raw = typeck.expr_ty(callee);
|
||||
let callee_ty = callee_ty_raw.peel_refs();
|
||||
if matches!(get_type_diagnostic_name(cx, callee_ty), Some(sym::Arc | sym::Rc))
|
||||
if matches!(callee_ty.opt_diag_name(cx), Some(sym::Arc | sym::Rc))
|
||||
|| !check_inputs(typeck, body.params, None, args)
|
||||
{
|
||||
return;
|
||||
|
|
@ -218,7 +216,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
|
|||
"redundant closure",
|
||||
|diag| {
|
||||
if let Some(mut snippet) = snippet_opt(cx, callee.span) {
|
||||
if path_to_local(callee).is_some_and(|l| {
|
||||
if callee.res_local_id().is_some_and(|l| {
|
||||
// FIXME: Do we really need this `local_used_in` check?
|
||||
// Isn't it checking something like... `callee(callee)`?
|
||||
// If somehow this check is needed, add some test for it,
|
||||
|
|
@ -307,7 +305,7 @@ fn check_inputs(
|
|||
matches!(
|
||||
p.pat.kind,
|
||||
PatKind::Binding(BindingMode::NONE, id, _, None)
|
||||
if path_to_local_id(arg, id)
|
||||
if arg.res_local_id() == Some(id)
|
||||
)
|
||||
// Only allow adjustments which change regions (i.e. re-borrowing).
|
||||
&& typeck
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span};
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::{is_expn_of, path_def_id, sym};
|
||||
use clippy_utils::{is_expn_of, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{BindingMode, Block, BlockCheckMode, Expr, ExprKind, Node, PatKind, QPath, Stmt, StmtKind};
|
||||
|
|
@ -59,7 +60,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
|
|||
&& let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = *look_in_block(cx, &write_call.kind)
|
||||
&& let ExprKind::Call(write_recv_path, []) = write_recv.kind
|
||||
&& write_fun.ident.name == sym::write_fmt
|
||||
&& let Some(def_id) = path_def_id(cx, write_recv_path)
|
||||
&& let Some(def_id) = write_recv_path.basic_res().opt_def_id()
|
||||
{
|
||||
// match calls to std::io::stdout() / std::io::stderr ()
|
||||
let (dest_name, prefix) = match cx.tcx.get_diagnostic_name(def_id) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::macros::{is_panic, root_macro_call_first_node};
|
||||
use clippy_utils::method_chain_args;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
|
|
@ -84,9 +84,7 @@ fn lint_impl_body(cx: &LateContext<'_>, item_def_id: hir::OwnerId, impl_span: Sp
|
|||
// check for `unwrap`
|
||||
if let Some(arglists) = method_chain_args(expr, &[sym::unwrap]) {
|
||||
let receiver_ty = self.typeck_results.expr_ty(arglists[0].0).peel_refs();
|
||||
if is_type_diagnostic_item(self.lcx, receiver_ty, sym::Option)
|
||||
|| is_type_diagnostic_item(self.lcx, receiver_ty, sym::Result)
|
||||
{
|
||||
if receiver_ty.is_diag_item(self.lcx, sym::Option) || receiver_ty.is_diag_item(self.lcx, sym::Result) {
|
||||
self.result.push(expr.span);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use clippy_utils::consts::Constant::{F32, F64, Int};
|
||||
use clippy_utils::consts::{ConstEvalCtxt, Constant};
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
|
||||
use clippy_utils::{
|
||||
eq_expr_value, get_parent_expr, has_ambiguous_literal_in_expr, higher, is_in_const_context,
|
||||
is_inherent_method_call, is_no_std_crate, numeric_literal, peel_blocks, sugg, sym,
|
||||
eq_expr_value, get_parent_expr, has_ambiguous_literal_in_expr, higher, is_in_const_context, is_no_std_crate,
|
||||
numeric_literal, peel_blocks, sugg, sym,
|
||||
};
|
||||
use rustc_ast::ast;
|
||||
use rustc_errors::Applicability;
|
||||
|
|
@ -737,7 +738,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic {
|
|||
if let ExprKind::MethodCall(path, receiver, args, _) = &expr.kind {
|
||||
let recv_ty = cx.typeck_results().expr_ty(receiver);
|
||||
|
||||
if recv_ty.is_floating_point() && !is_no_std_crate(cx) && is_inherent_method_call(cx, expr) {
|
||||
if recv_ty.is_floating_point() && !is_no_std_crate(cx) && cx.ty_based_def(expr).opt_parent(cx).is_impl(cx) {
|
||||
match path.ident.name {
|
||||
sym::ln => check_ln1p(cx, expr, receiver),
|
||||
sym::log => check_log_base(cx, expr, receiver, args),
|
||||
|
|
|
|||
|
|
@ -9,9 +9,10 @@ use clippy_utils::macros::{
|
|||
root_macro_call_first_node,
|
||||
};
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::{SpanRangeExt, snippet};
|
||||
use clippy_utils::ty::{implements_trait, is_type_lang_item};
|
||||
use clippy_utils::{is_diag_trait_item, is_from_proc_macro, is_in_test, trait_ref_of_method};
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use clippy_utils::{is_from_proc_macro, is_in_test, trait_ref_of_method};
|
||||
use itertools::Itertools;
|
||||
use rustc_ast::{
|
||||
FormatArgPosition, FormatArgPositionKind, FormatArgsPiece, FormatArgumentKind, FormatCount, FormatOptions,
|
||||
|
|
@ -344,7 +345,7 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> {
|
|||
if let Some(placeholder_span) = placeholder.span
|
||||
&& *options != FormatOptions::default()
|
||||
&& let ty = self.cx.typeck_results().expr_ty(arg).peel_refs()
|
||||
&& is_type_lang_item(self.cx, ty, LangItem::FormatArguments)
|
||||
&& ty.is_lang_item(self.cx, LangItem::FormatArguments)
|
||||
{
|
||||
span_lint_and_then(
|
||||
self.cx,
|
||||
|
|
@ -497,8 +498,11 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> {
|
|||
let cx = self.cx;
|
||||
if !value.span.from_expansion()
|
||||
&& let ExprKind::MethodCall(_, receiver, [], to_string_span) = value.kind
|
||||
&& let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(value.hir_id)
|
||||
&& is_diag_trait_item(cx, method_def_id, sym::ToString)
|
||||
&& cx
|
||||
.typeck_results()
|
||||
.type_dependent_def_id(value.hir_id)
|
||||
.opt_parent(cx)
|
||||
.is_diag_item(cx, sym::ToString)
|
||||
&& let receiver_ty = cx.typeck_results().expr_ty(receiver)
|
||||
&& let Some(display_trait_id) = cx.tcx.get_diagnostic_item(sym::Display)
|
||||
&& let (n_needed_derefs, target) =
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
|
||||
use clippy_utils::macros::{FormatArgsStorage, find_format_arg_expr, is_format_macro, root_macro_call_first_node};
|
||||
use clippy_utils::{get_parent_as_impl, is_diag_trait_item, path_to_local, peel_ref_operators, sym};
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath};
|
||||
use clippy_utils::{get_parent_as_impl, peel_ref_operators, sym};
|
||||
use rustc_ast::{FormatArgsPiece, FormatTrait};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, Impl, ImplItem, ImplItemKind, QPath};
|
||||
|
|
@ -157,8 +158,12 @@ impl FormatImplExpr<'_, '_> {
|
|||
&& path.ident.name == sym::to_string
|
||||
// Is the method a part of the ToString trait? (i.e. not to_string() implemented
|
||||
// separately)
|
||||
&& let Some(expr_def_id) = self.cx.typeck_results().type_dependent_def_id(self.expr.hir_id)
|
||||
&& is_diag_trait_item(self.cx, expr_def_id, sym::ToString)
|
||||
&& self
|
||||
.cx
|
||||
.typeck_results()
|
||||
.type_dependent_def_id(self.expr.hir_id)
|
||||
.opt_parent(self.cx)
|
||||
.is_diag_item(self.cx, sym::ToString)
|
||||
// Is the method is called on self
|
||||
&& let ExprKind::Path(QPath::Resolved(_, path)) = self_arg.kind
|
||||
&& let [segment] = path.segments
|
||||
|
|
@ -210,7 +215,7 @@ impl FormatImplExpr<'_, '_> {
|
|||
// Since the argument to fmt is itself a reference: &self
|
||||
let reference = peel_ref_operators(self.cx, arg);
|
||||
// Is the reference self?
|
||||
if path_to_local(reference).map(|x| self.cx.tcx.hir_name(x)) == Some(kw::SelfLower) {
|
||||
if reference.res_local_id().map(|x| self.cx.tcx.hir_name(x)) == Some(kw::SelfLower) {
|
||||
let FormatTraitNames { name, .. } = self.format_trait_impl;
|
||||
span_lint(
|
||||
self.cx,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::higher;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use rustc_hir::{AssignOpKind, Expr, ExprKind, LangItem, MatchSource};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
|
@ -41,7 +41,10 @@ declare_clippy_lint! {
|
|||
declare_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]);
|
||||
|
||||
fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||
is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String)
|
||||
cx.typeck_results()
|
||||
.expr_ty(e)
|
||||
.peel_refs()
|
||||
.is_lang_item(cx, LangItem::String)
|
||||
}
|
||||
fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||
let e = e.peel_blocks().peel_borrows();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use clippy_config::Conf;
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::macros::span_is_local;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::path_def_id;
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{Visitor, walk_path};
|
||||
|
|
@ -90,7 +90,12 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto {
|
|||
|diag| {
|
||||
// If the target type is likely foreign mention the orphan rules as it's a common source of
|
||||
// confusion
|
||||
if path_def_id(cx, target_ty.peel_refs()).is_none_or(|id| !id.is_local()) {
|
||||
if target_ty
|
||||
.peel_refs()
|
||||
.basic_res()
|
||||
.opt_def_id()
|
||||
.is_none_or(|id| !id.is_local())
|
||||
{
|
||||
diag.help(
|
||||
"`impl From<Local> for Foreign` is allowed by the orphan rules, for more information see\n\
|
||||
https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::sym;
|
||||
use clippy_utils::ty::is_c_void;
|
||||
use clippy_utils::{path_def_id, sym};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{Expr, ExprKind, QPath};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -41,7 +42,7 @@ impl LateLintPass<'_> for FromRawWithVoidPtr {
|
|||
if let ExprKind::Call(box_from_raw, [arg]) = expr.kind
|
||||
&& let ExprKind::Path(QPath::TypeRelative(ty, seg)) = box_from_raw.kind
|
||||
&& seg.ident.name == sym::from_raw
|
||||
&& let Some(type_str) = path_def_id(cx, ty).and_then(|id| def_id_matches_type(cx, id))
|
||||
&& let Some(type_str) = ty.basic_res().opt_def_id().and_then(|id| def_id_matches_type(cx, id))
|
||||
&& let arg_kind = cx.typeck_results().expr_ty(arg).kind()
|
||||
&& let ty::RawPtr(ty, _) = arg_kind
|
||||
&& is_c_void(cx, *ty)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::{is_in_const_context, is_integer_literal, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, LangItem, PrimTy, QPath, TyKind, def};
|
||||
|
|
@ -89,5 +89,5 @@ impl<'tcx> LateLintPass<'tcx> for FromStrRadix10 {
|
|||
|
||||
/// Checks if a Ty is `String` or `&str`
|
||||
fn is_ty_stringish(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
|
||||
is_type_lang_item(cx, ty, LangItem::String) || ty.peel_refs().is_str()
|
||||
ty.is_lang_item(cx, LangItem::String) || ty.peel_refs().is_str()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
use clippy_utils::res::MaybeResPath;
|
||||
use rustc_hir::{self as hir, HirId, HirIdSet, intravisit};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::iter_input_pats;
|
||||
use clippy_utils::ty::is_unsafe_fn;
|
||||
use clippy_utils::visitors::for_each_expr;
|
||||
use clippy_utils::{iter_input_pats, path_to_local};
|
||||
|
||||
use core::ops::ControlFlow;
|
||||
|
||||
|
|
@ -87,7 +88,7 @@ fn raw_ptr_arg(cx: &LateContext<'_>, arg: &hir::Param<'_>) -> Option<HirId> {
|
|||
}
|
||||
|
||||
fn check_arg(cx: &LateContext<'_>, raw_ptrs: &HirIdSet, arg: &hir::Expr<'_>) {
|
||||
if path_to_local(arg).is_some_and(|id| raw_ptrs.contains(&id)) {
|
||||
if arg.res_local_id().is_some_and(|id| raw_ptrs.contains(&id)) {
|
||||
span_lint(
|
||||
cx,
|
||||
NOT_UNSAFE_PTR_ARG_DEREF,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use rustc_errors::Diag;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LintContext};
|
||||
|
|
@ -6,7 +7,7 @@ use rustc_middle::ty::{self, Ty};
|
|||
use rustc_span::{Span, sym};
|
||||
|
||||
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
|
||||
use clippy_utils::ty::{AdtVariantInfo, approx_ty_size, is_type_diagnostic_item};
|
||||
use clippy_utils::ty::{AdtVariantInfo, approx_ty_size};
|
||||
use clippy_utils::{is_no_std_crate, trait_ref_of_method};
|
||||
|
||||
use super::{RESULT_LARGE_ERR, RESULT_UNIT_ERR};
|
||||
|
|
@ -24,7 +25,7 @@ fn result_err_ty<'tcx>(
|
|||
&& let ty = cx
|
||||
.tcx
|
||||
.instantiate_bound_regions_with_erased(cx.tcx.fn_sig(id).instantiate_identity().output())
|
||||
&& is_type_diagnostic_item(cx, ty, sym::Result)
|
||||
&& ty.is_diag_item(cx, sym::Result)
|
||||
&& let ty::Adt(_, args) = ty.kind()
|
||||
{
|
||||
let err_ty = args.type_at(1);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::visitors::for_each_expr_without_closures;
|
||||
use clippy_utils::{eq_expr_value, higher, sym};
|
||||
use core::ops::ControlFlow;
|
||||
|
|
@ -95,7 +95,7 @@ fn mutex_lock_call<'tcx>(
|
|||
if let ExprKind::MethodCall(path, self_arg, [], _) = &expr.kind
|
||||
&& path.ident.name == sym::lock
|
||||
&& let ty = cx.typeck_results().expr_ty(self_arg).peel_refs()
|
||||
&& is_type_diagnostic_item(cx, ty, sym::Mutex)
|
||||
&& ty.is_diag_item(cx, sym::Mutex)
|
||||
&& op_mutex.is_none_or(|op| eq_expr_value(cx, self_arg, op))
|
||||
{
|
||||
ControlFlow::Break(self_arg)
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ use clippy_config::Conf;
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath};
|
||||
use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context};
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{
|
||||
contains_return, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, is_res_lang_ctor,
|
||||
path_res, peel_blocks, sym,
|
||||
contains_return, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, peel_blocks, sym,
|
||||
};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::{OptionNone, OptionSome};
|
||||
|
|
@ -73,8 +73,8 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
|
|||
&& let ExprKind::Call(then_call, [then_arg]) = then_expr.kind
|
||||
&& !expr.span.from_expansion()
|
||||
&& !then_expr.span.from_expansion()
|
||||
&& is_res_lang_ctor(cx, path_res(cx, then_call), OptionSome)
|
||||
&& is_res_lang_ctor(cx, path_res(cx, peel_blocks(els)), OptionNone)
|
||||
&& then_call.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome)
|
||||
&& peel_blocks(els).res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone)
|
||||
&& !is_else_clause(cx.tcx, expr)
|
||||
&& !is_in_const_context(cx)
|
||||
&& self.msrv.meets(cx, msrvs::BOOL_THEN)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::{IntoSpan, SpanRangeExt, first_line_of_span, indent_of, reindent_multiline, snippet};
|
||||
use clippy_utils::ty::needs_ordered_drop;
|
||||
use clippy_utils::visitors::for_each_expr_without_closures;
|
||||
use clippy_utils::{
|
||||
ContainsName, HirEqInterExpr, SpanlessEq, capture_local_usage, get_enclosing_block, hash_expr, hash_stmt,
|
||||
path_to_local,
|
||||
};
|
||||
use core::iter;
|
||||
use core::ops::ControlFlow;
|
||||
|
|
@ -149,7 +149,7 @@ fn eq_binding_names(s: &Stmt<'_>, names: &[(HirId, Symbol)]) -> bool {
|
|||
/// Checks if the statement modifies or moves any of the given locals.
|
||||
fn modifies_any_local<'tcx>(cx: &LateContext<'tcx>, s: &'tcx Stmt<'_>, locals: &HirIdSet) -> bool {
|
||||
for_each_expr_without_closures(s, |e| {
|
||||
if let Some(id) = path_to_local(e)
|
||||
if let Some(id) = e.res_local_id()
|
||||
&& locals.contains(&id)
|
||||
&& !capture_local_usage(cx, e).is_imm_ref()
|
||||
{
|
||||
|
|
@ -198,7 +198,7 @@ fn scan_block_for_eq<'tcx>(
|
|||
let mut cond_locals = HirIdSet::default();
|
||||
for &cond in conds {
|
||||
let _: Option<!> = for_each_expr_without_closures(cond, |e| {
|
||||
if let Some(id) = path_to_local(e) {
|
||||
if let Some(id) = e.res_local_id() {
|
||||
cond_locals.insert(id);
|
||||
}
|
||||
ControlFlow::Continue(())
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::ty::InteriorMut;
|
||||
use clippy_utils::{SpanlessEq, eq_expr_value, find_binding_init, hash_expr, path_to_local, search_same};
|
||||
use clippy_utils::{SpanlessEq, eq_expr_value, find_binding_init, hash_expr, search_same};
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
|
||||
|
|
@ -16,7 +17,7 @@ fn method_caller_is_mutable<'tcx>(
|
|||
interior_mut.is_interior_mut_ty(cx, caller_ty)
|
||||
|| caller_ty.is_mutable_ptr()
|
||||
// `find_binding_init` will return the binding iff its not mutable
|
||||
|| path_to_local(caller_expr)
|
||||
|| caller_expr.res_local_id()
|
||||
.and_then(|hid| find_binding_init(cx, hid))
|
||||
.is_none()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use rustc_errors::{Applicability, Diag};
|
||||
use rustc_hir::intravisit::{Visitor, VisitorExt, walk_body, walk_expr, walk_ty};
|
||||
use rustc_hir::{self as hir, AmbigArg, Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
|
||||
|
|
@ -14,7 +15,6 @@ use rustc_span::Span;
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::{IntoSpan, SpanRangeExt, snippet};
|
||||
use clippy_utils::sym;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
|
|
@ -227,14 +227,14 @@ impl<'tcx> ImplicitHasherType<'tcx> {
|
|||
|
||||
let ty = lower_ty(cx.tcx, hir_ty);
|
||||
|
||||
if is_type_diagnostic_item(cx, ty, sym::HashMap) && params_len == 2 {
|
||||
if ty.is_diag_item(cx, sym::HashMap) && params_len == 2 {
|
||||
Some(ImplicitHasherType::HashMap(
|
||||
hir_ty.span,
|
||||
ty,
|
||||
snippet(cx, params[0].span, "K"),
|
||||
snippet(cx, params[1].span, "V"),
|
||||
))
|
||||
} else if is_type_diagnostic_item(cx, ty, sym::HashSet) && params_len == 1 {
|
||||
} else if ty.is_diag_item(cx, sym::HashSet) && params_len == 1 {
|
||||
Some(ImplicitHasherType::HashSet(
|
||||
hir_ty.span,
|
||||
ty,
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ use clippy_config::Conf;
|
|||
use clippy_utils::consts::{ConstEvalCtxt, Constant};
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::higher::IfLet;
|
||||
use clippy_utils::is_lint_allowed;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::ty::is_copy;
|
||||
use clippy_utils::{is_lint_allowed, path_to_local};
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -225,7 +226,7 @@ impl<'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
||||
if let Some(local_id) = path_to_local(expr) {
|
||||
if let Some(local_id) = expr.res_local_id() {
|
||||
let Self {
|
||||
cx,
|
||||
ref mut slice_lint_info,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{peel_blocks, peel_hir_expr_while, sym};
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
|
|
@ -47,7 +47,11 @@ impl<'tcx> LateLintPass<'tcx> for IneffectiveOpenOptions {
|
|||
if let ExprKind::MethodCall(name, recv, [_], _) = expr.kind
|
||||
&& name.ident.name == sym::open
|
||||
&& !expr.span.from_expansion()
|
||||
&& is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv).peel_refs(), sym::FsOpenOptions)
|
||||
&& cx
|
||||
.typeck_results()
|
||||
.expr_ty(recv)
|
||||
.peel_refs()
|
||||
.is_diag_item(cx, sym::FsOpenOptions)
|
||||
{
|
||||
let mut append = false;
|
||||
let mut write = None;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::ty::{get_type_diagnostic_name, implements_trait};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use clippy_utils::{higher, sym};
|
||||
use rustc_hir::{BorrowKind, Closure, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -235,7 +236,7 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
|
|||
} else if method.ident.name == sym::collect {
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
if matches!(
|
||||
get_type_diagnostic_name(cx, ty),
|
||||
ty.opt_diag_name(cx),
|
||||
Some(
|
||||
sym::BinaryHeap
|
||||
| sym::BTreeMap
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::ty::{implements_trait, is_type_lang_item};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use clippy_utils::{return_ty, trait_ref_of_method};
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem};
|
||||
|
|
@ -104,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
|
|||
&& impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
|
||||
&& !impl_item.span.from_expansion()
|
||||
// Check if return type is String
|
||||
&& is_type_lang_item(cx, return_ty(cx, impl_item.owner_id), LangItem::String)
|
||||
&& return_ty(cx, impl_item.owner_id).is_lang_item(cx, LangItem::String)
|
||||
// Filters instances of to_string which are required by a trait
|
||||
&& trait_ref_of_method(cx, impl_item.owner_id).is_none()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::higher::ForLoop;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::sym;
|
||||
|
|
@ -55,9 +55,7 @@ impl LateLintPass<'_> for IterOverHashType {
|
|||
if let Some(for_loop) = ForLoop::hir(expr)
|
||||
&& !for_loop.body.span.from_expansion()
|
||||
&& let ty = cx.typeck_results().expr_ty(for_loop.arg).peel_refs()
|
||||
&& hash_iter_tys
|
||||
.into_iter()
|
||||
.any(|sym| is_type_diagnostic_item(cx, ty, sym))
|
||||
&& hash_iter_tys.into_iter().any(|sym| ty.is_diag_item(cx, sym))
|
||||
{
|
||||
span_lint(
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
|
||||
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
|
||||
use clippy_utils::source::{SpanRangeExt, snippet_with_context};
|
||||
use clippy_utils::sugg::{Sugg, has_enclosing_paren};
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use clippy_utils::{
|
||||
fulfill_or_allowed, get_parent_as_impl, is_trait_method, parent_item_name, peel_ref_operators, sym,
|
||||
};
|
||||
use clippy_utils::{fulfill_or_allowed, get_parent_as_impl, parent_item_name, peel_ref_operators, sym};
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::Res;
|
||||
|
|
@ -204,7 +203,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
|
|||
}
|
||||
|
||||
if let ExprKind::MethodCall(method, lhs_expr, [rhs_expr], _) = expr.kind
|
||||
&& is_trait_method(cx, expr, sym::PartialEq)
|
||||
&& cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::PartialEq)
|
||||
&& !expr.span.from_expansion()
|
||||
{
|
||||
check_empty_expr(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use clippy_utils::diagnostics::span_lint_hir_and_then;
|
||||
use clippy_utils::path_to_local_id;
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::visitors::is_local_used;
|
||||
use rustc_errors::Applicability;
|
||||
|
|
@ -145,7 +145,7 @@ fn check_assign<'tcx>(
|
|||
&& let Some(expr) = block.stmts.iter().last()
|
||||
&& let hir::StmtKind::Semi(expr) = expr.kind
|
||||
&& let hir::ExprKind::Assign(var, value, _) = expr.kind
|
||||
&& path_to_local_id(var, decl)
|
||||
&& var.res_local_id() == Some(decl)
|
||||
{
|
||||
if block
|
||||
.stmts
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{is_diag_item_method, is_trait_method, path_to_local_id, sym};
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes};
|
||||
use clippy_utils::sym;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Body, Closure, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -73,10 +73,13 @@ impl_lint_pass!(LinesFilterMapOk => [LINES_FILTER_MAP_OK]);
|
|||
impl LateLintPass<'_> for LinesFilterMapOk {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
if let ExprKind::MethodCall(fm_method, fm_receiver, fm_args, fm_span) = expr.kind
|
||||
&& is_trait_method(cx, expr, sym::Iterator)
|
||||
&& cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)
|
||||
&& let fm_method_name = fm_method.ident.name
|
||||
&& matches!(fm_method_name, sym::filter_map | sym::flat_map | sym::flatten)
|
||||
&& is_type_diagnostic_item(cx, cx.typeck_results().expr_ty_adjusted(fm_receiver), sym::IoLines)
|
||||
&& cx
|
||||
.typeck_results()
|
||||
.expr_ty_adjusted(fm_receiver)
|
||||
.is_diag_item(cx, sym::IoLines)
|
||||
&& should_lint(cx, fm_args, fm_method_name)
|
||||
&& self.msrv.meets(cx, msrvs::MAP_WHILE)
|
||||
{
|
||||
|
|
@ -117,10 +120,15 @@ fn should_lint(cx: &LateContext<'_>, args: &[Expr<'_>], method_name: Symbol) ->
|
|||
params: [param], value, ..
|
||||
} = cx.tcx.hir_body(*body)
|
||||
&& let ExprKind::MethodCall(method, receiver, [], _) = value.kind
|
||||
&& path_to_local_id(receiver, param.pat.hir_id)
|
||||
&& let Some(method_did) = cx.typeck_results().type_dependent_def_id(value.hir_id)
|
||||
{
|
||||
is_diag_item_method(cx, method_did, sym::Result) && method.ident.name == sym::ok
|
||||
method.ident.name == sym::ok
|
||||
&& receiver.res_local_id() == Some(param.pat.hir_id)
|
||||
&& cx
|
||||
.typeck_results()
|
||||
.type_dependent_def_id(value.hir_id)
|
||||
.opt_parent(cx)
|
||||
.opt_impl_ty(cx)
|
||||
.is_diag_item(cx, sym::Result)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use std::ops::ControlFlow;
|
||||
|
||||
use clippy_utils::diagnostics::span_lint_hir_and_then;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath};
|
||||
use clippy_utils::visitors::for_each_expr;
|
||||
use clippy_utils::{eq_expr_value, higher, path_to_local_id, sym};
|
||||
use clippy_utils::{eq_expr_value, higher, sym};
|
||||
use rustc_errors::{Applicability, MultiSpan};
|
||||
use rustc_hir::{Expr, ExprKind, LangItem, Node, Pat, PatKind};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -49,7 +49,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'_>, iterable: &Expr
|
|||
{
|
||||
// Destructured iterator element `(idx, _)`, look for uses of the binding
|
||||
for_each_expr(cx, body, |expr| {
|
||||
if path_to_local_id(expr, binding_id) {
|
||||
if expr.res_local_id() == Some(binding_id) {
|
||||
check_index_usage(cx, expr, pat, enumerate_span, chars_span, chars_recv);
|
||||
}
|
||||
CONTINUE
|
||||
|
|
@ -58,7 +58,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'_>, iterable: &Expr
|
|||
// Bound as a tuple, look for `tup.0`
|
||||
for_each_expr(cx, body, |expr| {
|
||||
if let ExprKind::Field(e, field) = expr.kind
|
||||
&& path_to_local_id(e, binding_id)
|
||||
&& e.res_local_id() == Some(binding_id)
|
||||
&& field.name == sym::integer(0)
|
||||
{
|
||||
check_index_usage(cx, expr, pat, enumerate_span, chars_span, chars_recv);
|
||||
|
|
@ -81,7 +81,7 @@ fn check_index_usage<'tcx>(
|
|||
return;
|
||||
};
|
||||
|
||||
let is_string_like = |ty: Ty<'_>| ty.is_str() || is_type_lang_item(cx, ty, LangItem::String);
|
||||
let is_string_like = |ty: Ty<'_>| ty.is_str() || ty.is_lang_item(cx, LangItem::String);
|
||||
let message = match parent_expr.kind {
|
||||
ExprKind::MethodCall(segment, recv, ..)
|
||||
// We currently only lint `str` methods (which `String` can deref to), so a `.is_str()` check is sufficient here
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use super::EXPLICIT_INTO_ITER_LOOP;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::is_trait_method;
|
||||
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::Expr;
|
||||
|
|
@ -43,7 +43,11 @@ impl AdjustKind {
|
|||
}
|
||||
|
||||
pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<'_>) {
|
||||
if !is_trait_method(cx, call_expr, sym::IntoIterator) {
|
||||
if !cx
|
||||
.ty_based_def(call_expr)
|
||||
.opt_parent(cx)
|
||||
.is_diag_item(cx, sym::IntoIterator)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use super::EXPLICIT_ITER_LOOP;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::sym;
|
||||
use clippy_utils::ty::{
|
||||
implements_trait, implements_trait_with_env, is_copy, is_type_lang_item, make_normalized_projection,
|
||||
implements_trait, implements_trait_with_env, is_copy, make_normalized_projection,
|
||||
make_normalized_projection_with_regions, normalize_with_regions,
|
||||
};
|
||||
use rustc_errors::Applicability;
|
||||
|
|
@ -127,8 +128,7 @@ fn is_ref_iterable<'tcx>(
|
|||
let self_ty = typeck.expr_ty(self_arg);
|
||||
let self_is_copy = is_copy(cx, self_ty);
|
||||
|
||||
if is_type_lang_item(cx, self_ty.peel_refs(), rustc_hir::LangItem::OwnedBox)
|
||||
&& !msrv.meets(cx, msrvs::BOX_INTO_ITER)
|
||||
if self_ty.peel_refs().is_lang_item(cx, rustc_hir::LangItem::OwnedBox) && !msrv.meets(cx, msrvs::BOX_INTO_ITER)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::FOR_KV_MAP;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{pat_is_wild, sugg};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Pat, PatKind};
|
||||
|
|
@ -34,7 +34,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx
|
|||
_ => arg,
|
||||
};
|
||||
|
||||
if is_type_diagnostic_item(cx, ty, sym::HashMap) || is_type_diagnostic_item(cx, ty, sym::BTreeMap) {
|
||||
if ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap) {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
FOR_KV_MAP,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use super::ITER_NEXT_LOOP;
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::is_trait_method;
|
||||
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
|
||||
use rustc_hir::Expr;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::sym;
|
||||
|
||||
pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>) {
|
||||
if is_trait_method(cx, arg, sym::Iterator) {
|
||||
if cx.ty_based_def(arg).opt_parent(cx).is_diag_item(cx, sym::Iterator) {
|
||||
span_lint(
|
||||
cx,
|
||||
ITER_NEXT_LOOP,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use super::MANUAL_FIND;
|
||||
use super::utils::make_iterator_snippet;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use clippy_utils::usage::contains_return_break_continue_macro;
|
||||
use clippy_utils::{higher, is_res_lang_ctor, path_res, peel_blocks_with_stmt};
|
||||
use clippy_utils::{higher, peel_blocks_with_stmt};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, Node, Pat, PatKind, Stmt, StmtKind};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -34,8 +34,8 @@ pub(super) fn check<'tcx>(
|
|||
&& let StmtKind::Semi(semi) = stmt.kind
|
||||
&& let ExprKind::Ret(Some(ret_value)) = semi.kind
|
||||
&& let ExprKind::Call(ctor, [inner_ret]) = ret_value.kind
|
||||
&& is_res_lang_ctor(cx, path_res(cx, ctor), LangItem::OptionSome)
|
||||
&& path_res(cx, inner_ret) == Res::Local(binding_id)
|
||||
&& ctor.res(cx).ctor_parent(cx).is_lang_item(cx, LangItem::OptionSome)
|
||||
&& inner_ret.res_local_id() == Some(binding_id)
|
||||
&& !contains_return_break_continue_macro(cond)
|
||||
&& let Some((last_stmt, last_ret)) = last_stmt_and_ret(cx, expr)
|
||||
{
|
||||
|
|
@ -150,7 +150,7 @@ fn last_stmt_and_ret<'tcx>(
|
|||
&& let Some((_, Node::Block(block))) = parent_iter.next()
|
||||
&& let Some((last_stmt, last_ret)) = extract(block)
|
||||
&& last_stmt.hir_id == node_hir
|
||||
&& is_res_lang_ctor(cx, path_res(cx, last_ret), LangItem::OptionNone)
|
||||
&& last_ret.res(cx).ctor_parent(cx).is_lang_item(cx, LangItem::OptionNone)
|
||||
&& let Some((_, Node::Expr(_block))) = parent_iter.next()
|
||||
// This includes the function header
|
||||
&& let Some((_, func)) = parent_iter.next()
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ use super::MANUAL_FLATTEN;
|
|||
use super::utils::make_iterator_snippet;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::{HasSession, indent_of, reindent_multiline, snippet_with_applicability};
|
||||
use clippy_utils::visitors::is_local_used;
|
||||
use clippy_utils::{higher, is_refutable, path_to_local_id, peel_blocks_with_stmt, span_contains_comment};
|
||||
use clippy_utils::{higher, is_refutable, peel_blocks_with_stmt, span_contains_comment};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{Expr, Pat, PatKind};
|
||||
|
|
@ -27,7 +28,7 @@ pub(super) fn check<'tcx>(
|
|||
= higher::IfLet::hir(cx, inner_expr)
|
||||
// Ensure match_expr in `if let` statement is the same as the pat from the for-loop
|
||||
&& let PatKind::Binding(_, pat_hir_id, _, _) = pat.kind
|
||||
&& path_to_local_id(let_expr, pat_hir_id)
|
||||
&& let_expr.res_local_id() == Some(pat_hir_id)
|
||||
// Ensure the `if let` statement is for the `Some` variant of `Option` or the `Ok` variant of `Result`
|
||||
&& let PatKind::TupleStruct(ref qpath, [inner_pat], _) = let_pat.kind
|
||||
&& let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(qpath, let_pat.hir_id)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use super::{IncrementVisitor, InitializeVisitor, MANUAL_MEMCPY};
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::is_copy;
|
||||
use clippy_utils::usage::local_used_in;
|
||||
use clippy_utils::{get_enclosing_block, higher, path_to_local, sugg};
|
||||
use clippy_utils::{get_enclosing_block, higher, sugg};
|
||||
use rustc_ast::ast;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::walk_block;
|
||||
|
|
@ -67,7 +68,7 @@ pub(super) fn check<'tcx>(
|
|||
&& !local_used_in(cx, canonical_id, base_left)
|
||||
&& !local_used_in(cx, canonical_id, base_right)
|
||||
// Source and destination must be different
|
||||
&& path_to_local(base_left) != path_to_local(base_right)
|
||||
&& base_left.res_local_id() != base_right.res_local_id()
|
||||
{
|
||||
Some((
|
||||
ty,
|
||||
|
|
@ -128,7 +129,7 @@ fn build_manual_memcpy_suggestion<'tcx>(
|
|||
let print_limit = |end: &Expr<'_>, end_str: &str, base: &Expr<'_>, sugg: MinifyingSugg<'static>| {
|
||||
if let ExprKind::MethodCall(method, recv, [], _) = end.kind
|
||||
&& method.ident.name == sym::len
|
||||
&& path_to_local(recv) == path_to_local(base)
|
||||
&& recv.res_local_id() == base.res_local_id()
|
||||
{
|
||||
if sugg.to_string() == end_str {
|
||||
sugg::EMPTY.into()
|
||||
|
|
@ -364,7 +365,7 @@ fn get_details_from_idx<'tcx>(
|
|||
starts: &[Start<'tcx>],
|
||||
) -> Option<(StartKind<'tcx>, Offset)> {
|
||||
fn get_start<'tcx>(e: &Expr<'_>, starts: &[Start<'tcx>]) -> Option<StartKind<'tcx>> {
|
||||
let id = path_to_local(e)?;
|
||||
let id = e.res_local_id()?;
|
||||
starts.iter().find(|start| start.id == id).map(|start| start.kind)
|
||||
}
|
||||
|
||||
|
|
@ -425,7 +426,7 @@ fn get_assignments<'a, 'tcx>(
|
|||
.chain(*expr)
|
||||
.filter(move |e| {
|
||||
if let ExprKind::AssignOp(_, place, _) = e.kind {
|
||||
path_to_local(place).is_some_and(|id| {
|
||||
place.res_local_id().is_some_and(|id| {
|
||||
!loop_counters
|
||||
.iter()
|
||||
// skip the first item which should be `StartKind::Range`
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::MISSING_SPIN_LOOP;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::std_or_core;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Block, Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -40,7 +40,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &'
|
|||
&& let ExprKind::MethodCall(method, callee, ..) = unpack_cond(cond).kind
|
||||
&& [sym::load, sym::compare_exchange, sym::compare_exchange_weak].contains(&method.ident.name)
|
||||
&& let callee_ty = cx.typeck_results().expr_ty(callee)
|
||||
&& is_type_diagnostic_item(cx, callee_ty, sym::AtomicBool)
|
||||
&& callee_ty.is_diag_item(cx, sym::AtomicBool)
|
||||
&& let Some(std_or_core) = std_or_core(cx)
|
||||
{
|
||||
span_lint_and_sugg(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use super::MUT_RANGE_BOUND;
|
||||
use clippy_utils::diagnostics::span_lint_and_note;
|
||||
use clippy_utils::{get_enclosing_block, higher, path_to_local};
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::{get_enclosing_block, higher};
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{BindingMode, Expr, ExprKind, HirId, Node, PatKind};
|
||||
use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
|
||||
|
|
@ -39,7 +40,7 @@ fn mut_warn_with_span(cx: &LateContext<'_>, span: Option<Span>) {
|
|||
}
|
||||
|
||||
fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option<HirId> {
|
||||
if let Some(hir_id) = path_to_local(bound)
|
||||
if let Some(hir_id) = bound.res_local_id()
|
||||
&& let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
|
||||
&& let PatKind::Binding(BindingMode::MUT, ..) = pat.kind
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use super::SAME_ITEM_PUSH;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::msrvs::Msrv;
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath};
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||
use clippy_utils::{msrvs, path_to_local, std_or_core, sym};
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use clippy_utils::{msrvs, std_or_core, sym};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
|
|
@ -125,7 +126,7 @@ impl<'a, 'tcx> SameItemPushVisitor<'a, 'tcx> {
|
|||
if !self.non_deterministic_expr
|
||||
&& !self.multiple_pushes
|
||||
&& let Some((vec, _, _)) = self.vec_push
|
||||
&& let Some(hir_id) = path_to_local(vec)
|
||||
&& let Some(hir_id) = vec.res_local_id()
|
||||
{
|
||||
!self.used_locals.contains(&hir_id)
|
||||
} else {
|
||||
|
|
@ -141,7 +142,7 @@ impl<'tcx> Visitor<'tcx> for SameItemPushVisitor<'_, 'tcx> {
|
|||
ExprKind::Loop(..) | ExprKind::Match(..) | ExprKind::If(..) => self.non_deterministic_expr = true,
|
||||
ExprKind::Block(block, _) => self.visit_block(block),
|
||||
_ => {
|
||||
if let Some(hir_id) = path_to_local(expr) {
|
||||
if let Some(hir_id) = expr.res_local_id() {
|
||||
self.used_locals.insert(hir_id);
|
||||
}
|
||||
walk_expr(self, expr);
|
||||
|
|
@ -186,7 +187,7 @@ fn get_vec_push<'tcx>(
|
|||
&& let ExprKind::MethodCall(path, self_expr, [pushed_item], _) = &semi_stmt.kind
|
||||
// Check that the method being called is push() on a Vec
|
||||
&& path.ident.name == sym::push
|
||||
&& is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_expr), sym::Vec)
|
||||
&& cx.typeck_results().expr_ty(self_expr).is_diag_item(cx, sym::Vec)
|
||||
{
|
||||
return Some((self_expr, pushed_item, semi_stmt.span.ctxt()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::UNUSED_ENUMERATE_INDEX;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{pat_is_wild, sugg};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::DefKind;
|
||||
|
|
@ -17,7 +17,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>, arg: &Expr<'_
|
|||
&& let ExprKind::MethodCall(_method, self_arg, [], _) = arg.kind
|
||||
&& let ty = cx.typeck_results().expr_ty(arg)
|
||||
&& pat_is_wild(cx, &index.kind, body)
|
||||
&& is_type_diagnostic_item(cx, ty, sym::Enumerate)
|
||||
&& ty.is_diag_item(cx, sym::Enumerate)
|
||||
&& let Some((DefKind::AssocFn, call_id)) = cx.typeck_results().type_dependent_def(arg.hir_id)
|
||||
&& cx.tcx.is_diagnostic_item(sym::enumerate_method, call_id)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::ty::{has_iter_method, implements_trait};
|
||||
use clippy_utils::{get_parent_expr, is_integer_const, path_to_local, path_to_local_id, sugg};
|
||||
use clippy_utils::{get_parent_expr, is_integer_const, sugg};
|
||||
use rustc_ast::ast::{LitIntType, LitKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{Visitor, walk_expr, walk_local};
|
||||
|
|
@ -47,7 +48,7 @@ impl<'a, 'tcx> IncrementVisitor<'a, 'tcx> {
|
|||
impl<'tcx> Visitor<'tcx> for IncrementVisitor<'_, 'tcx> {
|
||||
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
|
||||
// If node is a variable
|
||||
if let Some(def_id) = path_to_local(expr) {
|
||||
if let Some(def_id) = expr.res_local_id() {
|
||||
if let Some(parent) = get_parent_expr(self.cx, expr) {
|
||||
let state = self.states.entry(def_id).or_insert(IncrementVisitorVarState::Initial);
|
||||
if *state == IncrementVisitorVarState::IncrOnce {
|
||||
|
|
@ -175,7 +176,7 @@ impl<'tcx> Visitor<'tcx> for InitializeVisitor<'_, 'tcx> {
|
|||
}
|
||||
|
||||
// If node is the desired variable, see how it's used
|
||||
if path_to_local_id(expr, self.var_id) {
|
||||
if expr.res_local_id() == Some(self.var_id) {
|
||||
if self.past_loop {
|
||||
self.state = InitializeVisitorState::DontWarn;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ use std::ops::ControlFlow;
|
|||
|
||||
use super::WHILE_LET_ON_ITERATOR;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::visitors::is_res_used;
|
||||
use clippy_utils::{get_enclosing_loop_or_multi_call_closure, higher, is_refutable, is_res_lang_ctor, is_trait_method};
|
||||
use clippy_utils::{get_enclosing_loop_or_multi_call_closure, higher, is_refutable};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::intravisit::{Visitor, walk_expr};
|
||||
|
|
@ -19,11 +20,11 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
|||
if let Some(higher::WhileLet { if_then, let_pat, let_expr, label, .. }) = higher::WhileLet::hir(expr)
|
||||
// check for `Some(..)` pattern
|
||||
&& let PatKind::TupleStruct(ref pat_path, some_pat, _) = let_pat.kind
|
||||
&& is_res_lang_ctor(cx, cx.qpath_res(pat_path, let_pat.hir_id), LangItem::OptionSome)
|
||||
&& cx.qpath_res(pat_path, let_pat.hir_id).ctor_parent(cx).is_lang_item(cx, LangItem::OptionSome)
|
||||
// check for call to `Iterator::next`
|
||||
&& let ExprKind::MethodCall(method_name, iter_expr, [], _) = let_expr.kind
|
||||
&& method_name.ident.name == sym::next
|
||||
&& is_trait_method(cx, let_expr, sym::Iterator)
|
||||
&& cx.ty_based_def(let_expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)
|
||||
&& let Some(iter_expr_struct) = try_parse_iter_expr(cx, iter_expr)
|
||||
// get the loop containing the match expression
|
||||
&& !uses_iter(cx, &iter_expr_struct, if_then)
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ use clippy_config::Conf;
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::higher::If;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::HasSession as _;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, peel_and_count_ty_refs};
|
||||
use clippy_utils::ty::peel_and_count_ty_refs;
|
||||
use clippy_utils::{eq_expr_value, peel_blocks, span_contains_comment};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
||||
|
|
@ -104,7 +105,7 @@ impl ManualAbsDiff {
|
|||
fn are_ty_eligible<'tcx>(&self, cx: &LateContext<'tcx>, a: &Expr<'_>, b: &Expr<'_>) -> Option<(Ty<'tcx>, usize)> {
|
||||
let is_int = |ty: Ty<'_>| matches!(ty.kind(), ty::Uint(_) | ty::Int(_)) && self.msrv.meets(cx, msrvs::ABS_DIFF);
|
||||
let is_duration =
|
||||
|ty| is_type_diagnostic_item(cx, ty, sym::Duration) && self.msrv.meets(cx, msrvs::DURATION_ABS_DIFF);
|
||||
|ty: Ty<'_>| ty.is_diag_item(cx, sym::Duration) && self.msrv.meets(cx, msrvs::DURATION_ABS_DIFF);
|
||||
|
||||
let a_ty = cx.typeck_results().expr_ty(a).peel_refs();
|
||||
let (b_ty, b_n_refs, _) = peel_and_count_ty_refs(cx.typeck_results().expr_ty(b));
|
||||
|
|
|
|||
|
|
@ -3,13 +3,11 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant};
|
|||
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
|
||||
use clippy_utils::higher::If;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes};
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use clippy_utils::visitors::is_const_evaluatable;
|
||||
use clippy_utils::{
|
||||
MaybePath, eq_expr_value, is_diag_trait_item, is_in_const_context, is_trait_method, path_res, path_to_local_id,
|
||||
peel_blocks, peel_blocks_with_stmt, sym,
|
||||
};
|
||||
use clippy_utils::{eq_expr_value, is_in_const_context, peel_blocks, peel_blocks_with_stmt, sym};
|
||||
use itertools::Itertools;
|
||||
use rustc_errors::{Applicability, Diag};
|
||||
use rustc_hir::def::Res;
|
||||
|
|
@ -292,10 +290,12 @@ fn is_if_elseif_else_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx
|
|||
/// # ;
|
||||
/// ```
|
||||
fn is_max_min_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<ClampSuggestion<'tcx>> {
|
||||
if let ExprKind::MethodCall(seg_second, receiver, [arg_second], _) = &expr.kind
|
||||
&& (cx.typeck_results().expr_ty_adjusted(receiver).is_floating_point() || is_trait_method(cx, expr, sym::Ord))
|
||||
if let ExprKind::MethodCall(seg_second, receiver, [arg_second], _) = expr.kind
|
||||
&& (cx.typeck_results().expr_ty_adjusted(receiver).is_floating_point()
|
||||
|| cx.ty_based_def(expr).assoc_fn_parent(cx).is_diag_item(cx, sym::Ord))
|
||||
&& let ExprKind::MethodCall(seg_first, input, [arg_first], _) = &receiver.kind
|
||||
&& (cx.typeck_results().expr_ty_adjusted(input).is_floating_point() || is_trait_method(cx, receiver, sym::Ord))
|
||||
&& (cx.typeck_results().expr_ty_adjusted(input).is_floating_point()
|
||||
|| cx.ty_based_def(receiver).assoc_fn_parent(cx).is_diag_item(cx, sym::Ord))
|
||||
{
|
||||
let is_float = cx.typeck_results().expr_ty_adjusted(input).is_floating_point();
|
||||
let (min, max) = match (seg_first.ident.name, seg_second.ident.name) {
|
||||
|
|
@ -331,18 +331,18 @@ fn is_call_max_min_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>)
|
|||
fn segment<'tcx>(cx: &LateContext<'_>, func: &Expr<'tcx>) -> Option<FunctionType<'tcx>> {
|
||||
match func.kind {
|
||||
ExprKind::Path(QPath::Resolved(None, path)) => {
|
||||
let id = path.res.opt_def_id()?;
|
||||
match cx.tcx.get_diagnostic_name(id) {
|
||||
let def = path.res.opt_def(cx)?;
|
||||
match cx.tcx.get_diagnostic_name(def.1) {
|
||||
Some(sym::cmp_min) => Some(FunctionType::CmpMin),
|
||||
Some(sym::cmp_max) => Some(FunctionType::CmpMax),
|
||||
_ if is_diag_trait_item(cx, id, sym::Ord) => {
|
||||
_ if def.assoc_fn_parent(cx).is_diag_item(cx, sym::Ord) => {
|
||||
Some(FunctionType::OrdOrFloat(path.segments.last().expect("infallible")))
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
},
|
||||
ExprKind::Path(QPath::TypeRelative(ty, seg)) => {
|
||||
matches!(path_res(cx, ty), Res::PrimTy(PrimTy::Float(_))).then(|| FunctionType::OrdOrFloat(seg))
|
||||
matches!(ty.basic_res(), Res::PrimTy(PrimTy::Float(_))).then(|| FunctionType::OrdOrFloat(seg))
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
|
|
@ -435,7 +435,7 @@ fn is_match_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Opt
|
|||
let first = BinaryOp::new(first)?;
|
||||
let second = BinaryOp::new(second)?;
|
||||
if let PatKind::Binding(_, binding, _, None) = &last_arm.pat.kind
|
||||
&& path_to_local_id(peel_blocks_with_stmt(last_arm.body), *binding)
|
||||
&& peel_blocks_with_stmt(last_arm.body).res_local_id() == Some(*binding)
|
||||
&& last_arm.guard.is_none()
|
||||
{
|
||||
// Proceed as normal
|
||||
|
|
@ -516,7 +516,7 @@ fn is_two_if_pattern<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) ->
|
|||
},
|
||||
span: first_expr.span.to(second_expr.span),
|
||||
make_assignment: Some(maybe_input_first_path),
|
||||
hir_with_ignore_attr: Some(first_expr.hir_id()),
|
||||
hir_with_ignore_attr: Some(first_expr.hir_id),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
|
@ -655,8 +655,8 @@ fn is_clamp_meta_pattern<'tcx>(
|
|||
let (min, max) = (second_expr, first_expr);
|
||||
let refers_to_input = match input_hir_ids {
|
||||
Some((first_hir_id, second_hir_id)) => {
|
||||
path_to_local_id(peel_blocks(first_bin.left), first_hir_id)
|
||||
&& path_to_local_id(peel_blocks(second_bin.left), second_hir_id)
|
||||
peel_blocks(first_bin.left).res_local_id() == Some(first_hir_id)
|
||||
&& peel_blocks(second_bin.left).res_local_id() == Some(second_hir_id)
|
||||
},
|
||||
None => eq_expr_value(cx, first_bin.left, second_bin.left),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::consts::ConstEvalCtxt;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::is_from_proc_macro;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::{is_from_proc_macro, path_to_local};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
|
@ -138,7 +139,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
|
|||
// Checking all possible scenarios using a function would be a hopeless task, as we have
|
||||
// 16 possible alignments of constants/operands. For now, let's use `partition`.
|
||||
&& let mut exprs = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
|
||||
&& exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2
|
||||
&& exprs.iter_mut().partition_in_place(|i| i.res_local_id().is_some()) == 2
|
||||
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||
&& (
|
||||
is_not_const(cx.tcx, cx.tcx.hir_enclosing_body_owner(expr.hir_id).into())
|
||||
|
|
@ -149,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
|
|||
&& let ctxt = expr.span.ctxt()
|
||||
&& let Some(const_1) = ecx.eval_local(const_1, ctxt)
|
||||
&& let Some(const_2) = ecx.eval_local(const_2, ctxt)
|
||||
&& path_to_local(first).is_some_and(|f| path_to_local(second).is_some_and(|s| f == s))
|
||||
&& first.res_local_id().is_some_and(|f| second.res_local_id().is_some_and(|s| f == s))
|
||||
// The actual infinity check, we also allow `NEG_INFINITY` before` INFINITY` just in
|
||||
// case somebody does that for some reason
|
||||
&& (const_1.is_pos_infinity() && const_2.is_neg_infinity()
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::span_lint_hir_and_then;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes};
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::sym;
|
||||
use clippy_utils::visitors::{is_local_used, local_used_once};
|
||||
use clippy_utils::{is_trait_method, path_to_local_id, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BindingMode, ExprKind, LetStmt, Node, PatKind, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -81,8 +82,8 @@ impl LateLintPass<'_> for ManualHashOne {
|
|||
&& !hash_expr.span.from_expansion()
|
||||
&& let ExprKind::MethodCall(seg, hashed_value, [ref_to_hasher], _) = hash_expr.kind
|
||||
&& seg.ident.name == sym::hash
|
||||
&& is_trait_method(cx, hash_expr, sym::Hash)
|
||||
&& path_to_local_id(ref_to_hasher.peel_borrows(), hasher)
|
||||
&& cx.ty_based_def(hash_expr).opt_parent(cx).is_diag_item(cx, sym::Hash)
|
||||
&& ref_to_hasher.peel_borrows().res_local_id() == Some(hasher)
|
||||
|
||||
&& let maybe_finish_stmt = stmts.next()
|
||||
// There should be no more statements referencing `hasher`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use crate::manual_ignore_case_cmp::MatchType::{Literal, ToAscii};
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::sym;
|
||||
use clippy_utils::ty::{get_type_diagnostic_name, is_type_diagnostic_item, is_type_lang_item};
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::ExprKind::{Binary, Lit, MethodCall};
|
||||
|
|
@ -58,7 +58,7 @@ fn get_ascii_type<'a>(cx: &LateContext<'a>, kind: rustc_hir::ExprKind<'_>) -> Op
|
|||
if needs_ref_to_cmp(cx, ty)
|
||||
|| ty.is_str()
|
||||
|| ty.is_slice()
|
||||
|| matches!(get_type_diagnostic_name(cx, ty), Some(sym::OsStr | sym::OsString))
|
||||
|| matches!(ty.opt_diag_name(cx), Some(sym::OsStr | sym::OsString))
|
||||
{
|
||||
return Some((expr.span, ToAscii(is_lower, ty_raw)));
|
||||
}
|
||||
|
|
@ -72,8 +72,8 @@ fn get_ascii_type<'a>(cx: &LateContext<'a>, kind: rustc_hir::ExprKind<'_>) -> Op
|
|||
fn needs_ref_to_cmp(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
|
||||
ty.is_char()
|
||||
|| *ty.kind() == ty::Uint(UintTy::U8)
|
||||
|| is_type_diagnostic_item(cx, ty, sym::Vec)
|
||||
|| is_type_lang_item(cx, ty, LangItem::String)
|
||||
|| ty.is_diag_item(cx, sym::Vec)
|
||||
|| ty.is_lang_item(cx, LangItem::String)
|
||||
}
|
||||
|
||||
impl LateLintPass<'_> for ManualIgnoreCaseCmp {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ use clippy_config::Conf;
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::macros::matching_root_macro_call;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{higher, is_in_const_context, path_to_local, peel_ref_operators, sym};
|
||||
use clippy_utils::{higher, is_in_const_context, peel_ref_operators, sym};
|
||||
use rustc_ast::LitKind::{Byte, Char};
|
||||
use rustc_ast::ast::RangeLimits;
|
||||
use rustc_errors::Applicability;
|
||||
|
|
@ -125,7 +126,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
|
|||
}
|
||||
|
||||
fn get_ty_sugg<'tcx>(cx: &LateContext<'tcx>, arg: &Expr<'_>) -> Option<(Span, Ty<'tcx>)> {
|
||||
let local_hid = path_to_local(arg)?;
|
||||
let local_hid = arg.res_local_id()?;
|
||||
if let Node::Param(Param { ty_span, span, .. }) = cx.tcx.parent_hir_node(local_hid)
|
||||
// `ty_span` and `span` are the same for inferred type, thus a type suggestion must be given
|
||||
&& ty_span == span
|
||||
|
|
|
|||
|
|
@ -2,16 +2,14 @@ use crate::question_mark::{QUESTION_MARK, QuestionMark};
|
|||
use clippy_config::types::MatchLintBehaviour;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::higher::IfLetOrMatch;
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath};
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{
|
||||
MaybePath, is_lint_allowed, is_never_expr, is_wild, msrvs, pat_and_expr_can_be_question_mark, path_res, peel_blocks,
|
||||
};
|
||||
use clippy_utils::{is_lint_allowed, is_never_expr, is_wild, msrvs, pat_and_expr_can_be_question_mark, peel_blocks};
|
||||
use rustc_ast::BindingMode;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{CtorOf, DefKind, Res};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, HirId, MatchSource, Pat, PatExpr, PatExprKind, PatKind, QPath, Stmt, StmtKind};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, MatchSource, Pat, PatExpr, PatExprKind, PatKind, QPath, Stmt, StmtKind};
|
||||
use rustc_lint::{LateContext, LintContext};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::symbol::{Symbol, sym};
|
||||
|
|
@ -131,39 +129,25 @@ fn is_arms_disjointed(cx: &LateContext<'_>, arm1: &Arm<'_>, arm2: &Arm<'_>) -> b
|
|||
|
||||
/// Returns `true` if the given pattern is a variant of an enum.
|
||||
pub fn is_enum_variant(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
|
||||
struct Pat<'hir>(&'hir rustc_hir::Pat<'hir>);
|
||||
|
||||
impl<'hir> MaybePath<'hir> for Pat<'hir> {
|
||||
fn qpath_opt(&self) -> Option<&QPath<'hir>> {
|
||||
match self.0.kind {
|
||||
PatKind::Struct(ref qpath, fields, _)
|
||||
if fields
|
||||
.iter()
|
||||
.all(|field| is_wild(field.pat) || matches!(field.pat.kind, PatKind::Binding(..))) =>
|
||||
{
|
||||
Some(qpath)
|
||||
},
|
||||
PatKind::TupleStruct(ref qpath, pats, _)
|
||||
if pats
|
||||
.iter()
|
||||
.all(|pat| is_wild(pat) || matches!(pat.kind, PatKind::Binding(..))) =>
|
||||
{
|
||||
Some(qpath)
|
||||
},
|
||||
PatKind::Expr(&PatExpr {
|
||||
kind: PatExprKind::Path(ref qpath),
|
||||
..
|
||||
}) => Some(qpath),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn hir_id(&self) -> HirId {
|
||||
self.0.hir_id
|
||||
}
|
||||
}
|
||||
|
||||
let res = path_res(cx, &Pat(pat));
|
||||
let path = match pat.kind {
|
||||
PatKind::Struct(ref qpath, fields, _)
|
||||
if fields
|
||||
.iter()
|
||||
.all(|field| is_wild(field.pat) || matches!(field.pat.kind, PatKind::Binding(..))) =>
|
||||
{
|
||||
(qpath, pat.hir_id)
|
||||
},
|
||||
PatKind::TupleStruct(ref qpath, pats, _)
|
||||
if pats
|
||||
.iter()
|
||||
.all(|pat| is_wild(pat) || matches!(pat.kind, PatKind::Binding(..))) =>
|
||||
{
|
||||
(qpath, pat.hir_id)
|
||||
},
|
||||
PatKind::Expr(e) if let Some((qpath, id)) = e.opt_qpath() => (qpath, id),
|
||||
_ => return false,
|
||||
};
|
||||
let res = path.res(cx);
|
||||
matches!(
|
||||
res,
|
||||
Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(CtorOf::Variant, _), _)
|
||||
|
|
@ -384,7 +368,7 @@ fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>, check_types: boo
|
|||
}
|
||||
let ty = typeck_results.pat_ty(pat);
|
||||
// Option and Result are allowed, everything else isn't.
|
||||
if !(is_type_diagnostic_item(cx, ty, sym::Option) || is_type_diagnostic_item(cx, ty, sym::Result)) {
|
||||
if !(ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result)) {
|
||||
has_disallowed = true;
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::{is_trait_method, peel_hir_expr_refs};
|
||||
use clippy_utils::peel_hir_expr_refs;
|
||||
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{Expr, ExprKind, Mutability, QPath};
|
||||
|
|
@ -52,7 +53,7 @@ impl LateLintPass<'_> for ManualMainSeparatorStr {
|
|||
&& path.ident.name == sym::to_string
|
||||
&& let ExprKind::Path(QPath::Resolved(None, path)) = receiver.kind
|
||||
&& let Res::Def(DefKind::Const, receiver_def_id) = path.res
|
||||
&& is_trait_method(cx, target, sym::ToString)
|
||||
&& cx.ty_based_def(target).opt_parent(cx).is_diag_item(cx, sym::ToString)
|
||||
&& cx.tcx.is_diagnostic_item(sym::path_main_separator, receiver_def_id)
|
||||
&& let ty::Ref(_, ty, Mutability::Not) = cx.typeck_results().expr_ty_adjusted(expr).kind()
|
||||
&& ty.is_str()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
|
||||
use clippy_utils::msrvs::Msrv;
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};
|
||||
use clippy_utils::{is_none_pattern, msrvs, peel_hir_expr_refs, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
|
|
@ -189,7 +190,7 @@ fn check_arms(cx: &LateContext<'_>, none_arm: &Arm<'_>, some_arm: &Arm<'_>) -> b
|
|||
|
||||
fn returns_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
match expr.kind {
|
||||
ExprKind::Path(_) => clippy_utils::is_path_diagnostic_item(cx, expr, sym::default_fn),
|
||||
ExprKind::Path(_) => expr.res(cx).is_diag_item(cx, sym::default_fn),
|
||||
ExprKind::Closure(cl) => is_empty_slice(cx, cx.tcx.hir_body(cl.body).value),
|
||||
_ => false,
|
||||
}
|
||||
|
|
@ -214,11 +215,11 @@ fn is_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||
_ => false,
|
||||
},
|
||||
ExprKind::Array([]) => true,
|
||||
ExprKind::Call(def, []) => clippy_utils::is_path_diagnostic_item(cx, def, sym::default_fn),
|
||||
ExprKind::Call(def, []) => def.res(cx).is_diag_item(cx, sym::default_fn),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_slice_from_ref(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
clippy_utils::is_path_diagnostic_item(cx, expr, sym::slice_from_ref)
|
||||
expr.basic_res().is_diag_item(cx, sym::slice_from_ref)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::consts::{ConstEvalCtxt, FullInt};
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::is_in_const_context;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::{is_in_const_context, path_to_local};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, Node, TyKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
|
|
@ -64,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
|
|||
&& let ExprKind::Binary(rem2_op, rem2_lhs, rem2_rhs) = add_other.kind
|
||||
&& rem2_op.node == BinOpKind::Rem
|
||||
&& const1 == const2
|
||||
&& let Some(hir_id) = path_to_local(rem2_lhs)
|
||||
&& let Some(hir_id) = rem2_lhs.res_local_id()
|
||||
&& let Some(const3) = check_for_unsigned_int_constant(cx, ctxt, rem2_rhs)
|
||||
// Also ensures the const is nonzero since zero can't be a divisor
|
||||
&& const2 == const3
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use clippy_config::Conf;
|
|||
use clippy_utils::SpanlessEq;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::ty::{get_type_diagnostic_name, is_type_lang_item};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::ExprKind::Assign;
|
||||
|
|
@ -189,7 +189,7 @@ fn check_to_owned(
|
|||
&& let Some(chars_expr_def_id) = cx.typeck_results().type_dependent_def_id(chars_expr.hir_id)
|
||||
&& cx.tcx.is_diagnostic_item(sym::str_chars, chars_expr_def_id)
|
||||
&& let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()
|
||||
&& is_type_lang_item(cx, ty, hir::LangItem::String)
|
||||
&& ty.is_lang_item(cx, hir::LangItem::String)
|
||||
&& SpanlessEq::new(cx).eq_expr(left_expr, str_expr)
|
||||
&& let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind
|
||||
&& let hir::ExprKind::Closure(closure) = closure_expr.kind
|
||||
|
|
@ -250,7 +250,7 @@ fn match_acceptable_sym(cx: &LateContext<'_>, collect_def_id: DefId) -> bool {
|
|||
|
||||
fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: Msrv) -> bool {
|
||||
let ty = cx.typeck_results().expr_ty(expr).peel_refs();
|
||||
let required = match get_type_diagnostic_name(cx, ty) {
|
||||
let required = match ty.opt_diag_name(cx) {
|
||||
Some(sym::BinaryHeap) => msrvs::BINARY_HEAP_RETAIN,
|
||||
Some(sym::BTreeSet) => msrvs::BTREE_SET_RETAIN,
|
||||
Some(sym::BTreeMap) => msrvs::BTREE_MAP_RETAIN,
|
||||
|
|
@ -264,7 +264,7 @@ fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: Msrv)
|
|||
|
||||
fn match_map_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
|
||||
let ty = cx.typeck_results().expr_ty(expr).peel_refs();
|
||||
matches!(get_type_diagnostic_name(cx, ty), Some(sym::BTreeMap | sym::HashMap))
|
||||
matches!(ty.opt_diag_name(cx), Some(sym::BTreeMap | sym::HashMap))
|
||||
}
|
||||
|
||||
fn make_span_lint_and_sugg(cx: &LateContext<'_>, span: Span, sugg: String) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_context};
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{iter_input_pats, method_chain_args};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -205,9 +205,9 @@ fn lint_map_unit_fn(
|
|||
) {
|
||||
let var_arg = &map_args.0;
|
||||
|
||||
let (map_type, variant, lint) = if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(var_arg), sym::Option) {
|
||||
let (map_type, variant, lint) = if cx.typeck_results().expr_ty(var_arg).is_diag_item(cx, sym::Option) {
|
||||
("Option", "Some", OPTION_MAP_UNIT_FN)
|
||||
} else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(var_arg), sym::Result) {
|
||||
} else if cx.typeck_results().expr_ty(var_arg).is_diag_item(cx, sym::Result) {
|
||||
("Result", "Ok", RESULT_MAP_UNIT_FN)
|
||||
} else {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{higher, is_res_lang_ctor, sym};
|
||||
use clippy_utils::{higher, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, LangItem, PatKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -57,8 +57,8 @@ impl<'tcx> LateLintPass<'tcx> for MatchResultOk {
|
|||
if let ExprKind::MethodCall(ok_path, recv, [], ..) = let_expr.kind //check is expr.ok() has type Result<T,E>.ok(, _)
|
||||
&& let PatKind::TupleStruct(ref pat_path, [ok_pat], _) = let_pat.kind //get operation
|
||||
&& ok_path.ident.name == sym::ok
|
||||
&& is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result)
|
||||
&& is_res_lang_ctor(cx, cx.qpath_res(pat_path, let_pat.hir_id), LangItem::OptionSome)
|
||||
&& cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Result)
|
||||
&& cx.qpath_res(pat_path, let_pat.hir_id).ctor_parent(cx).is_lang_item(cx, LangItem::OptionSome)
|
||||
&& let ctxt = expr.span.ctxt()
|
||||
&& let_expr.span.ctxt() == ctxt
|
||||
&& let_pat.span.ctxt() == ctxt
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
use clippy_utils::diagnostics::span_lint_hir_and_then;
|
||||
use clippy_utils::higher::IfLetOrMatch;
|
||||
use clippy_utils::msrvs::Msrv;
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath};
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::visitors::is_local_used;
|
||||
use clippy_utils::{
|
||||
SpanlessEq, get_ref_operators, is_res_lang_ctor, is_unit_expr, path_to_local, peel_blocks_with_stmt,
|
||||
peel_ref_operators,
|
||||
};
|
||||
use clippy_utils::{SpanlessEq, get_ref_operators, is_unit_expr, peel_blocks_with_stmt, peel_ref_operators};
|
||||
use rustc_ast::BorrowKind;
|
||||
use rustc_errors::MultiSpan;
|
||||
use rustc_hir::LangItem::OptionNone;
|
||||
|
|
@ -67,7 +65,7 @@ fn check_arm<'tcx>(
|
|||
&& outer_pat.span.eq_ctxt(inner_scrutinee.span)
|
||||
// match expression must be a local binding
|
||||
// match <local> { .. }
|
||||
&& let Some(binding_id) = path_to_local(peel_ref_operators(cx, inner_scrutinee))
|
||||
&& let Some(binding_id) = peel_ref_operators(cx, inner_scrutinee).res_local_id()
|
||||
&& !pat_contains_disallowed_or(cx, inner_then_pat, msrv)
|
||||
// the binding must come from the pattern of the containing match arm
|
||||
// ..<local>.. => match <local> { .. }
|
||||
|
|
@ -136,7 +134,10 @@ fn arm_is_wild_like(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
|
|||
kind: PatExprKind::Path(qpath),
|
||||
hir_id,
|
||||
..
|
||||
}) => is_res_lang_ctor(cx, cx.qpath_res(qpath, *hir_id), OptionNone),
|
||||
}) => cx
|
||||
.qpath_res(qpath, *hir_id)
|
||||
.ctor_parent(cx)
|
||||
.is_lang_item(cx, OptionNone),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::{path_to_local_id, peel_blocks, strip_pat_refs};
|
||||
use clippy_utils::{peel_blocks, strip_pat_refs};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{ExprKind, LetStmt, MatchSource, PatKind, QPath};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -17,7 +18,7 @@ pub(crate) fn check(cx: &LateContext<'_>, local: &LetStmt<'_>) -> bool {
|
|||
&& args.len() == 1
|
||||
&& let PatKind::Binding(binding, arg, ..) = strip_pat_refs(&args[0]).kind
|
||||
&& let body = peel_blocks(arms[0].body)
|
||||
&& path_to_local_id(body, arg)
|
||||
&& body.res_local_id() == Some(arg)
|
||||
{
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
span_lint_and_sugg(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};
|
||||
use clippy_utils::visitors::contains_unsafe_block;
|
||||
use clippy_utils::{is_res_lang_ctor, path_res, path_to_local_id};
|
||||
|
||||
use rustc_hir::LangItem::{OptionNone, OptionSome};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, HirId, Pat, PatKind};
|
||||
|
|
@ -66,15 +65,15 @@ fn is_some_expr(cx: &LateContext<'_>, target: HirId, ctxt: SyntaxContext, expr:
|
|||
&& let ExprKind::Call(callee, [arg]) = inner_expr.kind
|
||||
{
|
||||
return ctxt == expr.span.ctxt()
|
||||
&& is_res_lang_ctor(cx, path_res(cx, callee), OptionSome)
|
||||
&& path_to_local_id(arg, target);
|
||||
&& callee.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome)
|
||||
&& arg.res_local_id() == Some(target);
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn is_none_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
if let Some(inner_expr) = peels_blocks_incl_unsafe_opt(expr) {
|
||||
return is_res_lang_ctor(cx, path_res(cx, inner_expr), OptionNone);
|
||||
return inner_expr.res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone);
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
@ -98,7 +97,7 @@ pub(super) fn check_match<'tcx>(
|
|||
expr: &'tcx Expr<'_>,
|
||||
) {
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
if is_type_diagnostic_item(cx, ty, sym::Option)
|
||||
if ty.is_diag_item(cx, sym::Option)
|
||||
&& let [first_arm, second_arm] = arms
|
||||
&& first_arm.guard.is_none()
|
||||
&& second_arm.guard.is_none()
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ use super::MANUAL_MAP;
|
|||
use super::manual_utils::{SomeExpr, check_with};
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
|
||||
use clippy_utils::{is_res_lang_ctor, path_res};
|
||||
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath};
|
||||
use rustc_hir::LangItem::OptionSome;
|
||||
use rustc_hir::{Arm, Block, BlockCheckMode, Expr, ExprKind, Pat, UnsafeSource};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -91,7 +90,7 @@ fn get_some_expr<'tcx>(
|
|||
// TODO: Allow more complex expressions.
|
||||
match expr.kind {
|
||||
ExprKind::Call(callee, [arg])
|
||||
if ctxt == expr.span.ctxt() && is_res_lang_ctor(cx, path_res(cx, callee), OptionSome) =>
|
||||
if ctxt == expr.span.ctxt() && callee.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome) =>
|
||||
{
|
||||
Some(SomeExpr::new_no_negated(arg, needs_unsafe_block))
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath};
|
||||
use clippy_utils::source::{indent_of, reindent_multiline};
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::{option_arg_ty, peel_and_count_ty_refs};
|
||||
use clippy_utils::{get_parent_expr, is_res_lang_ctor, path_res, peel_blocks, span_contains_comment};
|
||||
use clippy_utils::{get_parent_expr, peel_blocks, span_contains_comment};
|
||||
use rustc_ast::{BindingMode, Mutability};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr};
|
||||
|
|
@ -72,7 +73,10 @@ fn is_variant_or_wildcard(cx: &LateContext<'_>, pat: &Pat<'_>, can_be_wild: bool
|
|||
true
|
||||
},
|
||||
PatKind::TupleStruct(qpath, ..) => {
|
||||
is_res_lang_ctor(cx, cx.qpath_res(&qpath, pat.hir_id), ResultErr) == must_match_err
|
||||
cx.qpath_res(&qpath, pat.hir_id)
|
||||
.ctor_parent(cx)
|
||||
.is_lang_item(cx, ResultErr)
|
||||
== must_match_err
|
||||
},
|
||||
PatKind::Binding(_, _, _, Some(pat)) | PatKind::Ref(pat, _) => {
|
||||
is_variant_or_wildcard(cx, pat, can_be_wild, must_match_err)
|
||||
|
|
@ -103,7 +107,7 @@ fn is_ok_or_err<'hir>(cx: &LateContext<'_>, pat: &Pat<'hir>) -> Option<(bool, &'
|
|||
/// Check if `expr` contains `Some(ident)`, possibly as a block
|
||||
fn is_some_ident<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, ident: &Ident, ty: Ty<'tcx>) -> bool {
|
||||
if let ExprKind::Call(body_callee, [body_arg]) = peel_blocks(expr).kind
|
||||
&& is_res_lang_ctor(cx, path_res(cx, body_callee), OptionSome)
|
||||
&& body_callee.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome)
|
||||
&& cx.typeck_results().expr_ty(body_arg) == ty
|
||||
&& let ExprKind::Path(QPath::Resolved(
|
||||
_,
|
||||
|
|
@ -120,7 +124,7 @@ fn is_some_ident<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, ident: &Ident, t
|
|||
|
||||
/// Check if `expr` is `None`, possibly as a block
|
||||
fn is_none(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
is_res_lang_ctor(cx, path_res(cx, peel_blocks(expr)), OptionNone)
|
||||
peel_blocks(expr).res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone)
|
||||
}
|
||||
|
||||
/// Suggest replacing `expr` by `scrutinee.METHOD()`, where `METHOD` is either `ok` or
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use clippy_utils::consts::ConstEvalCtxt;
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath};
|
||||
use clippy_utils::source::{SpanRangeExt as _, indent_of, reindent_multiline};
|
||||
use rustc_ast::{BindingMode, ByRef};
|
||||
use rustc_errors::Applicability;
|
||||
|
|
@ -10,8 +11,8 @@ use rustc_span::sym;
|
|||
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::{expr_type_is_certain, get_type_diagnostic_name, implements_trait};
|
||||
use clippy_utils::{is_default_equivalent, is_lint_allowed, path_res, peel_blocks, span_contains_comment};
|
||||
use clippy_utils::ty::{expr_type_is_certain, implements_trait};
|
||||
use clippy_utils::{is_default_equivalent, is_lint_allowed, peel_blocks, span_contains_comment};
|
||||
|
||||
use super::{MANUAL_UNWRAP_OR, MANUAL_UNWRAP_OR_DEFAULT};
|
||||
|
||||
|
|
@ -114,7 +115,8 @@ fn handle(
|
|||
&& is_default_equivalent(cx, peel_blocks(body_none))
|
||||
{
|
||||
// We now check if the condition is a None variant, in which case we need to specify the type
|
||||
if path_res(cx, condition)
|
||||
if condition
|
||||
.res(cx)
|
||||
.opt_def_id()
|
||||
.is_some_and(|id| Some(cx.tcx.parent(id)) == cx.tcx.lang_items().option_none_variant())
|
||||
{
|
||||
|
|
@ -174,7 +176,7 @@ fn handle(
|
|||
}
|
||||
|
||||
fn find_type_name<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'static str> {
|
||||
match get_type_diagnostic_name(cx, ty)? {
|
||||
match ty.opt_diag_name(cx)? {
|
||||
sym::Option => Some("Option"),
|
||||
sym::Result => Some("Result"),
|
||||
_ => None,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
use crate::map_unit_fn::OPTION_MAP_UNIT_FN;
|
||||
use crate::matches::MATCH_AS_REF;
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};
|
||||
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::{is_copy, is_type_diagnostic_item, is_unsafe_fn, peel_and_count_ty_refs};
|
||||
use clippy_utils::ty::{is_copy, is_unsafe_fn, peel_and_count_ty_refs};
|
||||
use clippy_utils::{
|
||||
CaptureKind, can_move_expr_to_closure, expr_requires_coercion, is_else_clause, is_lint_allowed, is_res_lang_ctor,
|
||||
path_res, path_to_local_id, peel_blocks, peel_hir_expr_refs, peel_hir_expr_while,
|
||||
CaptureKind, can_move_expr_to_closure, expr_requires_coercion, is_else_clause, is_lint_allowed, peel_blocks,
|
||||
peel_hir_expr_refs, peel_hir_expr_while,
|
||||
};
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_errors::Applicability;
|
||||
|
|
@ -33,8 +34,7 @@ where
|
|||
let (scrutinee_ty, ty_ref_count, ty_mutability) = peel_and_count_ty_refs(cx.typeck_results().expr_ty(scrutinee));
|
||||
let ty_mutability = ty_mutability.unwrap_or(Mutability::Mut);
|
||||
|
||||
if !(is_type_diagnostic_item(cx, scrutinee_ty, sym::Option)
|
||||
&& is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym::Option))
|
||||
if !(scrutinee_ty.is_diag_item(cx, sym::Option) && cx.typeck_results().expr_ty(expr).is_diag_item(cx, sym::Option))
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
|
@ -138,7 +138,7 @@ where
|
|||
{
|
||||
snippet_with_applicability(cx, func.span, "..", &mut app).into_owned()
|
||||
} else {
|
||||
if path_to_local_id(some_expr.expr, id)
|
||||
if some_expr.expr.res_local_id() == Some(id)
|
||||
&& !is_lint_allowed(cx, MATCH_AS_REF, expr.hir_id)
|
||||
&& binding_ref.is_some()
|
||||
{
|
||||
|
|
@ -190,7 +190,7 @@ pub struct SuggInfo<'a> {
|
|||
fn can_pass_as_func<'tcx>(cx: &LateContext<'tcx>, binding: HirId, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
|
||||
match expr.kind {
|
||||
ExprKind::Call(func, [arg])
|
||||
if path_to_local_id(arg, binding)
|
||||
if arg.res_local_id() == Some(binding)
|
||||
&& cx.typeck_results().expr_adjustments(arg).is_empty()
|
||||
&& !is_unsafe_fn(cx, cx.typeck_results().expr_ty(func).peel_refs()) =>
|
||||
{
|
||||
|
|
@ -259,9 +259,19 @@ pub(super) fn try_parse_pattern<'tcx>(
|
|||
kind: PatExprKind::Path(qpath),
|
||||
hir_id,
|
||||
..
|
||||
}) if is_res_lang_ctor(cx, cx.qpath_res(qpath, *hir_id), OptionNone) => Some(OptionPat::None),
|
||||
}) if cx
|
||||
.qpath_res(qpath, *hir_id)
|
||||
.ctor_parent(cx)
|
||||
.is_lang_item(cx, OptionNone) =>
|
||||
{
|
||||
Some(OptionPat::None)
|
||||
},
|
||||
PatKind::TupleStruct(ref qpath, [pattern], _)
|
||||
if is_res_lang_ctor(cx, cx.qpath_res(qpath, pat.hir_id), OptionSome) && pat.span.ctxt() == ctxt =>
|
||||
if cx
|
||||
.qpath_res(qpath, pat.hir_id)
|
||||
.ctor_parent(cx)
|
||||
.is_lang_item(cx, OptionSome)
|
||||
&& pat.span.ctxt() == ctxt =>
|
||||
{
|
||||
Some(OptionPat::Some { pattern, ref_count })
|
||||
},
|
||||
|
|
@ -273,5 +283,5 @@ pub(super) fn try_parse_pattern<'tcx>(
|
|||
|
||||
// Checks for the `None` value.
|
||||
fn is_none_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
is_res_lang_ctor(cx, path_res(cx, peel_blocks(expr)), OptionNone)
|
||||
peel_blocks(expr).res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::{is_none_arm, is_res_lang_ctor, path_res, peel_blocks};
|
||||
use clippy_utils::{is_none_arm, peel_blocks};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, LangItem, Mutability, PatKind, QPath};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -58,10 +59,13 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr:
|
|||
// Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`)
|
||||
fn is_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option<Mutability> {
|
||||
if let PatKind::TupleStruct(ref qpath, [first_pat, ..], _) = arm.pat.kind
|
||||
&& is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), LangItem::OptionSome)
|
||||
&& cx
|
||||
.qpath_res(qpath, arm.pat.hir_id)
|
||||
.ctor_parent(cx)
|
||||
.is_lang_item(cx, LangItem::OptionSome)
|
||||
&& let PatKind::Binding(BindingMode(ByRef::Yes(mutabl), _), .., ident, _) = first_pat.kind
|
||||
&& let ExprKind::Call(e, [arg]) = peel_blocks(arm.body).kind
|
||||
&& is_res_lang_ctor(cx, path_res(cx, e), LangItem::OptionSome)
|
||||
&& e.res(cx).ctor_parent(cx).is_lang_item(cx, LangItem::OptionSome)
|
||||
&& let ExprKind::Path(QPath::Resolved(_, path2)) = arg.kind
|
||||
&& path2.segments.len() == 1
|
||||
&& ident.name == path2.segments[0].ident.name
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::{SpanlessEq, fulfill_or_allowed, hash_expr, is_lint_allowed, path_to_local, search_same};
|
||||
use clippy_utils::{SpanlessEq, fulfill_or_allowed, hash_expr, is_lint_allowed, search_same};
|
||||
use core::cmp::Ordering;
|
||||
use core::{iter, slice};
|
||||
use itertools::Itertools;
|
||||
|
|
@ -61,8 +62,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
|
|||
let check_eq_with_pat = |expr_a: &Expr<'_>, expr_b: &Expr<'_>| {
|
||||
let mut local_map: HirIdMap<HirId> = HirIdMap::default();
|
||||
let eq_fallback = |a: &Expr<'_>, b: &Expr<'_>| {
|
||||
if let Some(a_id) = path_to_local(a)
|
||||
&& let Some(b_id) = path_to_local(b)
|
||||
if let Some(a_id) = a.res_local_id()
|
||||
&& let Some(b_id) = b.res_local_id()
|
||||
&& let entry = match local_map.entry(a_id) {
|
||||
HirIdMapEntry::Vacant(entry) => entry,
|
||||
// check if using the same bindings as before
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use std::ops::ControlFlow;
|
||||
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::sym;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{Visitor, walk_expr};
|
||||
|
|
@ -58,7 +58,7 @@ impl MatchExprVisitor<'_, '_> {
|
|||
if let Some(case_method) = get_case_method(segment_ident) {
|
||||
let ty = self.cx.typeck_results().expr_ty(receiver).peel_refs();
|
||||
|
||||
if is_type_lang_item(self.cx, ty, LangItem::String) || ty.kind() == &ty::Str {
|
||||
if ty.is_lang_item(self.cx, LangItem::String) || ty.kind() == &ty::Str {
|
||||
return ControlFlow::Break(case_method);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{is_refutable, peel_hir_pat_refs, recurse_or_patterns};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||
|
|
@ -16,8 +16,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
|
|||
let ty = cx.typeck_results().expr_ty(ex).peel_refs();
|
||||
let adt_def = match ty.kind() {
|
||||
ty::Adt(adt_def, _)
|
||||
if adt_def.is_enum()
|
||||
&& !(is_type_diagnostic_item(cx, ty, sym::Option) || is_type_diagnostic_item(cx, ty, sym::Result)) =>
|
||||
if adt_def.is_enum() && !(ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result)) =>
|
||||
{
|
||||
adt_def
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_note;
|
||||
use clippy_utils::macros::{is_panic, root_macro_call};
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::visitors::is_local_used;
|
||||
use clippy_utils::{is_in_const_context, is_wild, peel_blocks_with_stmt};
|
||||
use rustc_hir::{Arm, Expr, PatKind};
|
||||
|
|
@ -16,7 +16,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm<'
|
|||
}
|
||||
|
||||
let ex_ty = cx.typeck_results().expr_ty(ex).peel_refs();
|
||||
if is_type_diagnostic_item(cx, ex_ty, sym::Result) {
|
||||
if ex_ty.is_diag_item(cx, sym::Result) {
|
||||
for arm in arms {
|
||||
if let PatKind::TupleStruct(ref path, inner, _) = arm.pat.kind {
|
||||
let path_str = rustc_hir_pretty::qpath_to_string(&cx.tcx, path);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use super::NEEDLESS_MATCH;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, same_type_modulo_regions};
|
||||
use clippy_utils::ty::same_type_modulo_regions;
|
||||
use clippy_utils::{
|
||||
SpanlessEq, eq_expr_value, get_parent_expr_for_hir, higher, is_else_clause, is_res_lang_ctor, over, path_res,
|
||||
peel_blocks_with_stmt,
|
||||
SpanlessEq, eq_expr_value, get_parent_expr_for_hir, higher, is_else_clause, over, peel_blocks_with_stmt,
|
||||
};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::OptionNone;
|
||||
|
|
@ -104,8 +104,8 @@ fn check_if_let_inner(cx: &LateContext<'_>, if_let: &higher::IfLet<'_>) -> bool
|
|||
return false;
|
||||
}
|
||||
let let_expr_ty = cx.typeck_results().expr_ty(if_let.let_expr);
|
||||
if is_type_diagnostic_item(cx, let_expr_ty, sym::Option) {
|
||||
return is_res_lang_ctor(cx, path_res(cx, else_expr), OptionNone)
|
||||
if let_expr_ty.is_diag_item(cx, sym::Option) {
|
||||
return else_expr.res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone)
|
||||
|| eq_expr_value(cx, if_let.let_expr, else_expr);
|
||||
}
|
||||
return eq_expr_value(cx, if_let.let_expr, else_expr);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::macros::matching_root_macro_call;
|
||||
use clippy_utils::msrvs::Msrv;
|
||||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::visitors::{for_each_expr_without_closures, is_local_used};
|
||||
use clippy_utils::{is_in_const_context, path_to_local, sym};
|
||||
use clippy_utils::{is_in_const_context, sym};
|
||||
use rustc_ast::{BorrowKind, LitKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
|
|
@ -164,7 +165,7 @@ fn get_pat_binding<'tcx>(
|
|||
guard_expr: &Expr<'_>,
|
||||
outer_arm: &Arm<'tcx>,
|
||||
) -> Option<PatBindingInfo> {
|
||||
if let Some(local) = path_to_local(guard_expr)
|
||||
if let Some(local) = guard_expr.res_local_id()
|
||||
&& !is_local_used(cx, outer_arm.body, local)
|
||||
{
|
||||
let mut span = None;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use super::REDUNDANT_PATTERN_MATCHING;
|
||||
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
||||
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
|
||||
use clippy_utils::source::walk_span_to_context;
|
||||
use clippy_utils::sugg::{Sugg, make_unop};
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, needs_ordered_drop};
|
||||
use clippy_utils::ty::needs_ordered_drop;
|
||||
use clippy_utils::visitors::{any_temporaries_need_ordered_drop, for_each_expr_without_closures};
|
||||
use clippy_utils::{higher, is_expn_of, is_trait_method, sym};
|
||||
use clippy_utils::{higher, is_expn_of, sym};
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::{self, OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk};
|
||||
|
|
@ -216,7 +217,7 @@ fn find_method_sugg_for_if_let<'tcx>(
|
|||
if keyword == "while"
|
||||
&& let ExprKind::MethodCall(method_path, _, [], _) = let_expr.kind
|
||||
&& method_path.ident.name == sym::next
|
||||
&& is_trait_method(cx, let_expr, sym::Iterator)
|
||||
&& cx.ty_based_def(let_expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -460,7 +461,7 @@ fn is_pat_variant(cx: &LateContext<'_>, pat: &Pat<'_>, path: &QPath<'_>, expecte
|
|||
Item::Diag(expected_ty, expected_variant) => {
|
||||
let ty = cx.typeck_results().pat_ty(pat);
|
||||
|
||||
if is_type_diagnostic_item(cx, ty, expected_ty) {
|
||||
if ty.is_diag_item(cx, expected_ty) {
|
||||
let variant = ty
|
||||
.ty_adt_def()
|
||||
.expect("struct pattern type is not an ADT")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::get_parent_expr;
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::option_arg_ty;
|
||||
use clippy_utils::{get_parent_expr, is_res_lang_ctor, path_res};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::ResultErr;
|
||||
use rustc_hir::{Expr, ExprKind, LangItem, MatchSource, QPath};
|
||||
|
|
@ -25,7 +26,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, scrutine
|
|||
&& let ExprKind::Path(ref match_fun_path) = match_fun.kind
|
||||
&& matches!(match_fun_path, QPath::LangItem(LangItem::TryTraitBranch, ..))
|
||||
&& let ExprKind::Call(err_fun, [err_arg]) = try_arg.kind
|
||||
&& is_res_lang_ctor(cx, path_res(cx, err_fun), ResultErr)
|
||||
&& err_fun.res(cx).ctor_parent(cx).is_lang_item(cx, ResultErr)
|
||||
&& let Some(return_ty) = find_return_type(cx, &expr.kind)
|
||||
{
|
||||
let (prefix, suffix, err_ty) = if let Some(ty) = result_error_type(cx, return_ty) {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::{MaybeDef, MaybeQPath};
|
||||
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::is_non_aggregate_primitive_type;
|
||||
use clippy_utils::{
|
||||
is_default_equivalent, is_expr_used_or_unified, is_res_lang_ctor, path_res, peel_ref_operators, std_or_core,
|
||||
};
|
||||
use clippy_utils::{is_default_equivalent, is_expr_used_or_unified, peel_ref_operators, std_or_core};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::{OptionNone, OptionSome};
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
|
|
@ -129,7 +128,7 @@ impl_lint_pass!(MemReplace =>
|
|||
[MEM_REPLACE_OPTION_WITH_NONE, MEM_REPLACE_OPTION_WITH_SOME, MEM_REPLACE_WITH_UNINIT, MEM_REPLACE_WITH_DEFAULT]);
|
||||
|
||||
fn check_replace_option_with_none(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) -> bool {
|
||||
if is_res_lang_ctor(cx, path_res(cx, src), OptionNone) {
|
||||
if src.res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone) {
|
||||
// Since this is a late pass (already type-checked),
|
||||
// and we already know that the second argument is an
|
||||
// `Option`, we do not need to check the first
|
||||
|
|
@ -163,7 +162,7 @@ fn check_replace_option_with_some(
|
|||
msrv: Msrv,
|
||||
) -> bool {
|
||||
if let ExprKind::Call(src_func, [src_arg]) = src.kind
|
||||
&& is_res_lang_ctor(cx, path_res(cx, src_func), OptionSome)
|
||||
&& src_func.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome)
|
||||
&& msrv.meets(cx, msrvs::OPTION_REPLACE)
|
||||
{
|
||||
// We do not have to check for a `const` context here, because `core::mem::replace()` and
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::{MaybeDef, MaybeResPath};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::visitors::is_local_used;
|
||||
use clippy_utils::{path_to_local_id, peel_blocks, peel_ref_operators, strip_pat_refs};
|
||||
use clippy_utils::{peel_blocks, peel_ref_operators, strip_pat_refs};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Closure, Expr, ExprKind, PatKind};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -23,10 +23,14 @@ pub(super) fn check<'tcx>(
|
|||
&& let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind
|
||||
&& let ExprKind::Binary(ref op, l, r) = body.value.kind
|
||||
&& op.node == BinOpKind::Eq
|
||||
&& is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(filter_recv).peel_refs(), sym::SliceIter)
|
||||
&& cx
|
||||
.typeck_results()
|
||||
.expr_ty(filter_recv)
|
||||
.peel_refs()
|
||||
.is_diag_item(cx, sym::SliceIter)
|
||||
&& let operand_is_arg = (|expr| {
|
||||
let expr = peel_ref_operators(cx, peel_blocks(expr));
|
||||
path_to_local_id(expr, arg_id)
|
||||
expr.res_local_id() == Some(arg_id)
|
||||
})
|
||||
&& let needle = if operand_is_arg(l) {
|
||||
r
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -17,7 +17,7 @@ pub(super) fn check<'tcx>(
|
|||
&& let Some(impl_id) = cx.tcx.impl_of_assoc(bytes_id)
|
||||
&& cx.tcx.type_of(impl_id).instantiate_identity().is_str()
|
||||
&& let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs()
|
||||
&& (ty.is_str() || is_type_lang_item(cx, ty, hir::LangItem::String))
|
||||
&& (ty.is_str() || ty.is_lang_item(cx, hir::LangItem::String))
|
||||
{
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
span_lint_and_sugg(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::sym;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, LangItem};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -14,7 +14,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 caller_type = if ty.is_str() {
|
||||
"str"
|
||||
} else if is_type_lang_item(cx, ty, LangItem::String) {
|
||||
} else if ty.is_lang_item(cx, LangItem::String) {
|
||||
"String"
|
||||
} else {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::{SpanRangeExt, indent_of, reindent_multiline};
|
||||
use clippy_utils::sym;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, LangItem};
|
||||
|
|
@ -43,7 +43,7 @@ pub(super) fn check<'tcx>(
|
|||
|| ext_str.chars().skip(1).all(|c| c.is_lowercase() || c.is_ascii_digit()))
|
||||
&& !ext_str.chars().skip(1).all(|c| c.is_ascii_digit())
|
||||
&& let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs()
|
||||
&& (recv_ty.is_str() || is_type_lang_item(cx, recv_ty, LangItem::String))
|
||||
&& (recv_ty.is_str() || recv_ty.is_lang_item(cx, LangItem::String))
|
||||
{
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::method_chain_args;
|
||||
use clippy_utils::res::MaybeQPath;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::{method_chain_args, path_def_id};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, Lint};
|
||||
|
|
@ -17,7 +18,7 @@ pub(super) fn check(
|
|||
) -> bool {
|
||||
if let Some(args) = method_chain_args(info.chain, chain_methods)
|
||||
&& let hir::ExprKind::Call(fun, [arg_char]) = info.other.kind
|
||||
&& let Some(id) = path_def_id(cx, fun).map(|ctor_id| cx.tcx.parent(ctor_id))
|
||||
&& let Some(id) = fun.res(cx).opt_def_id().map(|ctor_id| cx.tcx.parent(ctor_id))
|
||||
&& Some(id) == cx.tcx.lang_items().option_some_variant()
|
||||
{
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::is_range_full;
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, LangItem, QPath};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -29,9 +29,9 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span
|
|||
|
||||
fn match_acceptable_type(cx: &LateContext<'_>, expr: &Expr<'_>, types: &[rustc_span::Symbol]) -> bool {
|
||||
let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs();
|
||||
types.iter().any(|&ty| is_type_diagnostic_item(cx, expr_ty, ty))
|
||||
types.iter().any(|&ty| expr_ty.is_diag_item(cx, ty))
|
||||
// String type is a lang item but not a diagnostic item for now so we need a separate check
|
||||
|| is_type_lang_item(cx, expr_ty, LangItem::String)
|
||||
|| expr_ty.is_lang_item(cx, LangItem::String)
|
||||
}
|
||||
|
||||
fn suggest(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::is_trait_method;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
|
||||
use clippy_utils::ty::{get_iterator_item_ty, is_copy};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::Expr;
|
||||
|
|
@ -19,7 +19,9 @@ pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span,
|
|||
{
|
||||
subst.type_at(0)
|
||||
},
|
||||
_ if is_trait_method(cx, expr, sym::Iterator) && msrv.meets(cx, msrvs::ITERATOR_COPIED) => {
|
||||
_ if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)
|
||||
&& msrv.meets(cx, msrvs::ITERATOR_COPIED) =>
|
||||
{
|
||||
match get_iterator_item_ty(cx, recv_ty) {
|
||||
// <T as Iterator>::Item
|
||||
Some(ty) => ty,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
|
||||
use clippy_utils::ty::{has_non_owning_mutable_access, implements_trait};
|
||||
use clippy_utils::{is_mutable, is_trait_method, path_to_local_with_projections, sym};
|
||||
use clippy_utils::{is_mutable, path_to_local_with_projections, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, Node, PatKind};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -13,7 +14,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, self_expr: &'_ Exp
|
|||
let typeck = cx.typeck_results();
|
||||
|
||||
// if the "last" method is that of Iterator
|
||||
if is_trait_method(cx, expr, sym::Iterator)
|
||||
if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)
|
||||
// if self implements DoubleEndedIterator
|
||||
&& let Some(deiter_id) = cx.tcx.get_diagnostic_item(sym::DoubleEndedIterator)
|
||||
&& let self_type = cx.typeck_results().expr_ty(self_expr)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::methods::DRAIN_COLLECT;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::{is_range_full, std_or_core};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, LangItem, Path, QPath};
|
||||
|
|
@ -35,8 +35,8 @@ fn check_vec(cx: &LateContext<'_>, args: &[Expr<'_>], expr: Ty<'_>, recv: Ty<'_>
|
|||
|
||||
/// Checks `std::string::String`
|
||||
fn check_string(cx: &LateContext<'_>, args: &[Expr<'_>], expr: Ty<'_>, recv: Ty<'_>, recv_path: &Path<'_>) -> bool {
|
||||
is_type_lang_item(cx, expr, LangItem::String)
|
||||
&& is_type_lang_item(cx, recv, LangItem::String)
|
||||
expr.is_lang_item(cx, LangItem::String)
|
||||
&& recv.is_lang_item(cx, LangItem::String)
|
||||
&& matches!(args, [arg] if is_range_full(cx, arg, Some(recv_path)))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use super::ERR_EXPECT;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::ty::{has_debug_impl, is_type_diagnostic_item};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::ty::has_debug_impl;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
|
|
@ -16,7 +17,7 @@ pub(super) fn check(
|
|||
err_span: Span,
|
||||
msrv: Msrv,
|
||||
) {
|
||||
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result)
|
||||
if cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Result)
|
||||
// Grabs the `Result<T, E>` type
|
||||
&& let result_type = cx.typeck_results().expr_ty(recv)
|
||||
// Tests if the T type in a `Result<T, E>` is not None
|
||||
|
|
@ -40,7 +41,7 @@ pub(super) fn check(
|
|||
/// Given a `Result<T, E>` type, return its data (`T`).
|
||||
fn get_data_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> {
|
||||
match ty.kind() {
|
||||
ty::Adt(_, args) if is_type_diagnostic_item(cx, ty, sym::Result) => args.types().next(),
|
||||
ty::Adt(_, args) if ty.is_diag_item(cx, sym::Result) => args.types().next(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span, root_macro_call_first_node};
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
|
||||
use clippy_utils::visitors::for_each_expr;
|
||||
use clippy_utils::{contains_return, is_inside_always_const_context, peel_blocks};
|
||||
use rustc_errors::Applicability;
|
||||
|
|
@ -26,9 +26,9 @@ pub(super) fn check<'tcx>(
|
|||
let arg_root = get_arg_root(cx, arg);
|
||||
if contains_call(cx, arg_root) && !contains_return(arg_root) {
|
||||
let receiver_type = cx.typeck_results().expr_ty_adjusted(receiver);
|
||||
let closure_args = if is_type_diagnostic_item(cx, receiver_type, sym::Option) {
|
||||
let closure_args = if receiver_type.is_diag_item(cx, sym::Option) {
|
||||
"||"
|
||||
} else if is_type_diagnostic_item(cx, receiver_type, sym::Result) {
|
||||
} else if receiver_type.is_diag_item(cx, sym::Result) {
|
||||
"|_|"
|
||||
} else {
|
||||
return;
|
||||
|
|
@ -83,7 +83,7 @@ fn get_arg_root<'a>(cx: &LateContext<'_>, arg: &'a hir::Expr<'a>) -> &'a hir::Ex
|
|||
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 base_type = arg_type.peel_refs();
|
||||
base_type.is_str() || is_type_lang_item(cx, base_type, hir::LangItem::String)
|
||||
base_type.is_str() || base_type.is_lang_item(cx, hir::LangItem::String)
|
||||
} {
|
||||
receiver
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::sym;
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, LangItem};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -10,7 +10,7 @@ use super::EXTEND_WITH_DRAIN;
|
|||
|
||||
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) {
|
||||
let ty = cx.typeck_results().expr_ty(recv).peel_refs();
|
||||
if is_type_diagnostic_item(cx, ty, sym::Vec)
|
||||
if ty.is_diag_item(cx, sym::Vec)
|
||||
//check source object
|
||||
&& let ExprKind::MethodCall(src_method, drain_vec, [drain_arg], _) = &arg.kind
|
||||
&& src_method.ident.name == sym::drain
|
||||
|
|
@ -18,10 +18,10 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg:
|
|||
//check if actual src type is mutable for code suggestion
|
||||
&& let immutable = src_ty.is_mutable_ptr()
|
||||
&& let src_ty = src_ty.peel_refs()
|
||||
&& is_type_diagnostic_item(cx, src_ty, sym::Vec)
|
||||
&& src_ty.is_diag_item(cx, sym::Vec)
|
||||
//check drain range
|
||||
&& let src_ty_range = cx.typeck_results().expr_ty(drain_arg).peel_refs()
|
||||
&& is_type_lang_item(cx, src_ty_range, LangItem::RangeFull)
|
||||
&& src_ty_range.is_lang_item(cx, LangItem::RangeFull)
|
||||
{
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
span_lint_and_sugg(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::get_parent_expr;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::{Span, sym};
|
||||
|
|
@ -10,7 +10,7 @@ use super::FILETYPE_IS_FILE;
|
|||
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {
|
||||
let ty = cx.typeck_results().expr_ty(recv);
|
||||
|
||||
if !is_type_diagnostic_item(cx, ty, sym::FileType) {
|
||||
if !ty.is_diag_item(cx, sym::FileType) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue