From aae86ccc473aee83059a0bf21db9847bc65a5c37 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 31 Oct 2023 17:38:41 +0000 Subject: [PATCH 01/10] Rename hook. --- clippy_utils/src/consts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 79c04c7c7f4a..50a73745acb8 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -710,7 +710,7 @@ fn field_of_struct<'tcx>( field: &Ident, ) -> Option> { if let mir::Const::Val(result, ty) = result - && let Some(dc) = lcx.tcx.try_destructure_mir_constant_for_diagnostics(result, ty) + && let Some(dc) = lcx.tcx.try_destructure_mir_constant_for_user_output(result, ty) && let Some(dc_variant) = dc.variant && let Some(variant) = adt_def.variants().get(dc_variant) && let Some(field_idx) = variant.fields.iter().position(|el| el.name == field.name) From e1ec2d5cc98cea75d222fc67d31e1d15bfc1d6f1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 2 Nov 2023 14:10:12 +1100 Subject: [PATCH 02/10] Minimize `pub` usage in `source_map.rs`. Most notably, this commit changes the `pub use crate::*;` in that file to `use crate::*;`. This requires a lot of `use` items in other crates to be adjusted, because everything defined within `rustc_span::*` was also available via `rustc_span::source_map::*`, which is bizarre. The commit also removes `SourceMap::span_to_relative_line_string`, which is unused. --- clippy_lints/src/attrs.rs | 3 +-- clippy_lints/src/booleans.rs | 3 +-- clippy_lints/src/cargo/common_metadata.rs | 2 +- clippy_lints/src/cargo/feature_name.rs | 2 +- clippy_lints/src/cargo/multiple_crate_versions.rs | 2 +- clippy_lints/src/cargo/wildcard_dependencies.rs | 2 +- clippy_lints/src/cognitive_complexity.rs | 3 +-- clippy_lints/src/derive.rs | 3 +-- clippy_lints/src/doc.rs | 4 ++-- clippy_lints/src/escape.rs | 2 +- clippy_lints/src/formatting.rs | 2 +- clippy_lints/src/implicit_hasher.rs | 2 +- clippy_lints/src/item_name_repetitions.rs | 2 +- clippy_lints/src/large_enum_variant.rs | 2 +- clippy_lints/src/len_zero.rs | 3 ++- clippy_lints/src/lifetimes.rs | 2 +- clippy_lints/src/loops/manual_find.rs | 2 +- clippy_lints/src/loops/manual_flatten.rs | 2 +- clippy_lints/src/loops/mod.rs | 2 +- clippy_lints/src/loops/mut_range_bound.rs | 2 +- clippy_lints/src/map_unit_fn.rs | 3 +-- clippy_lints/src/mem_replace.rs | 2 +- clippy_lints/src/methods/expect_fun_call.rs | 2 +- clippy_lints/src/methods/filetype_is_file.rs | 3 +-- clippy_lints/src/methods/filter_map.rs | 2 +- clippy_lints/src/methods/filter_map_identity.rs | 3 +-- clippy_lints/src/methods/flat_map_identity.rs | 3 +-- clippy_lints/src/methods/flat_map_option.rs | 3 +-- clippy_lints/src/methods/inspect_for_each.rs | 3 +-- clippy_lints/src/methods/into_iter_on_ref.rs | 2 +- clippy_lints/src/methods/map_identity.rs | 3 +-- clippy_lints/src/methods/open_options.rs | 4 ++-- clippy_lints/src/methods/option_map_unwrap_or.rs | 3 +-- clippy_lints/src/methods/or_fun_call.rs | 2 +- clippy_lints/src/methods/search_is_some.rs | 2 +- clippy_lints/src/methods/unnecessary_fold.rs | 3 +-- clippy_lints/src/methods/wrong_self_convention.rs | 2 +- clippy_lints/src/misc.rs | 2 +- clippy_lints/src/misc_early/mod.rs | 2 +- clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs | 2 +- clippy_lints/src/missing_doc.rs | 3 +-- clippy_lints/src/missing_inline.rs | 3 +-- clippy_lints/src/mut_key.rs | 2 +- clippy_lints/src/needless_for_each.rs | 3 +-- clippy_lints/src/neg_multiply.rs | 2 +- clippy_lints/src/non_expressive_names.rs | 3 +-- clippy_lints/src/operators/arithmetic_side_effects.rs | 4 ++-- clippy_lints/src/operators/bit_mask.rs | 2 +- clippy_lints/src/operators/const_comparisons.rs | 3 ++- clippy_lints/src/operators/double_comparison.rs | 2 +- clippy_lints/src/operators/identity_op.rs | 2 +- clippy_lints/src/operators/numeric_arithmetic.rs | 2 +- clippy_lints/src/pattern_type_mismatch.rs | 2 +- clippy_lints/src/ptr.rs | 3 +-- clippy_lints/src/ranges.rs | 3 ++- clippy_lints/src/redundant_clone.rs | 3 +-- clippy_lints/src/regex.rs | 2 +- clippy_lints/src/returns.rs | 3 +-- clippy_lints/src/tabs_in_doc_comments.rs | 2 +- clippy_lints/src/types/mod.rs | 2 +- clippy_lints/src/types/utils.rs | 2 +- clippy_lints/src/unicode.rs | 2 +- clippy_lints/src/unsafe_removed_from_name.rs | 2 +- clippy_lints/src/unused_unit.rs | 3 +-- clippy_lints/src/unwrap.rs | 3 +-- clippy_lints/src/vec.rs | 3 +-- clippy_utils/src/diagnostics.rs | 2 +- clippy_utils/src/sugg.rs | 2 +- 68 files changed, 74 insertions(+), 94 deletions(-) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index db01ddbde04e..d6b9d0eb5824 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -19,9 +19,8 @@ use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, use rustc_middle::lint::in_external_macro; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; -use rustc_span::source_map::Span; use rustc_span::symbol::Symbol; -use rustc_span::{sym, DUMMY_SP}; +use rustc_span::{sym, DUMMY_SP, Span}; use semver::Version; static UNIX_SYSTEMS: &[&str] = &[ diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index 04cca9e3177c..172e42fd692f 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -10,8 +10,7 @@ use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp}; use rustc_lint::{LateContext, LateLintPass, Level}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/cargo/common_metadata.rs b/clippy_lints/src/cargo/common_metadata.rs index 805121bcced3..99fe6c1e790e 100644 --- a/clippy_lints/src/cargo/common_metadata.rs +++ b/clippy_lints/src/cargo/common_metadata.rs @@ -3,7 +3,7 @@ use cargo_metadata::Metadata; use clippy_utils::diagnostics::span_lint; use rustc_lint::LateContext; -use rustc_span::source_map::DUMMY_SP; +use rustc_span::DUMMY_SP; use super::CARGO_COMMON_METADATA; diff --git a/clippy_lints/src/cargo/feature_name.rs b/clippy_lints/src/cargo/feature_name.rs index 37c169dbd95e..9e69919c7273 100644 --- a/clippy_lints/src/cargo/feature_name.rs +++ b/clippy_lints/src/cargo/feature_name.rs @@ -1,7 +1,7 @@ use cargo_metadata::Metadata; use clippy_utils::diagnostics::span_lint_and_help; use rustc_lint::LateContext; -use rustc_span::source_map::DUMMY_SP; +use rustc_span::DUMMY_SP; use super::{NEGATIVE_FEATURE_NAMES, REDUNDANT_FEATURE_NAMES}; diff --git a/clippy_lints/src/cargo/multiple_crate_versions.rs b/clippy_lints/src/cargo/multiple_crate_versions.rs index f9b17d45e9fb..f7a5b1857be2 100644 --- a/clippy_lints/src/cargo/multiple_crate_versions.rs +++ b/clippy_lints/src/cargo/multiple_crate_versions.rs @@ -6,7 +6,7 @@ use if_chain::if_chain; use itertools::Itertools; use rustc_hir::def_id::LOCAL_CRATE; use rustc_lint::LateContext; -use rustc_span::source_map::DUMMY_SP; +use rustc_span::DUMMY_SP; use super::MULTIPLE_CRATE_VERSIONS; diff --git a/clippy_lints/src/cargo/wildcard_dependencies.rs b/clippy_lints/src/cargo/wildcard_dependencies.rs index 7fa6acbf557b..4dcc9cbe3a75 100644 --- a/clippy_lints/src/cargo/wildcard_dependencies.rs +++ b/clippy_lints/src/cargo/wildcard_dependencies.rs @@ -2,7 +2,7 @@ use cargo_metadata::Metadata; use clippy_utils::diagnostics::span_lint; use if_chain::if_chain; use rustc_lint::LateContext; -use rustc_span::source_map::DUMMY_SP; +use rustc_span::DUMMY_SP; use super::WILDCARD_DEPENDENCIES; diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs index a8926b29ac83..74ecaa60c7ca 100644 --- a/clippy_lints/src/cognitive_complexity.rs +++ b/clippy_lints/src/cognitive_complexity.rs @@ -12,8 +12,7 @@ use rustc_hir::{Body, Expr, ExprKind, FnDecl}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::Span; -use rustc_span::{sym, BytePos}; +use rustc_span::{sym, BytePos, Span}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index 2bdac1352dce..fb9302eef28a 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -17,8 +17,7 @@ use rustc_middle::ty::{ }; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index fc9b381664a3..b3bcca4645ad 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -30,8 +30,8 @@ use rustc_resolve::rustdoc::{ use rustc_session::parse::ParseSess; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::edition::Edition; -use rustc_span::source_map::{BytePos, FilePathMapping, SourceMap, Span}; -use rustc_span::{sym, FileName, Pos}; +use rustc_span::{sym, BytePos, FileName, Pos, Span}; +use rustc_span::source_map::{FilePathMapping, SourceMap}; use std::ops::Range; use std::{io, thread}; use url::Url; diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index dbe3453e7bfa..87f516d8e0ec 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, TraitRef, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::Span; +use rustc_span::Span; use rustc_span::symbol::kw; use rustc_target::spec::abi::Abi; diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index 4ebf0e9667df..136a8a90f4a0 100644 --- a/clippy_lints/src/formatting.rs +++ b/clippy_lints/src/formatting.rs @@ -6,7 +6,7 @@ use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind, UnOp}; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Span; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs index 2b2ea156cd4d..230c68f5bf51 100644 --- a/clippy_lints/src/implicit_hasher.rs +++ b/clippy_lints/src/implicit_hasher.rs @@ -10,7 +10,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{Ty, TypeckResults}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Span; +use rustc_span::Span; use rustc_span::symbol::sym; use if_chain::if_chain; diff --git a/clippy_lints/src/item_name_repetitions.rs b/clippy_lints/src/item_name_repetitions.rs index 8b4984da3dd1..602774cdfbd1 100644 --- a/clippy_lints/src/item_name_repetitions.rs +++ b/clippy_lints/src/item_name_repetitions.rs @@ -7,7 +7,7 @@ use clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_sta use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, Variant, VariantData}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::source_map::Span; +use rustc_span::Span; use rustc_span::symbol::Symbol; declare_clippy_lint! { diff --git a/clippy_lints/src/large_enum_variant.rs b/clippy_lints/src/large_enum_variant.rs index b22b57a3006f..080062646f70 100644 --- a/clippy_lints/src/large_enum_variant.rs +++ b/clippy_lints/src/large_enum_variant.rs @@ -9,7 +9,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{Adt, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::source_map::Span; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index c06b35ca0dab..65eb8846bdfd 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -15,7 +15,8 @@ use rustc_hir::{ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, AssocKind, FnSig, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::{Span, Spanned, Symbol}; +use rustc_span::{Span, Symbol}; +use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; declare_clippy_lint! { diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 0004a150d51b..d5db769b7e3a 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -20,7 +20,7 @@ use rustc_middle::hir::nested_filter as middle_nested_filter; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::Span; +use rustc_span::Span; use rustc_span::symbol::{kw, Ident, Symbol}; declare_clippy_lint! { diff --git a/clippy_lints/src/loops/manual_find.rs b/clippy_lints/src/loops/manual_find.rs index 0aaa66e6bcee..a9a9058c93f3 100644 --- a/clippy_lints/src/loops/manual_find.rs +++ b/clippy_lints/src/loops/manual_find.rs @@ -10,7 +10,7 @@ use rustc_hir::def::Res; use rustc_hir::lang_items::LangItem; use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Node, Pat, PatKind, Stmt, StmtKind}; use rustc_lint::LateContext; -use rustc_span::source_map::Span; +use rustc_span::Span; pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, diff --git a/clippy_lints/src/loops/manual_flatten.rs b/clippy_lints/src/loops/manual_flatten.rs index 559a2c03f146..124a35f8f540 100644 --- a/clippy_lints/src/loops/manual_flatten.rs +++ b/clippy_lints/src/loops/manual_flatten.rs @@ -9,7 +9,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::{Expr, Pat, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::source_map::Span; +use rustc_span::Span; /// Check for unnecessary `if let` usage in a for loop where only the `Some` or `Ok` variant of the /// iterator element is used. diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 1fb16adad7a1..cd7f3e0c6bfb 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -24,7 +24,7 @@ use clippy_utils::msrvs::Msrv; use rustc_hir::{Expr, ExprKind, LoopSource, Pat}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::source_map::Span; +use rustc_span::Span; use utils::{make_iterator_snippet, IncrementVisitor, InitializeVisitor}; declare_clippy_lint! { diff --git a/clippy_lints/src/loops/mut_range_bound.rs b/clippy_lints/src/loops/mut_range_bound.rs index b83d148b5f24..2c12d9582d63 100644 --- a/clippy_lints/src/loops/mut_range_bound.rs +++ b/clippy_lints/src/loops/mut_range_bound.rs @@ -9,7 +9,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty; -use rustc_span::source_map::Span; +use rustc_span::Span; pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<'_>) { if_chain! { diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs index f0a0f482af29..18595d4a4695 100644 --- a/clippy_lints/src/map_unit_fn.rs +++ b/clippy_lints/src/map_unit_fn.rs @@ -8,8 +8,7 @@ use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index 8a921d4af165..a3170fec647f 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -11,7 +11,7 @@ use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::source_map::Span; +use rustc_span::Span; use rustc_span::symbol::sym; declare_clippy_lint! { diff --git a/clippy_lints/src/methods/expect_fun_call.rs b/clippy_lints/src/methods/expect_fun_call.rs index 40e487bf6505..a49970b5351d 100644 --- a/clippy_lints/src/methods/expect_fun_call.rs +++ b/clippy_lints/src/methods/expect_fun_call.rs @@ -6,7 +6,7 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::source_map::Span; +use rustc_span::Span; use rustc_span::symbol::sym; use std::borrow::Cow; diff --git a/clippy_lints/src/methods/filetype_is_file.rs b/clippy_lints/src/methods/filetype_is_file.rs index 3fef53739fbd..7818be81119b 100644 --- a/clippy_lints/src/methods/filetype_is_file.rs +++ b/clippy_lints/src/methods/filetype_is_file.rs @@ -4,8 +4,7 @@ use clippy_utils::ty::is_type_diagnostic_item; use if_chain::if_chain; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; use super::FILETYPE_IS_FILE; diff --git a/clippy_lints/src/methods/filter_map.rs b/clippy_lints/src/methods/filter_map.rs index c9eaa185acce..597e0da238ed 100644 --- a/clippy_lints/src/methods/filter_map.rs +++ b/clippy_lints/src/methods/filter_map.rs @@ -11,7 +11,7 @@ use rustc_hir::def::Res; use rustc_hir::{Closure, Expr, ExprKind, PatKind, PathSegment, QPath, UnOp}; use rustc_lint::LateContext; use rustc_middle::ty::adjustment::Adjust; -use rustc_span::source_map::Span; +use rustc_span::Span; use rustc_span::symbol::{sym, Ident, Symbol}; use std::borrow::Cow; diff --git a/clippy_lints/src/methods/filter_map_identity.rs b/clippy_lints/src/methods/filter_map_identity.rs index 20878f1e4dfe..8291c373f371 100644 --- a/clippy_lints/src/methods/filter_map_identity.rs +++ b/clippy_lints/src/methods/filter_map_identity.rs @@ -3,8 +3,7 @@ use clippy_utils::{is_expr_untyped_identity_function, is_trait_method}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; use super::FILTER_MAP_IDENTITY; diff --git a/clippy_lints/src/methods/flat_map_identity.rs b/clippy_lints/src/methods/flat_map_identity.rs index 8849a4f49420..651ea34f9d0e 100644 --- a/clippy_lints/src/methods/flat_map_identity.rs +++ b/clippy_lints/src/methods/flat_map_identity.rs @@ -3,8 +3,7 @@ use clippy_utils::{is_expr_untyped_identity_function, is_trait_method}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; use super::FLAT_MAP_IDENTITY; diff --git a/clippy_lints/src/methods/flat_map_option.rs b/clippy_lints/src/methods/flat_map_option.rs index 172c397fbc80..0a4a381b8618 100644 --- a/clippy_lints/src/methods/flat_map_option.rs +++ b/clippy_lints/src/methods/flat_map_option.rs @@ -4,8 +4,7 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; use super::FLAT_MAP_OPTION; use clippy_utils::ty::is_type_diagnostic_item; diff --git a/clippy_lints/src/methods/inspect_for_each.rs b/clippy_lints/src/methods/inspect_for_each.rs index 23cc192c38e3..ad4b6fa130e3 100644 --- a/clippy_lints/src/methods/inspect_for_each.rs +++ b/clippy_lints/src/methods/inspect_for_each.rs @@ -2,8 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::is_trait_method; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; use super::INSPECT_FOR_EACH; diff --git a/clippy_lints/src/methods/into_iter_on_ref.rs b/clippy_lints/src/methods/into_iter_on_ref.rs index 8adf9e370592..bbd964c10995 100644 --- a/clippy_lints/src/methods/into_iter_on_ref.rs +++ b/clippy_lints/src/methods/into_iter_on_ref.rs @@ -6,7 +6,7 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty}; -use rustc_span::source_map::Span; +use rustc_span::Span; use rustc_span::symbol::{sym, Symbol}; use super::INTO_ITER_ON_REF; diff --git a/clippy_lints/src/methods/map_identity.rs b/clippy_lints/src/methods/map_identity.rs index 57581363cfa0..bcfd0de8efe1 100644 --- a/clippy_lints/src/methods/map_identity.rs +++ b/clippy_lints/src/methods/map_identity.rs @@ -4,8 +4,7 @@ use clippy_utils::{is_expr_untyped_identity_function, is_trait_method}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; use super::MAP_IDENTITY; diff --git a/clippy_lints/src/methods/open_options.rs b/clippy_lints/src/methods/open_options.rs index c0f5a2799451..65c986dcacce 100644 --- a/clippy_lints/src/methods/open_options.rs +++ b/clippy_lints/src/methods/open_options.rs @@ -3,8 +3,8 @@ use clippy_utils::ty::is_type_diagnostic_item; use rustc_ast::ast::LitKind; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; -use rustc_span::source_map::{Span, Spanned}; -use rustc_span::sym; +use rustc_span::source_map::Spanned; +use rustc_span::{sym, Span}; use super::NONSENSICAL_OPEN_OPTIONS; diff --git a/clippy_lints/src/methods/option_map_unwrap_or.rs b/clippy_lints/src/methods/option_map_unwrap_or.rs index fcbe005fb286..605a89cd7085 100644 --- a/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -9,8 +9,7 @@ use rustc_hir::intravisit::{walk_path, Visitor}; use rustc_hir::{self, ExprKind, HirId, Node, PatKind, Path, QPath}; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; use super::MAP_UNWRAP_OR; diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs index 942f3bd79a61..94527d67ac1c 100644 --- a/clippy_lints/src/methods/or_fun_call.rs +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -7,7 +7,7 @@ use if_chain::if_chain; use rustc_errors::Applicability; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::source_map::Span; +use rustc_span::Span; use rustc_span::symbol::{self, sym, Symbol}; use {rustc_ast as ast, rustc_hir as hir}; diff --git a/clippy_lints/src/methods/search_is_some.rs b/clippy_lints/src/methods/search_is_some.rs index 04ddaaa2f461..05a9a06c8c7d 100644 --- a/clippy_lints/src/methods/search_is_some.rs +++ b/clippy_lints/src/methods/search_is_some.rs @@ -8,7 +8,7 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::PatKind; use rustc_lint::LateContext; -use rustc_span::source_map::Span; +use rustc_span::Span; use rustc_span::symbol::sym; use super::SEARCH_IS_SOME; diff --git a/clippy_lints/src/methods/unnecessary_fold.rs b/clippy_lints/src/methods/unnecessary_fold.rs index 6e23754bf46e..6d51c4ab0544 100644 --- a/clippy_lints/src/methods/unnecessary_fold.rs +++ b/clippy_lints/src/methods/unnecessary_fold.rs @@ -8,8 +8,7 @@ use rustc_hir as hir; use rustc_hir::PatKind; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; use super::UNNECESSARY_FOLD; diff --git a/clippy_lints/src/methods/wrong_self_convention.rs b/clippy_lints/src/methods/wrong_self_convention.rs index 1fbf783b8860..0a810a13f3f9 100644 --- a/clippy_lints/src/methods/wrong_self_convention.rs +++ b/clippy_lints/src/methods/wrong_self_convention.rs @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::ty::is_copy; use rustc_lint::LateContext; use rustc_middle::ty::Ty; -use rustc_span::source_map::Span; +use rustc_span::Span; use std::fmt; use super::WRONG_SELF_CONVENTION; diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 9c8b47fb3032..b4e343741b43 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -16,7 +16,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::Span; +use rustc_span::Span; use crate::ref_patterns::REF_PATTERNS; diff --git a/clippy_lints/src/misc_early/mod.rs b/clippy_lints/src/misc_early/mod.rs index b226b8781237..89bf4484426e 100644 --- a/clippy_lints/src/misc_early/mod.rs +++ b/clippy_lints/src/misc_early/mod.rs @@ -17,7 +17,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Span; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs b/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs index 7c4ae746e90e..00f46629f102 100644 --- a/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs +++ b/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use rustc_ast::ast::{Pat, PatKind}; use rustc_errors::Applicability; use rustc_lint::EarlyContext; -use rustc_span::source_map::Span; +use rustc_span::Span; use super::UNNEEDED_WILDCARD_PATTERN; diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 0629dee4f722..973caa72b772 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -16,8 +16,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::Visibility; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::def_id::CRATE_DEF_ID; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index 93f6025c71d6..12114dc4cee0 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -3,8 +3,7 @@ use rustc_ast::ast; use rustc_hir as hir; use rustc_lint::{self, LateContext, LateLintPass, LintContext}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/mut_key.rs b/clippy_lints/src/mut_key.rs index 5878f899541a..4a19e2facfde 100644 --- a/clippy_lints/src/mut_key.rs +++ b/clippy_lints/src/mut_key.rs @@ -8,7 +8,7 @@ use rustc_middle::query::Key; use rustc_middle::ty::{Adt, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::Span; +use rustc_span::Span; use rustc_span::symbol::sym; use std::iter; diff --git a/clippy_lints/src/needless_for_each.rs b/clippy_lints/src/needless_for_each.rs index 98bf122fab74..579b4a920b7d 100644 --- a/clippy_lints/src/needless_for_each.rs +++ b/clippy_lints/src/needless_for_each.rs @@ -3,8 +3,7 @@ use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::{Closure, Expr, ExprKind, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Span; -use rustc_span::{sym, Symbol}; +use rustc_span::{sym, Span, Symbol}; use if_chain::if_chain; diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs index db0e22842d14..8b69f94cbba2 100644 --- a/clippy_lints/src/neg_multiply.rs +++ b/clippy_lints/src/neg_multiply.rs @@ -8,7 +8,7 @@ use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Span; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs index d562047cbf15..1029de91bc8b 100644 --- a/clippy_lints/src/non_expressive_names.rs +++ b/clippy_lints/src/non_expressive_names.rs @@ -6,8 +6,7 @@ use rustc_ast::visit::{walk_block, walk_expr, walk_pat, Visitor}; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; use rustc_span::symbol::{Ident, Symbol}; use std::cmp::Ordering; diff --git a/clippy_lints/src/operators/arithmetic_side_effects.rs b/clippy_lints/src/operators/arithmetic_side_effects.rs index a10aa65e5948..9a5c57402db9 100644 --- a/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -7,9 +7,9 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty; use rustc_session::impl_lint_pass; -use rustc_span::source_map::{Span, Spanned}; +use rustc_span::{Span, Symbol}; +use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; -use rustc_span::Symbol; use {rustc_ast as ast, rustc_hir as hir}; const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[["f32", "f32"], ["f64", "f64"], ["std::string::String", "str"]]; diff --git a/clippy_lints/src/operators/bit_mask.rs b/clippy_lints/src/operators/bit_mask.rs index c146f3ae95b3..2e026c369ee3 100644 --- a/clippy_lints/src/operators/bit_mask.rs +++ b/clippy_lints/src/operators/bit_mask.rs @@ -2,7 +2,7 @@ use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::LateContext; -use rustc_span::source_map::Span; +use rustc_span::Span; use super::{BAD_BIT_MASK, INEFFECTIVE_BIT_MASK}; diff --git a/clippy_lints/src/operators/const_comparisons.rs b/clippy_lints/src/operators/const_comparisons.rs index abe8df195434..ec2bb869973f 100644 --- a/clippy_lints/src/operators/const_comparisons.rs +++ b/clippy_lints/src/operators/const_comparisons.rs @@ -8,7 +8,8 @@ use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::LateContext; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::{Ty, TypeckResults}; -use rustc_span::source_map::{Span, Spanned}; +use rustc_span::Span; +use rustc_span::source_map::Spanned; use clippy_utils::diagnostics::span_lint_and_note; use clippy_utils::source::snippet; diff --git a/clippy_lints/src/operators/double_comparison.rs b/clippy_lints/src/operators/double_comparison.rs index 56a86d0ffa21..d48e8286f2ca 100644 --- a/clippy_lints/src/operators/double_comparison.rs +++ b/clippy_lints/src/operators/double_comparison.rs @@ -4,7 +4,7 @@ use clippy_utils::source::snippet_with_applicability; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::LateContext; -use rustc_span::source_map::Span; +use rustc_span::Span; use super::DOUBLE_COMPARISONS; diff --git a/clippy_lints/src/operators/identity_op.rs b/clippy_lints/src/operators/identity_op.rs index 14a12da862ef..8ecb038627f5 100644 --- a/clippy_lints/src/operators/identity_op.rs +++ b/clippy_lints/src/operators/identity_op.rs @@ -6,7 +6,7 @@ use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, Node}; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::source_map::Span; +use rustc_span::Span; use super::IDENTITY_OP; diff --git a/clippy_lints/src/operators/numeric_arithmetic.rs b/clippy_lints/src/operators/numeric_arithmetic.rs index 80389cbf84be..ea933168cfd5 100644 --- a/clippy_lints/src/operators/numeric_arithmetic.rs +++ b/clippy_lints/src/operators/numeric_arithmetic.rs @@ -3,7 +3,7 @@ use clippy_utils::consts::constant_simple; use clippy_utils::diagnostics::span_lint; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::source_map::Span; +use rustc_span::Span; #[derive(Default)] pub struct Context { diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs index 9f98195d311f..dcd1e7af0c2c 100644 --- a/clippy_lints/src/pattern_type_mismatch.rs +++ b/clippy_lints/src/pattern_type_mismatch.rs @@ -5,7 +5,7 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::Span; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 310051efc508..7d42cb677e92 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -21,8 +21,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, Binder, ClauseKind, ExistentialPredicate, List, PredicateKind, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; use rustc_span::symbol::Symbol; use rustc_target::spec::abi::Abi; use rustc_trait_selection::infer::InferCtxtExt as _; diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index 3287675a82de..bd368465b075 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -11,7 +11,8 @@ use rustc_hir::{BinOpKind, Expr, ExprKind, HirId}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::source_map::{Span, Spanned}; +use rustc_span::Span; +use rustc_span::source_map::Spanned; use std::cmp::Ordering; declare_clippy_lint! { diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index 2c0086b09813..7a686e35d40c 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -12,8 +12,7 @@ use rustc_middle::mir; use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::{BytePos, Span}; -use rustc_span::sym; +use rustc_span::{sym, BytePos, Span}; macro_rules! unwrap_or_continue { ($x:expr) => { diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index b795e4b15bac..cb78eec9e8d7 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -9,7 +9,7 @@ use rustc_hir::def_id::DefIdMap; use rustc_hir::{BorrowKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::source_map::{BytePos, Span}; +use rustc_span::{BytePos, Span}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index d6b9a49d2fe0..c84f42343388 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -14,8 +14,7 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, GenericArgKind, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::Span; -use rustc_span::{BytePos, Pos}; +use rustc_span::{BytePos, Pos, Span}; use std::borrow::Cow; declare_clippy_lint! { diff --git a/clippy_lints/src/tabs_in_doc_comments.rs b/clippy_lints/src/tabs_in_doc_comments.rs index e223aea297fc..97095e48ddf1 100644 --- a/clippy_lints/src/tabs_in_doc_comments.rs +++ b/clippy_lints/src/tabs_in_doc_comments.rs @@ -3,7 +3,7 @@ use rustc_ast::ast; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::{BytePos, Span}; +use rustc_span::{BytePos, Span}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 788678a63b76..83f3f93a0443 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -18,7 +18,7 @@ use rustc_hir::{ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::Span; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/types/utils.rs b/clippy_lints/src/types/utils.rs index a30748db88fc..39469841bd40 100644 --- a/clippy_lints/src/types/utils.rs +++ b/clippy_lints/src/types/utils.rs @@ -2,7 +2,7 @@ use clippy_utils::last_path_segment; use if_chain::if_chain; use rustc_hir::{GenericArg, GenericArgsParentheses, QPath, TyKind}; use rustc_lint::LateContext; -use rustc_span::source_map::Span; +use rustc_span::Span; pub(super) fn match_borrows_parameter(_cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option { let last = last_path_segment(qpath); diff --git a/clippy_lints/src/unicode.rs b/clippy_lints/src/unicode.rs index e275bfd37b00..a62665b8f37e 100644 --- a/clippy_lints/src/unicode.rs +++ b/clippy_lints/src/unicode.rs @@ -7,7 +7,7 @@ use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, HirId}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Span; +use rustc_span::Span; use unicode_normalization::UnicodeNormalization; declare_clippy_lint! { diff --git a/clippy_lints/src/unsafe_removed_from_name.rs b/clippy_lints/src/unsafe_removed_from_name.rs index 7ee785804f0a..c43d5dc94b3e 100644 --- a/clippy_lints/src/unsafe_removed_from_name.rs +++ b/clippy_lints/src/unsafe_removed_from_name.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint; use rustc_ast::ast::{Item, ItemKind, UseTree, UseTreeKind}; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Span; +use rustc_span::Span; use rustc_span::symbol::Ident; declare_clippy_lint! { diff --git a/clippy_lints/src/unused_unit.rs b/clippy_lints/src/unused_unit.rs index 95e74718d806..70f52172e94c 100644 --- a/clippy_lints/src/unused_unit.rs +++ b/clippy_lints/src/unused_unit.rs @@ -6,8 +6,7 @@ use rustc_ast::{ast, ClosureBinder}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Span; -use rustc_span::BytePos; +use rustc_span::{BytePos, Span}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index 9a0d83d83f1f..55837bd5ab9c 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -15,8 +15,7 @@ use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index fc17e7c6d5aa..799e04180775 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -14,8 +14,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::source_map::Span; -use rustc_span::sym; +use rustc_span::{sym, Span}; #[expect(clippy::module_name_repetitions)] #[derive(Clone)] diff --git a/clippy_utils/src/diagnostics.rs b/clippy_utils/src/diagnostics.rs index edd87546a5f8..61c15aff355d 100644 --- a/clippy_utils/src/diagnostics.rs +++ b/clippy_utils/src/diagnostics.rs @@ -11,7 +11,7 @@ use rustc_errors::{Applicability, Diagnostic, MultiSpan}; use rustc_hir::HirId; use rustc_lint::{LateContext, Lint, LintContext}; -use rustc_span::source_map::Span; +use rustc_span::Span; use std::env; fn docs_link(diag: &mut Diagnostic, lint: &'static Lint) { diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 836f8cc19168..fe274b9c50b7 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -16,7 +16,7 @@ use rustc_lint::{EarlyContext, LateContext, LintContext}; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::{FakeReadCause, Mutability}; use rustc_middle::ty; -use rustc_span::source_map::{BytePos, CharPos, Pos, Span, SyntaxContext}; +use rustc_span::{BytePos, CharPos, Pos, Span, SyntaxContext}; use std::borrow::Cow; use std::fmt::{self, Display, Write as _}; use std::ops::{Add, Neg, Not, Sub}; From 77c1e3aaa10aa78e7841b03a674acdc22bb6f758 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 2 Nov 2023 17:35:56 +0100 Subject: [PATCH 03/10] Merge commit '09ac14c901abc43bd0d617ae4a44e8a4fed98d9c' into clippyup --- .github/workflows/clippy.yml | 2 +- .github/workflows/clippy_bors.yml | 6 +- CHANGELOG.md | 3 + Cargo.toml | 3 +- book/src/lint_configuration.md | 143 ++-- clippy_config/Cargo.toml | 21 + .../src/utils => clippy_config/src}/conf.rs | 171 ++--- clippy_config/src/lib.rs | 23 + clippy_config/src/metadata.rs | 116 +++ {clippy_utils => clippy_config}/src/msrvs.rs | 14 +- clippy_config/src/types.rs | 142 ++++ clippy_dev/src/main.rs | 1 - clippy_dev/src/new_lint.rs | 4 +- clippy_dev/src/update_lints.rs | 2 +- clippy_lints/Cargo.toml | 5 +- clippy_lints/src/absolute_paths.rs | 4 +- clippy_lints/src/almost_complete_range.rs | 31 +- clippy_lints/src/approx_const.rs | 6 +- clippy_lints/src/arc_with_non_send_sync.rs | 26 +- .../src/assertions_on_result_states.rs | 6 +- clippy_lints/src/async_yields_async.rs | 6 +- clippy_lints/src/attrs.rs | 81 +- clippy_lints/src/await_holding_invalid.rs | 15 +- clippy_lints/src/blocks_in_if_conditions.rs | 4 +- clippy_lints/src/bool_assert_comparison.rs | 4 +- clippy_lints/src/bool_to_int_with_if.rs | 31 +- clippy_lints/src/booleans.rs | 13 +- clippy_lints/src/borrow_deref_ref.rs | 6 +- clippy_lints/src/box_default.rs | 19 +- clippy_lints/src/casts/as_ptr_cast_mut.rs | 17 +- .../src/casts/cast_abs_to_unsigned.rs | 2 +- clippy_lints/src/casts/cast_lossless.rs | 2 +- clippy_lints/src/casts/cast_ptr_alignment.rs | 9 +- .../src/casts/cast_slice_different_sizes.rs | 2 +- .../src/casts/cast_slice_from_raw_parts.rs | 2 +- clippy_lints/src/casts/mod.rs | 72 +- clippy_lints/src/casts/ptr_as_ptr.rs | 2 +- clippy_lints/src/casts/ptr_cast_constness.rs | 4 +- clippy_lints/src/casts/unnecessary_cast.rs | 17 +- clippy_lints/src/checked_conversions.rs | 6 +- clippy_lints/src/collapsible_if.rs | 4 +- clippy_lints/src/collection_is_never_read.rs | 4 +- clippy_lints/src/crate_in_macro_def.rs | 4 +- clippy_lints/src/declared_lints.rs | 9 +- clippy_lints/src/default.rs | 8 +- .../src/default_constructed_unit_structs.rs | 4 +- .../src/default_instead_of_iter_empty.rs | 9 +- clippy_lints/src/default_numeric_fallback.rs | 4 +- .../src/default_union_representation.rs | 4 +- clippy_lints/src/dereference.rs | 61 +- clippy_lints/src/derivable_impls.rs | 6 +- clippy_lints/src/derive.rs | 4 +- clippy_lints/src/disallowed_macros.rs | 9 +- clippy_lints/src/disallowed_methods.rs | 8 +- clippy_lints/src/disallowed_names.rs | 2 +- clippy_lints/src/disallowed_script_idents.rs | 2 +- clippy_lints/src/disallowed_types.rs | 11 +- clippy_lints/src/doc.rs | 42 +- clippy_lints/src/double_parens.rs | 4 +- clippy_lints/src/drop_forget_ref.rs | 14 +- clippy_lints/src/else_if_without_else.rs | 4 +- clippy_lints/src/empty_drop.rs | 4 +- clippy_lints/src/empty_enum.rs | 4 +- .../src/empty_structs_with_brackets.rs | 12 +- clippy_lints/src/entry.rs | 6 +- clippy_lints/src/enum_clike.rs | 2 +- clippy_lints/src/equatable_if_let.rs | 7 +- clippy_lints/src/error_impl_error.rs | 28 +- clippy_lints/src/escape.rs | 4 +- clippy_lints/src/eta_reduction.rs | 66 +- clippy_lints/src/excessive_bools.rs | 13 +- clippy_lints/src/exhaustive_items.rs | 8 +- clippy_lints/src/exit.rs | 2 +- clippy_lints/src/explicit_write.rs | 21 +- .../src/extra_unused_type_parameters.rs | 32 +- clippy_lints/src/fallible_impl_from.rs | 4 +- clippy_lints/src/float_literal.rs | 8 +- clippy_lints/src/floating_point_arithmetic.rs | 30 +- clippy_lints/src/format.rs | 13 +- clippy_lints/src/format_args.rs | 24 +- clippy_lints/src/format_impl.rs | 8 +- clippy_lints/src/format_push_string.rs | 16 +- clippy_lints/src/formatting.rs | 4 +- clippy_lints/src/four_forward_slashes.rs | 4 +- clippy_lints/src/from_over_into.rs | 20 +- clippy_lints/src/from_raw_with_void_ptr.rs | 26 +- clippy_lints/src/functions/mod.rs | 24 +- clippy_lints/src/functions/must_use.rs | 7 +- clippy_lints/src/functions/result.rs | 4 +- clippy_lints/src/future_not_send.rs | 4 +- clippy_lints/src/if_not_else.rs | 16 +- clippy_lints/src/if_then_some_else_none.rs | 21 +- clippy_lints/src/ignored_unit_patterns.rs | 6 +- clippy_lints/src/implicit_hasher.rs | 4 +- clippy_lints/src/implicit_return.rs | 4 +- clippy_lints/src/implicit_saturating_add.rs | 28 +- clippy_lints/src/implicit_saturating_sub.rs | 4 +- clippy_lints/src/implied_bounds_in_impls.rs | 82 ++- .../src/inconsistent_struct_constructor.rs | 6 +- clippy_lints/src/index_refutable_slice.rs | 6 +- clippy_lints/src/indexing_slicing.rs | 4 +- clippy_lints/src/infinite_iter.rs | 2 +- clippy_lints/src/inherent_impl.rs | 4 +- clippy_lints/src/inherent_to_string.rs | 8 +- clippy_lints/src/init_numbered_fields.rs | 2 +- clippy_lints/src/inline_fn_without_body.rs | 2 +- clippy_lints/src/instant_subtraction.rs | 10 +- clippy_lints/src/int_plus_one.rs | 4 +- .../src/invalid_upcast_comparisons.rs | 2 +- clippy_lints/src/item_name_repetitions.rs | 19 +- clippy_lints/src/items_after_statements.rs | 4 +- clippy_lints/src/items_after_test_module.rs | 13 +- .../src/iter_not_returning_iterator.rs | 4 +- clippy_lints/src/iter_without_into_iter.rs | 67 +- clippy_lints/src/large_enum_variant.rs | 4 +- clippy_lints/src/large_futures.rs | 4 +- clippy_lints/src/large_stack_arrays.rs | 52 +- clippy_lints/src/large_stack_frames.rs | 4 +- clippy_lints/src/len_zero.rs | 35 +- clippy_lints/src/let_underscore.rs | 29 +- clippy_lints/src/lib.rs | 24 +- clippy_lints/src/lifetimes.rs | 16 +- clippy_lints/src/lines_filter_map_ok.rs | 53 +- clippy_lints/src/literal_representation.rs | 12 +- clippy_lints/src/loops/explicit_iter_loop.rs | 40 +- clippy_lints/src/loops/for_kv_map.rs | 12 +- clippy_lints/src/loops/mod.rs | 83 ++- clippy_lints/src/loops/never_loop.rs | 6 +- .../src/loops/unused_enumerate_index.rs | 62 ++ clippy_lints/src/manual_assert.rs | 18 +- clippy_lints/src/manual_async_fn.rs | 6 +- clippy_lints/src/manual_bits.rs | 6 +- clippy_lints/src/manual_clamp.rs | 94 +-- clippy_lints/src/manual_float_methods.rs | 82 +-- clippy_lints/src/manual_hash_one.rs | 11 +- clippy_lints/src/manual_is_ascii_check.rs | 20 +- clippy_lints/src/manual_let_else.rs | 53 +- clippy_lints/src/manual_main_separator_str.rs | 48 +- clippy_lints/src/manual_non_exhaustive.rs | 8 +- clippy_lints/src/manual_range_patterns.rs | 4 +- clippy_lints/src/manual_rem_euclid.rs | 51 +- clippy_lints/src/manual_retain.rs | 50 +- .../src/manual_slice_size_calculation.rs | 4 +- clippy_lints/src/manual_string_new.rs | 33 +- clippy_lints/src/manual_strip.rs | 6 +- clippy_lints/src/map_unit_fn.rs | 8 +- clippy_lints/src/matches/manual_filter.rs | 20 +- clippy_lints/src/matches/mod.rs | 80 +- clippy_lints/src/matches/redundant_guards.rs | 39 +- clippy_lints/src/matches/single_match.rs | 5 +- clippy_lints/src/mem_replace.rs | 12 +- clippy_lints/src/methods/bytes_nth.rs | 11 +- .../src/methods/cloned_instead_of_copied.rs | 2 +- clippy_lints/src/methods/err_expect.rs | 2 +- clippy_lints/src/methods/filter_map.rs | 30 +- .../src/methods/filter_map_bool_then.rs | 2 +- clippy_lints/src/methods/filter_map_next.rs | 2 +- clippy_lints/src/methods/format_collect.rs | 16 +- clippy_lints/src/methods/get_first.rs | 40 +- clippy_lints/src/methods/get_unwrap.rs | 6 +- .../src/methods/is_digit_ascii_radix.rs | 2 +- clippy_lints/src/methods/iter_kv_map.rs | 13 +- .../src/methods/iter_out_of_bounds.rs | 2 +- .../src/methods/iter_overeager_cloned.rs | 88 +-- clippy_lints/src/methods/manual_try_fold.rs | 6 +- clippy_lints/src/methods/map_clone.rs | 2 +- clippy_lints/src/methods/map_unwrap_or.rs | 2 +- clippy_lints/src/methods/mod.rs | 690 +++++++++++------- clippy_lints/src/methods/needless_collect.rs | 51 +- .../src/methods/option_as_ref_deref.rs | 2 +- .../src/methods/option_map_unwrap_or.rs | 2 +- clippy_lints/src/methods/or_fun_call.rs | 6 +- .../src/methods/path_ends_with_ext.rs | 5 +- .../src/methods/read_line_without_trim.rs | 9 +- .../src/methods/readonly_write_lock.rs | 21 +- clippy_lints/src/methods/seek_from_current.rs | 18 +- .../seek_to_start_instead_of_rewind.rs | 18 +- clippy_lints/src/methods/str_splitn.rs | 20 +- .../src/methods/string_lit_chars_any.rs | 6 +- .../methods/suspicious_command_arg_space.rs | 7 +- clippy_lints/src/methods/type_id_on_box.rs | 4 +- .../unnecessary_fallible_conversions.rs | 122 ++++ .../src/methods/unnecessary_literal_unwrap.rs | 2 +- .../src/methods/unnecessary_to_owned.rs | 89 ++- clippy_lints/src/methods/waker_clone_wake.rs | 32 + clippy_lints/src/min_ident_chars.rs | 8 +- clippy_lints/src/misc.rs | 8 +- clippy_lints/src/misc_early/mod.rs | 32 +- .../src/mismatching_type_param_order.rs | 4 +- clippy_lints/src/missing_assert_message.rs | 4 +- .../src/missing_asserts_for_indexing.rs | 27 +- clippy_lints/src/missing_const_for_fn.rs | 8 +- .../src/missing_enforced_import_rename.rs | 4 +- clippy_lints/src/missing_fields_in_debug.rs | 4 +- clippy_lints/src/missing_inline.rs | 2 +- clippy_lints/src/missing_trait_methods.rs | 4 +- .../src/mixed_read_write_in_expression.rs | 4 +- clippy_lints/src/multi_assignments.rs | 4 +- .../src/multiple_unsafe_ops_per_block.rs | 4 +- clippy_lints/src/mut_key.rs | 2 +- clippy_lints/src/mut_mut.rs | 2 +- clippy_lints/src/mut_reference.rs | 4 +- clippy_lints/src/mutex_atomic.rs | 8 +- .../src/needless_arbitrary_self_type.rs | 4 +- clippy_lints/src/needless_bool.rs | 12 +- clippy_lints/src/needless_borrowed_ref.rs | 4 +- .../src/needless_borrows_for_generic_args.rs | 43 +- clippy_lints/src/needless_continue.rs | 10 +- clippy_lints/src/needless_else.rs | 4 +- clippy_lints/src/needless_for_each.rs | 4 +- clippy_lints/src/needless_late_init.rs | 4 +- .../src/needless_parens_on_range_literals.rs | 10 +- clippy_lints/src/needless_pass_by_ref_mut.rs | 15 +- clippy_lints/src/needless_pass_by_value.rs | 4 +- clippy_lints/src/needless_question_mark.rs | 6 +- clippy_lints/src/needless_update.rs | 2 +- clippy_lints/src/neg_cmp_op_on_partial_ord.rs | 4 +- clippy_lints/src/no_effect.rs | 13 +- clippy_lints/src/no_mangle_with_rust_abi.rs | 7 +- clippy_lints/src/non_canonical_impls.rs | 29 +- clippy_lints/src/non_copy_const.rs | 8 +- clippy_lints/src/non_expressive_names.rs | 2 +- clippy_lints/src/nonstandard_macro_braces.rs | 89 +-- clippy_lints/src/octal_escapes.rs | 4 +- clippy_lints/src/only_used_in_recursion.rs | 21 +- .../src/operators/arithmetic_side_effects.rs | 16 +- clippy_lints/src/operators/eq_op.rs | 19 +- clippy_lints/src/operators/mod.rs | 72 +- clippy_lints/src/option_env_unwrap.rs | 23 +- clippy_lints/src/option_if_let_else.rs | 14 +- .../src/overflow_check_conditional.rs | 2 +- clippy_lints/src/panic_in_result_fn.rs | 4 +- clippy_lints/src/panic_unimplemented.rs | 13 +- clippy_lints/src/partial_pub_fields.rs | 4 +- clippy_lints/src/partialeq_ne_impl.rs | 2 +- clippy_lints/src/partialeq_to_none.rs | 4 +- clippy_lints/src/pass_by_ref_or_value.rs | 13 +- .../src/permissions_set_readonly_false.rs | 10 +- clippy_lints/src/ptr.rs | 185 +++-- clippy_lints/src/ptr_offset_with_cast.rs | 4 +- clippy_lints/src/pub_use.rs | 27 +- clippy_lints/src/question_mark.rs | 24 +- clippy_lints/src/ranges.rs | 16 +- clippy_lints/src/raw_strings.rs | 8 +- clippy_lints/src/rc_clone_in_vec_init.rs | 4 +- clippy_lints/src/read_zero_byte_vec.rs | 29 +- clippy_lints/src/redundant_async_block.rs | 28 +- clippy_lints/src/redundant_clone.rs | 2 +- clippy_lints/src/redundant_closure_call.rs | 25 +- clippy_lints/src/redundant_else.rs | 4 +- clippy_lints/src/redundant_field_names.rs | 4 +- clippy_lints/src/redundant_locals.rs | 4 +- clippy_lints/src/redundant_pub_crate.rs | 4 +- clippy_lints/src/redundant_slicing.rs | 4 +- .../src/redundant_static_lifetimes.rs | 2 +- .../src/redundant_type_annotations.rs | 24 +- clippy_lints/src/ref_patterns.rs | 6 +- .../src/reserve_after_initialization.rs | 43 +- clippy_lints/src/return_self_not_must_use.rs | 4 +- clippy_lints/src/returns.rs | 12 +- clippy_lints/src/same_name_method.rs | 16 +- clippy_lints/src/semicolon_block.rs | 8 +- .../src/semicolon_if_nothing_returned.rs | 4 +- clippy_lints/src/shadow.rs | 12 +- .../src/significant_drop_tightening.rs | 33 +- clippy_lints/src/single_call_fn.rs | 4 +- .../src/single_char_lifetime_names.rs | 4 +- clippy_lints/src/single_range_in_vec_init.rs | 4 +- clippy_lints/src/size_of_ref.rs | 4 +- .../src/slow_vector_initialization.rs | 4 +- clippy_lints/src/std_instead_of_core.rs | 33 +- clippy_lints/src/strings.rs | 26 +- clippy_lints/src/suspicious_doc_comments.rs | 4 +- .../src/suspicious_operation_groupings.rs | 4 +- .../src/suspicious_xor_used_as_pow.rs | 33 +- clippy_lints/src/swap.rs | 10 +- clippy_lints/src/swap_ptr_to_ref.rs | 18 +- clippy_lints/src/tabs_in_doc_comments.rs | 4 +- clippy_lints/src/temporary_assignment.rs | 2 +- clippy_lints/src/tests_outside_test_module.rs | 4 +- clippy_lints/src/to_digit_is_some.rs | 4 +- clippy_lints/src/trailing_empty_array.rs | 4 +- clippy_lints/src/trait_bounds.rs | 18 +- clippy_lints/src/transmute/mod.rs | 38 +- .../src/transmute/transmute_ptr_to_ref.rs | 2 +- .../src/transmute/transmute_undefined_repr.rs | 22 +- .../src/transmute/transmuting_null.rs | 12 +- clippy_lints/src/tuple_array_conversions.rs | 2 +- clippy_lints/src/types/mod.rs | 16 +- .../src/undocumented_unsafe_blocks.rs | 24 +- clippy_lints/src/unicode.rs | 4 +- clippy_lints/src/unit_return_expecting_ord.rs | 2 +- clippy_lints/src/unit_types/let_unit_value.rs | 11 +- clippy_lints/src/unit_types/mod.rs | 8 +- clippy_lints/src/unnamed_address.rs | 2 +- clippy_lints/src/unnecessary_box_returns.rs | 4 +- .../src/unnecessary_map_on_constructor.rs | 36 +- .../src/unnecessary_owned_empty_strings.rs | 4 +- clippy_lints/src/unnecessary_self_imports.rs | 4 +- .../src/unnecessary_struct_initialization.rs | 20 +- clippy_lints/src/unnecessary_wraps.rs | 4 +- clippy_lints/src/unnested_or_patterns.rs | 6 +- clippy_lints/src/unused_async.rs | 4 +- clippy_lints/src/unused_peekable.rs | 14 +- clippy_lints/src/unused_rounding.rs | 23 +- clippy_lints/src/unused_unit.rs | 4 +- clippy_lints/src/unwrap.rs | 6 +- clippy_lints/src/unwrap_in_result.rs | 4 +- clippy_lints/src/upper_case_acronyms.rs | 4 +- clippy_lints/src/use_self.rs | 6 +- clippy_lints/src/useless_conversion.rs | 69 +- clippy_lints/src/utils/author.rs | 12 +- clippy_lints/src/utils/dump_hir.rs | 12 +- .../src/utils/format_args_collector.rs | 15 +- clippy_lints/src/utils/internal_lints.rs | 2 +- .../almost_standard_lint_formulation.rs | 2 +- .../internal_lints/lint_without_lint_pass.rs | 5 +- .../internal_lints/metadata_collector.rs | 28 +- .../internal_lints/unnecessary_def_path.rs | 3 +- ...rnal.rs => unsorted_clippy_utils_paths.rs} | 10 +- clippy_lints/src/utils/mod.rs | 143 ---- clippy_lints/src/vec.rs | 11 +- clippy_lints/src/vec_init_then_push.rs | 10 +- clippy_lints/src/visibility.rs | 4 +- clippy_lints/src/wildcard_imports.rs | 4 +- clippy_lints/src/write.rs | 45 +- clippy_lints/src/zero_div_zero.rs | 4 +- clippy_lints/src/zero_sized_map_values.rs | 4 +- clippy_utils/Cargo.toml | 5 +- clippy_utils/src/check_proc_macro.rs | 4 +- clippy_utils/src/consts.rs | 22 +- clippy_utils/src/diagnostics.rs | 2 +- clippy_utils/src/hir_utils.rs | 8 +- clippy_utils/src/lib.rs | 136 ++-- clippy_utils/src/paths.rs | 21 +- clippy_utils/src/qualify_min_const_fn.rs | 2 +- clippy_utils/src/source.rs | 8 +- clippy_utils/src/str_utils.rs | 18 +- clippy_utils/src/sugg.rs | 5 +- clippy_utils/src/ty.rs | 22 +- clippy_utils/src/ty/type_certainty/mod.rs | 4 +- declare_clippy_lint/src/lib.rs | 28 +- lintcheck/src/main.rs | 2 +- rust-toolchain | 2 +- src/driver.rs | 10 +- tests/compile-test.rs | 1 + tests/dogfood.rs | 12 +- .../ui-internal/invalid_msrv_attr_impl.fixed | 2 +- tests/ui-internal/invalid_msrv_attr_impl.rs | 2 +- tests/ui/auxiliary/proc_macros.rs | 10 +- tests/ui/bool_to_int_with_if.fixed | 8 +- tests/ui/bool_to_int_with_if.rs | 8 +- tests/ui/bool_to_int_with_if.stderr | 2 +- tests/ui/comparison_to_empty.fixed | 8 +- tests/ui/comparison_to_empty.rs | 8 +- tests/ui/comparison_to_empty.stderr | 8 +- tests/ui/doc/doc-fixable.fixed | 3 + tests/ui/doc/doc-fixable.rs | 3 + tests/ui/enum_variants.rs | 17 + tests/ui/enum_variants.stderr | 14 +- tests/ui/floating_point_mul_add.fixed | 3 + tests/ui/floating_point_mul_add.rs | 3 + tests/ui/floating_point_mul_add.stderr | 8 +- tests/ui/get_first.fixed | 5 +- tests/ui/get_first.rs | 5 +- tests/ui/get_first.stderr | 10 +- tests/ui/if_not_else_bittest.rs | 11 + tests/ui/ignored_unit_patterns.fixed | 16 + tests/ui/ignored_unit_patterns.rs | 16 + tests/ui/ignored_unit_patterns.stderr | 14 +- tests/ui/into_iter_without_iter.rs | 202 +++-- tests/ui/into_iter_without_iter.stderr | 90 +-- tests/ui/iter_without_into_iter.rs | 230 +++--- tests/ui/iter_without_into_iter.stderr | 154 ++-- tests/ui/let_and_return.fixed | 21 +- tests/ui/let_and_return.rs | 19 + tests/ui/let_and_return.stderr | 26 +- tests/ui/manual_filter.rs | 4 +- tests/ui/manual_filter.stderr | 6 +- tests/ui/manual_let_else.rs | 4 +- tests/ui/manual_let_else.stderr | 48 +- tests/ui/manual_map_option_2.fixed | 4 +- tests/ui/manual_map_option_2.rs | 4 +- tests/ui/manual_map_option_2.stderr | 19 +- tests/ui/manual_string_new.fixed | 1 + tests/ui/manual_string_new.rs | 1 + tests/ui/manual_string_new.stderr | 18 +- tests/ui/map_identity.fixed | 24 + tests/ui/map_identity.rs | 26 + tests/ui/map_identity.stderr | 29 +- tests/ui/min_rust_version_invalid_attr.rs | 5 +- tests/ui/min_rust_version_invalid_attr.stderr | 24 +- tests/ui/needless_if.fixed | 16 +- tests/ui/needless_if.rs | 16 +- tests/ui/needless_if.stderr | 21 +- tests/ui/needless_late_init.fixed | 4 +- tests/ui/needless_late_init.rs | 4 +- tests/ui/option_if_let_else.fixed | 17 +- tests/ui/option_if_let_else.rs | 19 +- tests/ui/option_if_let_else.stderr | 67 +- tests/ui/redundant_guards.fixed | 2 +- tests/ui/redundant_guards.rs | 2 +- .../redundant_pattern_matching_option.fixed | 13 +- tests/ui/redundant_pattern_matching_option.rs | 13 +- .../redundant_pattern_matching_option.stderr | 56 +- .../ui/unnecessary_fallible_conversions.fixed | 6 + tests/ui/unnecessary_fallible_conversions.rs | 6 + .../unnecessary_fallible_conversions.stderr | 17 + ...ecessary_fallible_conversions_unfixable.rs | 43 ++ ...sary_fallible_conversions_unfixable.stderr | 41 ++ tests/ui/unused_enumerate_index.fixed | 58 ++ tests/ui/unused_enumerate_index.rs | 58 ++ tests/ui/unused_enumerate_index.stderr | 26 + tests/ui/useless_conversion_try.rs | 2 +- tests/ui/waker_clone_wake.fixed | 29 + tests/ui/waker_clone_wake.rs | 29 + tests/ui/waker_clone_wake.stderr | 17 + tests/versioncheck.rs | 1 + 418 files changed, 4889 insertions(+), 3577 deletions(-) create mode 100644 clippy_config/Cargo.toml rename {clippy_lints/src/utils => clippy_config/src}/conf.rs (88%) create mode 100644 clippy_config/src/lib.rs create mode 100644 clippy_config/src/metadata.rs rename {clippy_utils => clippy_config}/src/msrvs.rs (89%) create mode 100644 clippy_config/src/types.rs create mode 100644 clippy_lints/src/loops/unused_enumerate_index.rs create mode 100644 clippy_lints/src/methods/unnecessary_fallible_conversions.rs create mode 100644 clippy_lints/src/methods/waker_clone_wake.rs rename clippy_lints/src/utils/internal_lints/{clippy_lints_internal.rs => unsorted_clippy_utils_paths.rs} (85%) create mode 100644 tests/ui/if_not_else_bittest.rs create mode 100644 tests/ui/unnecessary_fallible_conversions.fixed create mode 100644 tests/ui/unnecessary_fallible_conversions.rs create mode 100644 tests/ui/unnecessary_fallible_conversions.stderr create mode 100644 tests/ui/unnecessary_fallible_conversions_unfixable.rs create mode 100644 tests/ui/unnecessary_fallible_conversions_unfixable.stderr create mode 100644 tests/ui/unused_enumerate_index.fixed create mode 100644 tests/ui/unused_enumerate_index.rs create mode 100644 tests/ui/unused_enumerate_index.stderr create mode 100644 tests/ui/waker_clone_wake.fixed create mode 100644 tests/ui/waker_clone_wake.rs create mode 100644 tests/ui/waker_clone_wake.stderr diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 410ff53a251b..99d80bec0255 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -60,7 +60,7 @@ jobs: working-directory: clippy_lints - name: Test clippy_utils - run: cargo test --features deny-warnings,internal + run: cargo test --features deny-warnings working-directory: clippy_utils - name: Test rustc_tools_util diff --git a/.github/workflows/clippy_bors.yml b/.github/workflows/clippy_bors.yml index 9b96f8dc2533..f67233dec624 100644 --- a/.github/workflows/clippy_bors.yml +++ b/.github/workflows/clippy_bors.yml @@ -120,9 +120,13 @@ jobs: working-directory: clippy_lints - name: Test clippy_utils - run: cargo test --features deny-warnings,internal + run: cargo test --features deny-warnings working-directory: clippy_utils + - name: Test clippy_config + run: cargo test --features deny-warnings + working-directory: clippy_config + - name: Test rustc_tools_util run: cargo test --features deny-warnings working-directory: rustc_tools_util diff --git a/CHANGELOG.md b/CHANGELOG.md index 26c9877dbffb..87a96bdeba65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5528,6 +5528,7 @@ Released 2018-09-13 [`unknown_clippy_lints`]: https://rust-lang.github.io/rust-clippy/master/index.html#unknown_clippy_lints [`unnecessary_box_returns`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns [`unnecessary_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast +[`unnecessary_fallible_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fallible_conversions [`unnecessary_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_filter_map [`unnecessary_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_find_map [`unnecessary_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fold @@ -5560,6 +5561,7 @@ Released 2018-09-13 [`unstable_as_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#unstable_as_slice [`unused_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_async [`unused_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_collect +[`unused_enumerate_index`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_enumerate_index [`unused_format_specs`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_format_specs [`unused_io_amount`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_io_amount [`unused_label`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_label @@ -5589,6 +5591,7 @@ Released 2018-09-13 [`verbose_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask [`verbose_file_reads`]: https://rust-lang.github.io/rust-clippy/master/index.html#verbose_file_reads [`vtable_address_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#vtable_address_comparisons +[`waker_clone_wake`]: https://rust-lang.github.io/rust-clippy/master/index.html#waker_clone_wake [`while_immutable_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_immutable_condition [`while_let_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_let_loop [`while_let_on_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_let_on_iterator diff --git a/Cargo.toml b/Cargo.toml index 2c50addfd7df..4b6688a76b46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,11 +21,12 @@ name = "clippy-driver" path = "src/driver.rs" [dependencies] +clippy_config = { path = "clippy_config" } clippy_lints = { path = "clippy_lints" } rustc_tools_util = "0.3.0" tempfile = { version = "3.2", optional = true } termize = "0.1" -color-print = "0.3.4" # Sync version with Cargo +color-print = "0.3.4" anstream = "0.5.0" [dev-dependencies] diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index c7eeed179546..841a5b6d0077 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -26,7 +26,7 @@ arithmetic-side-effects-allowed = ["SomeType", "AnotherType"] A type, say `SomeType`, listed in this configuration has the same behavior of `["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`. -**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet`) +**Default Value:** `[]` --- **Affected lints:** @@ -49,7 +49,7 @@ Pairs are asymmetric, which means that `["SomeType", "AnotherType"]` is not the arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", "*"]] ``` -**Default Value:** `[]` (`Vec<[String; 2]>`) +**Default Value:** `[]` --- **Affected lints:** @@ -65,7 +65,7 @@ Suppress checking of the passed type names in unary operations like "negation" ( arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"] ``` -**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet`) +**Default Value:** `[]` --- **Affected lints:** @@ -75,7 +75,7 @@ arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"] ## `avoid-breaking-exported-api` Suppress lints whenever the suggested change would cause breakage for other crates. -**Default Value:** `true` (`bool`) +**Default Value:** `true` --- **Affected lints:** @@ -98,9 +98,7 @@ Suppress lints whenever the suggested change would cause breakage for other crat ## `msrv` -The minimum rust version that the project supports - -**Default Value:** `Msrv { stack: [] }` (`crate::Msrv`) +The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml` --- **Affected lints:** @@ -157,7 +155,7 @@ The minimum rust version that the project supports ## `cognitive-complexity-threshold` The maximum cognitive complexity a function can have -**Default Value:** `25` (`u64`) +**Default Value:** `25` --- **Affected lints:** @@ -167,7 +165,7 @@ The maximum cognitive complexity a function can have ## `excessive-nesting-threshold` The maximum amount of nesting a block can reside in -**Default Value:** `0` (`u64`) +**Default Value:** `0` --- **Affected lints:** @@ -179,7 +177,7 @@ The list of disallowed names to lint about. NB: `bar` is not here since it has l `".."` can be used as part of the list to indicate that the configured values should be appended to the default configuration of Clippy. By default, any configuration will replace the default value. -**Default Value:** `["foo", "baz", "quux"]` (`Vec`) +**Default Value:** `["foo", "baz", "quux"]` --- **Affected lints:** @@ -189,7 +187,7 @@ default configuration of Clippy. By default, any configuration will replace the ## `semicolon-inside-block-ignore-singleline` Whether to lint only if it's multiline. -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -199,7 +197,7 @@ Whether to lint only if it's multiline. ## `semicolon-outside-block-ignore-multiline` Whether to lint only if it's singleline. -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -213,9 +211,7 @@ default configuration of Clippy. By default, any configuration will replace the * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`. * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list. -Default list: - -**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` (`Vec`) +**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` --- **Affected lints:** @@ -225,7 +221,7 @@ Default list: ## `too-many-arguments-threshold` The maximum number of argument a function or method can have -**Default Value:** `7` (`u64`) +**Default Value:** `7` --- **Affected lints:** @@ -235,7 +231,7 @@ The maximum number of argument a function or method can have ## `type-complexity-threshold` The maximum complexity a type can have -**Default Value:** `250` (`u64`) +**Default Value:** `250` --- **Affected lints:** @@ -245,7 +241,7 @@ The maximum complexity a type can have ## `single-char-binding-names-threshold` The maximum number of single char bindings a scope may have -**Default Value:** `4` (`u64`) +**Default Value:** `4` --- **Affected lints:** @@ -255,7 +251,7 @@ The maximum number of single char bindings a scope may have ## `too-large-for-stack` The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap -**Default Value:** `200` (`u64`) +**Default Value:** `200` --- **Affected lints:** @@ -266,7 +262,7 @@ The maximum size of objects (in bytes) that will be linted. Larger objects are o ## `enum-variant-name-threshold` The minimum number of enum variants for the lints about variant names to trigger -**Default Value:** `3` (`u64`) +**Default Value:** `3` --- **Affected lints:** @@ -276,7 +272,7 @@ The minimum number of enum variants for the lints about variant names to trigger ## `struct-field-name-threshold` The minimum number of struct fields for the lints about field names to trigger -**Default Value:** `3` (`u64`) +**Default Value:** `3` --- **Affected lints:** @@ -286,7 +282,7 @@ The minimum number of struct fields for the lints about field names to trigger ## `enum-variant-size-threshold` The maximum size of an enum's variant to avoid box suggestion -**Default Value:** `200` (`u64`) +**Default Value:** `200` --- **Affected lints:** @@ -296,7 +292,7 @@ The maximum size of an enum's variant to avoid box suggestion ## `verbose-bit-mask-threshold` The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros' -**Default Value:** `1` (`u64`) +**Default Value:** `1` --- **Affected lints:** @@ -306,7 +302,7 @@ The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros' ## `literal-representation-threshold` The lower bound for linting decimal literals -**Default Value:** `16384` (`u64`) +**Default Value:** `16384` --- **Affected lints:** @@ -314,9 +310,8 @@ The lower bound for linting decimal literals ## `trivial-copy-size-limit` -The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by reference. - -**Default Value:** `None` (`Option`) +The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by +reference. By default there is no limit --- **Affected lints:** @@ -326,7 +321,7 @@ The maximum size (in bytes) to consider a `Copy` type for passing by value inste ## `pass-by-value-size-limit` The minimum size (in bytes) to consider a type for passing by reference instead of by value. -**Default Value:** `256` (`u64`) +**Default Value:** `256` --- **Affected lints:** @@ -336,7 +331,7 @@ The minimum size (in bytes) to consider a type for passing by reference instead ## `too-many-lines-threshold` The maximum number of lines a function or method can have -**Default Value:** `100` (`u64`) +**Default Value:** `100` --- **Affected lints:** @@ -346,7 +341,7 @@ The maximum number of lines a function or method can have ## `array-size-threshold` The maximum allowed size for arrays on the stack -**Default Value:** `512000` (`u64`) +**Default Value:** `512000` --- **Affected lints:** @@ -357,7 +352,7 @@ The maximum allowed size for arrays on the stack ## `stack-size-threshold` The maximum allowed stack size for functions in bytes -**Default Value:** `512000` (`u64`) +**Default Value:** `512000` --- **Affected lints:** @@ -367,7 +362,7 @@ The maximum allowed stack size for functions in bytes ## `vec-box-size-threshold` The size of the boxed type in bytes, where boxing in a `Vec` is allowed -**Default Value:** `4096` (`u64`) +**Default Value:** `4096` --- **Affected lints:** @@ -377,7 +372,7 @@ The size of the boxed type in bytes, where boxing in a `Vec` is allowed ## `max-trait-bounds` The maximum number of bounds a trait can have to be linted -**Default Value:** `3` (`u64`) +**Default Value:** `3` --- **Affected lints:** @@ -387,7 +382,7 @@ The maximum number of bounds a trait can have to be linted ## `max-struct-bools` The maximum number of bool fields a struct can have -**Default Value:** `3` (`u64`) +**Default Value:** `3` --- **Affected lints:** @@ -397,7 +392,7 @@ The maximum number of bool fields a struct can have ## `max-fn-params-bools` The maximum number of bool parameters a function can have -**Default Value:** `3` (`u64`) +**Default Value:** `3` --- **Affected lints:** @@ -407,7 +402,7 @@ The maximum number of bool parameters a function can have ## `warn-on-all-wildcard-imports` Whether to allow certain wildcard imports (prelude, super in tests). -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -417,7 +412,7 @@ Whether to allow certain wildcard imports (prelude, super in tests). ## `disallowed-macros` The list of disallowed macros, written as fully qualified paths. -**Default Value:** `[]` (`Vec`) +**Default Value:** `[]` --- **Affected lints:** @@ -427,7 +422,7 @@ The list of disallowed macros, written as fully qualified paths. ## `disallowed-methods` The list of disallowed methods, written as fully qualified paths. -**Default Value:** `[]` (`Vec`) +**Default Value:** `[]` --- **Affected lints:** @@ -437,7 +432,7 @@ The list of disallowed methods, written as fully qualified paths. ## `disallowed-types` The list of disallowed types, written as fully qualified paths. -**Default Value:** `[]` (`Vec`) +**Default Value:** `[]` --- **Affected lints:** @@ -447,7 +442,7 @@ The list of disallowed types, written as fully qualified paths. ## `unreadable-literal-lint-fractions` Should the fraction of a decimal be linted to include separators. -**Default Value:** `true` (`bool`) +**Default Value:** `true` --- **Affected lints:** @@ -457,7 +452,7 @@ Should the fraction of a decimal be linted to include separators. ## `upper-case-acronyms-aggressive` Enables verbose mode. Triggers if there is more than one uppercase char next to each other -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -468,7 +463,7 @@ Enables verbose mode. Triggers if there is more than one uppercase char next to Whether the matches should be considered by the lint, and whether there should be filtering for common types. -**Default Value:** `WellKnownTypes` (`crate::manual_let_else::MatchLintBehaviour`) +**Default Value:** `"WellKnownTypes"` --- **Affected lints:** @@ -478,11 +473,11 @@ be filtering for common types. ## `cargo-ignore-publish` For internal testing only, ignores the current `publish` settings in the Cargo manifest. -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** -* [`_cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#_cargo_common_metadata) +* [`cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata) ## `standard-macro-braces` @@ -492,7 +487,7 @@ A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If could be used with a full path two `MacroMatcher`s have to be added one with the full path `crate_name::macro_name` and one with just the macro name. -**Default Value:** `[]` (`Vec`) +**Default Value:** `[]` --- **Affected lints:** @@ -502,7 +497,7 @@ could be used with a full path two `MacroMatcher`s have to be added one with the ## `enforced-import-renames` The list of imports to always rename, a fully qualified path followed by the rename. -**Default Value:** `[]` (`Vec`) +**Default Value:** `[]` --- **Affected lints:** @@ -512,7 +507,7 @@ The list of imports to always rename, a fully qualified path followed by the ren ## `allowed-scripts` The list of unicode scripts allowed to be used in the scope. -**Default Value:** `["Latin"]` (`Vec`) +**Default Value:** `["Latin"]` --- **Affected lints:** @@ -522,7 +517,7 @@ The list of unicode scripts allowed to be used in the scope. ## `enable-raw-pointer-heuristic-for-send` Whether to apply the raw pointer heuristic to determine if a type is `Send`. -**Default Value:** `true` (`bool`) +**Default Value:** `true` --- **Affected lints:** @@ -534,7 +529,7 @@ When Clippy suggests using a slice pattern, this is the maximum number of elemen the slice pattern that is suggested. If more elements are necessary, the lint is suppressed. For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements. -**Default Value:** `3` (`u64`) +**Default Value:** `3` --- **Affected lints:** @@ -544,7 +539,7 @@ For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements. ## `await-holding-invalid-types` -**Default Value:** `[]` (`Vec`) +**Default Value:** `[]` --- **Affected lints:** @@ -554,7 +549,7 @@ For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements. ## `max-include-file-size` The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes -**Default Value:** `1000000` (`u64`) +**Default Value:** `1000000` --- **Affected lints:** @@ -564,7 +559,7 @@ The maximum size of a file included via `include_bytes!()` or `include_str!()`, ## `allow-expect-in-tests` Whether `expect` should be allowed in test functions or `#[cfg(test)]` -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -574,7 +569,7 @@ Whether `expect` should be allowed in test functions or `#[cfg(test)]` ## `allow-unwrap-in-tests` Whether `unwrap` should be allowed in test functions or `#[cfg(test)]` -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -584,7 +579,7 @@ Whether `unwrap` should be allowed in test functions or `#[cfg(test)]` ## `allow-dbg-in-tests` Whether `dbg!` should be allowed in test functions or `#[cfg(test)]` -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -594,7 +589,7 @@ Whether `dbg!` should be allowed in test functions or `#[cfg(test)]` ## `allow-print-in-tests` Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]` -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -605,7 +600,7 @@ Whether print macros (ex. `println!`) should be allowed in test functions or `#[ ## `large-error-threshold` The maximum size of the `Err`-variant in a `Result` returned from a function -**Default Value:** `128` (`u64`) +**Default Value:** `128` --- **Affected lints:** @@ -616,7 +611,7 @@ The maximum size of the `Err`-variant in a `Result` returned from a function A list of paths to types that should be treated like `Arc`, i.e. ignored but for the generic parameters for determining interior mutability -**Default Value:** `["bytes::Bytes"]` (`Vec`) +**Default Value:** `["bytes::Bytes"]` --- **Affected lints:** @@ -627,7 +622,7 @@ for the generic parameters for determining interior mutability ## `allow-mixed-uninlined-format-args` Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)` -**Default Value:** `true` (`bool`) +**Default Value:** `true` --- **Affected lints:** @@ -641,7 +636,7 @@ suggested counterparts are unavailable in constant code. This configuration will cause restriction lints to trigger even if no suggestion can be made. -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -652,7 +647,7 @@ if no suggestion can be made. Whether to **only** check for missing documentation in items visible within the current crate. For example, `pub(crate)` items. -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -662,7 +657,7 @@ crate. For example, `pub(crate)` items. ## `future-size-threshold` The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint -**Default Value:** `16384` (`u64`) +**Default Value:** `16384` --- **Affected lints:** @@ -672,7 +667,7 @@ The maximum byte size a `Future` can have, before it triggers the `clippy::large ## `unnecessary-box-size` The byte size a `T` in `Box` can have, below which it triggers the `clippy::unnecessary_box` lint -**Default Value:** `128` (`u64`) +**Default Value:** `128` --- **Affected lints:** @@ -682,7 +677,7 @@ The byte size a `T` in `Box` can have, below which it triggers the `clippy::u ## `allow-private-module-inception` Whether to allow module inception if it's not public. -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -694,7 +689,7 @@ Allowed names below the minimum allowed characters. The value `".."` can be used the list to indicate, that the configured values should be appended to the default configuration of Clippy. By default, any configuration will replace the default value. -**Default Value:** `{"j", "z", "i", "y", "n", "x", "w"}` (`rustc_data_structures::fx::FxHashSet`) +**Default Value:** `["j", "z", "i", "y", "n", "x", "w"]` --- **Affected lints:** @@ -704,7 +699,7 @@ configuration of Clippy. By default, any configuration will replace the default ## `min-ident-chars-threshold` Minimum chars an ident can have, anything below or equal to this will be linted. -**Default Value:** `1` (`u64`) +**Default Value:** `1` --- **Affected lints:** @@ -714,7 +709,7 @@ Minimum chars an ident can have, anything below or equal to this will be linted. ## `accept-comment-above-statement` Whether to accept a safety comment to be placed above the statement containing the `unsafe` block -**Default Value:** `true` (`bool`) +**Default Value:** `true` --- **Affected lints:** @@ -724,7 +719,7 @@ Whether to accept a safety comment to be placed above the statement containing t ## `accept-comment-above-attributes` Whether to accept a safety comment to be placed above the attributes for the `unsafe` block -**Default Value:** `true` (`bool`) +**Default Value:** `true` --- **Affected lints:** @@ -734,7 +729,7 @@ Whether to accept a safety comment to be placed above the attributes for the `un ## `allow-one-hash-in-raw-strings` Whether to allow `r#""#` when `r""` can be used -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -745,7 +740,7 @@ Whether to allow `r#""#` when `r""` can be used The maximum number of segments a path can have before being linted, anything above this will be linted. -**Default Value:** `2` (`u64`) +**Default Value:** `2` --- **Affected lints:** @@ -755,7 +750,7 @@ be linted. ## `absolute-paths-allowed-crates` Which crates to allow absolute paths from -**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet`) +**Default Value:** `[]` --- **Affected lints:** @@ -765,7 +760,7 @@ Which crates to allow absolute paths from ## `allowed-dotfiles` Additional dotfiles (files or directories starting with a dot) to allow -**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet`) +**Default Value:** `[]` --- **Affected lints:** @@ -774,7 +769,7 @@ Additional dotfiles (files or directories starting with a dot) to allow ## `enforce-iter-loop-reborrow` #### Example -``` +```no_run let mut vec = vec![1, 2, 3]; let rmvec = &mut vec; for _ in rmvec.iter() {} @@ -782,14 +777,14 @@ for _ in rmvec.iter_mut() {} ``` Use instead: -``` +```no_run let mut vec = vec![1, 2, 3]; let rmvec = &mut vec; for _ in &*rmvec {} for _ in &mut *rmvec {} ``` -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml new file mode 100644 index 000000000000..2d41087b51d1 --- /dev/null +++ b/clippy_config/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "clippy_config" +version = "0.1.75" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rustc-semver = "1.1" +serde = { version = "1.0", features = ["derive"] } +toml = "0.7.3" + +[dev-dependencies] +walkdir = "2.3" + +[features] +deny-warnings = [] + +[package.metadata.rust-analyzer] +# This crate uses #[feature(rustc_private)] +rustc_private = true diff --git a/clippy_lints/src/utils/conf.rs b/clippy_config/src/conf.rs similarity index 88% rename from clippy_lints/src/utils/conf.rs rename to clippy_config/src/conf.rs index 8829f188fe79..47259776921b 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_config/src/conf.rs @@ -1,11 +1,11 @@ -//! Read configurations files. - -#![allow(clippy::module_name_repetitions)] - +use crate::msrvs::Msrv; +use crate::types::{DisallowedPath, MacroMatcher, MatchLintBehaviour, Rename}; +use crate::ClippyConfiguration; +use rustc_data_structures::fx::FxHashSet; use rustc_session::Session; use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext}; -use serde::de::{Deserializer, IgnoredAny, IntoDeserializer, MapAccess, Visitor}; -use serde::Deserialize; +use serde::de::{IgnoredAny, IntoDeserializer, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; use std::fmt::{Debug, Display, Formatter}; use std::ops::Range; use std::path::PathBuf; @@ -38,43 +38,12 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[ const DEFAULT_DISALLOWED_NAMES: &[&str] = &["foo", "baz", "quux"]; const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z", "w", "n"]; -/// Holds information used by `MISSING_ENFORCED_IMPORT_RENAMES` lint. -#[derive(Clone, Debug, Deserialize)] -pub struct Rename { - pub path: String, - pub rename: String, -} - -#[derive(Clone, Debug, Deserialize)] -#[serde(untagged)] -pub enum DisallowedPath { - Simple(String), - WithReason { path: String, reason: Option }, -} - -impl DisallowedPath { - pub fn path(&self) -> &str { - let (Self::Simple(path) | Self::WithReason { path, .. }) = self; - - path - } - - pub fn reason(&self) -> Option { - match self { - Self::WithReason { - reason: Some(reason), .. - } => Some(format!("{reason} (from clippy.toml)")), - _ => None, - } - } -} - /// Conf with parse errors #[derive(Default)] -pub struct TryConf { - pub conf: Conf, - pub errors: Vec, - pub warnings: Vec, +struct TryConf { + conf: Conf, + errors: Vec, + warnings: Vec, } impl TryConf { @@ -88,9 +57,9 @@ impl TryConf { } #[derive(Debug)] -pub struct ConfError { - pub message: String, - pub span: Span, +struct ConfError { + message: String, + span: Span, } impl ConfError { @@ -112,10 +81,31 @@ impl ConfError { } } +macro_rules! wrap_option { + () => { + None + }; + ($x:literal) => { + Some($x) + }; +} + +macro_rules! default_text { + ($value:expr) => {{ + let mut text = String::new(); + $value.serialize(toml::ser::ValueSerializer::new(&mut text)).unwrap(); + text + }}; + ($value:expr, $override:expr) => { + $override.to_string() + }; +} + macro_rules! define_Conf { ($( $(#[doc = $doc:literal])+ $(#[conf_deprecated($dep:literal, $new_conf:ident)])? + $(#[default_text = $default_text:expr])? ($name:ident: $ty:ty = $default:expr), )*) => { /// Clippy lint configuration @@ -124,6 +114,7 @@ macro_rules! define_Conf { } mod defaults { + use super::*; $(pub fn $name() -> $ty { $default })* } @@ -190,31 +181,21 @@ macro_rules! define_Conf { } } - pub mod metadata { - use crate::utils::ClippyConfiguration; - - macro_rules! wrap_option { - () => (None); - ($x:literal) => (Some($x)); - } - - pub fn get_configuration_metadata() -> Vec { - vec![ - $( - { - let deprecation_reason = wrap_option!($($dep)?); - - ClippyConfiguration::new( - stringify!($name), - stringify!($ty), - format!("{:?}", super::defaults::$name()), - concat!($($doc, '\n',)*), - deprecation_reason, - ) - }, - )+ - ] - } + pub fn get_configuration_metadata() -> Vec { + vec![ + $( + { + let deprecation_reason = wrap_option!($($dep)?); + + ClippyConfiguration::new( + stringify!($name), + default_text!(defaults::$name() $(, $default_text)?), + concat!($($doc, '\n',)*), + deprecation_reason, + ) + }, + )+ + ] } }; } @@ -236,7 +217,7 @@ define_Conf! { /// /// A type, say `SomeType`, listed in this configuration has the same behavior of /// `["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`. - (arithmetic_side_effects_allowed: rustc_data_structures::fx::FxHashSet = <_>::default()), + (arithmetic_side_effects_allowed: FxHashSet = <_>::default()), /// Lint: ARITHMETIC_SIDE_EFFECTS. /// /// Suppress checking of the passed type pair names in binary operations like addition or @@ -263,15 +244,16 @@ define_Conf! { /// ```toml /// arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"] /// ``` - (arithmetic_side_effects_allowed_unary: rustc_data_structures::fx::FxHashSet = <_>::default()), + (arithmetic_side_effects_allowed_unary: FxHashSet = <_>::default()), /// Lint: ENUM_VARIANT_NAMES, LARGE_TYPES_PASSED_BY_VALUE, TRIVIALLY_COPY_PASS_BY_REF, UNNECESSARY_WRAPS, UNUSED_SELF, UPPER_CASE_ACRONYMS, WRONG_SELF_CONVENTION, BOX_COLLECTION, REDUNDANT_ALLOCATION, RC_BUFFER, VEC_BOX, OPTION_OPTION, LINKEDLIST, RC_MUTEX, UNNECESSARY_BOX_RETURNS, SINGLE_CALL_FN. /// /// Suppress lints whenever the suggested change would cause breakage for other crates. (avoid_breaking_exported_api: bool = true), /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE. /// - /// The minimum rust version that the project supports - (msrv: crate::Msrv = crate::Msrv::empty()), + /// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml` + #[default_text = ""] + (msrv: Msrv = Msrv::empty()), /// DEPRECATED LINT: BLACKLISTED_NAME. /// /// Use the Disallowed Names lint instead @@ -295,7 +277,7 @@ define_Conf! { /// The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value /// `".."` can be used as part of the list to indicate that the configured values should be appended to the /// default configuration of Clippy. By default, any configuration will replace the default value. - (disallowed_names: Vec = super::DEFAULT_DISALLOWED_NAMES.iter().map(ToString::to_string).collect()), + (disallowed_names: Vec = DEFAULT_DISALLOWED_NAMES.iter().map(ToString::to_string).collect()), /// Lint: SEMICOLON_INSIDE_BLOCK. /// /// Whether to lint only if it's multiline. @@ -311,9 +293,7 @@ define_Conf! { /// default configuration of Clippy. By default, any configuration will replace the default value. For example: /// * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`. /// * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list. - /// - /// Default list: - (doc_valid_idents: Vec = super::DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string).collect()), + (doc_valid_idents: Vec = DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string).collect()), /// Lint: TOO_MANY_ARGUMENTS. /// /// The maximum number of argument a function or method can have @@ -352,7 +332,9 @@ define_Conf! { (literal_representation_threshold: u64 = 16384), /// Lint: TRIVIALLY_COPY_PASS_BY_REF. /// - /// The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by reference. + /// The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by + /// reference. By default there is no limit + #[default_text = ""] (trivial_copy_size_limit: Option = None), /// Lint: LARGE_TYPES_PASSED_BY_VALUE. /// @@ -393,15 +375,15 @@ define_Conf! { /// Lint: DISALLOWED_MACROS. /// /// The list of disallowed macros, written as fully qualified paths. - (disallowed_macros: Vec = Vec::new()), + (disallowed_macros: Vec = Vec::new()), /// Lint: DISALLOWED_METHODS. /// /// The list of disallowed methods, written as fully qualified paths. - (disallowed_methods: Vec = Vec::new()), + (disallowed_methods: Vec = Vec::new()), /// Lint: DISALLOWED_TYPES. /// /// The list of disallowed types, written as fully qualified paths. - (disallowed_types: Vec = Vec::new()), + (disallowed_types: Vec = Vec::new()), /// Lint: UNREADABLE_LITERAL. /// /// Should the fraction of a decimal be linted to include separators. @@ -414,9 +396,8 @@ define_Conf! { /// /// Whether the matches should be considered by the lint, and whether there should /// be filtering for common types. - (matches_for_let_else: crate::manual_let_else::MatchLintBehaviour = - crate::manual_let_else::MatchLintBehaviour::WellKnownTypes), - /// Lint: _CARGO_COMMON_METADATA. + (matches_for_let_else: MatchLintBehaviour = MatchLintBehaviour::WellKnownTypes), + /// Lint: CARGO_COMMON_METADATA. /// /// For internal testing only, ignores the current `publish` settings in the Cargo manifest. (cargo_ignore_publish: bool = false), @@ -427,11 +408,11 @@ define_Conf! { /// A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If the macro /// could be used with a full path two `MacroMatcher`s have to be added one with the full path /// `crate_name::macro_name` and one with just the macro name. - (standard_macro_braces: Vec = Vec::new()), + (standard_macro_braces: Vec = Vec::new()), /// Lint: MISSING_ENFORCED_IMPORT_RENAMES. /// /// The list of imports to always rename, a fully qualified path followed by the rename. - (enforced_import_renames: Vec = Vec::new()), + (enforced_import_renames: Vec = Vec::new()), /// Lint: DISALLOWED_SCRIPT_IDENTS. /// /// The list of unicode scripts allowed to be used in the scope. @@ -447,7 +428,7 @@ define_Conf! { /// For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements. (max_suggested_slice_pattern_length: u64 = 3), /// Lint: AWAIT_HOLDING_INVALID_TYPE. - (await_holding_invalid_types: Vec = Vec::new()), + (await_holding_invalid_types: Vec = Vec::new()), /// Lint: LARGE_INCLUDE_FILE. /// /// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes @@ -511,8 +492,8 @@ define_Conf! { /// Allowed names below the minimum allowed characters. The value `".."` can be used as part of /// the list to indicate, that the configured values should be appended to the default /// configuration of Clippy. By default, any configuration will replace the default value. - (allowed_idents_below_min_chars: rustc_data_structures::fx::FxHashSet = - super::DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string).collect()), + (allowed_idents_below_min_chars: FxHashSet = + DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string).collect()), /// Lint: MIN_IDENT_CHARS. /// /// Minimum chars an ident can have, anything below or equal to this will be linted. @@ -537,19 +518,17 @@ define_Conf! { /// Lint: ABSOLUTE_PATHS. /// /// Which crates to allow absolute paths from - (absolute_paths_allowed_crates: rustc_data_structures::fx::FxHashSet = - rustc_data_structures::fx::FxHashSet::default()), + (absolute_paths_allowed_crates: FxHashSet = FxHashSet::default()), /// Lint: PATH_ENDS_WITH_EXT. /// /// Additional dotfiles (files or directories starting with a dot) to allow - (allowed_dotfiles: rustc_data_structures::fx::FxHashSet = - rustc_data_structures::fx::FxHashSet::default()), + (allowed_dotfiles: FxHashSet = FxHashSet::default()), /// Lint: EXPLICIT_ITER_LOOP /// /// Whether to recommend using implicit into iter for reborrowed values. /// /// #### Example - /// ``` + /// ```no_run /// let mut vec = vec![1, 2, 3]; /// let rmvec = &mut vec; /// for _ in rmvec.iter() {} @@ -557,7 +536,7 @@ define_Conf! { /// ``` /// /// Use instead: - /// ``` + /// ```no_run /// let mut vec = vec![1, 2, 3]; /// let rmvec = &mut vec; /// for _ in &*rmvec {} @@ -779,7 +758,7 @@ mod tests { #[test] fn configs_are_tested() { - let mut names: FxHashSet = super::metadata::get_configuration_metadata() + let mut names: FxHashSet = crate::get_configuration_metadata() .into_iter() .map(|meta| meta.name.replace('_', "-")) .collect(); diff --git a/clippy_config/src/lib.rs b/clippy_config/src/lib.rs new file mode 100644 index 000000000000..f5dcb16d670d --- /dev/null +++ b/clippy_config/src/lib.rs @@ -0,0 +1,23 @@ +#![feature(rustc_private, let_chains)] +#![cfg_attr(feature = "deny-warnings", deny(warnings))] +#![warn(rust_2018_idioms, unused_lifetimes)] +#![allow( + clippy::must_use_candidate, + clippy::missing_panics_doc, + rustc::untranslatable_diagnostic_trivial +)] + +extern crate rustc_ast; +extern crate rustc_data_structures; +#[allow(unused_extern_crates)] +extern crate rustc_driver; +extern crate rustc_session; +extern crate rustc_span; + +mod conf; +mod metadata; +pub mod msrvs; +pub mod types; + +pub use conf::{get_configuration_metadata, lookup_conf_file, Conf}; +pub use metadata::ClippyConfiguration; diff --git a/clippy_config/src/metadata.rs b/clippy_config/src/metadata.rs new file mode 100644 index 000000000000..2451fbc91e89 --- /dev/null +++ b/clippy_config/src/metadata.rs @@ -0,0 +1,116 @@ +use std::fmt::{self, Write}; + +#[derive(Debug, Clone, Default)] +pub struct ClippyConfiguration { + pub name: String, + pub default: String, + pub lints: Vec, + pub doc: String, + pub deprecation_reason: Option<&'static str>, +} + +impl fmt::Display for ClippyConfiguration { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "- `{}`: {}", self.name, self.doc)?; + if !self.default.is_empty() { + write!(f, " (default: `{}`)", self.default)?; + } + Ok(()) + } +} + +impl ClippyConfiguration { + pub fn new( + name: &'static str, + default: String, + doc_comment: &'static str, + deprecation_reason: Option<&'static str>, + ) -> Self { + let (lints, doc) = parse_config_field_doc(doc_comment) + .unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string())); + + Self { + name: to_kebab(name), + lints, + doc, + default, + deprecation_reason, + } + } + + pub fn to_markdown_paragraph(&self) -> String { + let mut out = format!( + "## `{}`\n{}\n\n", + self.name, + self.doc + .lines() + .map(|line| line.strip_prefix(" ").unwrap_or(line)) + .collect::>() + .join("\n"), + ); + + if !self.default.is_empty() { + write!(out, "**Default Value:** `{}`\n\n", self.default).unwrap(); + } + + write!( + out, + "---\n**Affected lints:**\n{}\n\n", + self.lints + .iter() + .map(|name| name.to_string().split_whitespace().next().unwrap().to_string()) + .map(|name| format!("* [`{name}`](https://rust-lang.github.io/rust-clippy/master/index.html#{name})")) + .collect::>() + .join("\n"), + ) + .unwrap(); + + out + } + + pub fn to_markdown_link(&self) -> String { + const BOOK_CONFIGS_PATH: &str = "https://doc.rust-lang.org/clippy/lint_configuration.html"; + format!("[`{}`]: {BOOK_CONFIGS_PATH}#{}", self.name, self.name) + } +} + +/// This parses the field documentation of the config struct. +/// +/// ```rust, ignore +/// parse_config_field_doc(cx, "Lint: LINT_NAME_1, LINT_NAME_2. Papa penguin, papa penguin") +/// ``` +/// +/// Would yield: +/// ```rust, ignore +/// Some(["lint_name_1", "lint_name_2"], "Papa penguin, papa penguin") +/// ``` +fn parse_config_field_doc(doc_comment: &str) -> Option<(Vec, String)> { + const DOC_START: &str = " Lint: "; + if doc_comment.starts_with(DOC_START) + && let Some(split_pos) = doc_comment.find('.') + { + let mut doc_comment = doc_comment.to_string(); + let mut documentation = doc_comment.split_off(split_pos); + + // Extract lints + doc_comment.make_ascii_lowercase(); + let lints: Vec = doc_comment + .split_off(DOC_START.len()) + .split(", ") + .map(str::to_string) + .collect(); + + // Format documentation correctly + // split off leading `.` from lint name list and indent for correct formatting + documentation = documentation.trim_start_matches('.').trim().replace("\n ", "\n "); + + Some((lints, documentation)) + } else { + None + } +} + +/// Transforms a given `snake_case_string` to a tasty `kebab-case-string` +fn to_kebab(config_name: &str) -> String { + config_name.replace('_', "-") +} diff --git a/clippy_utils/src/msrvs.rs b/clippy_config/src/msrvs.rs similarity index 89% rename from clippy_utils/src/msrvs.rs rename to clippy_config/src/msrvs.rs index c6a48874e09b..011d54629d41 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_config/src/msrvs.rs @@ -1,10 +1,9 @@ use rustc_ast::Attribute; use rustc_semver::RustcVersion; use rustc_session::Session; +use rustc_span::{sym, Symbol}; use serde::Deserialize; -use crate::attrs::get_unique_attr; - macro_rules! msrv_aliases { ($($major:literal,$minor:literal,$patch:literal { $($name:ident),* $(,)? @@ -101,7 +100,16 @@ impl Msrv { } fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option { - if let Some(msrv_attr) = get_unique_attr(sess, attrs, "msrv") { + let sym_msrv = Symbol::intern("msrv"); + let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv])); + + if let Some(msrv_attr) = msrv_attrs.next() { + if let Some(duplicate) = msrv_attrs.last() { + sess.struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times") + .span_note(msrv_attr.span, "first definition found here") + .emit(); + } + if let Some(msrv) = msrv_attr.value_str() { if let Ok(version) = RustcVersion::parse(msrv.as_str()) { return Some(version); diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs new file mode 100644 index 000000000000..e898221ffa77 --- /dev/null +++ b/clippy_config/src/types.rs @@ -0,0 +1,142 @@ +use serde::de::{self, Deserializer, Visitor}; +use serde::{ser, Deserialize, Serialize}; +use std::fmt; +use std::hash::{Hash, Hasher}; + +#[derive(Clone, Debug, Deserialize)] +pub struct Rename { + pub path: String, + pub rename: String, +} + +#[derive(Clone, Debug, Deserialize)] +#[serde(untagged)] +pub enum DisallowedPath { + Simple(String), + WithReason { path: String, reason: Option }, +} + +impl DisallowedPath { + pub fn path(&self) -> &str { + let (Self::Simple(path) | Self::WithReason { path, .. }) = self; + + path + } + + pub fn reason(&self) -> Option { + match self { + Self::WithReason { + reason: Some(reason), .. + } => Some(format!("{reason} (from clippy.toml)")), + _ => None, + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub enum MatchLintBehaviour { + AllTypes, + WellKnownTypes, + Never, +} + +#[derive(Clone, Debug)] +pub struct MacroMatcher { + pub name: String, + pub braces: (String, String), +} + +impl Hash for MacroMatcher { + fn hash(&self, state: &mut H) { + self.name.hash(state); + } +} + +impl PartialEq for MacroMatcher { + fn eq(&self, other: &Self) -> bool { + self.name == other.name + } +} +impl Eq for MacroMatcher {} + +impl<'de> Deserialize<'de> for MacroMatcher { + fn deserialize(deser: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "lowercase")] + enum Field { + Name, + Brace, + } + struct MacVisitor; + impl<'de> Visitor<'de> for MacVisitor { + type Value = MacroMatcher; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("struct MacroMatcher") + } + + fn visit_map(self, mut map: V) -> Result + where + V: de::MapAccess<'de>, + { + let mut name = None; + let mut brace: Option = None; + while let Some(key) = map.next_key()? { + match key { + Field::Name => { + if name.is_some() { + return Err(de::Error::duplicate_field("name")); + } + name = Some(map.next_value()?); + }, + Field::Brace => { + if brace.is_some() { + return Err(de::Error::duplicate_field("brace")); + } + brace = Some(map.next_value()?); + }, + } + } + let name = name.ok_or_else(|| de::Error::missing_field("name"))?; + let brace = brace.ok_or_else(|| de::Error::missing_field("brace"))?; + Ok(MacroMatcher { + name, + braces: [("(", ")"), ("{", "}"), ("[", "]")] + .into_iter() + .find(|b| b.0 == brace) + .map(|(o, c)| (o.to_owned(), c.to_owned())) + .ok_or_else(|| de::Error::custom(format!("expected one of `(`, `{{`, `[` found `{brace}`")))?, + }) + } + } + + const FIELDS: &[&str] = &["name", "brace"]; + deser.deserialize_struct("MacroMatcher", FIELDS, MacVisitor) + } +} + +// these impls are never actually called but are used by the various config options that default to +// empty lists +macro_rules! unimplemented_serialize { + ($($t:ty,)*) => { + $( + impl Serialize for $t { + fn serialize(&self, _serializer: S) -> Result + where + S: ser::Serializer, + { + Err(ser::Error::custom("unimplemented")) + } + } + )* + } +} + +unimplemented_serialize! { + DisallowedPath, + Rename, + MacroMatcher, +} diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs index fca750fafc79..5bd9994e18d5 100644 --- a/clippy_dev/src/main.rs +++ b/clippy_dev/src/main.rs @@ -199,7 +199,6 @@ fn get_clap_config() -> ArgMatches { "cargo", "nursery", "internal", - "internal_warn", ]), Arg::new("type").long("type").help("What directory the lint belongs in"), Arg::new("msrv") diff --git a/clippy_dev/src/new_lint.rs b/clippy_dev/src/new_lint.rs index be2386bb1d24..eeea53ce46f8 100644 --- a/clippy_dev/src/new_lint.rs +++ b/clippy_dev/src/new_lint.rs @@ -346,11 +346,11 @@ fn get_lint_declaration(name_upper: &str, category: &str) -> String { /// ### Why is this bad? /// /// ### Example - /// ```rust + /// ```no_run /// // example code where clippy issues a warning /// ``` /// Use instead: - /// ```rust + /// ```no_run /// // example code which does not raise clippy warning /// ``` #[clippy::version = "{}"] diff --git a/clippy_dev/src/update_lints.rs b/clippy_dev/src/update_lints.rs index 842aeed2aa40..6b76a44debff 100644 --- a/clippy_dev/src/update_lints.rs +++ b/clippy_dev/src/update_lints.rs @@ -588,7 +588,7 @@ impl Lint { .collect() } - /// Returns all internal lints (not `internal_warn` lints) + /// Returns all internal lints #[must_use] fn internal_lints(lints: &[Self]) -> Vec { lints.iter().filter(|l| l.group == "internal").cloned().collect() diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index 4d5b3bf8a948..4bc27fd48e2f 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -11,6 +11,7 @@ edition = "2021" [dependencies] arrayvec = { version = "0.7", default-features = false } cargo_metadata = "0.15.3" +clippy_config = { path = "../clippy_config" } clippy_utils = { path = "../clippy_utils" } declare_clippy_lint = { path = "../declare_clippy_lint" } if_chain = "1.0" @@ -32,9 +33,9 @@ url = "2.2" walkdir = "2.3" [features] -deny-warnings = ["clippy_utils/deny-warnings"] +deny-warnings = ["clippy_config/deny-warnings", "clippy_utils/deny-warnings"] # build clippy with internal lints enabled, off by default -internal = ["clippy_utils/internal", "serde_json", "tempfile", "regex"] +internal = ["serde_json", "tempfile", "regex"] [package.metadata.rust-analyzer] # This crate uses #[feature(rustc_private)] diff --git a/clippy_lints/src/absolute_paths.rs b/clippy_lints/src/absolute_paths.rs index 04417c4c4600..582423603eb1 100644 --- a/clippy_lints/src/absolute_paths.rs +++ b/clippy_lints/src/absolute_paths.rs @@ -24,11 +24,11 @@ declare_clippy_lint! { /// using absolute paths is the proper way of referencing items in one. /// /// ### Example - /// ```rust + /// ```no_run /// let x = std::f64::consts::PI; /// ``` /// Use any of the below instead, or anything else: - /// ```rust + /// ```no_run /// use std::f64; /// use std::f64::consts; /// use std::f64::consts::PI; diff --git a/clippy_lints/src/almost_complete_range.rs b/clippy_lints/src/almost_complete_range.rs index 32d80f42e7e0..e85878eb5709 100644 --- a/clippy_lints/src/almost_complete_range.rs +++ b/clippy_lints/src/almost_complete_range.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{trim_span, walk_span_to_context}; use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits}; use rustc_errors::Applicability; @@ -17,11 +17,11 @@ declare_clippy_lint! { /// This (`'a'..'z'`) is almost certainly a typo meant to include all letters. /// /// ### Example - /// ```rust + /// ```no_run /// let _ = 'a'..'z'; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let _ = 'a'..='z'; /// ``` #[clippy::version = "1.68.0"] @@ -82,33 +82,20 @@ fn check_range(cx: &EarlyContext<'_>, span: Span, start: &Expr, end: &Expr, sugg ( Ok(LitKind::Byte(b'a') | LitKind::Char('a')), Ok(LitKind::Byte(b'z') | LitKind::Char('z')) - ) - | ( + ) | ( Ok(LitKind::Byte(b'A') | LitKind::Char('A')), Ok(LitKind::Byte(b'Z') | LitKind::Char('Z')), - ) - | ( + ) | ( Ok(LitKind::Byte(b'0') | LitKind::Char('0')), Ok(LitKind::Byte(b'9') | LitKind::Char('9')), ) ) && !in_external_macro(cx.sess(), span) { - span_lint_and_then( - cx, - ALMOST_COMPLETE_RANGE, - span, - "almost complete ascii range", - |diag| { - if let Some((span, sugg)) = sugg { - diag.span_suggestion( - span, - "use an inclusive range", - sugg, - Applicability::MaybeIncorrect, - ); - } + span_lint_and_then(cx, ALMOST_COMPLETE_RANGE, span, "almost complete ascii range", |diag| { + if let Some((span, sugg)) = sugg { + diag.span_suggestion(span, "use an inclusive range", sugg, Applicability::MaybeIncorrect); } - ); + }); } } diff --git a/clippy_lints/src/approx_const.rs b/clippy_lints/src/approx_const.rs index ccf82f132f4e..b4f778f12b93 100644 --- a/clippy_lints/src/approx_const.rs +++ b/clippy_lints/src/approx_const.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::msrvs::{self, Msrv}; use rustc_ast::ast::{FloatTy, LitFloatType, LitKind}; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -24,12 +24,12 @@ declare_clippy_lint! { /// issue](https://github.com/rust-lang/rust/issues). /// /// ### Example - /// ```rust + /// ```no_run /// let x = 3.14; /// let y = 1_f64 / x; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let x = std::f32::consts::PI; /// let y = std::f64::consts::FRAC_1_PI; /// ``` diff --git a/clippy_lints/src/arc_with_non_send_sync.rs b/clippy_lints/src/arc_with_non_send_sync.rs index 35a04b5e44a3..192bc7d9ddce 100644 --- a/clippy_lints/src/arc_with_non_send_sync.rs +++ b/clippy_lints/src/arc_with_non_send_sync.rs @@ -18,7 +18,7 @@ declare_clippy_lint! { /// either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc` /// /// ### Example - /// ```rust + /// ```no_run /// # use std::cell::RefCell; /// # use std::sync::Arc; /// @@ -62,19 +62,21 @@ impl<'tcx> LateLintPass<'tcx> for ArcWithNonSendSync { ARC_WITH_NON_SEND_SYNC, expr.span, "usage of an `Arc` that is not `Send` or `Sync`", - |diag| with_forced_trimmed_paths!({ - if !is_send { - diag.note(format!("the trait `Send` is not implemented for `{arg_ty}`")); - } - if !is_sync { - diag.note(format!("the trait `Sync` is not implemented for `{arg_ty}`")); - } + |diag| { + with_forced_trimmed_paths!({ + if !is_send { + diag.note(format!("the trait `Send` is not implemented for `{arg_ty}`")); + } + if !is_sync { + diag.note(format!("the trait `Sync` is not implemented for `{arg_ty}`")); + } - diag.note(format!("required for `{ty}` to implement `Send` and `Sync`")); + diag.note(format!("required for `{ty}` to implement `Send` and `Sync`")); - diag.help("consider using an `Rc` instead or wrapping the inner type with a `Mutex`"); - } - )); + diag.help("consider using an `Rc` instead or wrapping the inner type with a `Mutex`"); + }); + }, + ); } } } diff --git a/clippy_lints/src/assertions_on_result_states.rs b/clippy_lints/src/assertions_on_result_states.rs index 2980c9d6db3d..71ec87a88741 100644 --- a/clippy_lints/src/assertions_on_result_states.rs +++ b/clippy_lints/src/assertions_on_result_states.rs @@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates { return; } } - let semicolon = if is_expr_final_block_expr(cx.tcx, e) {";"} else {""}; + let semicolon = if is_expr_final_block_expr(cx.tcx, e) { ";" } else { "" }; let mut app = Applicability::MachineApplicable; match method_segment.ident.as_str() { "is_ok" if type_suitable_to_unwrap(cx, args.type_at(1)) => { @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates { ), app, ); - } + }, "is_err" if type_suitable_to_unwrap(cx, args.type_at(0)) => { span_lint_and_sugg( cx, @@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates { ), app, ); - } + }, _ => (), }; } diff --git a/clippy_lints/src/async_yields_async.rs b/clippy_lints/src/async_yields_async.rs index 050df68a0fa1..ec2447dae965 100644 --- a/clippy_lints/src/async_yields_async.rs +++ b/clippy_lints/src/async_yields_async.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::source::snippet; use clippy_utils::ty::implements_trait; use rustc_errors::Applicability; -use rustc_hir::{CoroutineSource, Body, BodyId, CoroutineKind, ExprKind, QPath}; +use rustc_hir::{Body, BodyId, CoroutineKind, CoroutineSource, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -15,7 +15,7 @@ declare_clippy_lint! { /// An await is likely missing. /// /// ### Example - /// ```rust + /// ```no_run /// async fn foo() {} /// /// fn bar() { @@ -26,7 +26,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// async fn foo() {} /// /// fn bar() { diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index db01ddbde04e..64bfa8d904cd 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -1,9 +1,9 @@ //! checks for attributes +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then}; use clippy_utils::is_from_proc_macro; use clippy_utils::macros::{is_panic, macro_backtrace}; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments}; use if_chain::if_chain; use rustc_ast::token::{Token, TokenKind}; @@ -129,7 +129,7 @@ declare_clippy_lint! { /// a valid semver. Failing that, the contained information is useless. /// /// ### Example - /// ```rust + /// ```no_run /// #[deprecated(since = "forever")] /// fn something_else() { /* ... */ } /// ``` @@ -156,14 +156,14 @@ declare_clippy_lint! { /// currently works for basic cases but is not perfect. /// /// ### Example - /// ```rust + /// ```no_run /// #[allow(dead_code)] /// /// fn not_quite_good_code() { } /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// // Good (as inner attribute) /// #![allow(dead_code)] /// @@ -198,25 +198,25 @@ declare_clippy_lint! { /// Does not detect empty lines after doc attributes (e.g. `#[doc = ""]`). /// /// ### Example - /// ```rust + /// ```no_run /// /// Some doc comment with a blank line after it. /// /// fn not_quite_good_code() { } /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// /// Good (no blank line) /// fn this_is_fine() { } /// ``` /// - /// ```rust + /// ```no_run /// // Good (convert to a regular comment) /// /// fn this_is_fine_too() { } /// ``` /// - /// ```rust + /// ```no_run /// //! Good (convert to a comment on an inner attribute) /// /// fn this_is_fine_as_well() { } @@ -236,12 +236,12 @@ declare_clippy_lint! { /// These lints should only be enabled on a lint-by-lint basis and with careful consideration. /// /// ### Example - /// ```rust + /// ```no_run /// #![deny(clippy::restriction)] /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// #![deny(clippy::as_conversions)] /// ``` #[clippy::version = "1.47.0"] @@ -265,13 +265,13 @@ declare_clippy_lint! { /// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765) /// /// ### Example - /// ```rust + /// ```no_run /// #[cfg_attr(rustfmt, rustfmt_skip)] /// fn main() { } /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// #[rustfmt::skip] /// fn main() { } /// ``` @@ -290,13 +290,13 @@ declare_clippy_lint! { /// by the conditional compilation engine. /// /// ### Example - /// ```rust + /// ```no_run /// #[cfg(linux)] /// fn conditional() { } /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # mod hidden { /// #[cfg(target_os = "linux")] /// fn conditional() { } @@ -325,14 +325,14 @@ declare_clippy_lint! { /// ensure that others understand the reasoning /// /// ### Example - /// ```rust + /// ```no_run /// #![feature(lint_reasons)] /// /// #![allow(clippy::some_lint)] /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// #![feature(lint_reasons)] /// /// #![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")] @@ -352,7 +352,7 @@ declare_clippy_lint! { /// panicking with the expected message, and not another unrelated panic. /// /// ### Example - /// ```rust + /// ```no_run /// fn random() -> i32 { 0 } /// /// #[should_panic] @@ -363,7 +363,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// fn random() -> i32 { 0 } /// /// #[should_panic = "attempt to divide by zero"] @@ -386,13 +386,13 @@ declare_clippy_lint! { /// If there is only one condition, no need to wrap it into `any` or `all` combinators. /// /// ### Example - /// ```rust + /// ```no_run /// #[cfg(any(unix))] /// pub struct Bar; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// #[cfg(unix)] /// pub struct Bar; /// ``` @@ -409,16 +409,16 @@ declare_clippy_lint! { /// /// ### Why is this bad? /// Misspelling `feature` as `features` can be sometimes hard to spot. It - /// may cause conditional compilation not work quitely. + /// may cause conditional compilation not work quietly. /// /// ### Example - /// ```rust + /// ```no_run /// #[cfg(features = "some-feature")] /// fn conditional() { } /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// #[cfg(feature = "some-feature")] /// fn conditional() { } /// ``` @@ -602,9 +602,26 @@ fn check_should_panic_reason(cx: &LateContext<'_>, attr: &Attribute) { if let AttrArgs::Delimited(args) = &normal_attr.item.args && let mut tt_iter = args.tokens.trees() - && let Some(TokenTree::Token(Token { kind: TokenKind::Ident(sym::expected, _), .. }, _)) = tt_iter.next() - && let Some(TokenTree::Token(Token { kind: TokenKind::Eq, .. }, _)) = tt_iter.next() - && let Some(TokenTree::Token(Token { kind: TokenKind::Literal(_), .. }, _)) = tt_iter.next() + && let Some(TokenTree::Token( + Token { + kind: TokenKind::Ident(sym::expected, _), + .. + }, + _, + )) = tt_iter.next() + && let Some(TokenTree::Token( + Token { + kind: TokenKind::Eq, .. + }, + _, + )) = tt_iter.next() + && let Some(TokenTree::Token( + Token { + kind: TokenKind::Literal(_), + .. + }, + _, + )) = tt_iter.next() { // `#[should_panic(expected = "..")]` found, good return; @@ -914,7 +931,9 @@ fn check_nested_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) { fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) { for item in items { if let NestedMetaItem::MetaItem(meta) = item { - if meta.has_name(sym!(features)) && let Some(val) = meta.value_str() { + if meta.has_name(sym!(features)) + && let Some(val) = meta.value_str() + { span_lint_and_sugg( cx, MAYBE_MISUSED_CFG, @@ -933,16 +952,16 @@ fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) { } fn check_minimal_cfg_condition(cx: &EarlyContext<'_>, attr: &Attribute) { - if attr.has_name(sym::cfg) && - let Some(items) = attr.meta_item_list() + if attr.has_name(sym::cfg) + && let Some(items) = attr.meta_item_list() { check_nested_cfg(cx, &items); } } fn check_misused_cfg(cx: &EarlyContext<'_>, attr: &Attribute) { - if attr.has_name(sym::cfg) && - let Some(items) = attr.meta_item_list() + if attr.has_name(sym::cfg) + && let Some(items) = attr.meta_item_list() { check_nested_misused_cfg(cx, &items); } diff --git a/clippy_lints/src/await_holding_invalid.rs b/clippy_lints/src/await_holding_invalid.rs index 0c356934992f..06b74b972b70 100644 --- a/clippy_lints/src/await_holding_invalid.rs +++ b/clippy_lints/src/await_holding_invalid.rs @@ -1,15 +1,14 @@ +use clippy_config::types::DisallowedPath; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::{match_def_path, paths}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; -use rustc_hir::{CoroutineSource, Body, CoroutineKind}; +use rustc_hir::{Body, CoroutineKind, CoroutineSource}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::CoroutineLayout; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{sym, Span}; -use crate::utils::conf::DisallowedPath; - declare_clippy_lint! { /// ### What it does /// Checks for calls to await while holding a non-async-aware MutexGuard. @@ -29,7 +28,7 @@ declare_clippy_lint! { /// to wrap the `.lock()` call in a block instead of explicitly dropping the guard. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::sync::Mutex; /// # async fn baz() {} /// async fn foo(x: &Mutex) { @@ -47,7 +46,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # use std::sync::Mutex; /// # async fn baz() {} /// async fn foo(x: &Mutex) { @@ -87,7 +86,7 @@ declare_clippy_lint! { /// to wrap the `.borrow[_mut]()` call in a block instead of explicitly dropping the ref. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::cell::RefCell; /// # async fn baz() {} /// async fn foo(x: &RefCell) { @@ -105,7 +104,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # use std::cell::RefCell; /// # async fn baz() {} /// async fn foo(x: &RefCell) { @@ -151,7 +150,7 @@ declare_clippy_lint! { /// ] /// ``` /// - /// ```rust + /// ```no_run /// # async fn baz() {} /// struct CustomLockType; /// struct OtherCustomLockType; diff --git a/clippy_lints/src/blocks_in_if_conditions.rs b/clippy_lints/src/blocks_in_if_conditions.rs index 1593d7b0fb38..04bf541a5bdc 100644 --- a/clippy_lints/src/blocks_in_if_conditions.rs +++ b/clippy_lints/src/blocks_in_if_conditions.rs @@ -21,7 +21,7 @@ declare_clippy_lint! { /// Style, using blocks in the condition makes it hard to read. /// /// ### Examples - /// ```rust + /// ```no_run /// # fn somefunc() -> bool { true }; /// if { true } { /* ... */ } /// @@ -29,7 +29,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # fn somefunc() -> bool { true }; /// if true { /* ... */ } /// diff --git a/clippy_lints/src/bool_assert_comparison.rs b/clippy_lints/src/bool_assert_comparison.rs index 4503597713af..665dbd6f708c 100644 --- a/clippy_lints/src/bool_assert_comparison.rs +++ b/clippy_lints/src/bool_assert_comparison.rs @@ -18,13 +18,13 @@ declare_clippy_lint! { /// It is shorter to use the equivalent. /// /// ### Example - /// ```rust + /// ```no_run /// assert_eq!("a".is_empty(), false); /// assert_ne!("a".is_empty(), true); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// assert!(!"a".is_empty()); /// ``` #[clippy::version = "1.53.0"] diff --git a/clippy_lints/src/bool_to_int_with_if.rs b/clippy_lints/src/bool_to_int_with_if.rs index 1828dd651527..156cb34df9cd 100644 --- a/clippy_lints/src/bool_to_int_with_if.rs +++ b/clippy_lints/src/bool_to_int_with_if.rs @@ -21,7 +21,7 @@ declare_clippy_lint! { /// See https://doc.rust-lang.org/std/primitive.bool.html#impl-From%3Cbool%3E /// /// ### Example - /// ```rust + /// ```no_run /// # let condition = false; /// if condition { /// 1_i64 @@ -30,12 +30,12 @@ declare_clippy_lint! { /// }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let condition = false; /// i64::from(condition); /// ``` /// or - /// ```rust + /// ```no_run /// # let condition = false; /// condition as i64; /// ``` @@ -55,7 +55,11 @@ impl<'tcx> LateLintPass<'tcx> for BoolToIntWithIf { } fn check_if_else<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) { - if let Some(If { cond, then, r#else: Some(r#else) }) = If::hir(expr) + if let Some(If { + cond, + then, + r#else: Some(r#else), + }) = If::hir(expr) && let Some(then_lit) = int_literal(then) && let Some(else_lit) = int_literal(r#else) { @@ -90,19 +94,18 @@ fn check_if_else<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx> let into_snippet = snippet.clone().maybe_par(); let as_snippet = snippet.as_ty(ty); - span_lint_and_then(cx, + span_lint_and_then( + cx, BOOL_TO_INT_WITH_IF, expr.span, "boolean to int conversion using if", |diag| { - diag.span_suggestion( - expr.span, - "replace with from", - suggestion, - applicability, - ); - diag.note(format!("`{as_snippet}` or `{into_snippet}.into()` can also be valid options")); - }); + diag.span_suggestion(expr.span, "replace with from", suggestion, applicability); + diag.note(format!( + "`{as_snippet}` or `{into_snippet}.into()` can also be valid options" + )); + }, + ); }; } @@ -110,7 +113,7 @@ fn check_if_else<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx> fn int_literal<'tcx>(expr: &'tcx rustc_hir::Expr<'tcx>) -> Option<&'tcx rustc_hir::Expr<'tcx>> { if let ExprKind::Block(block, _) = expr.kind && let Block { - stmts: [], // Shouldn't lint if statements with side effects + stmts: [], // Shouldn't lint if statements with side effects expr: Some(expr), .. } = block diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index 04cca9e3177c..37ce65676c7e 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -472,8 +472,9 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> { self.bool_expr(e); }, ExprKind::Unary(UnOp::Not, inner) => { - if let ExprKind::Unary(UnOp::Not, ex) = inner.kind && - !self.cx.typeck_results().node_types()[ex.hir_id].is_bool() { + if let ExprKind::Unary(UnOp::Not, ex) = inner.kind + && !self.cx.typeck_results().node_types()[ex.hir_id].is_bool() + { return; } if self.cx.typeck_results().node_types()[inner.hir_id].is_bool() { @@ -500,10 +501,10 @@ struct NotSimplificationVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for NotSimplificationVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind && - !inner.span.from_expansion() && - let Some(suggestion) = simplify_not(self.cx, inner) - && self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow + if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind + && !inner.span.from_expansion() + && let Some(suggestion) = simplify_not(self.cx, inner) + && self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow { span_lint_and_sugg( self.cx, diff --git a/clippy_lints/src/borrow_deref_ref.rs b/clippy_lints/src/borrow_deref_ref.rs index b3dbbb08f8eb..739ce8f67c23 100644 --- a/clippy_lints/src/borrow_deref_ref.rs +++ b/clippy_lints/src/borrow_deref_ref.rs @@ -19,7 +19,7 @@ declare_clippy_lint! { /// /// ### Known problems /// False negative on such code: - /// ``` + /// ```no_run /// let x = &12; /// let addr_x = &x as *const _ as usize; /// let addr_y = &&*x as *const _ as usize; // assert ok now, and lint triggered. @@ -28,14 +28,14 @@ declare_clippy_lint! { /// ``` /// /// ### Example - /// ```rust + /// ```no_run /// let s = &String::new(); /// /// let a: &String = &* s; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let s = &String::new(); /// let a: &String = s; /// ``` diff --git a/clippy_lints/src/box_default.rs b/clippy_lints/src/box_default.rs index cc9bd727937b..9c78c6e532d3 100644 --- a/clippy_lints/src/box_default.rs +++ b/clippy_lints/src/box_default.rs @@ -24,11 +24,11 @@ declare_clippy_lint! { /// [in certain cases](https://nnethercote.github.io/perf-book/standard-library-types.html#box). /// /// ### Example - /// ```rust + /// ```no_run /// let x: Box = Box::new(Default::default()); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let x: Box = Box::default(); /// ``` #[clippy::version = "1.66.0"] @@ -61,9 +61,9 @@ impl LateLintPass<'_> for BoxDefault { } else if let Some(arg_ty) = cx.typeck_results().expr_ty(arg).make_suggestable(cx.tcx, true) { with_forced_trimmed_paths!(format!("Box::<{arg_ty}>::default()")) } else { - return + return; }, - Applicability::MachineApplicable + Applicability::MachineApplicable, ); } } @@ -110,7 +110,8 @@ fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { Node::Expr(Expr { kind: ExprKind::Call(path, args), .. - }) | Node::Block(Block { + }) + | Node::Block(Block { expr: Some(Expr { kind: ExprKind::Call(path, args), @@ -119,10 +120,10 @@ fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { .. }), ) => { - if let Some(index) = args.iter().position(|arg| arg.hir_id == expr.hir_id) && - let Some(sig) = expr_sig(cx, path) && - let Some(input) = sig.input(index) && - !cx.typeck_results().expr_ty_adjusted(expr).boxed_ty().is_trait() + if let Some(index) = args.iter().position(|arg| arg.hir_id == expr.hir_id) + && let Some(sig) = expr_sig(cx, path) + && let Some(input) = sig.input(index) + && !cx.typeck_results().expr_ty_adjusted(expr).boxed_ty().is_trait() { input.no_bound_vars().is_some() } else { diff --git a/clippy_lints/src/casts/as_ptr_cast_mut.rs b/clippy_lints/src/casts/as_ptr_cast_mut.rs index 1e56ed5f4508..55294f5f3864 100644 --- a/clippy_lints/src/casts/as_ptr_cast_mut.rs +++ b/clippy_lints/src/casts/as_ptr_cast_mut.rs @@ -9,12 +9,19 @@ use rustc_middle::ty::{self, Ty, TypeAndMut}; use super::AS_PTR_CAST_MUT; pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>) { - if let ty::RawPtr(ptrty @ TypeAndMut { mutbl: Mutability::Mut, .. }) = cast_to.kind() - && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Not, .. }) = - cx.typeck_results().node_type(cast_expr.hir_id).kind() + if let ty::RawPtr( + ptrty @ TypeAndMut { + mutbl: Mutability::Mut, .. + }, + ) = cast_to.kind() + && let ty::RawPtr(TypeAndMut { + mutbl: Mutability::Not, .. + }) = cx.typeck_results().node_type(cast_expr.hir_id).kind() && let ExprKind::MethodCall(method_name, receiver, [], _) = cast_expr.peel_blocks().kind && method_name.ident.name == rustc_span::sym::as_ptr - && let Some(as_ptr_did) = cx.typeck_results().type_dependent_def_id(cast_expr.peel_blocks().hir_id) + && let Some(as_ptr_did) = cx + .typeck_results() + .type_dependent_def_id(cast_expr.peel_blocks().hir_id) && let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did).instantiate_identity() && let Some(first_param_ty) = as_ptr_sig.skip_binder().inputs().iter().next() && let ty::Ref(_, _, Mutability::Not) = first_param_ty.kind() @@ -30,7 +37,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, &format!("casting the result of `as_ptr` to *{ptrty}"), "replace with", format!("{recv}.as_mut_ptr()"), - applicability + applicability, ); } } diff --git a/clippy_lints/src/casts/cast_abs_to_unsigned.rs b/clippy_lints/src/casts/cast_abs_to_unsigned.rs index 442262983337..c16633483214 100644 --- a/clippy_lints/src/casts/cast_abs_to_unsigned.rs +++ b/clippy_lints/src/casts/cast_abs_to_unsigned.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg::Sugg; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; diff --git a/clippy_lints/src/casts/cast_lossless.rs b/clippy_lints/src/casts/cast_lossless.rs index c586b572be9a..fe2455f4b239 100644 --- a/clippy_lints/src/casts/cast_lossless.rs +++ b/clippy_lints/src/casts/cast_lossless.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::in_constant; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_opt; use clippy_utils::ty::is_isize_or_usize; use rustc_errors::Applicability; diff --git a/clippy_lints/src/casts/cast_ptr_alignment.rs b/clippy_lints/src/casts/cast_ptr_alignment.rs index 9e8ef2825374..f12f03fbe794 100644 --- a/clippy_lints/src/casts/cast_ptr_alignment.rs +++ b/clippy_lints/src/casts/cast_ptr_alignment.rs @@ -26,8 +26,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { // There probably is no obvious reason to do this, just to be consistent with `as` cases. && !is_hir_ty_cfg_dependant(cx, cast_to) { - let (cast_from, cast_to) = - (cx.typeck_results().expr_ty(self_arg), cx.typeck_results().expr_ty(expr)); + let (cast_from, cast_to) = (cx.typeck_results().expr_ty(self_arg), cx.typeck_results().expr_ty(expr)); lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); } } @@ -81,9 +80,9 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { cx.tcx.get_diagnostic_name(def_id), Some( sym::ptr_write_unaligned - | sym::ptr_read_unaligned - | sym::intrinsics_unaligned_volatile_load - | sym::intrinsics_unaligned_volatile_store + | sym::ptr_read_unaligned + | sym::intrinsics_unaligned_volatile_load + | sym::intrinsics_unaligned_volatile_store ) ) { diff --git a/clippy_lints/src/casts/cast_slice_different_sizes.rs b/clippy_lints/src/casts/cast_slice_different_sizes.rs index 4d9cc4cacc3e..d14104029137 100644 --- a/clippy_lints/src/casts/cast_slice_different_sizes.rs +++ b/clippy_lints/src/casts/cast_slice_different_sizes.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source; use if_chain::if_chain; use rustc_ast::Mutability; diff --git a/clippy_lints/src/casts/cast_slice_from_raw_parts.rs b/clippy_lints/src/casts/cast_slice_from_raw_parts.rs index eb0f75b2f605..badadf2c9f65 100644 --- a/clippy_lints/src/casts/cast_slice_from_raw_parts.rs +++ b/clippy_lints/src/casts/cast_slice_from_raw_parts.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use if_chain::if_chain; use rustc_errors::Applicability; diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index b00130ffd76d..49a90a2f3c22 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -22,8 +22,8 @@ mod unnecessary_cast; mod utils; mod zero_ptr; +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::is_hir_ty_cfg_dependant; -use clippy_utils::msrvs::{self, Msrv}; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; @@ -45,7 +45,7 @@ declare_clippy_lint! { /// those places in the code. /// /// ### Example - /// ```rust + /// ```no_run /// let x = u64::MAX; /// x as f64; /// ``` @@ -67,7 +67,7 @@ declare_clippy_lint! { /// as a one-time check to see where numerical wrapping can arise. /// /// ### Example - /// ```rust + /// ```no_run /// let y: i8 = -1; /// y as u128; // will return 18446744073709551615 /// ``` @@ -90,13 +90,13 @@ declare_clippy_lint! { /// checks could be beneficial. /// /// ### Example - /// ```rust + /// ```no_run /// fn as_u8(x: u64) -> u8 { /// x as u8 /// } /// ``` /// Use instead: - /// ``` + /// ```no_run /// fn as_u8(x: u64) -> u8 { /// if let Ok(x) = u8::try_from(x) { /// x @@ -132,7 +132,7 @@ declare_clippy_lint! { /// example below. /// /// ### Example - /// ```rust + /// ```no_run /// u32::MAX as i32; // will yield a value of `-1` /// ``` #[clippy::version = "pre 1.29.0"] @@ -155,7 +155,7 @@ declare_clippy_lint! { /// people reading the code to know that the conversion is lossless. /// /// ### Example - /// ```rust + /// ```no_run /// fn as_u64(x: u8) -> u64 { /// x as u64 /// } @@ -163,7 +163,7 @@ declare_clippy_lint! { /// /// Using `::from` would look like this: /// - /// ```rust + /// ```no_run /// fn as_u64(x: u8) -> u64 { /// u64::from(x) /// } @@ -191,14 +191,14 @@ declare_clippy_lint! { /// intermediate references, raw pointers and trait objects may or may not work. /// /// ### Example - /// ```rust + /// ```no_run /// let _ = 2i32 as i32; /// let _ = 0.5 as f32; /// ``` /// /// Better: /// - /// ```rust + /// ```no_run /// let _ = 2_i32; /// let _ = 0.5_f32; /// ``` @@ -223,7 +223,7 @@ declare_clippy_lint! { /// u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis. /// /// ### Example - /// ```rust + /// ```no_run /// let _ = (&1u8 as *const u8) as *const u16; /// let _ = (&mut 1u8 as *mut u8) as *mut u16; /// @@ -249,13 +249,13 @@ declare_clippy_lint! { /// Casting to isize also doesn't make sense since there are no signed addresses. /// /// ### Example - /// ```rust + /// ```no_run /// fn fun() -> i32 { 1 } /// let _ = fun as i64; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # fn fun() -> i32 { 1 } /// let _ = fun as usize; /// ``` @@ -276,7 +276,7 @@ declare_clippy_lint! { /// a comment) to perform the truncation. /// /// ### Example - /// ```rust + /// ```no_run /// fn fn1() -> i16 { /// 1 /// }; @@ -284,7 +284,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// // Cast to usize first, then comment with the reason for the truncation /// fn fn1() -> i16 { /// 1 @@ -310,7 +310,7 @@ declare_clippy_lint! { /// pointer casts in your code. /// /// ### Example - /// ```rust + /// ```no_run /// // fn1 is cast as `usize` /// fn fn1() -> u16 { /// 1 @@ -319,7 +319,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// // maybe you intended to call the function? /// fn fn2() -> u16 { /// 1 @@ -378,14 +378,14 @@ declare_clippy_lint! { /// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`. /// /// ### Example - /// ```rust + /// ```no_run /// let ptr: *const u32 = &42_u32; /// let mut_ptr: *mut u32 = &mut 42_u32; /// let _ = ptr as *const i32; /// let _ = mut_ptr as *mut i32; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let ptr: *const u32 = &42_u32; /// let mut_ptr: *mut u32 = &mut 42_u32; /// let _ = ptr.cast::(); @@ -408,13 +408,13 @@ declare_clippy_lint! { /// type. /// /// ### Example - /// ```rust + /// ```no_run /// let ptr: *const u32 = &42_u32; /// let mut_ptr = ptr as *mut u32; /// let ptr = mut_ptr as *const u32; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let ptr: *const u32 = &42_u32; /// let mut_ptr = ptr.cast_mut(); /// let ptr = mut_ptr.cast_const(); @@ -434,7 +434,7 @@ declare_clippy_lint! { /// The resulting integral value will not match the value of the variant it came from. /// /// ### Example - /// ```rust + /// ```no_run /// enum E { X = 256 }; /// let _ = E::X as u8; /// ``` @@ -457,7 +457,7 @@ declare_clippy_lint! { /// /// ### Example /// // Missing data - /// ```rust + /// ```no_run /// let a = [1_i32, 2, 3, 4]; /// let p = &a as *const [i32] as *const [u8]; /// unsafe { @@ -465,7 +465,7 @@ declare_clippy_lint! { /// } /// ``` /// // Undefined Behavior (note: also potential alignment issues) - /// ```rust + /// ```no_run /// let a = [1_u8, 2, 3, 4]; /// let p = &a as *const [u8] as *const [u32]; /// unsafe { @@ -473,7 +473,7 @@ declare_clippy_lint! { /// } /// ``` /// Instead use `ptr::slice_from_raw_parts` to construct a slice from a data pointer and the correct length - /// ```rust + /// ```no_run /// let a = [1_i32, 2, 3, 4]; /// let old_ptr = &a as *const [i32]; /// // The data pointer is cast to a pointer to the target `u8` not `[u8]` @@ -497,7 +497,7 @@ declare_clippy_lint! { /// The cast is easily confused with casting a c-like enum value to an integer. /// /// ### Example - /// ```rust + /// ```no_run /// enum E { X(i32) }; /// let _ = E::X as usize; /// ``` @@ -515,12 +515,12 @@ declare_clippy_lint! { /// The `unsigned_abs()` method avoids panic when called on the MIN value. /// /// ### Example - /// ```rust + /// ```no_run /// let x: i32 = -42; /// let y: u32 = x.abs() as u32; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let x: i32 = -42; /// let y: u32 = x.unsigned_abs(); /// ``` @@ -541,13 +541,13 @@ declare_clippy_lint! { /// The lint is allowed by default as using `_` is less wordy than always specifying the type. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo(n: usize) {} /// let n: u16 = 256; /// foo(n as _); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn foo(n: usize) {} /// let n: u16 = 256; /// foo(n as usize); @@ -570,7 +570,7 @@ declare_clippy_lint! { /// Read the `ptr::addr_of` docs for more information. /// /// ### Example - /// ```rust + /// ```no_run /// let val = 1; /// let p = &val as *const i32; /// @@ -578,7 +578,7 @@ declare_clippy_lint! { /// let p_mut = &mut val_mut as *mut i32; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let val = 1; /// let p = std::ptr::addr_of!(val); /// @@ -627,13 +627,13 @@ declare_clippy_lint! { /// mutability is used, making it unlikely that having it as a mutable pointer is correct. /// /// ### Example - /// ```rust + /// ```no_run /// let mut vec = Vec::::with_capacity(1); /// let ptr = vec.as_ptr() as *mut u8; /// unsafe { ptr.write(4) }; // UNDEFINED BEHAVIOUR /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let mut vec = Vec::::with_capacity(1); /// let ptr = vec.as_mut_ptr(); /// unsafe { ptr.write(4) }; @@ -675,12 +675,12 @@ declare_clippy_lint! { /// {`std`, `core`}`::ptr::`{`null`, `null_mut`}. /// /// ### Example - /// ```rust + /// ```no_run /// let a = 0 as *const u32; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let a = std::ptr::null::(); /// ``` #[clippy::version = "pre 1.29.0"] diff --git a/clippy_lints/src/casts/ptr_as_ptr.rs b/clippy_lints/src/casts/ptr_as_ptr.rs index 181dbcf6e9a8..0c555c1acc57 100644 --- a/clippy_lints/src/casts/ptr_as_ptr.rs +++ b/clippy_lints/src/casts/ptr_as_ptr.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; use rustc_errors::Applicability; diff --git a/clippy_lints/src/casts/ptr_cast_constness.rs b/clippy_lints/src/casts/ptr_cast_constness.rs index ce1ab10910cc..0172e9336494 100644 --- a/clippy_lints/src/casts/ptr_cast_constness.rs +++ b/clippy_lints/src/casts/ptr_cast_constness.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{Msrv, POINTER_CAST_CONSTNESS}; use clippy_utils::sugg::Sugg; use if_chain::if_chain; use rustc_errors::Applicability; @@ -18,7 +18,7 @@ pub(super) fn check<'tcx>( msrv: &Msrv, ) { if_chain! { - if msrv.meets(POINTER_CAST_CONSTNESS); + if msrv.meets(msrvs::POINTER_CAST_CONSTNESS); if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, ty: from_ty }) = cast_from.kind(); if let ty::RawPtr(TypeAndMut { mutbl: to_mutbl, ty: to_ty }) = cast_to.kind(); if matches!((from_mutbl, to_mutbl), diff --git a/clippy_lints/src/casts/unnecessary_cast.rs b/clippy_lints/src/casts/unnecessary_cast.rs index 86057bb74ee9..61bfce07e1a0 100644 --- a/clippy_lints/src/casts/unnecessary_cast.rs +++ b/clippy_lints/src/casts/unnecessary_cast.rs @@ -97,7 +97,9 @@ pub(super) fn check<'tcx>( } // skip cast of fn call that returns type alias - if let ExprKind::Cast(inner, ..) = expr.kind && is_cast_from_ty_alias(cx, inner, cast_from) { + if let ExprKind::Cast(inner, ..) = expr.kind + && is_cast_from_ty_alias(cx, inner, cast_from) + { return false; } @@ -189,11 +191,10 @@ fn lint_unnecessary_cast( let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr) && let ExprKind::MethodCall(..) = parent_expr.kind && literal_str.starts_with('-') - { - format!("({literal_str}_{cast_to})") - - } else { - format!("{literal_str}_{cast_to}") + { + format!("({literal_str}_{cast_to})") + } else { + format!("{literal_str}_{cast_to}") }; span_lint_and_sugg( @@ -269,7 +270,9 @@ fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx && let Some(parent) = get_parent_node(cx.tcx, hir_id) && let Node::Local(l) = parent { - if let Some(e) = l.init && is_cast_from_ty_alias(cx, e, cast_from) { + if let Some(e) = l.init + && is_cast_from_ty_alias(cx, e, cast_from) + { return ControlFlow::Break::<()>(()); } diff --git a/clippy_lints/src/checked_conversions.rs b/clippy_lints/src/checked_conversions.rs index 9102a89e3772..d31c2268a657 100644 --- a/clippy_lints/src/checked_conversions.rs +++ b/clippy_lints/src/checked_conversions.rs @@ -1,7 +1,7 @@ //! lint on manually implemented checked conversions that could be transformed into `try_from` +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{in_constant, is_integer_literal, SpanlessEq}; use if_chain::if_chain; @@ -19,13 +19,13 @@ declare_clippy_lint! { /// Reduces the readability of statements & is error prone. /// /// ### Example - /// ```rust + /// ```no_run /// # let foo: u32 = 5; /// foo <= i32::MAX as u32; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let foo = 1; /// # #[allow(unused)] /// i32::try_from(foo).is_ok(); diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index b38e09dc09f4..d21ef195d9b7 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -32,7 +32,7 @@ declare_clippy_lint! { /// makes code look more complex than it really is. /// /// ### Example - /// ```rust + /// ```no_run /// # let (x, y) = (true, true); /// if x { /// if y { @@ -42,7 +42,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let (x, y) = (true, true); /// if x && y { /// // … diff --git a/clippy_lints/src/collection_is_never_read.rs b/clippy_lints/src/collection_is_never_read.rs index ac5ac542cf94..1dfc2e251d9f 100644 --- a/clippy_lints/src/collection_is_never_read.rs +++ b/clippy_lints/src/collection_is_never_read.rs @@ -20,7 +20,7 @@ declare_clippy_lint! { /// instead. /// /// ### Example - /// ```rust + /// ```no_run /// # let samples = vec![3, 1, 2]; /// let mut sorted_samples = samples.clone(); /// sorted_samples.sort(); @@ -29,7 +29,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let samples = vec![3, 1, 2]; /// let mut sorted_samples = samples.clone(); /// sorted_samples.sort(); diff --git a/clippy_lints/src/crate_in_macro_def.rs b/clippy_lints/src/crate_in_macro_def.rs index 726674d88f17..a2005638d247 100644 --- a/clippy_lints/src/crate_in_macro_def.rs +++ b/clippy_lints/src/crate_in_macro_def.rs @@ -18,7 +18,7 @@ declare_clippy_lint! { /// https://doc.rust-lang.org/reference/macros-by-example.html#hygiene /// /// ### Example - /// ```rust + /// ```no_run /// #[macro_export] /// macro_rules! print_message { /// () => { @@ -28,7 +28,7 @@ declare_clippy_lint! { /// pub const MESSAGE: &str = "Hello!"; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// #[macro_export] /// macro_rules! print_message { /// () => { diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 77438b27f900..1a646ba38c35 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -6,8 +6,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ #[cfg(feature = "internal")] crate::utils::internal_lints::almost_standard_lint_formulation::ALMOST_STANDARD_LINT_FORMULATION_INFO, #[cfg(feature = "internal")] - crate::utils::internal_lints::clippy_lints_internal::CLIPPY_LINTS_INTERNAL_INFO, - #[cfg(feature = "internal")] crate::utils::internal_lints::collapsible_calls::COLLAPSIBLE_SPAN_LINT_CALLS_INFO, #[cfg(feature = "internal")] crate::utils::internal_lints::compiler_lint_functions::COMPILER_LINT_FUNCTIONS_INFO, @@ -30,6 +28,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ #[cfg(feature = "internal")] crate::utils::internal_lints::lint_without_lint_pass::MISSING_CLIPPY_VERSION_ATTRIBUTE_INFO, #[cfg(feature = "internal")] + crate::utils::internal_lints::metadata_collector::METADATA_COLLECTOR_INFO, + #[cfg(feature = "internal")] crate::utils::internal_lints::msrv_attr_impl::MISSING_MSRV_ATTR_IMPL_INFO, #[cfg(feature = "internal")] crate::utils::internal_lints::outer_expn_data_pass::OUTER_EXPN_EXPN_DATA_INFO, @@ -37,6 +37,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::utils::internal_lints::produce_ice::PRODUCE_ICE_INFO, #[cfg(feature = "internal")] crate::utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH_INFO, + #[cfg(feature = "internal")] + crate::utils::internal_lints::unsorted_clippy_utils_paths::UNSORTED_CLIPPY_UTILS_PATHS_INFO, crate::absolute_paths::ABSOLUTE_PATHS_INFO, crate::allow_attributes::ALLOW_ATTRIBUTES_INFO, crate::almost_complete_range::ALMOST_COMPLETE_RANGE_INFO, @@ -272,6 +274,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::loops::NEVER_LOOP_INFO, crate::loops::SAME_ITEM_PUSH_INFO, crate::loops::SINGLE_ELEMENT_LOOP_INFO, + crate::loops::UNUSED_ENUMERATE_INDEX_INFO, crate::loops::WHILE_IMMUTABLE_CONDITION_INFO, crate::loops::WHILE_LET_LOOP_INFO, crate::loops::WHILE_LET_ON_ITERATOR_INFO, @@ -428,6 +431,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::TYPE_ID_ON_BOX_INFO, crate::methods::UNINIT_ASSUMED_INIT_INFO, crate::methods::UNIT_HASH_INFO, + crate::methods::UNNECESSARY_FALLIBLE_CONVERSIONS_INFO, crate::methods::UNNECESSARY_FILTER_MAP_INFO, crate::methods::UNNECESSARY_FIND_MAP_INFO, crate::methods::UNNECESSARY_FOLD_INFO, @@ -441,6 +445,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::USELESS_ASREF_INFO, crate::methods::VEC_RESIZE_TO_ZERO_INFO, crate::methods::VERBOSE_FILE_READS_INFO, + crate::methods::WAKER_CLONE_WAKE_INFO, crate::methods::WRONG_SELF_CONVENTION_INFO, crate::methods::ZST_OFFSET_INFO, crate::min_ident_chars::MIN_IDENT_CHARS_INFO, diff --git a/clippy_lints/src/default.rs b/clippy_lints/src/default.rs index 5787f19cc6cb..c74b2b8831ec 100644 --- a/clippy_lints/src/default.rs +++ b/clippy_lints/src/default.rs @@ -23,12 +23,12 @@ declare_clippy_lint! { /// generic `Default`. /// /// ### Example - /// ```rust + /// ```no_run /// let s: String = Default::default(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let s = String::default(); /// ``` #[clippy::version = "pre 1.29.0"] @@ -49,7 +49,7 @@ declare_clippy_lint! { /// Assignments to patterns that are of tuple type are not linted. /// /// ### Example - /// ``` + /// ```no_run /// # #[derive(Default)] /// # struct A { i: i32 } /// let mut a: A = Default::default(); @@ -57,7 +57,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ``` + /// ```no_run /// # #[derive(Default)] /// # struct A { i: i32 } /// let a = A { diff --git a/clippy_lints/src/default_constructed_unit_structs.rs b/clippy_lints/src/default_constructed_unit_structs.rs index 0676777e7968..bf070432ef99 100644 --- a/clippy_lints/src/default_constructed_unit_structs.rs +++ b/clippy_lints/src/default_constructed_unit_structs.rs @@ -17,7 +17,7 @@ declare_clippy_lint! { /// This adds code complexity and an unnecessary function call. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::marker::PhantomData; /// #[derive(Default)] /// struct S { @@ -29,7 +29,7 @@ declare_clippy_lint! { /// }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::marker::PhantomData; /// struct S { /// _marker: PhantomData diff --git a/clippy_lints/src/default_instead_of_iter_empty.rs b/clippy_lints/src/default_instead_of_iter_empty.rs index 2d11fa6b647d..553b670fdb70 100644 --- a/clippy_lints/src/default_instead_of_iter_empty.rs +++ b/clippy_lints/src/default_instead_of_iter_empty.rs @@ -14,12 +14,12 @@ declare_clippy_lint! { /// ### Why is this bad? /// `std::iter::empty()` is the more idiomatic way. /// ### Example - /// ```rust + /// ```no_run /// let _ = std::iter::Empty::::default(); /// let iter: std::iter::Empty = std::iter::Empty::default(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let _ = std::iter::empty::(); /// let iter: std::iter::Empty = std::iter::empty(); /// ``` @@ -68,7 +68,10 @@ fn make_sugg( _ => None, }) { - format!("std::iter::empty::<{}>()", snippet_with_context(cx, iter_ty.span, ctxt, "..", applicability).0) + format!( + "std::iter::empty::<{}>()", + snippet_with_context(cx, iter_ty.span, ctxt, "..", applicability).0 + ) } else { "std::iter::empty()".to_owned() } diff --git a/clippy_lints/src/default_numeric_fallback.rs b/clippy_lints/src/default_numeric_fallback.rs index d09428dbc1f5..b296ea20f9c5 100644 --- a/clippy_lints/src/default_numeric_fallback.rs +++ b/clippy_lints/src/default_numeric_fallback.rs @@ -31,13 +31,13 @@ declare_clippy_lint! { /// This lint can only be allowed at the function level or above. /// /// ### Example - /// ```rust + /// ```no_run /// let i = 10; /// let f = 1.23; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let i = 10i32; /// let f = 1.23f64; /// ``` diff --git a/clippy_lints/src/default_union_representation.rs b/clippy_lints/src/default_union_representation.rs index 63ec81950208..8c6749a95faf 100644 --- a/clippy_lints/src/default_union_representation.rs +++ b/clippy_lints/src/default_union_representation.rs @@ -17,7 +17,7 @@ declare_clippy_lint! { /// specified layout. These cases may lead to undefined behavior in unsafe blocks. /// /// ### Example - /// ```rust + /// ```no_run /// union Foo { /// a: i32, /// b: u32, @@ -30,7 +30,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// #[repr(C)] /// union Foo { /// a: i32, diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index efe82036dc80..6c109a51f83b 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -29,14 +29,14 @@ declare_clippy_lint! { /// when not part of a method chain. /// /// ### Example - /// ```rust + /// ```no_run /// use std::ops::Deref; /// let a: &mut String = &mut String::from("foo"); /// let b: &str = a.deref(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let a: &mut String = &mut String::from("foo"); /// let b = &*a; /// ``` @@ -68,7 +68,7 @@ declare_clippy_lint! { /// in such a case can change the semantics of the code. /// /// ### Example - /// ```rust + /// ```no_run /// fn fun(_a: &i32) {} /// /// let x: &i32 = &&&&&&5; @@ -76,7 +76,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # fn fun(_a: &i32) {} /// let x: &i32 = &5; /// fun(x); @@ -95,7 +95,7 @@ declare_clippy_lint! { /// The address-of operator at the use site is clearer about the need for a reference. /// /// ### Example - /// ```rust + /// ```no_run /// let x = Some(""); /// if let Some(ref x) = x { /// // use `x` here @@ -103,7 +103,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let x = Some(""); /// if let Some(x) = x { /// // use `&x` here @@ -123,12 +123,12 @@ declare_clippy_lint! { /// This unnecessarily complicates the code. /// /// ### Example - /// ```rust + /// ```no_run /// let x = String::new(); /// let y: &str = &*x; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let x = String::new(); /// let y: &str = &x; /// ``` @@ -353,23 +353,26 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { // priority. if let Some(fn_id) = typeck.type_dependent_def_id(hir_id) && let Some(trait_id) = cx.tcx.trait_of_item(fn_id) - && let arg_ty - = cx.tcx.erase_regions(use_cx.adjustments.last().map_or(expr_ty, |a| a.target)) + && let arg_ty = cx + .tcx + .erase_regions(use_cx.adjustments.last().map_or(expr_ty, |a| a.target)) && let ty::Ref(_, sub_ty, _) = *arg_ty.kind() && let args = cx .typeck_results() - .node_args_opt(hir_id).map(|args| &args[1..]).unwrap_or_default() - && let impl_ty = if cx.tcx.fn_sig(fn_id) - .instantiate_identity() - .skip_binder() - .inputs()[0].is_ref() - { - // Trait methods taking `&self` - sub_ty - } else { - // Trait methods taking `self` - arg_ty - } && impl_ty.is_ref() + .node_args_opt(hir_id) + .map(|args| &args[1..]) + .unwrap_or_default() + && let impl_ty = + if cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder().inputs()[0] + .is_ref() + { + // Trait methods taking `&self` + sub_ty + } else { + // Trait methods taking `self` + arg_ty + } + && impl_ty.is_ref() && implements_trait( cx, impl_ty, @@ -414,9 +417,9 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { let (required_refs, msg) = if can_auto_borrow { (1, if deref_count == 1 { borrow_msg } else { deref_msg }) } else if let Some(&Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(_, mutability)), - .. - }) = next_adjust + kind: Adjust::Borrow(AutoBorrow::Ref(_, mutability)), + .. + }) = next_adjust && matches!(mutability, AutoBorrowMutability::Mut { .. }) && !stability.is_reborrow_stable() { @@ -705,9 +708,11 @@ fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> boo { match parent.kind { ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _, _) - if child.hir_id == e.hir_id => true, - ExprKind::Match(.., MatchSource::TryDesugar(_) | MatchSource::AwaitDesugar) - | ExprKind::Field(_, _) => true, + if child.hir_id == e.hir_id => + { + true + }, + ExprKind::Match(.., MatchSource::TryDesugar(_) | MatchSource::AwaitDesugar) | ExprKind::Field(_, _) => true, _ => false, } } else { diff --git a/clippy_lints/src/derivable_impls.rs b/clippy_lints/src/derivable_impls.rs index d2bfc4f8e273..a450becc647f 100644 --- a/clippy_lints/src/derivable_impls.rs +++ b/clippy_lints/src/derivable_impls.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::indent_of; use clippy_utils::{is_default_equivalent, peel_blocks}; use rustc_errors::Applicability; @@ -21,7 +21,7 @@ declare_clippy_lint! { /// It is less concise. /// /// ### Example - /// ```rust + /// ```no_run /// struct Foo { /// bar: bool /// } @@ -36,7 +36,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// #[derive(Default)] /// struct Foo { /// bar: bool diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index 2bdac1352dce..6aaa9e39b8b4 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -173,7 +173,7 @@ declare_clippy_lint! { /// `Eq` themselves. /// /// ### Example - /// ```rust + /// ```no_run /// #[derive(PartialEq)] /// struct Foo { /// i_am_eq: i32, @@ -181,7 +181,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// #[derive(PartialEq, Eq)] /// struct Foo { /// i_am_eq: i32, diff --git a/clippy_lints/src/disallowed_macros.rs b/clippy_lints/src/disallowed_macros.rs index 7469f813ef87..324b5e0798ed 100644 --- a/clippy_lints/src/disallowed_macros.rs +++ b/clippy_lints/src/disallowed_macros.rs @@ -1,3 +1,4 @@ +use clippy_config::types::DisallowedPath; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::macro_backtrace; use rustc_ast::Attribute; @@ -8,8 +9,6 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{ExpnId, Span}; -use crate::utils::conf; - declare_clippy_lint! { /// ### What it does /// Denies the configured macros in clippy.toml @@ -35,7 +34,7 @@ declare_clippy_lint! { /// { path = "serde::Serialize", reason = "no serializing" }, /// ] /// ``` - /// ``` + /// ```no_run /// use serde::Serialize; /// /// // Example code where clippy issues a warning @@ -55,13 +54,13 @@ declare_clippy_lint! { } pub struct DisallowedMacros { - conf_disallowed: Vec, + conf_disallowed: Vec, disallowed: DefIdMap, seen: FxHashSet, } impl DisallowedMacros { - pub fn new(conf_disallowed: Vec) -> Self { + pub fn new(conf_disallowed: Vec) -> Self { Self { conf_disallowed, disallowed: DefIdMap::default(), diff --git a/clippy_lints/src/disallowed_methods.rs b/clippy_lints/src/disallowed_methods.rs index 95d3f7547b42..d23aeebb5a8a 100644 --- a/clippy_lints/src/disallowed_methods.rs +++ b/clippy_lints/src/disallowed_methods.rs @@ -1,13 +1,11 @@ +use clippy_config::types::DisallowedPath; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::{fn_def_id, get_parent_expr, path_def_id}; - use rustc_hir::def_id::DefIdMap; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use crate::utils::conf; - declare_clippy_lint! { /// ### What it does /// Denies the configured methods and functions in clippy.toml @@ -59,12 +57,12 @@ declare_clippy_lint! { #[derive(Clone, Debug)] pub struct DisallowedMethods { - conf_disallowed: Vec, + conf_disallowed: Vec, disallowed: DefIdMap, } impl DisallowedMethods { - pub fn new(conf_disallowed: Vec) -> Self { + pub fn new(conf_disallowed: Vec) -> Self { Self { conf_disallowed, disallowed: DefIdMap::default(), diff --git a/clippy_lints/src/disallowed_names.rs b/clippy_lints/src/disallowed_names.rs index 04c2d44137a3..5e46b29b6397 100644 --- a/clippy_lints/src/disallowed_names.rs +++ b/clippy_lints/src/disallowed_names.rs @@ -15,7 +15,7 @@ declare_clippy_lint! { /// avoided. /// /// ### Example - /// ```rust + /// ```no_run /// let foo = 3.14; /// ``` #[clippy::version = "pre 1.29.0"] diff --git a/clippy_lints/src/disallowed_script_idents.rs b/clippy_lints/src/disallowed_script_idents.rs index c9fad98e4373..96a7f0e4fde1 100644 --- a/clippy_lints/src/disallowed_script_idents.rs +++ b/clippy_lints/src/disallowed_script_idents.rs @@ -30,7 +30,7 @@ declare_clippy_lint! { /// [`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents /// /// ### Example - /// ```rust + /// ```no_run /// // Assuming that `clippy.toml` contains the following line: /// // allowed-scripts = ["Latin", "Cyrillic"] /// let counter = 10; // OK, latin is allowed. diff --git a/clippy_lints/src/disallowed_types.rs b/clippy_lints/src/disallowed_types.rs index 1f56d0118a40..3578fb640fc4 100644 --- a/clippy_lints/src/disallowed_types.rs +++ b/clippy_lints/src/disallowed_types.rs @@ -1,5 +1,5 @@ +use clippy_config::types::DisallowedPath; use clippy_utils::diagnostics::span_lint_and_then; - use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; @@ -8,8 +8,6 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::Span; -use crate::utils::conf; - declare_clippy_lint! { /// ### What it does /// Denies the configured types in clippy.toml. @@ -50,15 +48,16 @@ declare_clippy_lint! { style, "use of disallowed types" } + #[derive(Clone, Debug)] pub struct DisallowedTypes { - conf_disallowed: Vec, + conf_disallowed: Vec, def_ids: FxHashMap, prim_tys: FxHashMap, } impl DisallowedTypes { - pub fn new(conf_disallowed: Vec) -> Self { + pub fn new(conf_disallowed: Vec) -> Self { Self { conf_disallowed, def_ids: FxHashMap::default(), @@ -123,7 +122,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedTypes { } } -fn emit(cx: &LateContext<'_>, name: &str, span: Span, conf: &conf::DisallowedPath) { +fn emit(cx: &LateContext<'_>, name: &str, span: Span, conf: &DisallowedPath) { span_lint_and_then( cx, DISALLOWED_TYPES, diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index fc9b381664a3..d4a698521acd 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -58,14 +58,14 @@ declare_clippy_lint! { /// would fail. /// /// ### Examples - /// ```rust + /// ```no_run /// /// Do something with the foo_bar parameter. See also /// /// that::other::module::foo. /// // ^ `foo_bar` and `that::other::module::foo` should be ticked. /// fn doit(foo_bar: usize) {} /// ``` /// - /// ```rust + /// ```no_run /// // Link text with `[]` brackets should be written as following: /// /// Consume the array and return the inner /// /// [`SmallVec<[T; INLINE_CAPACITY]>`][SmallVec]. @@ -88,7 +88,7 @@ declare_clippy_lint! { /// preconditions, so that users can be sure they are using them safely. /// /// ### Examples - /// ```rust + /// ```no_run ///# type Universe = (); /// /// This function should really be documented /// pub unsafe fn start_apocalypse(u: &mut Universe) { @@ -98,7 +98,7 @@ declare_clippy_lint! { /// /// At least write a line about safety: /// - /// ```rust + /// ```no_run ///# type Universe = (); /// /// # Safety /// /// @@ -126,7 +126,7 @@ declare_clippy_lint! { /// Since the following function returns a `Result` it has an `# Errors` section in /// its doc comment: /// - /// ```rust + /// ```no_run ///# use std::io; /// /// # Errors /// /// @@ -155,7 +155,7 @@ declare_clippy_lint! { /// Since the following function may panic it has a `# Panics` section in /// its doc comment: /// - /// ```rust + /// ```no_run /// /// # Panics /// /// /// /// Will panic if y is 0 @@ -182,7 +182,7 @@ declare_clippy_lint! { /// if the `fn main()` is left implicit. /// /// ### Examples - /// ```rust + /// ```no_run /// /// An example of a doctest with a `main()` function /// /// /// /// # Examples @@ -210,12 +210,12 @@ declare_clippy_lint! { /// It is likely a typo when defining an intra-doc link /// /// ### Example - /// ```rust + /// ```no_run /// /// See also: ['foo'] /// fn bar() {} /// ``` /// Use instead: - /// ```rust + /// ```no_run /// /// See also: [`foo`] /// fn bar() {} /// ``` @@ -235,7 +235,7 @@ declare_clippy_lint! { /// need to describe safety preconditions that users are required to uphold. /// /// ### Examples - /// ```rust + /// ```no_run ///# type Universe = (); /// /// # Safety /// /// @@ -248,7 +248,7 @@ declare_clippy_lint! { /// The function is safe, so there shouldn't be any preconditions /// that have to be explained for safety reasons. /// - /// ```rust + /// ```no_run ///# type Universe = (); /// /// This function should really be documented /// pub fn start_apocalypse(u: &mut Universe) { @@ -569,9 +569,7 @@ fn check_doc<'a, Events: Iterator, Range, Range, text: &str, edition: Edition, range: Range, valid_idents: &FxHashSet, text: &str } fn check_word(cx: &LateContext<'_>, word: &str, span: Span) { - /// Checks if a string is camel-case, i.e., contains at least two uppercase - /// letters (`Clippy` is ok) and one lower-case letter (`NASA` is ok). + /// Checks if a string is upper-camel-case, i.e., starts with an uppercase and + /// contains at least two uppercase letters (`Clippy` is ok) and one lower-case + /// letter (`NASA` is ok). /// Plurals are also excluded (`IDs` is ok). fn is_camel_case(s: &str) -> bool { - if s.starts_with(|c: char| c.is_ascii_digit()) { + if s.starts_with(|c: char| c.is_ascii_digit() | c.is_ascii_lowercase()) { return false; } diff --git a/clippy_lints/src/double_parens.rs b/clippy_lints/src/double_parens.rs index 29425b2e5541..63f32173b05e 100644 --- a/clippy_lints/src/double_parens.rs +++ b/clippy_lints/src/double_parens.rs @@ -12,7 +12,7 @@ declare_clippy_lint! { /// mistake. /// /// ### Example - /// ```rust + /// ```no_run /// fn simple_double_parens() -> i32 { /// ((0)) /// } @@ -22,7 +22,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// fn simple_no_parens() -> i32 { /// 0 /// } diff --git a/clippy_lints/src/drop_forget_ref.rs b/clippy_lints/src/drop_forget_ref.rs index 14122abbf2c2..177e04dfa6b1 100644 --- a/clippy_lints/src/drop_forget_ref.rs +++ b/clippy_lints/src/drop_forget_ref.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// have been intended. /// /// ### Example - /// ```rust + /// ```no_run /// struct Foo; /// let x = Foo; /// std::mem::drop(x); @@ -36,7 +36,7 @@ declare_clippy_lint! { /// have been intended. /// /// ### Example - /// ```rust + /// ```no_run /// struct Foo; /// let x = Foo; /// std::mem::forget(x); @@ -57,7 +57,7 @@ declare_clippy_lint! { /// destructor, possibly causing leaks. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::mem; /// # use std::rc::Rc; /// mem::forget(Rc::new(55)) @@ -90,7 +90,8 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { let is_copy = is_copy(cx, arg_ty); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); let (lint, msg, note_span) = match fn_name { - // early return for uplifted lints: dropping_references, dropping_copy_types, forgetting_references, forgetting_copy_types + // early return for uplifted lints: dropping_references, dropping_copy_types, forgetting_references, + // forgetting_copy_types sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return, sym::mem_forget if arg_ty.is_ref() => return, sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return, @@ -100,8 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { if !(arg_ty.needs_drop(cx.tcx, cx.param_env) || is_must_use_func_call(cx, arg) || is_must_use_ty(cx, arg_ty) - || drop_is_single_call_in_arm - ) => + || drop_is_single_call_in_arm) => { (DROP_NON_DROP, DROP_NON_DROP_SUMMARY.into(), Some(arg.span)) }, @@ -122,7 +122,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { } else { (FORGET_NON_DROP, FORGET_NON_DROP_SUMMARY.into(), Some(arg.span)) } - } + }, _ => return, }; span_lint_and_note( diff --git a/clippy_lints/src/else_if_without_else.rs b/clippy_lints/src/else_if_without_else.rs index bf4488570eaf..61db1c1abd16 100644 --- a/clippy_lints/src/else_if_without_else.rs +++ b/clippy_lints/src/else_if_without_else.rs @@ -15,7 +15,7 @@ declare_clippy_lint! { /// Some coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10). /// /// ### Example - /// ```rust + /// ```no_run /// # fn a() {} /// # fn b() {} /// # let x: i32 = 1; @@ -28,7 +28,7 @@ declare_clippy_lint! { /// /// Use instead: /// - /// ```rust + /// ```no_run /// # fn a() {} /// # fn b() {} /// # let x: i32 = 1; diff --git a/clippy_lints/src/empty_drop.rs b/clippy_lints/src/empty_drop.rs index 209fb66fa40f..5fcdca7cf362 100644 --- a/clippy_lints/src/empty_drop.rs +++ b/clippy_lints/src/empty_drop.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// destructured, which might be the intention behind adding the implementation as a marker. /// /// ### Example - /// ```rust + /// ```no_run /// struct S; /// /// impl Drop for S { @@ -24,7 +24,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct S; /// ``` #[clippy::version = "1.62.0"] diff --git a/clippy_lints/src/empty_enum.rs b/clippy_lints/src/empty_enum.rs index 1701d061128b..a5699727b5be 100644 --- a/clippy_lints/src/empty_enum.rs +++ b/clippy_lints/src/empty_enum.rs @@ -23,12 +23,12 @@ declare_clippy_lint! { /// /// /// ### Example - /// ```rust + /// ```no_run /// enum Test {} /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// #![feature(never_type)] /// /// struct Test(!); diff --git a/clippy_lints/src/empty_structs_with_brackets.rs b/clippy_lints/src/empty_structs_with_brackets.rs index 282157181abb..4e2a8b73c0ab 100644 --- a/clippy_lints/src/empty_structs_with_brackets.rs +++ b/clippy_lints/src/empty_structs_with_brackets.rs @@ -15,11 +15,11 @@ declare_clippy_lint! { /// Empty brackets after a struct declaration can be omitted. /// /// ### Example - /// ```rust + /// ```no_run /// struct Cookie {} /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct Cookie; /// ``` #[clippy::version = "1.62.0"] @@ -35,7 +35,8 @@ impl EarlyLintPass for EmptyStructsWithBrackets { if let ItemKind::Struct(var_data, _) = &item.kind && has_brackets(var_data) - && has_no_fields(cx, var_data, span_after_ident) { + && has_no_fields(cx, var_data, span_after_ident) + { span_lint_and_then( cx, EMPTY_STRUCTS_WITH_BRACKETS, @@ -46,8 +47,9 @@ impl EarlyLintPass for EmptyStructsWithBrackets { span_after_ident, "remove the brackets", ";", - Applicability::Unspecified); - }, + Applicability::Unspecified, + ); + }, ); } } diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index 70a467dde613..3e3c62e85d01 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -23,7 +23,7 @@ declare_clippy_lint! { /// /// ### Known problems /// The suggestion may have type inference errors in some cases. e.g. - /// ```rust + /// ```no_run /// let mut map = std::collections::HashMap::new(); /// let _ = if !map.contains_key(&0) { /// map.insert(0, 0) @@ -33,7 +33,7 @@ declare_clippy_lint! { /// ``` /// /// ### Example - /// ```rust + /// ```no_run /// # use std::collections::HashMap; /// # let mut map = HashMap::new(); /// # let k = 1; @@ -43,7 +43,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::collections::HashMap; /// # let mut map = HashMap::new(); /// # let k = 1; diff --git a/clippy_lints/src/enum_clike.rs b/clippy_lints/src/enum_clike.rs index 646767868e2c..003b5fc7261d 100644 --- a/clippy_lints/src/enum_clike.rs +++ b/clippy_lints/src/enum_clike.rs @@ -19,7 +19,7 @@ declare_clippy_lint! { /// architectures, but works fine on 64 bit. /// /// ### Example - /// ```rust + /// ```no_run /// # #[cfg(target_pointer_width = "64")] /// #[repr(usize)] /// enum NonPortable { diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs index c691e6c5402d..575fead5bf3e 100644 --- a/clippy_lints/src/equatable_if_let.rs +++ b/clippy_lints/src/equatable_if_let.rs @@ -68,7 +68,8 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if !in_external_macro(cx.sess(), expr.span) && let ExprKind::Let(let_expr) = expr.kind - && unary_pattern(let_expr.pat) { + && unary_pattern(let_expr.pat) + { let exp_ty = cx.typeck_results().expr_ty(let_expr.init); let pat_ty = cx.typeck_results().pat_ty(let_expr.pat); let mut applicability = Applicability::MachineApplicable; @@ -79,7 +80,9 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality { "({})", snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0, ), - _ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0.to_string(), + _ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability) + .0 + .to_string(), }; span_lint_and_sugg( cx, diff --git a/clippy_lints/src/error_impl_error.rs b/clippy_lints/src/error_impl_error.rs index 6d429fbd0353..bc878555c66d 100644 --- a/clippy_lints/src/error_impl_error.rs +++ b/clippy_lints/src/error_impl_error.rs @@ -41,10 +41,11 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError { }; match item.kind { - ItemKind::TyAlias(..) if item.ident.name == sym::Error - && is_visible_outside_module(cx, item.owner_id.def_id) - && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() - && implements_trait(cx, ty, error_def_id, &[]) => + ItemKind::TyAlias(..) + if item.ident.name == sym::Error + && is_visible_outside_module(cx, item.owner_id.def_id) + && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() + && implements_trait(cx, ty, error_def_id, &[]) => { span_lint( cx, @@ -53,13 +54,14 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError { "exported type alias named `Error` that implements `Error`", ); }, - ItemKind::Impl(imp) if let Some(trait_def_id) = imp.of_trait.and_then(|t| t.trait_def_id()) - && 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 hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id) - && let Some(ident) = cx.tcx.opt_item_ident(def_id.to_def_id()) - && ident.name == sym::Error - && is_visible_outside_module(cx, def_id) => + ItemKind::Impl(imp) + if let Some(trait_def_id) = imp.of_trait.and_then(|t| t.trait_def_id()) + && 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 hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id) + && let Some(ident) = cx.tcx.opt_item_ident(def_id.to_def_id()) + && ident.name == sym::Error + && is_visible_outside_module(cx, def_id) => { span_lint_hir_and_then( cx, @@ -69,9 +71,9 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError { "exported type named `Error` that implements `Error`", |diag| { diag.span_note(item.span, "`Error` was implemented here"); - } + }, ); - } + }, _ => {}, } } diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index dbe3453e7bfa..47ffde61fb71 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -28,12 +28,12 @@ declare_clippy_lint! { /// into something. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo(x: Box) {} /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// fn foo(x: u32) {} /// ``` #[clippy::version = "pre 1.29.0"] diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 38066503c079..fad8fbf04497 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -119,19 +119,21 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { match body.value.kind { ExprKind::Call(callee, args) - if matches!(callee.kind, ExprKind::Path(QPath::Resolved(..) | QPath::TypeRelative(..))) => + if matches!( + callee.kind, + ExprKind::Path(QPath::Resolved(..) | QPath::TypeRelative(..)) + ) => { let callee_ty = typeck.expr_ty(callee).peel_refs(); - if matches!( - type_diagnostic_name(cx, callee_ty), - Some(sym::Arc | sym::Rc) - ) || !check_inputs(typeck, body.params, None, args) { + if matches!(type_diagnostic_name(cx, callee_ty), Some(sym::Arc | sym::Rc)) + || !check_inputs(typeck, body.params, None, args) + { return; } - let callee_ty_adjusted = typeck.expr_adjustments(callee).last().map_or( - callee_ty, - |a| a.target.peel_refs(), - ); + let callee_ty_adjusted = typeck + .expr_adjustments(callee) + .last() + .map_or(callee_ty, |a| a.target.peel_refs()); let sig = match callee_ty_adjusted.kind() { ty::FnDef(def, _) => cx.tcx.fn_sig(def).skip_binder().skip_binder(), @@ -160,36 +162,26 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { // For now ignore all callee types which reference a type parameter. && !generic_args.types().any(|t| matches!(t.kind(), ty::Param(_))) { - span_lint_and_then( - cx, - REDUNDANT_CLOSURE, - expr.span, - "redundant closure", - |diag| { - if let Some(mut snippet) = snippet_opt(cx, callee.span) { - if let Ok((ClosureKind::FnMut, _)) - = cx.tcx.infer_ctxt().build().type_implements_fn_trait( - cx.param_env, - Binder::bind_with_vars(callee_ty_adjusted, List::empty()), - ImplPolarity::Positive, - ) && path_to_local(callee) - .map_or( - false, - |l| local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr), - ) - { - // Mutable closure is used after current expr; we cannot consume it. - snippet = format!("&mut {snippet}"); - } - diag.span_suggestion( - expr.span, - "replace the closure with the function itself", - snippet, - Applicability::MachineApplicable, - ); + span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| { + if let Some(mut snippet) = snippet_opt(cx, callee.span) { + if let Ok((ClosureKind::FnMut, _)) = cx.tcx.infer_ctxt().build().type_implements_fn_trait( + cx.param_env, + Binder::bind_with_vars(callee_ty_adjusted, List::empty()), + ImplPolarity::Positive, + ) && path_to_local(callee).map_or(false, |l| { + local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr) + }) { + // Mutable closure is used after current expr; we cannot consume it. + snippet = format!("&mut {snippet}"); } + diag.span_suggestion( + expr.span, + "replace the closure with the function itself", + snippet, + Applicability::MachineApplicable, + ); } - ); + }); } }, ExprKind::MethodCall(path, self_, args, _) if check_inputs(typeck, body.params, Some(self_), args) => { diff --git a/clippy_lints/src/excessive_bools.rs b/clippy_lints/src/excessive_bools.rs index aef2db38583e..1d18e194d15c 100644 --- a/clippy_lints/src/excessive_bools.rs +++ b/clippy_lints/src/excessive_bools.rs @@ -22,7 +22,7 @@ declare_clippy_lint! { /// readability and API. /// /// ### Example - /// ```rust + /// ```no_run /// struct S { /// is_pending: bool, /// is_processing: bool, @@ -31,7 +31,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// enum S { /// Pending, /// Processing, @@ -157,7 +157,7 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools { // functions with a body are already checked by `check_fn` if let TraitItemKind::Fn(fn_sig, TraitFn::Required(_)) = &trait_item.kind && fn_sig.header.abi == Abi::Rust - { + { self.check_fn_sig(cx, fn_sig.decl, fn_sig.span); } } @@ -174,11 +174,8 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools { let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id); if let Some(fn_header) = fn_kind.header() && fn_header.abi == Abi::Rust - && get_parent_as_impl(cx.tcx, hir_id) - .map_or(true, - |impl_item| impl_item.of_trait.is_none() - ) - { + && get_parent_as_impl(cx.tcx, hir_id).map_or(true, |impl_item| impl_item.of_trait.is_none()) + { self.check_fn_sig(cx, fn_decl, span); } } diff --git a/clippy_lints/src/exhaustive_items.rs b/clippy_lints/src/exhaustive_items.rs index 9fd13084dc9e..f976cfd3f225 100644 --- a/clippy_lints/src/exhaustive_items.rs +++ b/clippy_lints/src/exhaustive_items.rs @@ -17,14 +17,14 @@ declare_clippy_lint! { /// disable them by default. /// /// ### Example - /// ```rust + /// ```no_run /// enum Foo { /// Bar, /// Baz /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// #[non_exhaustive] /// enum Foo { /// Bar, @@ -47,14 +47,14 @@ declare_clippy_lint! { /// disable them by default. /// /// ### Example - /// ```rust + /// ```no_run /// struct Foo { /// bar: u8, /// baz: String, /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// #[non_exhaustive] /// struct Foo { /// bar: u8, diff --git a/clippy_lints/src/exit.rs b/clippy_lints/src/exit.rs index 5ecd0ffadf36..e14b1c556ecc 100644 --- a/clippy_lints/src/exit.rs +++ b/clippy_lints/src/exit.rs @@ -17,7 +17,7 @@ declare_clippy_lint! { /// the main function. /// /// ### Example - /// ``` + /// ```no_run /// std::process::exit(0) /// ``` /// diff --git a/clippy_lints/src/explicit_write.rs b/clippy_lints/src/explicit_write.rs index 6f6177340f48..4b5bcb06a1e8 100644 --- a/clippy_lints/src/explicit_write.rs +++ b/clippy_lints/src/explicit_write.rs @@ -19,7 +19,7 @@ declare_clippy_lint! { /// Using `(e)println! is clearer and more concise /// /// ### Example - /// ```rust + /// ```no_run /// # use std::io::Write; /// # let bar = "furchtbar"; /// writeln!(&mut std::io::stderr(), "foo: {:?}", bar).unwrap(); @@ -27,7 +27,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # use std::io::Write; /// # let bar = "furchtbar"; /// eprintln!("foo: {:?}", bar); @@ -58,7 +58,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite { Some(sym::io_stderr) => ("stderr", "e"), _ => return, }; - let Some(format_args) = find_format_args(cx, write_arg, ExpnId::root()) else { return; }; + let Some(format_args) = find_format_args(cx, write_arg, ExpnId::root()) else { + return; + }; // ordering is important here, since `writeln!` uses `write!` internally let calling_macro = if is_expn_of(write_call.span, "writeln").is_some() { @@ -78,18 +80,11 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite { macro_name.replace("write", "print"), ) } else { - ( - format!("{dest_name}().write_fmt(...)"), - "print".into(), - ) + (format!("{dest_name}().write_fmt(...)"), "print".into()) }; let mut applicability = Applicability::MachineApplicable; - let inputs_snippet = snippet_with_applicability( - cx, - format_args_inputs_span(&format_args), - "..", - &mut applicability, - ); + let inputs_snippet = + snippet_with_applicability(cx, format_args_inputs_span(&format_args), "..", &mut applicability); span_lint_and_sugg( cx, EXPLICIT_WRITE, diff --git a/clippy_lints/src/extra_unused_type_parameters.rs b/clippy_lints/src/extra_unused_type_parameters.rs index 0a885984abbf..d6c746901fc7 100644 --- a/clippy_lints/src/extra_unused_type_parameters.rs +++ b/clippy_lints/src/extra_unused_type_parameters.rs @@ -23,13 +23,13 @@ declare_clippy_lint! { /// requires using a turbofish, which serves no purpose but to satisfy the compiler. /// /// ### Example - /// ```rust + /// ```no_run /// fn unused_ty(x: u8) { /// // .. /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn no_unused_ty(x: u8) { /// // .. /// } @@ -177,20 +177,22 @@ impl<'cx, 'tcx> TypeWalker<'cx, 'tcx> { .iter() .rev() .map(|(idx, param)| { - if let Some(next) = explicit_params.get(idx + 1) && end != Some(next.def_id) { - // Extend the current span forward, up until the next param in the list. - param.span.until(next.span) - } else { - // Extend the current span back to include the comma following the previous - // param. If the span of the next param in the list has already been - // extended, we continue the chain. This is why we're iterating in reverse. - end = Some(param.def_id); + if let Some(next) = explicit_params.get(idx + 1) + && end != Some(next.def_id) + { + // Extend the current span forward, up until the next param in the list. + param.span.until(next.span) + } else { + // Extend the current span back to include the comma following the previous + // param. If the span of the next param in the list has already been + // extended, we continue the chain. This is why we're iterating in reverse. + end = Some(param.def_id); - // idx will never be 0, else we'd be removing the entire list of generics - let prev = explicit_params[idx - 1]; - let prev_span = self.get_bound_span(prev); - self.get_bound_span(param).with_lo(prev_span.hi()) - } + // idx will never be 0, else we'd be removing the entire list of generics + let prev = explicit_params[idx - 1]; + let prev_span = self.get_bound_span(prev); + self.get_bound_span(param).with_lo(prev_span.hi()) + } }) .collect() }; diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs index 2ef547526d4f..efb69476b94a 100644 --- a/clippy_lints/src/fallible_impl_from.rs +++ b/clippy_lints/src/fallible_impl_from.rs @@ -17,7 +17,7 @@ declare_clippy_lint! { /// `TryFrom` should be used if there's a possibility of failure. /// /// ### Example - /// ```rust + /// ```no_run /// struct Foo(i32); /// /// impl From for Foo { @@ -28,7 +28,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// struct Foo(i32); /// /// impl TryFrom for Foo { diff --git a/clippy_lints/src/float_literal.rs b/clippy_lints/src/float_literal.rs index d182bb621950..506a1191747f 100644 --- a/clippy_lints/src/float_literal.rs +++ b/clippy_lints/src/float_literal.rs @@ -18,13 +18,13 @@ declare_clippy_lint! { /// Rust will truncate the literal silently. /// /// ### Example - /// ```rust + /// ```no_run /// let v: f32 = 0.123_456_789_9; /// println!("{}", v); // 0.123_456_789 /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let v: f64 = 0.123_456_789_9; /// println!("{}", v); // 0.123_456_789_9 /// ``` @@ -44,12 +44,12 @@ declare_clippy_lint! { /// conversion to a float. /// /// ### Example - /// ```rust + /// ```no_run /// let _: f32 = 16_777_217.0; // 16_777_216.0 /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let _: f32 = 16_777_216.0; /// let _: f64 = 16_777_217.0; /// ``` diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index 29e5315f88b7..09a9d9924de3 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -27,7 +27,7 @@ declare_clippy_lint! { /// Negatively impacts accuracy. /// /// ### Example - /// ```rust + /// ```no_run /// let a = 3f32; /// let _ = a.powf(1.0 / 3.0); /// let _ = (1.0 + a).ln(); @@ -35,7 +35,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let a = 3f32; /// let _ = a.cbrt(); /// let _ = a.ln_1p(); @@ -57,7 +57,7 @@ declare_clippy_lint! { /// Negatively impacts accuracy and performance. /// /// ### Example - /// ```rust + /// ```no_run /// use std::f32::consts::E; /// /// let a = 3f32; @@ -83,7 +83,7 @@ declare_clippy_lint! { /// /// is better expressed as /// - /// ```rust + /// ```no_run /// use std::f32::consts::E; /// /// let a = 3f32; @@ -323,9 +323,9 @@ fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: let maybe_neg_sugg = |expr, hir_id| { let sugg = Sugg::hir(cx, expr, ".."); if matches!(op, BinOpKind::Sub) && hir_id == rhs.hir_id { - format!("-{}", sugg.maybe_par()) + -sugg } else { - sugg.to_string() + sugg } }; @@ -470,25 +470,13 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) { let maybe_neg_sugg = |expr| { let sugg = Sugg::hir(cx, expr, ".."); - if let BinOpKind::Sub = op { - format!("-{sugg}") - } else { - sugg.to_string() - } + if let BinOpKind::Sub = op { -sugg } else { sugg } }; let (recv, arg1, arg2) = if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, lhs) { - ( - inner_lhs, - Sugg::hir(cx, inner_rhs, "..").to_string(), - maybe_neg_sugg(rhs), - ) + (inner_lhs, Sugg::hir(cx, inner_rhs, ".."), maybe_neg_sugg(rhs)) } else if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, rhs) { - ( - inner_lhs, - maybe_neg_sugg(inner_rhs), - Sugg::hir(cx, lhs, "..").to_string(), - ) + (inner_lhs, maybe_neg_sugg(inner_rhs), Sugg::hir(cx, lhs, "..")) } else { return; }; diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index b748d3293679..18ed05c1ca62 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -23,13 +23,13 @@ declare_clippy_lint! { /// if `foo: &str`. /// /// ### Examples - /// ```rust + /// ```no_run /// let foo = "foo"; /// format!("{}", foo); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let foo = "foo"; /// foo.to_owned(); /// ``` @@ -54,7 +54,9 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat { ([], []) => span_useless_format_empty(cx, call_site, "String::new()".to_owned(), applicability), ([], [_]) => { // Simulate macro expansion, converting {{ and }} to { and }. - let Some(snippet) = snippet_opt(cx, format_args.span) else { return }; + let Some(snippet) = snippet_opt(cx, format_args.span) else { + return; + }; let s_expand = snippet.replace("{{", "{").replace("}}", "}"); let sugg = format!("{s_expand}.to_string()"); span_useless_format(cx, call_site, sugg, applicability); @@ -76,13 +78,14 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat { _ => false, }; let sugg = if is_new_string { - snippet_with_context(cx, value.span, call_site.ctxt(), "..", &mut applicability).0.into_owned() + snippet_with_context(cx, value.span, call_site.ctxt(), "..", &mut applicability) + .0 + .into_owned() } else { let sugg = Sugg::hir_with_context(cx, value, call_site.ctxt(), "", &mut applicability); format!("{}.to_string()", sugg.maybe_par()) }; span_useless_format(cx, call_site, sugg, applicability); - } }, _ => {}, diff --git a/clippy_lints/src/format_args.rs b/clippy_lints/src/format_args.rs index 39abf5c2def5..3c1f2d9d5dcd 100644 --- a/clippy_lints/src/format_args.rs +++ b/clippy_lints/src/format_args.rs @@ -1,11 +1,11 @@ use arrayvec::ArrayVec; +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::is_diag_trait_item; use clippy_utils::macros::{ find_format_arg_expr, find_format_args, format_arg_removal_span, format_placeholder_format_span, is_assert_macro, is_format_macro, is_panic, root_macro_call, root_macro_call_first_node, FormatParamUsage, }; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_opt; use clippy_utils::ty::{implements_trait, is_type_lang_item}; use if_chain::if_chain; @@ -35,12 +35,12 @@ declare_clippy_lint! { /// The recommended code is both shorter and avoids a temporary allocation. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::panic::Location; /// println!("error: {}", format!("something failed at {}", Location::caller())); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::panic::Location; /// println!("error: something failed at {}", Location::caller()); /// ``` @@ -61,12 +61,12 @@ declare_clippy_lint! { /// unnecessary. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::panic::Location; /// println!("error: something failed at {}", Location::caller().to_string()); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::panic::Location; /// println!("error: something failed at {}", Location::caller()); /// ``` @@ -87,7 +87,7 @@ declare_clippy_lint! { /// The inlined syntax, where allowed, is simpler. /// /// ### Example - /// ```rust + /// ```no_run /// # let var = 42; /// # let width = 1; /// # let prec = 2; @@ -98,7 +98,7 @@ declare_clippy_lint! { /// format!("{:.*}", prec, var); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let var = 42; /// # let width = 1; /// # let prec = 2; @@ -111,12 +111,12 @@ declare_clippy_lint! { /// /// If allow-mixed-uninlined-format-args is set to false in clippy.toml, /// the following code will also trigger the lint: - /// ```rust + /// ```no_run /// # let var = 42; /// format!("{} {}", var, 1+2); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let var = 42; /// format!("{var} {}", 1+2); /// ``` @@ -141,13 +141,13 @@ declare_clippy_lint! { /// an expected formatting operation such as adding padding isn't happening. /// /// ### Example - /// ```rust + /// ```no_run /// println!("{:.}", 1.0); /// /// println!("not padded: {:5}", format_args!("...")); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// println!("{}", 1.0); /// /// println!("not padded: {}", format_args!("...")); @@ -370,7 +370,7 @@ fn check_one_arg( }; fixes.push((pos_span, replacement)); fixes.push((arg_span, String::new())); - true // successful inlining, continue checking + true // successful inlining, continue checking } else { // Do not continue inlining (return false) in case // * if we can't inline a numbered argument, e.g. `print!("{0} ...", foo.bar, ...)` diff --git a/clippy_lints/src/format_impl.rs b/clippy_lints/src/format_impl.rs index 1d2f7cb71303..08ee7032c091 100644 --- a/clippy_lints/src/format_impl.rs +++ b/clippy_lints/src/format_impl.rs @@ -21,7 +21,7 @@ declare_clippy_lint! { /// /// ### Example /// - /// ```rust + /// ```no_run /// use std::fmt; /// /// struct Structure(i32); @@ -33,7 +33,7 @@ declare_clippy_lint! { /// /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::fmt; /// /// struct Structure(i32); @@ -59,7 +59,7 @@ declare_clippy_lint! { /// should write to the `Formatter`, not stdout/stderr. /// /// ### Example - /// ```rust + /// ```no_run /// use std::fmt::{Display, Error, Formatter}; /// /// struct S; @@ -72,7 +72,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::fmt::{Display, Error, Formatter}; /// /// struct S; diff --git a/clippy_lints/src/format_push_string.rs b/clippy_lints/src/format_push_string.rs index 45f67020c2db..ac45f5aedfa4 100644 --- a/clippy_lints/src/format_push_string.rs +++ b/clippy_lints/src/format_push_string.rs @@ -21,13 +21,13 @@ declare_clippy_lint! { /// While using `write!` in the suggested way should never fail, this isn't necessarily clear to the programmer. /// /// ### Example - /// ```rust + /// ```no_run /// let mut s = String::new(); /// s += &format!("0x{:X}", 1024); /// s.push_str(&format!("0x{:X}", 1024)); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::fmt::Write as _; // import without risk of name clashing /// /// let mut s = String::new(); @@ -58,7 +58,7 @@ fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { arms.iter().any(|arm| is_format(cx, arm.body)) }, Some(higher::IfLetOrMatch::IfLet(_, _, then, r#else)) => { - is_format(cx, then) ||r#else.is_some_and(|e| is_format(cx, e)) + is_format(cx, then) || r#else.is_some_and(|e| is_format(cx, e)) }, _ => false, } @@ -69,17 +69,15 @@ impl<'tcx> LateLintPass<'tcx> for FormatPushString { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { let arg = match expr.kind { ExprKind::MethodCall(_, _, [arg], _) => { - if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) && - match_def_path(cx, fn_def_id, &paths::PUSH_STR) { + if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) + && match_def_path(cx, fn_def_id, &paths::PUSH_STR) + { arg } else { return; } - } - ExprKind::AssignOp(op, left, arg) - if op.node == BinOpKind::Add && is_string(cx, left) => { - arg }, + ExprKind::AssignOp(op, left, arg) if op.node == BinOpKind::Add && is_string(cx, left) => arg, _ => return, }; if is_format(cx, arg) { diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index 4ebf0e9667df..10ddc3bda340 100644 --- a/clippy_lints/src/formatting.rs +++ b/clippy_lints/src/formatting.rs @@ -37,7 +37,7 @@ declare_clippy_lint! { /// This is either a typo in the binary operator or confusing. /// /// ### Example - /// ```rust + /// ```no_run /// # let foo = true; /// # let bar = false; /// // &&! looks like a different operator @@ -45,7 +45,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let foo = true; /// # let bar = false; /// if foo && !bar {} diff --git a/clippy_lints/src/four_forward_slashes.rs b/clippy_lints/src/four_forward_slashes.rs index 0ec52f89e716..69bc0b726fcc 100644 --- a/clippy_lints/src/four_forward_slashes.rs +++ b/clippy_lints/src/four_forward_slashes.rs @@ -14,7 +14,7 @@ declare_clippy_lint! { /// comment. /// /// ### Example - /// ```rust + /// ```no_run /// //// My amazing data structure /// pub struct Foo { /// // ... @@ -22,7 +22,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// /// My amazing data structure /// pub struct Foo { /// // ... diff --git a/clippy_lints/src/from_over_into.rs b/clippy_lints/src/from_over_into.rs index 2b899e21ef55..5477532bb958 100644 --- a/clippy_lints/src/from_over_into.rs +++ b/clippy_lints/src/from_over_into.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; 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::source::snippet_opt; use rustc_errors::Applicability; @@ -24,7 +24,7 @@ declare_clippy_lint! { /// According the std docs implementing `From<..>` is preferred since it gives you `Into<..>` for free where the reverse isn't true. /// /// ### Example - /// ```rust + /// ```no_run /// struct StringWrapper(String); /// /// impl Into for String { @@ -34,7 +34,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct StringWrapper(String); /// /// impl From for StringWrapper { @@ -88,7 +88,8 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { cx.tcx.sess.source_map().guess_head_span(item.span), "an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true", |diag| { - // If the target type is likely foreign mention the orphan rules as it's a common source of confusion + // 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()).map_or(true, |id| !id.is_local()) { diag.help( "`impl From for Foreign` is allowed by the orphan rules, for more information see\n\ @@ -96,7 +97,10 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { ); } - let message = format!("replace the `Into` implementation with `From<{}>`", middle_trait_ref.self_ty()); + let message = format!( + "replace the `Into` implementation with `From<{}>`", + middle_trait_ref.self_ty() + ); if let Some(suggestions) = convert_to_from(cx, into_trait_seg, target_ty, self_ty, impl_item_ref) { diag.multipart_suggestion(message, suggestions, Applicability::MachineApplicable); } else { @@ -110,12 +114,12 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { extract_msrv_attr!(LateContext); } -/// Finds the occurences of `Self` and `self` +/// Finds the occurrences of `Self` and `self` struct SelfFinder<'a, 'tcx> { cx: &'a LateContext<'tcx>, - /// Occurences of `Self` + /// Occurrences of `Self` upper: Vec, - /// Occurences of `self` + /// Occurrences of `self` lower: Vec, /// If any of the `self`/`Self` usages were from an expansion, or the body contained a binding /// already named `val` diff --git a/clippy_lints/src/from_raw_with_void_ptr.rs b/clippy_lints/src/from_raw_with_void_ptr.rs index 617c96b4fcbc..d9138d48b2ca 100644 --- a/clippy_lints/src/from_raw_with_void_ptr.rs +++ b/clippy_lints/src/from_raw_with_void_ptr.rs @@ -18,13 +18,13 @@ declare_clippy_lint! { /// For this to be safe, `c_void` would need to have the same memory layout as the original type, which is often not the case. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::ffi::c_void; /// let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void; /// let _ = unsafe { Box::from_raw(ptr) }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::ffi::c_void; /// # let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void; /// let _ = unsafe { Box::from_raw(ptr as *mut usize) }; @@ -40,14 +40,22 @@ declare_lint_pass!(FromRawWithVoidPtr => [FROM_RAW_WITH_VOID_PTR]); impl LateLintPass<'_> for FromRawWithVoidPtr { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { 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 arg_kind = cx.typeck_results().expr_ty(arg).kind() - && let RawPtr(TypeAndMut { ty, .. }) = arg_kind - && is_c_void(cx, *ty) { + && 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 arg_kind = cx.typeck_results().expr_ty(arg).kind() + && let RawPtr(TypeAndMut { ty, .. }) = arg_kind + && is_c_void(cx, *ty) + { let msg = format!("creating a `{type_str}` from a void raw pointer"); - span_lint_and_help(cx, FROM_RAW_WITH_VOID_PTR, expr.span, &msg, Some(arg.span), "cast this to a pointer of the appropriate type"); + span_lint_and_help( + cx, + FROM_RAW_WITH_VOID_PTR, + expr.span, + &msg, + Some(arg.span), + "cast this to a pointer of the appropriate type", + ); } } } diff --git a/clippy_lints/src/functions/mod.rs b/clippy_lints/src/functions/mod.rs index 716908483e9d..3f5cceec70ed 100644 --- a/clippy_lints/src/functions/mod.rs +++ b/clippy_lints/src/functions/mod.rs @@ -23,7 +23,7 @@ declare_clippy_lint! { /// grouping some parameters into a new type. /// /// ### Example - /// ```rust + /// ```no_run /// # struct Color; /// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) { /// // .. @@ -46,7 +46,7 @@ declare_clippy_lint! { /// multiple functions. /// /// ### Example - /// ```rust + /// ```no_run /// fn im_too_long() { /// println!(""); /// // ... 100 more LoC @@ -129,7 +129,7 @@ declare_clippy_lint! { /// a remnant of a refactoring that removed the return type. /// /// ### Examples - /// ```rust + /// ```no_run /// #[must_use] /// fn useless() { } /// ``` @@ -151,7 +151,7 @@ declare_clippy_lint! { /// attribute to improve the lint message. /// /// ### Examples - /// ```rust + /// ```no_run /// #[must_use] /// fn double_must_use() -> Result<(), ()> { /// unimplemented!(); @@ -183,7 +183,7 @@ declare_clippy_lint! { /// `#[must_use]`. /// /// ### Examples - /// ```rust + /// ```no_run /// // this could be annotated with `#[must_use]`. /// pub fn id(t: T) -> T { t } /// ``` @@ -211,7 +211,7 @@ declare_clippy_lint! { /// instead. /// /// ### Examples - /// ```rust + /// ```no_run /// pub fn read_u8() -> Result { Err(()) } /// ``` /// should become @@ -262,7 +262,7 @@ declare_clippy_lint! { /// The size determined by Clippy is platform-dependent. /// /// ### Examples - /// ```rust + /// ```no_run /// pub enum ParseError { /// UnparsedBytes([u8; 512]), /// UnexpectedEof, @@ -274,7 +274,7 @@ declare_clippy_lint! { /// } /// ``` /// should be - /// ``` + /// ```no_run /// pub enum ParseError { /// UnparsedBytes(Box<[u8; 512]>), /// UnexpectedEof, @@ -301,7 +301,7 @@ declare_clippy_lint! { /// /// ### Example - /// ```rust + /// ```no_run /// struct A { /// a: String, /// b: String, @@ -315,7 +315,7 @@ declare_clippy_lint! { /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct A { /// a: String, /// b: String, @@ -340,14 +340,14 @@ declare_clippy_lint! { /// Turbofish syntax (`::<>`) cannot be used when `impl Trait` is being used, making `impl Trait` less powerful. Readability may also be a factor. /// /// ### Example - /// ```rust + /// ```no_run /// trait MyTrait {} /// fn foo(a: impl MyTrait) { /// // [...] /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// trait MyTrait {} /// fn foo(a: T) { /// // [...] diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs index 57df5683c9d3..3aaf63ce340a 100644 --- a/clippy_lints/src/functions/must_use.rs +++ b/clippy_lints/src/functions/must_use.rs @@ -118,9 +118,10 @@ fn check_needless_must_use( if sig.header.is_async() { let infcx = cx.tcx.infer_ctxt().build(); if let Some(future_ty) = infcx.get_impl_future_output_ty(return_ty(cx, item_id)) - && !is_must_use_ty(cx, future_ty) { - return; - } + && !is_must_use_ty(cx, future_ty) + { + return; + } } span_lint_and_help( diff --git a/clippy_lints/src/functions/result.rs b/clippy_lints/src/functions/result.rs index 90fc0d4f662e..485235514ded 100644 --- a/clippy_lints/src/functions/result.rs +++ b/clippy_lints/src/functions/result.rs @@ -21,7 +21,9 @@ fn result_err_ty<'tcx>( ) -> Option<(&'tcx hir::Ty<'tcx>, Ty<'tcx>)> { if !in_external_macro(cx.sess(), item_span) && let hir::FnRetTy::Return(hir_ty) = decl.output - && let ty = cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).instantiate_identity().output()) + && let ty = cx + .tcx + .erase_late_bound_regions(cx.tcx.fn_sig(id).instantiate_identity().output()) && is_type_diagnostic_item(cx, ty, sym::Result) && let ty::Adt(_, args) = ty.kind() { diff --git a/clippy_lints/src/future_not_send.rs b/clippy_lints/src/future_not_send.rs index 621415c881cf..eee5b7540ba7 100644 --- a/clippy_lints/src/future_not_send.rs +++ b/clippy_lints/src/future_not_send.rs @@ -34,11 +34,11 @@ declare_clippy_lint! { /// produced. /// /// ### Example - /// ```rust + /// ```no_run /// async fn not_send(bytes: std::rc::Rc<[u8]>) {} /// ``` /// Use instead: - /// ```rust + /// ```no_run /// async fn is_send(bytes: std::sync::Arc<[u8]>) {} /// ``` #[clippy::version = "1.44.0"] diff --git a/clippy_lints/src/if_not_else.rs b/clippy_lints/src/if_not_else.rs index 3d59b783337a..cae561f7802e 100644 --- a/clippy_lints/src/if_not_else.rs +++ b/clippy_lints/src/if_not_else.rs @@ -1,6 +1,7 @@ //! lint on if branches that could be swapped so no `!` operation is necessary //! on the condition +use clippy_utils::consts::{constant_simple, Constant}; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::is_else_clause; use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; @@ -16,7 +17,7 @@ declare_clippy_lint! { /// Negations reduce the readability of statements. /// /// ### Example - /// ```rust + /// ```no_run /// # let v: Vec = vec![]; /// # fn a() {} /// # fn b() {} @@ -29,7 +30,7 @@ declare_clippy_lint! { /// /// Could be written: /// - /// ```rust + /// ```no_run /// # let v: Vec = vec![]; /// # fn a() {} /// # fn b() {} @@ -47,6 +48,13 @@ declare_clippy_lint! { declare_lint_pass!(IfNotElse => [IF_NOT_ELSE]); +fn is_zero_const(expr: &Expr<'_>, cx: &LateContext<'_>) -> bool { + if let Some(value) = constant_simple(cx, cx.typeck_results(), expr) { + return Constant::Int(0) == value; + } + false +} + impl LateLintPass<'_> for IfNotElse { fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) { // While loops will be desugared to ExprKind::If. This will cause the lint to fire. @@ -72,7 +80,9 @@ impl LateLintPass<'_> for IfNotElse { "remove the `!` and swap the blocks of the `if`/`else`", ); }, - ExprKind::Binary(ref kind, _, _) if kind.node == BinOpKind::Ne => { + ExprKind::Binary(ref kind, _, lhs) if kind.node == BinOpKind::Ne && !is_zero_const(lhs, cx) => { + // Disable firing the lint on `… != 0`, as these are likely to be bit tests. + // For example, `if foo & 0x0F00 != 0 { … } else { … }` already is in the "proper" order. span_lint_and_help( cx, IF_NOT_ELSE, diff --git a/clippy_lints/src/if_then_some_else_none.rs b/clippy_lints/src/if_then_some_else_none.rs index e2d19e245570..66c10ab228f4 100644 --- a/clippy_lints/src/if_then_some_else_none.rs +++ b/clippy_lints/src/if_then_some_else_none.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::eager_or_lazy::switch_to_eager_eval; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::Sugg; use clippy_utils::{contains_return, higher, is_else_clause, is_res_lang_ctor, path_res, peel_blocks}; @@ -21,7 +21,7 @@ declare_clippy_lint! { /// in comparison to `bool::then`. /// /// ### Example - /// ```rust + /// ```no_run /// # let v = vec![0]; /// let a = if v.is_empty() { /// println!("true!"); @@ -33,7 +33,7 @@ declare_clippy_lint! { /// /// Could be written: /// - /// ```rust + /// ```no_run /// # let v = vec![0]; /// let a = v.is_empty().then(|| { /// println!("true!"); @@ -76,7 +76,11 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { let ctxt = expr.span.ctxt(); - if let Some(higher::If { cond, then, r#else: Some(els) }) = higher::If::hir(expr) + if let Some(higher::If { + cond, + then, + r#else: Some(els), + }) = higher::If::hir(expr) && let ExprKind::Block(then_block, _) = then.kind && let Some(then_expr) = then_block.expr && let ExprKind::Call(then_call, [then_arg]) = then_expr.kind @@ -86,7 +90,9 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { && !contains_return(then_block.stmts) { let mut app = Applicability::Unspecified; - let cond_snip = Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "[condition]", &mut app).maybe_par().to_string(); + let cond_snip = Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "[condition]", &mut app) + .maybe_par() + .to_string(); let arg_snip = snippet_with_context(cx, then_arg.span, ctxt, "[body]", &mut app).0; let mut method_body = if then_block.stmts.is_empty() { arg_snip.into_owned() @@ -100,9 +106,8 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { "then" }; - let help = format!( - "consider using `bool::{method_name}` like: `{cond_snip}.{method_name}({method_body})`", - ); + let help = + format!("consider using `bool::{method_name}` like: `{cond_snip}.{method_name}({method_body})`",); span_lint_and_help( cx, IF_THEN_SOME_ELSE_NONE, diff --git a/clippy_lints/src/ignored_unit_patterns.rs b/clippy_lints/src/ignored_unit_patterns.rs index ef2a66d4a209..76bdfb94eb85 100644 --- a/clippy_lints/src/ignored_unit_patterns.rs +++ b/clippy_lints/src/ignored_unit_patterns.rs @@ -15,14 +15,14 @@ declare_clippy_lint! { /// would detect a type change that `_` would ignore. /// /// ### Example - /// ```rust + /// ```no_run /// match std::fs::create_dir("tmp-work-dir") { /// Ok(_) => println!("Working directory created"), /// Err(s) => eprintln!("Could not create directory: {s}"), /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// match std::fs::create_dir("tmp-work-dir") { /// Ok(()) => println!("Working directory created"), /// Err(s) => eprintln!("Could not create directory: {s}"), @@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for IgnoredUnitPatterns { }, _ => {}, } - if matches!(pat.kind, PatKind::Wild) && cx.typeck_results().pat_ty(pat).is_unit() { + if matches!(pat.kind, PatKind::Wild) && cx.typeck_results().pat_ty(pat).peel_refs().is_unit() { span_lint_and_sugg( cx, IGNORED_UNIT_PATTERNS, diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs index 2b2ea156cd4d..a1fcce18ff6b 100644 --- a/clippy_lints/src/implicit_hasher.rs +++ b/clippy_lints/src/implicit_hasher.rs @@ -35,7 +35,7 @@ declare_clippy_lint! { /// pieces of code, possibly including external crates. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::collections::HashMap; /// # use std::hash::{Hash, BuildHasher}; /// # trait Serialize {}; @@ -44,7 +44,7 @@ declare_clippy_lint! { /// pub fn foo(map: &mut HashMap) { } /// ``` /// could be rewritten as - /// ```rust + /// ```no_run /// # use std::collections::HashMap; /// # use std::hash::{Hash, BuildHasher}; /// # trait Serialize {}; diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs index a6b035d51062..c6bcf3ba40c5 100644 --- a/clippy_lints/src/implicit_return.rs +++ b/clippy_lints/src/implicit_return.rs @@ -24,13 +24,13 @@ declare_clippy_lint! { /// corresponding statements. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo(x: usize) -> usize { /// x /// } /// ``` /// add return - /// ```rust + /// ```no_run /// fn foo(x: usize) -> usize { /// return x; /// } diff --git a/clippy_lints/src/implicit_saturating_add.rs b/clippy_lints/src/implicit_saturating_add.rs index ee7973b82ab9..24f62490f967 100644 --- a/clippy_lints/src/implicit_saturating_add.rs +++ b/clippy_lints/src/implicit_saturating_add.rs @@ -18,7 +18,7 @@ declare_clippy_lint! { /// The built-in function is more readable and may be faster. /// /// ### Example - /// ```rust + /// ```no_run ///let mut u:u32 = 7000; /// /// if u != u32::MAX { @@ -26,7 +26,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run ///let mut u:u32 = 7000; /// /// u = u.saturating_add(1); @@ -82,18 +82,18 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd { fn get_int_max(ty: Ty<'_>) -> Option { match ty.peel_refs().kind() { - Int(IntTy::I8) => i8::max_value().try_into().ok(), - Int(IntTy::I16) => i16::max_value().try_into().ok(), - Int(IntTy::I32) => i32::max_value().try_into().ok(), - Int(IntTy::I64) => i64::max_value().try_into().ok(), - Int(IntTy::I128) => i128::max_value().try_into().ok(), - Int(IntTy::Isize) => isize::max_value().try_into().ok(), - Uint(UintTy::U8) => u8::max_value().try_into().ok(), - Uint(UintTy::U16) => u16::max_value().try_into().ok(), - Uint(UintTy::U32) => u32::max_value().try_into().ok(), - Uint(UintTy::U64) => u64::max_value().try_into().ok(), - Uint(UintTy::U128) => Some(u128::max_value()), - Uint(UintTy::Usize) => usize::max_value().try_into().ok(), + Int(IntTy::I8) => i8::MAX.try_into().ok(), + Int(IntTy::I16) => i16::MAX.try_into().ok(), + Int(IntTy::I32) => i32::MAX.try_into().ok(), + Int(IntTy::I64) => i64::MAX.try_into().ok(), + Int(IntTy::I128) => i128::MAX.try_into().ok(), + Int(IntTy::Isize) => isize::MAX.try_into().ok(), + Uint(UintTy::U8) => Some(u8::MAX.into()), + Uint(UintTy::U16) => Some(u16::MAX.into()), + Uint(UintTy::U32) => Some(u32::MAX.into()), + Uint(UintTy::U64) => Some(u64::MAX.into()), + Uint(UintTy::U128) => Some(u128::MAX), + Uint(UintTy::Usize) => usize::MAX.try_into().ok(), _ => None, } } diff --git a/clippy_lints/src/implicit_saturating_sub.rs b/clippy_lints/src/implicit_saturating_sub.rs index b99d45446817..859404289d97 100644 --- a/clippy_lints/src/implicit_saturating_sub.rs +++ b/clippy_lints/src/implicit_saturating_sub.rs @@ -15,7 +15,7 @@ declare_clippy_lint! { /// Simplicity and readability. Instead we can easily use an builtin function. /// /// ### Example - /// ```rust + /// ```no_run /// # let end: u32 = 10; /// # let start: u32 = 5; /// let mut i: u32 = end - start; @@ -26,7 +26,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let end: u32 = 10; /// # let start: u32 = 5; /// let mut i: u32 = end - start; diff --git a/clippy_lints/src/implied_bounds_in_impls.rs b/clippy_lints/src/implied_bounds_in_impls.rs index ec9044bba5cc..ff27a5d666d3 100644 --- a/clippy_lints/src/implied_bounds_in_impls.rs +++ b/clippy_lints/src/implied_bounds_in_impls.rs @@ -29,7 +29,7 @@ declare_clippy_lint! { /// (e.g. `trait A {} trait B: A {} trait C: B {}`, then having an `fn() -> impl A + C`) /// /// ### Example - /// ```rust + /// ```no_run /// # use std::ops::{Deref,DerefMut}; /// fn f() -> impl Deref + DerefMut { /// // ^^^^^^^^^^^^^^^^^^^ unnecessary bound, already implied by the `DerefMut` trait bound @@ -37,7 +37,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::ops::{Deref,DerefMut}; /// fn f() -> impl DerefMut { /// Box::new(123) @@ -230,19 +230,24 @@ fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) { // Example: // `impl Deref + DerefMut` is not allowed. // `DerefMut::Target` needs to match `Deref::Target`. - let implied_bounds: Vec<_> = opaque_ty.bounds.iter().filter_map(|bound| { - if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound - && let [.., path] = poly_trait.trait_ref.path.segments - && poly_trait.bound_generic_params.is_empty() - && let Some(trait_def_id) = path.res.opt_def_id() - && let predicates = cx.tcx.super_predicates_of(trait_def_id).predicates - && !predicates.is_empty() // If the trait has no supertrait, there is nothing to add. - { - Some((bound.span(), path, predicates, trait_def_id)) - } else { - None - } - }).collect(); + let implied_bounds: Vec<_> = opaque_ty + .bounds + .iter() + .filter_map(|bound| { + if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound + && let [.., path] = poly_trait.trait_ref.path.segments + && poly_trait.bound_generic_params.is_empty() + && let Some(trait_def_id) = path.res.opt_def_id() + && let predicates = cx.tcx.super_predicates_of(trait_def_id).predicates + && !predicates.is_empty() + // If the trait has no supertrait, there is nothing to add. + { + Some((bound.span(), path, predicates, trait_def_id)) + } else { + None + } + }) + .collect(); // Lint all bounds in the `impl Trait` type that are also in the `implied_bounds` vec. // This involves some extra logic when generic arguments are present, since @@ -253,30 +258,31 @@ fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) { && let implied_args = path.args.map_or([].as_slice(), |a| a.args) && let implied_bindings = path.args.map_or([].as_slice(), |a| a.bindings) && let Some(def_id) = poly_trait.trait_ref.path.res.opt_def_id() - && let Some((implied_by_span, implied_by_args, implied_by_bindings)) = implied_bounds - .iter() - .find_map(|&(span, implied_by_path, preds, implied_by_def_id)| { - let implied_by_args = implied_by_path.args.map_or([].as_slice(), |a| a.args); - let implied_by_bindings = implied_by_path.args.map_or([].as_slice(), |a| a.bindings); + && let Some((implied_by_span, implied_by_args, implied_by_bindings)) = + implied_bounds + .iter() + .find_map(|&(span, implied_by_path, preds, implied_by_def_id)| { + let implied_by_args = implied_by_path.args.map_or([].as_slice(), |a| a.args); + let implied_by_bindings = implied_by_path.args.map_or([].as_slice(), |a| a.bindings); - preds.iter().find_map(|(clause, _)| { - if let ClauseKind::Trait(tr) = clause.kind().skip_binder() - && tr.def_id() == def_id - && is_same_generics( - cx.tcx, - tr.trait_ref.args, - implied_by_args, - implied_args, - implied_by_def_id, - def_id, - ) - { - Some((span, implied_by_args, implied_by_bindings)) - } else { - None - } + preds.iter().find_map(|(clause, _)| { + if let ClauseKind::Trait(tr) = clause.kind().skip_binder() + && tr.def_id() == def_id + && is_same_generics( + cx.tcx, + tr.trait_ref.args, + implied_by_args, + implied_args, + implied_by_def_id, + def_id, + ) + { + Some((span, implied_by_args, implied_by_bindings)) + } else { + None + } + }) }) - }) { emit_lint( cx, @@ -286,7 +292,7 @@ fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) { implied_bindings, implied_by_bindings, implied_by_args, - implied_by_span + implied_by_span, ); } } diff --git a/clippy_lints/src/inconsistent_struct_constructor.rs b/clippy_lints/src/inconsistent_struct_constructor.rs index 1ad886f2cf35..a84f7351ad66 100644 --- a/clippy_lints/src/inconsistent_struct_constructor.rs +++ b/clippy_lints/src/inconsistent_struct_constructor.rs @@ -19,7 +19,7 @@ declare_clippy_lint! { /// Since the order of fields in a constructor doesn't affect the /// resulted instance as the below example indicates, /// - /// ```rust + /// ```no_run /// #[derive(Debug, PartialEq, Eq)] /// struct Foo { /// x: i32, @@ -35,7 +35,7 @@ declare_clippy_lint! { /// inconsistent order can be confusing and decreases readability and consistency. /// /// ### Example - /// ```rust + /// ```no_run /// struct Foo { /// x: i32, /// y: i32, @@ -47,7 +47,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # struct Foo { /// # x: i32, /// # y: i32, diff --git a/clippy_lints/src/index_refutable_slice.rs b/clippy_lints/src/index_refutable_slice.rs index f507f45d5bb9..c2f1f18e39d1 100644 --- a/clippy_lints/src/index_refutable_slice.rs +++ b/clippy_lints/src/index_refutable_slice.rs @@ -1,7 +1,7 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::IfLet; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::is_copy; use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local}; use if_chain::if_chain; @@ -31,7 +31,7 @@ declare_clippy_lint! { /// patterns. /// /// ### Example - /// ```rust + /// ```no_run /// let slice: Option<&[u32]> = Some(&[1, 2, 3]); /// /// if let Some(slice) = slice { @@ -39,7 +39,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let slice: Option<&[u32]> = Some(&[1, 2, 3]); /// /// if let Some(&[first, ..]) = slice { diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs index 4f4f571773fb..1ce7d85d3828 100644 --- a/clippy_lints/src/indexing_slicing.rs +++ b/clippy_lints/src/indexing_slicing.rs @@ -26,7 +26,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let x = [1, 2, 3, 4]; /// // Index within bounds /// @@ -65,7 +65,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # #![allow(unused)] /// /// # let x = vec![0; 5]; diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs index fe28c526be35..e9c53671a932 100644 --- a/clippy_lints/src/infinite_iter.rs +++ b/clippy_lints/src/infinite_iter.rs @@ -39,7 +39,7 @@ declare_clippy_lint! { /// this lint is not clever enough to analyze it. /// /// ### Example - /// ```rust + /// ```no_run /// let infinite_iter = 0..; /// # #[allow(unused)] /// [0..].iter().zip(infinite_iter.take_while(|x| *x > 5)); diff --git a/clippy_lints/src/inherent_impl.rs b/clippy_lints/src/inherent_impl.rs index 3d1113ff9ccc..a61a64161930 100644 --- a/clippy_lints/src/inherent_impl.rs +++ b/clippy_lints/src/inherent_impl.rs @@ -18,7 +18,7 @@ declare_clippy_lint! { /// Splitting the implementation of a type makes the code harder to navigate. /// /// ### Example - /// ```rust + /// ```no_run /// struct X; /// impl X { /// fn one() {} @@ -30,7 +30,7 @@ declare_clippy_lint! { /// /// Could be written: /// - /// ```rust + /// ```no_run /// struct X; /// impl X { /// fn one() {} diff --git a/clippy_lints/src/inherent_to_string.rs b/clippy_lints/src/inherent_to_string.rs index bc4ec33b7334..fe5eb5ccac52 100644 --- a/clippy_lints/src/inherent_to_string.rs +++ b/clippy_lints/src/inherent_to_string.rs @@ -15,7 +15,7 @@ declare_clippy_lint! { /// This method is also implicitly defined if a type implements the `Display` trait. As the functionality of `Display` is much more versatile, it should be preferred. /// /// ### Example - /// ```rust + /// ```no_run /// pub struct A; /// /// impl A { @@ -26,7 +26,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// use std::fmt; /// /// pub struct A; @@ -51,7 +51,7 @@ declare_clippy_lint! { /// This method is also implicitly defined if a type implements the `Display` trait. The less versatile inherent method will then shadow the implementation introduced by `Display`. /// /// ### Example - /// ```rust + /// ```no_run /// use std::fmt; /// /// pub struct A; @@ -70,7 +70,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// use std::fmt; /// /// pub struct A; diff --git a/clippy_lints/src/init_numbered_fields.rs b/clippy_lints/src/init_numbered_fields.rs index f95d2c2edb1e..269311a67d64 100644 --- a/clippy_lints/src/init_numbered_fields.rs +++ b/clippy_lints/src/init_numbered_fields.rs @@ -20,7 +20,7 @@ declare_clippy_lint! { /// benefit as opposed to tuple initializers /// /// ### Example - /// ```rust + /// ```no_run /// struct TupleStruct(u8, u16); /// /// let _ = TupleStruct { diff --git a/clippy_lints/src/inline_fn_without_body.rs b/clippy_lints/src/inline_fn_without_body.rs index d609a5ca4d46..899126565f79 100644 --- a/clippy_lints/src/inline_fn_without_body.rs +++ b/clippy_lints/src/inline_fn_without_body.rs @@ -18,7 +18,7 @@ declare_clippy_lint! { /// The inline attribute is ignored for trait methods without bodies. /// /// ### Example - /// ```rust + /// ```no_run /// trait Animal { /// #[inline] /// fn name(&self) -> &'static str; diff --git a/clippy_lints/src/instant_subtraction.rs b/clippy_lints/src/instant_subtraction.rs index a1a115f6d79f..32b2cb4385f8 100644 --- a/clippy_lints/src/instant_subtraction.rs +++ b/clippy_lints/src/instant_subtraction.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{self, span_lint_and_sugg}; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::Sugg; use clippy_utils::ty; @@ -21,13 +21,13 @@ declare_clippy_lint! { /// `prev_instant.elapsed()` also more clearly signals intention. /// /// ### Example - /// ```rust + /// ```no_run /// use std::time::Instant; /// let prev_instant = Instant::now(); /// let duration = Instant::now() - prev_instant; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::time::Instant; /// let prev_instant = Instant::now(); /// let duration = prev_instant.elapsed(); @@ -47,13 +47,13 @@ declare_clippy_lint! { /// unintentional panics. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::time::{Instant, Duration}; /// let time_passed = Instant::now() - Duration::from_secs(5); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # use std::time::{Instant, Duration}; /// let time_passed = Instant::now().checked_sub(Duration::from_secs(5)); /// ``` diff --git a/clippy_lints/src/int_plus_one.rs b/clippy_lints/src/int_plus_one.rs index 1b14e525d9a8..9ffcee07d287 100644 --- a/clippy_lints/src/int_plus_one.rs +++ b/clippy_lints/src/int_plus_one.rs @@ -16,14 +16,14 @@ declare_clippy_lint! { /// Readability -- better to use `> y` instead of `>= y + 1`. /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 1; /// # let y = 1; /// if x >= y + 1 {} /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let x = 1; /// # let y = 1; /// if x > y {} diff --git a/clippy_lints/src/invalid_upcast_comparisons.rs b/clippy_lints/src/invalid_upcast_comparisons.rs index 6ea637412d5b..de82935e66b6 100644 --- a/clippy_lints/src/invalid_upcast_comparisons.rs +++ b/clippy_lints/src/invalid_upcast_comparisons.rs @@ -26,7 +26,7 @@ declare_clippy_lint! { /// https://github.com/rust-lang/rust-clippy/issues/886 /// /// ### Example - /// ```rust + /// ```no_run /// let x: u8 = 1; /// (x as u32) > 300; /// ``` diff --git a/clippy_lints/src/item_name_repetitions.rs b/clippy_lints/src/item_name_repetitions.rs index 8b4984da3dd1..fe30697b9de7 100644 --- a/clippy_lints/src/item_name_repetitions.rs +++ b/clippy_lints/src/item_name_repetitions.rs @@ -26,7 +26,7 @@ declare_clippy_lint! { /// (the prefixes are `Foo1` and `Foo2` respectively), as also `Bar螃`, `Bar蟹` /// /// ### Example - /// ```rust + /// ```no_run /// enum Cake { /// BlackForestCake, /// HummingbirdCake, @@ -34,7 +34,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// enum Cake { /// BlackForest, /// Hummingbird, @@ -56,14 +56,14 @@ declare_clippy_lint! { /// It requires the user to type the module name twice. /// /// ### Example - /// ```rust + /// ```no_run /// mod cake { /// struct BlackForestCake; /// } /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// mod cake { /// struct BlackForest; /// } @@ -119,7 +119,7 @@ declare_clippy_lint! { /// (the prefixes are `foo1` and `foo2` respectively), as also `bar螃`, `bar蟹` /// /// ### Example - /// ```rust + /// ```no_run /// struct Cake { /// cake_sugar: u8, /// cake_flour: u8, @@ -127,7 +127,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct Cake { /// sugar: u8, /// flour: u8, @@ -320,6 +320,11 @@ fn check_variant(cx: &LateContext<'_>, threshold: u64, def: &EnumDef<'_>, item_n return; } + for var in def.variants { + check_enum_start(cx, item_name, var); + check_enum_end(cx, item_name, var); + } + let first = match def.variants.first() { Some(variant) => variant.ident.name.as_str(), None => return, @@ -328,8 +333,6 @@ fn check_variant(cx: &LateContext<'_>, threshold: u64, def: &EnumDef<'_>, item_n let mut post = pre.clone(); post.reverse(); for var in def.variants { - check_enum_start(cx, item_name, var); - check_enum_end(cx, item_name, var); let name = var.ident.name.as_str(); let variant_split = camel_case_split(name); diff --git a/clippy_lints/src/items_after_statements.rs b/clippy_lints/src/items_after_statements.rs index a7ec57e28505..9605d76fbf00 100644 --- a/clippy_lints/src/items_after_statements.rs +++ b/clippy_lints/src/items_after_statements.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// it's hard to figure out which item is meant in a statement. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo() { /// println!("cake"); /// } @@ -31,7 +31,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// fn foo() { /// println!("cake"); /// } diff --git a/clippy_lints/src/items_after_test_module.rs b/clippy_lints/src/items_after_test_module.rs index 41477242bcc0..35e01862cee8 100644 --- a/clippy_lints/src/items_after_test_module.rs +++ b/clippy_lints/src/items_after_test_module.rs @@ -14,7 +14,7 @@ declare_clippy_lint! { /// ### Why is this bad? /// Having items declared after the testing module is confusing and may lead to bad test coverage. /// ### Example - /// ```rust + /// ```no_run /// #[cfg(test)] /// mod tests { /// // [...] @@ -25,7 +25,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn my_function() { /// // [...] /// } @@ -74,9 +74,7 @@ impl LateLintPass<'_> for ItemsAfterTestModule { if let Some(last) = after.last() && after.iter().all(|&item| { - !matches!(item.kind, ItemKind::Mod(_)) - && !item.span.from_expansion() - && !is_from_proc_macro(cx, item) + !matches!(item.kind, ItemKind::Mod(_)) && !item.span.from_expansion() && !is_from_proc_macro(cx, item) }) && !fulfill_or_allowed(cx, ITEMS_AFTER_TEST_MODULE, after.iter().map(|item| item.hir_id())) { @@ -99,10 +97,7 @@ impl LateLintPass<'_> for ItemsAfterTestModule { { diag.multipart_suggestion_with_style( "move the items to before the test module was defined", - vec![ - (prev.span.shrink_to_hi(), items), - (items_span, String::new()) - ], + vec![(prev.span.shrink_to_hi(), items), (items_span, String::new())], Applicability::MachineApplicable, SuggestionStyle::HideCodeAlways, ); diff --git a/clippy_lints/src/iter_not_returning_iterator.rs b/clippy_lints/src/iter_not_returning_iterator.rs index 066d2c4b7874..505aadd1a110 100644 --- a/clippy_lints/src/iter_not_returning_iterator.rs +++ b/clippy_lints/src/iter_not_returning_iterator.rs @@ -15,7 +15,7 @@ declare_clippy_lint! { /// Methods named `iter` or `iter_mut` conventionally return an `Iterator`. /// /// ### Example - /// ```rust + /// ```no_run /// // `String` does not implement `Iterator` /// struct Data {} /// impl Data { @@ -25,7 +25,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::str::Chars; /// struct Data {} /// impl Data { diff --git a/clippy_lints/src/iter_without_into_iter.rs b/clippy_lints/src/iter_without_into_iter.rs index 0ee291a4e9da..3c291f25590d 100644 --- a/clippy_lints/src/iter_without_into_iter.rs +++ b/clippy_lints/src/iter_without_into_iter.rs @@ -19,8 +19,13 @@ declare_clippy_lint! { /// It's not bad, but having them is idiomatic and allows the type to be used in for loops directly /// (`for val in &iter {}`), without having to first call `iter()` or `iter_mut()`. /// + /// ### Limitations + /// This lint focuses on providing an idiomatic API. Therefore, it will only + /// lint on types which are accessible outside of the crate. For internal types, + /// the `IntoIterator` trait can be implemented on demand if it is actually needed. + /// /// ### Example - /// ```rust + /// ```no_run /// struct MySlice<'a>(&'a [u8]); /// impl<'a> MySlice<'a> { /// pub fn iter(&self) -> std::slice::Iter<'a, u8> { @@ -29,7 +34,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct MySlice<'a>(&'a [u8]); /// impl<'a> MySlice<'a> { /// pub fn iter(&self) -> std::slice::Iter<'a, u8> { @@ -61,8 +66,16 @@ declare_clippy_lint! { /// by just calling `.iter()`, instead of the more awkward `<&Type>::into_iter` or `(&val).into_iter()` syntax /// in case of ambiguity with another `IntoIterator` impl. /// + /// ### Limitations + /// This lint focuses on providing an idiomatic API. Therefore, it will only + /// lint on types which are accessible outside of the crate. For internal types, + /// these methods can be added on demand if they are actually needed. Otherwise, + /// it would trigger the [`dead_code`] lint for the unused method. + /// + /// [`dead_code`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#dead-code + /// /// ### Example - /// ```rust + /// ```no_run /// struct MySlice<'a>(&'a [u8]); /// impl<'a> IntoIterator for &MySlice<'a> { /// type Item = &'a u8; @@ -73,7 +86,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct MySlice<'a>(&'a [u8]); /// impl<'a> MySlice<'a> { /// pub fn iter(&self) -> std::slice::Iter<'a, u8> { @@ -104,6 +117,12 @@ fn is_nameable_in_impl_trait(ty: &rustc_hir::Ty<'_>) -> bool { !matches!(ty.kind, TyKind::OpaqueDef(..)) } +fn is_ty_exported(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { + ty.ty_adt_def() + .and_then(|adt| adt.did().as_local()) + .is_some_and(|did| cx.effective_visibilities.is_exported(did)) +} + /// Returns the deref chain of a type, starting with the type itself. fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl Iterator> + 'cx { iter::successors(Some(ty), |&ty| { @@ -136,17 +155,18 @@ impl LateLintPass<'_> for IterWithoutIntoIter { if let ItemKind::Impl(imp) = item.kind && let TyKind::Ref(_, self_ty_without_ref) = &imp.self_ty.kind && let Some(trait_ref) = imp.of_trait - && trait_ref.trait_def_id().is_some_and(|did| cx.tcx.is_diagnostic_item(sym::IntoIterator, did)) + && trait_ref + .trait_def_id() + .is_some_and(|did| cx.tcx.is_diagnostic_item(sym::IntoIterator, did)) && let &ty::Ref(_, ty, mtbl) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() && let expected_method_name = match mtbl { Mutability::Mut => sym::iter_mut, Mutability::Not => sym::iter, } - && !deref_chain(cx, ty) - .any(|ty| { - // We can't check inherent impls for slices, but we know that they have an `iter(_mut)` method - ty.peel_refs().is_slice() || adt_has_inherent_method(cx, ty, expected_method_name) - }) + && !deref_chain(cx, ty).any(|ty| { + // We can't check inherent impls for slices, but we know that they have an `iter(_mut)` method + ty.peel_refs().is_slice() || adt_has_inherent_method(cx, ty, expected_method_name) + }) && let Some(iter_assoc_span) = imp.items.iter().find_map(|item| { if item.ident.name == sym!(IntoIter) { Some(cx.tcx.hir().impl_item(item.id).expect_type().span) @@ -154,6 +174,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter { None } }) + && is_ty_exported(cx, ty) { span_lint_and_then( cx, @@ -165,7 +186,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter { // to avoid name ambiguities, as there might be an inherent into_iter method // that we don't want to call. let sugg = format!( -" + " impl {self_ty_without_ref} {{ fn {expected_method_name}({ref_self}self) -> {iter_ty} {{ <{ref_self}Self as IntoIterator>::into_iter(self) @@ -183,9 +204,9 @@ impl {self_ty_without_ref} {{ sugg, // Just like iter_without_into_iter, this suggestion is on a best effort basis // and requires potentially adding lifetimes or moving them around. - Applicability::Unspecified + Applicability::Unspecified, ); - } + }, ); } } @@ -221,11 +242,12 @@ impl {self_ty_without_ref} {{ cx.tcx, cx.param_env, iterator_did, - sym!(Item), + sym::Item, [ret_ty], ) // Only lint if the `IntoIterator` impl doesn't actually exist && !implements_trait(cx, ref_ty, into_iter_did, &[]) + && is_ty_exported(cx, ref_ty.peel_refs()) { let self_ty_snippet = format!("{borrow_prefix}{}", snippet(cx, imp.self_ty.span, "..")); @@ -233,22 +255,26 @@ impl {self_ty_without_ref} {{ cx, ITER_WITHOUT_INTO_ITER, item.span, - &format!("`{}` method without an `IntoIterator` impl for `{self_ty_snippet}`", item.ident), + &format!( + "`{}` method without an `IntoIterator` impl for `{self_ty_snippet}`", + item.ident + ), |diag| { // Get the lower span of the `impl` block, and insert the suggestion right before it: // impl X { // ^ fn iter(&self) -> impl IntoIterator { ... } // } - let span_behind_impl = cx.tcx + let span_behind_impl = cx + .tcx .def_span(cx.tcx.hir().parent_id(item.hir_id()).owner.def_id) .shrink_to_lo(); let sugg = format!( -" + " impl IntoIterator for {self_ty_snippet} {{ type IntoIter = {ret_ty}; - type Iter = {iter_ty}; - fn into_iter() -> Self::IntoIter {{ + type Item = {iter_ty}; + fn into_iter(self) -> Self::IntoIter {{ self.iter() }} }} @@ -262,7 +288,8 @@ impl IntoIterator for {self_ty_snippet} {{ // such as adding some lifetimes in the associated types, or importing types. Applicability::Unspecified, ); - }); + }, + ); } } } diff --git a/clippy_lints/src/large_enum_variant.rs b/clippy_lints/src/large_enum_variant.rs index b22b57a3006f..79522db3718a 100644 --- a/clippy_lints/src/large_enum_variant.rs +++ b/clippy_lints/src/large_enum_variant.rs @@ -38,7 +38,7 @@ declare_clippy_lint! { /// this may lead to a false positive. /// /// ### Example - /// ```rust + /// ```no_run /// enum Test { /// A(i32), /// B([i32; 8000]), @@ -46,7 +46,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// // Possibly better /// enum Test2 { /// A(i32), diff --git a/clippy_lints/src/large_futures.rs b/clippy_lints/src/large_futures.rs index 90096f0f506d..26a7278524e1 100644 --- a/clippy_lints/src/large_futures.rs +++ b/clippy_lints/src/large_futures.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// large size of a `Future` may cause stack overflows. /// /// ### Example - /// ```rust + /// ```no_run /// async fn large_future(_x: [u8; 16 * 1024]) {} /// /// pub async fn trigger() { @@ -26,7 +26,7 @@ declare_clippy_lint! { /// /// `Box::pin` the big future instead. /// - /// ```rust + /// ```no_run /// async fn large_future(_x: [u8; 16 * 1024]) {} /// /// pub async fn trigger() { diff --git a/clippy_lints/src/large_stack_arrays.rs b/clippy_lints/src/large_stack_arrays.rs index 0a5901bce046..5e312ab72402 100644 --- a/clippy_lints/src/large_stack_arrays.rs +++ b/clippy_lints/src/large_stack_arrays.rs @@ -39,27 +39,35 @@ impl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]); impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { if let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind - && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() - && let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind() - && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) - && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) - && !cx.tcx.hir().parent_iter(expr.hir_id) - .any(|(_, node)| matches!(node, Node::Item(Item { kind: ItemKind::Static(..), .. }))) - && self.maximum_allowed_size < u128::from(element_count) * u128::from(element_size) { - span_lint_and_help( - cx, - LARGE_STACK_ARRAYS, - expr.span, - &format!( - "allocating a local array larger than {} bytes", - self.maximum_allowed_size - ), - None, - &format!( - "consider allocating on the heap with `vec!{}.into_boxed_slice()`", - snippet(cx, expr.span, "[...]") - ), - ); - } + && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() + && let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind() + && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) + && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) + && !cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| { + matches!( + node, + Node::Item(Item { + kind: ItemKind::Static(..), + .. + }) + ) + }) + && self.maximum_allowed_size < u128::from(element_count) * u128::from(element_size) + { + span_lint_and_help( + cx, + LARGE_STACK_ARRAYS, + expr.span, + &format!( + "allocating a local array larger than {} bytes", + self.maximum_allowed_size + ), + None, + &format!( + "consider allocating on the heap with `vec!{}.into_boxed_slice()`", + snippet(cx, expr.span, "[...]") + ), + ); + } } } diff --git a/clippy_lints/src/large_stack_frames.rs b/clippy_lints/src/large_stack_frames.rs index 1d28d7dd0e7c..33636eb687f3 100644 --- a/clippy_lints/src/large_stack_frames.rs +++ b/clippy_lints/src/large_stack_frames.rs @@ -49,7 +49,7 @@ declare_clippy_lint! { /// ### Example /// This function creates four 500 KB arrays on the stack. Quite big but just small enough to not trigger `large_stack_arrays`. /// However, looking at the function as a whole, it's clear that this uses a lot of stack space. - /// ```rust + /// ```no_run /// struct QuiteLargeType([u8; 500_000]); /// fn foo() { /// // ... some function that uses a lot of stack space ... @@ -62,7 +62,7 @@ declare_clippy_lint! { /// /// Instead of doing this, allocate the arrays on the heap. /// This currently requires going through a `Vec` first and then converting it to a `Box`: - /// ```rust + /// ```no_run /// struct NotSoLargeType(Box<[u8]>); /// /// fn foo() { diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index c06b35ca0dab..08f095859e59 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -181,8 +181,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero { let mut applicability = Applicability::MachineApplicable; let lit1 = peel_ref_operators(cx, lt.init); - let lit_str = - Sugg::hir_with_context(cx, lit1, lt.span.ctxt(), "_", &mut applicability).maybe_par(); + let lit_str = Sugg::hir_with_context(cx, lit1, lt.span.ctxt(), "_", &mut applicability).maybe_par(); span_lint_and_sugg( cx, @@ -288,18 +287,26 @@ enum LenOutput { } fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> { - if let ty::Alias(_, alias_ty) = ty.kind() && - let Some(Node::Item(item)) = cx.tcx.hir().get_if_local(alias_ty.def_id) && - let Item { kind: ItemKind::OpaqueTy(opaque), .. } = item && - opaque.bounds.len() == 1 && - let GenericBound::LangItemTrait(LangItem::Future, _, _, generic_args) = &opaque.bounds[0] && - generic_args.bindings.len() == 1 && - let TypeBindingKind::Equality { - term: rustc_hir::Term::Ty(rustc_hir::Ty {kind: TyKind::Path(QPath::Resolved(_, path)), .. }), - } = &generic_args.bindings[0].kind && - path.segments.len() == 1 { - return Some(&path.segments[0]); - } + if let ty::Alias(_, alias_ty) = ty.kind() + && let Some(Node::Item(item)) = cx.tcx.hir().get_if_local(alias_ty.def_id) + && let Item { + kind: ItemKind::OpaqueTy(opaque), + .. + } = item + && opaque.bounds.len() == 1 + && let GenericBound::LangItemTrait(LangItem::Future, _, _, generic_args) = &opaque.bounds[0] + && generic_args.bindings.len() == 1 + && let TypeBindingKind::Equality { + term: + rustc_hir::Term::Ty(rustc_hir::Ty { + kind: TyKind::Path(QPath::Resolved(_, path)), + .. + }), + } = &generic_args.bindings[0].kind + && path.segments.len() == 1 + { + return Some(&path.segments[0]); + } None } diff --git a/clippy_lints/src/let_underscore.rs b/clippy_lints/src/let_underscore.rs index e7c875ab3a98..04f23a213f2b 100644 --- a/clippy_lints/src/let_underscore.rs +++ b/clippy_lints/src/let_underscore.rs @@ -17,7 +17,7 @@ declare_clippy_lint! { /// expr /// /// ### Example - /// ```rust + /// ```no_run /// fn f() -> Result { /// Ok(0) /// } @@ -69,7 +69,7 @@ declare_clippy_lint! { /// and ignore the resulting value. /// /// ### Example - /// ```rust + /// ```no_run /// async fn foo() -> Result<(), ()> { /// Ok(()) /// } @@ -77,7 +77,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # async fn context() { /// async fn foo() -> Result<(), ()> { /// Ok(()) @@ -107,14 +107,14 @@ declare_clippy_lint! { /// lints. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo() -> Result { /// Ok(123) /// } /// let _ = foo(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn foo() -> Result { /// Ok(123) /// } @@ -159,14 +159,15 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore { binding or dropping explicitly with `std::mem::drop`", ); } else if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() - && implements_trait(cx, cx.typeck_results().expr_ty(init), future_trait_def_id, &[]) { + && implements_trait(cx, cx.typeck_results().expr_ty(init), future_trait_def_id, &[]) + { span_lint_and_help( cx, LET_UNDERSCORE_FUTURE, local.span, "non-binding `let` on a future", None, - "consider awaiting the future or dropping explicitly with `std::mem::drop`" + "consider awaiting the future or dropping explicitly with `std::mem::drop`", ); } else if is_must_use_ty(cx, cx.typeck_results().expr_ty(init)) { span_lint_and_help( @@ -203,17 +204,17 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore { return; } - span_lint_and_help( + span_lint_and_help( cx, LET_UNDERSCORE_UNTYPED, local.span, "non-binding `let` without a type annotation", - Some( - Span::new(local.pat.span.hi(), - local.pat.span.hi() + BytePos(1), - local.pat.span.ctxt(), - local.pat.span.parent() - )), + Some(Span::new( + local.pat.span.hi(), + local.pat.span.hi() + BytePos(1), + local.pat.span.ctxt(), + local.pat.span.parent(), + )), "consider adding a type annotation", ); } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index a70a38ee08bf..ab978a677c23 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -50,7 +50,6 @@ extern crate clippy_utils; #[macro_use] extern crate declare_clippy_lint; -use clippy_utils::msrvs::Msrv; use rustc_data_structures::fx::FxHashSet; use rustc_lint::{Lint, LintId}; use rustc_session::Session; @@ -358,9 +357,7 @@ mod zero_div_zero; mod zero_sized_map_values; // end lints modules, do not remove this comment, it’s used in `update_lints` -use crate::utils::conf::metadata::get_configuration_metadata; -pub use crate::utils::conf::{lookup_conf_file, Conf}; -use crate::utils::FindAll; +use clippy_config::{get_configuration_metadata, Conf}; /// Register all pre expansion lints /// @@ -462,16 +459,13 @@ pub fn explain(name: &str) -> i32 { if let Some(info) = declared_lints::LINTS.iter().find(|info| info.lint.name == target) { println!("{}", info.explanation); // Check if the lint has configuration - let mdconf = get_configuration_metadata(); - if let Some(config_vec_positions) = mdconf - .iter() - .find_all(|cconf| cconf.lints.contains(&info.lint.name_lower()[8..].to_owned())) - { - // If it has, print it + let mut mdconf = get_configuration_metadata(); + let name = name.to_ascii_lowercase(); + mdconf.retain(|cconf| cconf.lints.contains(&name)); + if !mdconf.is_empty() { println!("### Configuration for {}:\n", info.lint.name_lower()); - for position in config_vec_positions { - let conf = &mdconf[position]; - println!(" - {}: {} (default: {})", conf.name, conf.doc, conf.default); + for conf in mdconf { + println!("{conf}"); } } 0 @@ -519,7 +513,9 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: // all the internal lints #[cfg(feature = "internal")] { - store.register_early_pass(|| Box::new(utils::internal_lints::clippy_lints_internal::ClippyLintsInternal)); + store.register_early_pass(|| { + Box::new(utils::internal_lints::unsorted_clippy_utils_paths::UnsortedClippyUtilsPaths) + }); store.register_early_pass(|| Box::new(utils::internal_lints::produce_ice::ProduceIce)); store.register_late_pass(|_| Box::new(utils::internal_lints::collapsible_calls::CollapsibleCalls)); store.register_late_pass(|_| { diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 0004a150d51b..4b89c0fa3612 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -38,7 +38,7 @@ declare_clippy_lint! { /// are mentioned due to potential false positives. /// /// ### Example - /// ```rust + /// ```no_run /// // Unnecessary lifetime annotations /// fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 { /// x @@ -46,7 +46,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// fn elided(x: &u8, y: u8) -> &u8 { /// x /// } @@ -69,7 +69,7 @@ declare_clippy_lint! { /// them leads to more readable code. /// /// ### Example - /// ```rust + /// ```no_run /// // unnecessary lifetimes /// fn unused_lifetime<'a>(x: u8) { /// // .. @@ -77,7 +77,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// fn no_lifetime(x: u8) { /// // ... /// } @@ -517,9 +517,11 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> { fn visit_poly_trait_ref(&mut self, poly_tref: &'tcx PolyTraitRef<'tcx>) { let trait_ref = &poly_tref.trait_ref; - if let Some(id) = trait_ref.trait_def_id() && lang_items::FN_TRAITS.iter().any(|&item| { - self.cx.tcx.lang_items().get(item) == Some(id) - }) { + if let Some(id) = trait_ref.trait_def_id() + && lang_items::FN_TRAITS + .iter() + .any(|&item| self.cx.tcx.lang_items().get(item) == Some(id)) + { let mut sub_visitor = RefVisitor::new(self.cx); sub_visitor.visit_trait_ref(trait_ref); self.nested_elision_site_lts.append(&mut sub_visitor.all_lts()); diff --git a/clippy_lints/src/lines_filter_map_ok.rs b/clippy_lints/src/lines_filter_map_ok.rs index ac949b672609..0a5f5a80cb72 100644 --- a/clippy_lints/src/lines_filter_map_ok.rs +++ b/clippy_lints/src/lines_filter_map_ok.rs @@ -34,7 +34,7 @@ declare_clippy_lint! { /// successful results, using `map_while()` would stop at the first error. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::{fs::File, io::{self, BufRead, BufReader}}; /// # let _ = || -> io::Result<()> { /// let mut lines = BufReader::new(File::open("some-path")?).lines().filter_map(Result::ok); @@ -43,7 +43,7 @@ declare_clippy_lint! { /// # Ok(()) }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::{fs::File, io::{self, BufRead, BufReader}}; /// # let _ = || -> io::Result<()> { /// let mut lines = BufReader::new(File::open("some-path")?).lines().map_while(Result::ok); @@ -59,41 +59,56 @@ declare_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_arg], fm_span) = expr.kind && - is_trait_method(cx, expr, sym::Iterator) && - (fm_method.ident.as_str() == "filter_map" || fm_method.ident.as_str() == "flat_map") && - is_type_diagnostic_item(cx, cx.typeck_results().expr_ty_adjusted(fm_receiver), sym::IoLines) + if let ExprKind::MethodCall(fm_method, fm_receiver, [fm_arg], fm_span) = expr.kind + && is_trait_method(cx, expr, sym::Iterator) + && (fm_method.ident.as_str() == "filter_map" || fm_method.ident.as_str() == "flat_map") + && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty_adjusted(fm_receiver), sym::IoLines) { let lint = match &fm_arg.kind { // Detect `Result::ok` - ExprKind::Path(qpath) => - cx.qpath_res(qpath, fm_arg.hir_id).opt_def_id().map(|did| - match_def_path(cx, did, &paths::CORE_RESULT_OK_METHOD)).unwrap_or_default(), + ExprKind::Path(qpath) => cx + .qpath_res(qpath, fm_arg.hir_id) + .opt_def_id() + .map(|did| match_def_path(cx, did, &paths::CORE_RESULT_OK_METHOD)) + .unwrap_or_default(), // Detect `|x| x.ok()` - ExprKind::Closure(Closure { body, .. }) => - if let Body { 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) + ExprKind::Closure(Closure { body, .. }) => { + if let Body { + 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.as_str() == "ok" } else { false } + }, _ => false, }; if lint { - span_lint_and_then(cx, + span_lint_and_then( + cx, LINES_FILTER_MAP_OK, fm_span, - &format!("`{}()` will run forever if the iterator repeatedly produces an `Err`", fm_method.ident), + &format!( + "`{}()` will run forever if the iterator repeatedly produces an `Err`", + fm_method.ident + ), |diag| { diag.span_note( fm_receiver.span, "this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error"); - diag.span_suggestion(fm_span, "replace with", "map_while(Result::ok)", Applicability::MaybeIncorrect); - }); - } + diag.span_suggestion( + fm_span, + "replace with", + "map_while(Result::ok)", + Applicability::MaybeIncorrect, + ); + }, + ); + } } } } diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs index 09ca0317337c..2c14bb72a9e0 100644 --- a/clippy_lints/src/literal_representation.rs +++ b/clippy_lints/src/literal_representation.rs @@ -23,14 +23,14 @@ declare_clippy_lint! { /// Reading long numbers is difficult without separators. /// /// ### Example - /// ```rust + /// ```no_run /// # let _: u64 = /// 61864918973511 /// # ; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let _: u64 = /// 61_864_918_973_511 /// # ; @@ -73,14 +73,14 @@ declare_clippy_lint! { /// grouped digits. /// /// ### Example - /// ```rust + /// ```no_run /// # let _: u64 = /// 618_64_9189_73_511 /// # ; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let _: u64 = /// 61_864_918_973_511 /// # ; @@ -100,7 +100,7 @@ declare_clippy_lint! { /// Negatively impacts readability. /// /// ### Example - /// ```rust + /// ```no_run /// let x: u32 = 0xFFF_FFF; /// let y: u8 = 0b01_011_101; /// ``` @@ -120,7 +120,7 @@ declare_clippy_lint! { /// Negatively impacts readability. /// /// ### Example - /// ```rust + /// ```no_run /// let x: u64 = 6186491_8973511; /// ``` #[clippy::version = "pre 1.29.0"] diff --git a/clippy_lints/src/loops/explicit_iter_loop.rs b/clippy_lints/src/loops/explicit_iter_loop.rs index 6ab256ef0010..1c2b7a169fc3 100644 --- a/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/clippy_lints/src/loops/explicit_iter_loop.rs @@ -1,6 +1,6 @@ use super::EXPLICIT_ITER_LOOP; +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::{ implements_trait, implements_trait_with_env, is_copy, make_normalized_projection, @@ -113,7 +113,9 @@ fn is_ref_iterable<'tcx>( let typeck = cx.typeck_results(); if let Some(trait_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator) && let Some(fn_id) = typeck.type_dependent_def_id(call_expr.hir_id) - && let sig = cx.tcx.liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder()) + && let sig = cx + .tcx + .liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder()) && let &[req_self_ty, req_res_ty] = &**sig.inputs_and_output && let param_env = cx.tcx.param_env(fn_id) && implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, &[]) @@ -131,8 +133,9 @@ fn is_ref_iterable<'tcx>( return Some((AdjustKind::None, self_ty)); } - let res_ty = cx.tcx.erase_regions(EarlyBinder::bind(req_res_ty) - .instantiate(cx.tcx, typeck.node_args(call_expr.hir_id))); + let res_ty = cx + .tcx + .erase_regions(EarlyBinder::bind(req_res_ty).instantiate(cx.tcx, typeck.node_args(call_expr.hir_id))); let mutbl = if let ty::Ref(_, _, mutbl) = *req_self_ty.kind() { Some(mutbl) } else { @@ -157,7 +160,7 @@ fn is_ref_iterable<'tcx>( let self_ty = if mutbl.is_mut() { self_ty } else { - Ty::new_ref(cx.tcx,region, TypeAndMut { ty, mutbl }) + Ty::new_ref(cx.tcx, region, TypeAndMut { ty, mutbl }) }; if implements_trait(cx, self_ty, trait_id, &[]) && let Some(ty) = @@ -172,10 +175,7 @@ fn is_ref_iterable<'tcx>( && !self_ty.is_ref() { // Attempt to borrow - let self_ty = Ty::new_ref(cx.tcx,cx.tcx.lifetimes.re_erased, TypeAndMut { - ty: self_ty, - mutbl, - }); + let self_ty = Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, TypeAndMut { ty: self_ty, mutbl }); if implements_trait(cx, self_ty, trait_id, &[]) && let Some(ty) = make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [self_ty]) && ty == res_ty @@ -187,12 +187,14 @@ fn is_ref_iterable<'tcx>( match adjustments { [] => Some((AdjustKind::None, self_ty)), &[ - Adjustment { kind: Adjust::Deref(_), ..}, + Adjustment { + kind: Adjust::Deref(_), .. + }, Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)), target, }, - .. + .., ] => { if enforce_iter_loop_reborrow && target != self_ty @@ -205,8 +207,14 @@ fn is_ref_iterable<'tcx>( } else { None } - } - &[Adjustment { kind: Adjust::Deref(_), target }, ..] => { + }, + &[ + Adjustment { + kind: Adjust::Deref(_), + target, + }, + .., + ] => { if is_copy(cx, target) && implements_trait(cx, target, trait_id, &[]) && let Some(ty) = @@ -217,13 +225,13 @@ fn is_ref_iterable<'tcx>( } else { None } - } + }, &[ Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)), target, }, - .. + .., ] => { if self_ty.is_ref() && implements_trait(cx, target, trait_id, &[]) @@ -235,7 +243,7 @@ fn is_ref_iterable<'tcx>( } else { None } - } + }, _ => None, } } else { diff --git a/clippy_lints/src/loops/for_kv_map.rs b/clippy_lints/src/loops/for_kv_map.rs index ed620460dbe6..94c951fc10a6 100644 --- a/clippy_lints/src/loops/for_kv_map.rs +++ b/clippy_lints/src/loops/for_kv_map.rs @@ -1,9 +1,8 @@ use super::FOR_KV_MAP; use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then}; use clippy_utils::source::snippet; -use clippy_utils::sugg; use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::visitors::is_local_used; +use clippy_utils::{pat_is_wild, sugg}; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Pat, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty; @@ -55,12 +54,3 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx } } } - -/// Returns `true` if the pattern is a `PatWild` or an ident prefixed with `_`. -fn pat_is_wild<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx PatKind<'_>, body: &'tcx Expr<'_>) -> bool { - match *pat { - PatKind::Wild => true, - PatKind::Binding(_, id, ident, None) if ident.as_str().starts_with('_') => !is_local_used(cx, body, id), - _ => false, - } -} diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 1fb16adad7a1..b99e0fd814ff 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -14,13 +14,14 @@ mod needless_range_loop; mod never_loop; mod same_item_push; mod single_element_loop; +mod unused_enumerate_index; mod utils; mod while_immutable_condition; mod while_let_loop; mod while_let_on_iterator; +use clippy_config::msrvs::Msrv; use clippy_utils::higher; -use clippy_utils::msrvs::Msrv; use rustc_hir::{Expr, ExprKind, LoopSource, Pat}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; @@ -36,7 +37,7 @@ declare_clippy_lint! { /// It is not as fast as a memcpy. /// /// ### Example - /// ```rust + /// ```no_run /// # let src = vec![1]; /// # let mut dst = vec![0; 65]; /// for i in 0..src.len() { @@ -45,7 +46,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let src = vec![1]; /// # let mut dst = vec![0; 65]; /// dst[64..(src.len() + 64)].clone_from_slice(&src[..]); @@ -67,7 +68,7 @@ declare_clippy_lint! { /// the bounds check that is done when indexing. /// /// ### Example - /// ```rust + /// ```no_run /// let vec = vec!['a', 'b', 'c']; /// for i in 0..vec.len() { /// println!("{}", vec[i]); @@ -75,7 +76,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let vec = vec!['a', 'b', 'c']; /// for i in vec { /// println!("{}", i); @@ -100,7 +101,7 @@ declare_clippy_lint! { /// types. /// /// ### Example - /// ```rust + /// ```no_run /// // with `y` a `Vec` or slice: /// # let y = vec![1]; /// for x in y.iter() { @@ -109,7 +110,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let y = vec![1]; /// for x in &y { /// // .. @@ -130,7 +131,7 @@ declare_clippy_lint! { /// Readability. /// /// ### Example - /// ```rust + /// ```no_run /// # let y = vec![1]; /// // with `y` a `Vec` or slice: /// for x in y.into_iter() { @@ -138,7 +139,7 @@ declare_clippy_lint! { /// } /// ``` /// can be rewritten to - /// ```rust + /// ```no_run /// # let y = vec![1]; /// for x in y { /// // .. @@ -217,7 +218,7 @@ declare_clippy_lint! { /// declutters the code and may be faster in some instances. /// /// ### Example - /// ```rust + /// ```no_run /// # let v = vec![1]; /// # fn bar(bar: usize, baz: usize) {} /// let mut i = 0; @@ -228,7 +229,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let v = vec![1]; /// # fn bar(bar: usize, baz: usize) {} /// for (i, item) in v.iter().enumerate() { bar(i, *item); } @@ -339,7 +340,7 @@ declare_clippy_lint! { /// code. /// /// ### Example - /// ```rust + /// ```no_run /// loop { /// ..; /// break; @@ -362,7 +363,7 @@ declare_clippy_lint! { /// False positive when mutation is followed by a `break`, but the `break` is not immediately /// after the mutation: /// - /// ```rust + /// ```no_run /// let mut x = 5; /// for _ in 0..x { /// x += 1; // x is a range bound that is mutated @@ -374,7 +375,7 @@ declare_clippy_lint! { /// False positive on nested loops ([#6072](https://github.com/rust-lang/rust-clippy/issues/6072)) /// /// ### Example - /// ```rust + /// ```no_run /// let mut foo = 42; /// for i in 0..foo { /// foo -= 1; @@ -402,7 +403,7 @@ declare_clippy_lint! { /// in the condition and only `Upvar` `b` gets mutated in the body, the lint will not trigger. /// /// ### Example - /// ```rust + /// ```no_run /// let i = 0; /// while i > 10 { /// println!("let me loop forever!"); @@ -425,7 +426,7 @@ declare_clippy_lint! { /// have better performance. /// /// ### Example - /// ```rust + /// ```no_run /// let item1 = 2; /// let item2 = 3; /// let mut vec: Vec = Vec::new(); @@ -438,7 +439,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let item1 = 2; /// let item2 = 3; /// let mut vec: Vec = vec![item1; 20]; @@ -459,7 +460,7 @@ declare_clippy_lint! { /// single element. /// /// ### Example - /// ```rust + /// ```no_run /// let item1 = 2; /// for item in &[item1] { /// println!("{}", item); @@ -467,7 +468,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let item1 = 2; /// let item = &item1; /// println!("{}", item); @@ -489,7 +490,7 @@ declare_clippy_lint! { /// /// ### Example /// - /// ```rust + /// ```no_run /// let x = vec![Some(1), Some(2), Some(3)]; /// for n in x { /// if let Some(n) = n { @@ -498,7 +499,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let x = vec![Some(1), Some(2), Some(3)]; /// for n in x.into_iter().flatten() { /// println!("{}", n); @@ -555,7 +556,7 @@ declare_clippy_lint! { /// /// ### Example /// - /// ```rust + /// ```no_run /// fn example(arr: Vec) -> Option { /// for el in arr { /// if el == 1 { @@ -566,7 +567,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn example(arr: Vec) -> Option { /// arr.into_iter().find(|&el| el == 1) /// } @@ -577,6 +578,33 @@ declare_clippy_lint! { "manual implementation of `Iterator::find`" } +declare_clippy_lint! { + /// ### What it does + /// Checks for uses of the `enumerate` method where the index is unused (`_`) + /// + /// ### Why is this bad? + /// The index from `.enumerate()` is immediately dropped. + /// + /// ### Example + /// ```rust + /// let v = vec![1, 2, 3, 4]; + /// for (_, x) in v.iter().enumerate() { + /// println!("{x}"); + /// } + /// ``` + /// Use instead: + /// ```rust + /// let v = vec![1, 2, 3, 4]; + /// for x in v.iter() { + /// println!("{x}"); + /// } + /// ``` + #[clippy::version = "1.75.0"] + pub UNUSED_ENUMERATE_INDEX, + style, + "using `.enumerate()` and immediately dropping the index" +} + declare_clippy_lint! { /// ### What it does /// Looks for loops that check for emptiness of a `Vec` in the condition and pop an element @@ -587,7 +615,7 @@ declare_clippy_lint! { /// pattern matching on the return value of `Vec::pop()`. /// /// ### Example - /// ```rust + /// ```no_run /// let mut numbers = vec![1, 2, 3, 4, 5]; /// while !numbers.is_empty() { /// let number = numbers.pop().unwrap(); @@ -595,7 +623,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let mut numbers = vec![1, 2, 3, 4, 5]; /// while let Some(number) = numbers.pop() { /// // use `number` @@ -619,6 +647,7 @@ impl Loops { } } } + impl_lint_pass!(Loops => [ MANUAL_MEMCPY, MANUAL_FLATTEN, @@ -638,7 +667,8 @@ impl_lint_pass!(Loops => [ SINGLE_ELEMENT_LOOP, MISSING_SPIN_LOOP, MANUAL_FIND, - MANUAL_WHILE_LET_SOME + MANUAL_WHILE_LET_SOME, + UNUSED_ENUMERATE_INDEX, ]); impl<'tcx> LateLintPass<'tcx> for Loops { @@ -717,6 +747,7 @@ impl Loops { same_item_push::check(cx, pat, arg, body, expr); manual_flatten::check(cx, pat, arg, body, span); manual_find::check(cx, pat, arg, body, span, expr); + unused_enumerate_index::check(cx, pat, arg, body); } fn check_for_loop_arg(&self, cx: &LateContext<'_>, _: &Pat<'_>, arg: &Expr<'_>) { diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs index 3d8a4cd948af..cc054cb46692 100644 --- a/clippy_lints/src/loops/never_loop.rs +++ b/clippy_lints/src/loops/never_loop.rs @@ -271,9 +271,9 @@ fn never_loop_expr<'tcx>( NeverLoopResult::Normal } }); - if let NeverLoopResult::Diverging = result && - let Some(macro_call) = root_macro_call_first_node(cx, expr) && - let Some(sym::todo_macro) = cx.tcx.get_diagnostic_name(macro_call.def_id) + if let NeverLoopResult::Diverging = result + && let Some(macro_call) = root_macro_call_first_node(cx, expr) + && let Some(sym::todo_macro) = cx.tcx.get_diagnostic_name(macro_call.def_id) { // We return MayContinueMainLoop here because we treat `todo!()` // as potentially containing any code, including a continue of the main loop. diff --git a/clippy_lints/src/loops/unused_enumerate_index.rs b/clippy_lints/src/loops/unused_enumerate_index.rs new file mode 100644 index 000000000000..62a2ab1ccb4c --- /dev/null +++ b/clippy_lints/src/loops/unused_enumerate_index.rs @@ -0,0 +1,62 @@ +use super::UNUSED_ENUMERATE_INDEX; +use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then}; +use clippy_utils::source::snippet; +use clippy_utils::{pat_is_wild, sugg}; +use rustc_hir::def::DefKind; +use rustc_hir::{Expr, ExprKind, Pat, PatKind}; +use rustc_lint::LateContext; +use rustc_middle::ty; + +/// Checks for the `UNUSED_ENUMERATE_INDEX` lint. +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>) { + let PatKind::Tuple(tuple, _) = pat.kind else { + return; + }; + + let ExprKind::MethodCall(_method, self_arg, [], _) = arg.kind else { + return; + }; + + let ty = cx.typeck_results().expr_ty(arg); + + if !pat_is_wild(cx, &tuple[0].kind, body) { + return; + } + + let name = match *ty.kind() { + ty::Adt(base, _substs) => cx.tcx.def_path_str(base.did()), + _ => return, + }; + + if name != "std::iter::Enumerate" && name != "core::iter::Enumerate" { + return; + } + + let Some((DefKind::AssocFn, call_id)) = cx.typeck_results().type_dependent_def(arg.hir_id) else { + return; + }; + + let call_name = cx.tcx.def_path_str(call_id); + + if call_name != "std::iter::Iterator::enumerate" && call_name != "core::iter::Iterator::enumerate" { + return; + } + + span_lint_and_then( + cx, + UNUSED_ENUMERATE_INDEX, + arg.span, + "you seem to use `.enumerate()` and immediately discard the index", + |diag| { + let base_iter = sugg::Sugg::hir(cx, self_arg, "base iter"); + multispan_sugg( + diag, + "remove the `.enumerate()` call", + vec![ + (pat.span, snippet(cx, tuple[1].span, "..").into_owned()), + (arg.span, base_iter.to_string()), + ], + ); + }, + ); +} diff --git a/clippy_lints/src/manual_assert.rs b/clippy_lints/src/manual_assert.rs index 45ea5aab4c2a..9a3da975f83c 100644 --- a/clippy_lints/src/manual_assert.rs +++ b/clippy_lints/src/manual_assert.rs @@ -16,14 +16,14 @@ declare_clippy_lint! { /// `assert!` is simpler than `if`-then-`panic!`. /// /// ### Example - /// ```rust + /// ```no_run /// let sad_people: Vec<&str> = vec![]; /// if !sad_people.is_empty() { /// panic!("there are sad people: {:?}", sad_people); /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let sad_people: Vec<&str> = vec![]; /// assert!(sad_people.is_empty(), "there are sad people: {:?}", sad_people); /// ``` @@ -64,7 +64,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualAssert { }; let cond_sugg = sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_par(); let sugg = format!("assert!({not}{cond_sugg}, {format_args_snip});"); - // we show to the user the suggestion without the comments, but when applying the fix, include the comments in the block + // we show to the user the suggestion without the comments, but when applying the fix, include the + // comments in the block span_lint_and_then( cx, MANUAL_ASSERT, @@ -77,16 +78,11 @@ impl<'tcx> LateLintPass<'tcx> for ManualAssert { expr.span.shrink_to_lo(), "add comments back", comments, - applicability + applicability, ); } - diag.span_suggestion( - expr.span, - "try instead", - sugg, - applicability - ); - } + diag.span_suggestion(expr.span, "try instead", sugg, applicability); + }, ); } } diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs index a75c76d6fe0d..998de38a9952 100644 --- a/clippy_lints/src/manual_async_fn.rs +++ b/clippy_lints/src/manual_async_fn.rs @@ -4,7 +4,7 @@ use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; use rustc_hir::{ - CoroutineSource, Block, Body, Closure, CoroutineKind, Expr, ExprKind, FnDecl, FnRetTy, GenericArg, GenericBound, + Block, Body, Closure, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl, FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, Term, TraitRef, Ty, TyKind, TypeBindingKind, }; use rustc_lint::{LateContext, LateLintPass}; @@ -20,13 +20,13 @@ declare_clippy_lint! { /// It's more idiomatic to use the dedicated syntax. /// /// ### Example - /// ```rust + /// ```no_run /// use std::future::Future; /// /// fn foo() -> impl Future { async { 42 } } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// async fn foo() -> i32 { 42 } /// ``` #[clippy::version = "1.45.0"] diff --git a/clippy_lints/src/manual_bits.rs b/clippy_lints/src/manual_bits.rs index 552c57d5e025..cd614c8951c1 100644 --- a/clippy_lints/src/manual_bits.rs +++ b/clippy_lints/src/manual_bits.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::get_parent_expr; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; @@ -20,11 +20,11 @@ declare_clippy_lint! { /// Can be written as the shorter `T::BITS`. /// /// ### Example - /// ```rust + /// ```no_run /// std::mem::size_of::() * 8; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// usize::BITS as usize; /// ``` #[clippy::version = "1.60.0"] diff --git a/clippy_lints/src/manual_clamp.rs b/clippy_lints/src/manual_clamp.rs index e75666e61f55..09c90e38e118 100644 --- a/clippy_lints/src/manual_clamp.rs +++ b/clippy_lints/src/manual_clamp.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; 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::sugg::Sugg; use clippy_utils::ty::implements_trait; use clippy_utils::visitors::is_const_evaluatable; @@ -38,7 +38,7 @@ declare_clippy_lint! { /// PR](https://github.com/rust-lang/rust-clippy/pull/9484#issuecomment-1278922613). /// /// ### Examples - /// ```rust + /// ```no_run /// # let (input, min, max) = (0, -2, 1); /// if input > max { /// max @@ -50,13 +50,13 @@ declare_clippy_lint! { /// # ; /// ``` /// - /// ```rust + /// ```no_run /// # let (input, min, max) = (0, -2, 1); /// input.max(min).min(max) /// # ; /// ``` /// - /// ```rust + /// ```no_run /// # let (input, min, max) = (0, -2, 1); /// match input { /// x if x > max => max, @@ -66,14 +66,14 @@ declare_clippy_lint! { /// # ; /// ``` /// - /// ```rust + /// ```no_run /// # let (input, min, max) = (0, -2, 1); /// let mut x = input; /// if x < min { x = min; } /// if x > max { x = max; } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let (input, min, max) = (0, -2, 1); /// input.clamp(min, max) /// # ; @@ -207,7 +207,7 @@ impl TypeClampability { /// Targets patterns like /// -/// ``` +/// ```no_run /// # let (input, min, max) = (0, -3, 12); /// /// if input < min { @@ -225,11 +225,11 @@ fn is_if_elseif_else_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx then, r#else: Some(else_if), }) = If::hir(expr) - && let Some(If { - cond: else_if_cond, - then: else_if_then, - r#else: Some(else_body), - }) = If::hir(peel_blocks(else_if)) + && let Some(If { + cond: else_if_cond, + then: else_if_then, + r#else: Some(else_body), + }) = If::hir(peel_blocks(else_if)) { let params = is_clamp_meta_pattern( cx, @@ -256,7 +256,7 @@ fn is_if_elseif_else_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx /// Targets patterns like /// -/// ``` +/// ```no_run /// # let (input, min_value, max_value) = (0, -3, 12); /// /// input.max(min_value).min(max_value) @@ -275,7 +275,12 @@ fn is_max_min_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> O _ => return None, }; Some(ClampSuggestion { - params: InputMinMax { input, min, max, is_float }, + params: InputMinMax { + input, + min, + max, + is_float, + }, span: expr.span, make_assignment: None, hir_with_ignore_attr: None, @@ -287,7 +292,7 @@ fn is_max_min_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> O /// Targets patterns like /// -/// ``` +/// ```no_run /// # let (input, min_value, max_value) = (0, -3, 12); /// # use std::cmp::{max, min}; /// min(max(input, min_value), max_value) @@ -346,11 +351,16 @@ fn is_call_max_min_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) ("max", "min") => (inner_arg, outer_arg), _ => return None, } - } + }, _ => return None, }; Some(ClampSuggestion { - params: InputMinMax { input, min, max, is_float }, + params: InputMinMax { + input, + min, + max, + is_float, + }, span, make_assignment: None, hir_with_ignore_attr: None, @@ -369,7 +379,7 @@ fn is_call_max_min_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) /// Targets patterns like /// -/// ``` +/// ```no_run /// # let (input, min, max) = (0, -3, 12); /// /// match input { @@ -384,7 +394,8 @@ fn is_match_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Opt // Find possible min/max branches let minmax_values = |a: &'tcx Arm<'tcx>| { if let PatKind::Binding(_, var_hir_id, _, None) = &a.pat.kind - && let Some(Guard::If(e)) = a.guard { + && let Some(Guard::If(e)) = a.guard + { Some((e, var_hir_id, a.body)) } else { None @@ -428,7 +439,7 @@ fn is_match_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Opt /// Targets patterns like /// -/// ``` +/// ```no_run /// # let (input, min, max) = (0, -3, 12); /// /// let mut x = input; @@ -441,18 +452,20 @@ fn is_two_if_pattern<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> .filter_map(|(maybe_set_first, maybe_set_second)| { if let StmtKind::Expr(first_expr) = *maybe_set_first && let StmtKind::Expr(second_expr) = *maybe_set_second - && let Some(If { cond: first_cond, then: first_then, r#else: None }) = If::hir(first_expr) - && let Some(If { cond: second_cond, then: second_then, r#else: None }) = If::hir(second_expr) - && let ExprKind::Assign( - maybe_input_first_path, - maybe_min_max_first, - _ - ) = peel_blocks_with_stmt(first_then).kind - && let ExprKind::Assign( - maybe_input_second_path, - maybe_min_max_second, - _ - ) = peel_blocks_with_stmt(second_then).kind + && let Some(If { + cond: first_cond, + then: first_then, + r#else: None, + }) = If::hir(first_expr) + && let Some(If { + cond: second_cond, + then: second_then, + r#else: None, + }) = If::hir(second_expr) + && let ExprKind::Assign(maybe_input_first_path, maybe_min_max_first, _) = + peel_blocks_with_stmt(first_then).kind + && let ExprKind::Assign(maybe_input_second_path, maybe_min_max_second, _) = + peel_blocks_with_stmt(second_then).kind && eq_expr_value(cx, maybe_input_first_path, maybe_input_second_path) && let Some(first_bin) = BinaryOp::new(first_cond) && let Some(second_bin) = BinaryOp::new(second_cond) @@ -462,7 +475,7 @@ fn is_two_if_pattern<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> &second_bin, maybe_min_max_first, maybe_min_max_second, - None + None, ) { Some(ClampSuggestion { @@ -485,7 +498,7 @@ fn is_two_if_pattern<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> /// Targets patterns like /// -/// ``` +/// ```no_run /// # let (mut input, min, max) = (0, -3, 12); /// /// if input < min { @@ -505,16 +518,9 @@ fn is_if_elseif_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> then: else_if_then, r#else: None, }) = If::hir(peel_blocks(else_if)) - && let ExprKind::Assign( - maybe_input_first_path, - maybe_min_max_first, - _ - ) = peel_blocks_with_stmt(then).kind - && let ExprKind::Assign( - maybe_input_second_path, - maybe_min_max_second, - _ - ) = peel_blocks_with_stmt(else_if_then).kind + && let ExprKind::Assign(maybe_input_first_path, maybe_min_max_first, _) = peel_blocks_with_stmt(then).kind + && let ExprKind::Assign(maybe_input_second_path, maybe_min_max_second, _) = + peel_blocks_with_stmt(else_if_then).kind { let params = is_clamp_meta_pattern( cx, diff --git a/clippy_lints/src/manual_float_methods.rs b/clippy_lints/src/manual_float_methods.rs index f09946955651..0c4101ceb6bb 100644 --- a/clippy_lints/src/manual_float_methods.rs +++ b/clippy_lints/src/manual_float_methods.rs @@ -17,12 +17,12 @@ declare_clippy_lint! { /// The method `is_infinite` is shorter and more readable. /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 1.0f32; /// if x == f32::INFINITY || x == f32::NEG_INFINITY {} /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let x = 1.0f32; /// if x.is_infinite() {} /// ``` @@ -40,13 +40,13 @@ declare_clippy_lint! { /// The method `is_finite` is shorter and more readable. /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 1.0f32; /// if x != f32::INFINITY && x != f32::NEG_INFINITY {} /// if x.abs() < f32::INFINITY {} /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let x = 1.0f32; /// if x.is_finite() {} /// if x.is_finite() {} @@ -114,46 +114,40 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods { _ => return, }; - span_lint_and_then( - cx, - variant.lint(), - expr.span, - variant.msg(), - |diag| { - match variant { - Variant::ManualIsInfinite => { - diag.span_suggestion( - expr.span, - "use the dedicated method instead", - format!("{local_snippet}.is_infinite()"), - Applicability::MachineApplicable, - ); - }, - Variant::ManualIsFinite => { - // TODO: There's probably some better way to do this, i.e., create - // multiple suggestions with notes between each of them - diag.span_suggestion_verbose( - expr.span, - "use the dedicated method instead", - format!("{local_snippet}.is_finite()"), - Applicability::MaybeIncorrect, - ) - .span_suggestion_verbose( - expr.span, - "this will alter how it handles NaN; if that is a problem, use instead", - format!("{local_snippet}.is_finite() || {local_snippet}.is_nan()"), - Applicability::MaybeIncorrect, - ) - .span_suggestion_verbose( - expr.span, - "or, for conciseness", - format!("!{local_snippet}.is_infinite()"), - Applicability::MaybeIncorrect, - ); - }, - } - }, - ); + span_lint_and_then(cx, variant.lint(), expr.span, variant.msg(), |diag| { + match variant { + Variant::ManualIsInfinite => { + diag.span_suggestion( + expr.span, + "use the dedicated method instead", + format!("{local_snippet}.is_infinite()"), + Applicability::MachineApplicable, + ); + }, + Variant::ManualIsFinite => { + // TODO: There's probably some better way to do this, i.e., create + // multiple suggestions with notes between each of them + diag.span_suggestion_verbose( + expr.span, + "use the dedicated method instead", + format!("{local_snippet}.is_finite()"), + Applicability::MaybeIncorrect, + ) + .span_suggestion_verbose( + expr.span, + "this will alter how it handles NaN; if that is a problem, use instead", + format!("{local_snippet}.is_finite() || {local_snippet}.is_nan()"), + Applicability::MaybeIncorrect, + ) + .span_suggestion_verbose( + expr.span, + "or, for conciseness", + format!("!{local_snippet}.is_infinite()"), + Applicability::MaybeIncorrect, + ); + }, + } + }); } } } diff --git a/clippy_lints/src/manual_hash_one.rs b/clippy_lints/src/manual_hash_one.rs index ea9113354504..472b4eb90066 100644 --- a/clippy_lints/src/manual_hash_one.rs +++ b/clippy_lints/src/manual_hash_one.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_hir_and_then; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_opt; use clippy_utils::visitors::{is_local_used, local_used_once}; use clippy_utils::{is_trait_method, path_to_local_id}; @@ -19,7 +19,7 @@ declare_clippy_lint! { /// It is more concise to use the `hash_one` method. /// /// ### Example - /// ```rust + /// ```no_run /// use std::hash::{BuildHasher, Hash, Hasher}; /// use std::collections::hash_map::RandomState; /// @@ -31,7 +31,7 @@ declare_clippy_lint! { /// let hash = hasher.finish(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::hash::BuildHasher; /// use std::collections::hash_map::RandomState; /// @@ -117,12 +117,11 @@ impl LateLintPass<'_> for ManualHashOne { finish_expr.span, // `needless_borrows_for_generic_args` will take care of // removing the `&` when it isn't needed - format!("{build_hasher}.hash_one(&{hashed_value})") - ) + format!("{build_hasher}.hash_one(&{hashed_value})"), + ), ], Applicability::MachineApplicable, ); - } }, ); diff --git a/clippy_lints/src/manual_is_ascii_check.rs b/clippy_lints/src/manual_is_ascii_check.rs index 9da20a28fba5..468f4170732d 100644 --- a/clippy_lints/src/manual_is_ascii_check.rs +++ b/clippy_lints/src/manual_is_ascii_check.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::macros::root_macro_call; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg::Sugg; use clippy_utils::{higher, in_constant}; use rustc_ast::ast::RangeLimits; @@ -23,7 +23,7 @@ declare_clippy_lint! { /// clear that it's not a specific subset of characters, but all /// ASCII (lowercase|uppercase|digit|hexdigit) characters. /// ### Example - /// ```rust + /// ```no_run /// fn main() { /// assert!(matches!('x', 'a'..='z')); /// assert!(matches!(b'X', b'A'..=b'Z')); @@ -37,7 +37,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn main() { /// assert!('x'.is_ascii_lowercase()); /// assert!(b'X'.is_ascii_uppercase()); @@ -98,15 +98,20 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck { } if let Some(macro_call) = root_macro_call(expr.span) - && is_matches_macro(cx, macro_call.def_id) { + && is_matches_macro(cx, macro_call.def_id) + { if let ExprKind::Match(recv, [arm, ..], _) = expr.kind { let range = check_pat(&arm.pat.kind); check_is_ascii(cx, macro_call.span, recv, &range); } } else if let ExprKind::MethodCall(path, receiver, [arg], ..) = expr.kind && path.ident.name == sym!(contains) - && let Some(higher::Range { start: Some(start), end: Some(end), limits: RangeLimits::Closed }) - = higher::Range::hir(receiver) { + && let Some(higher::Range { + start: Some(start), + end: Some(end), + limits: RangeLimits::Closed, + }) = higher::Range::hir(receiver) + { let range = check_range(start, end); if let ExprKind::AddrOf(BorrowKind::Ref, _, e) = arg.kind { check_is_ascii(cx, expr.span, e, &range); @@ -168,7 +173,8 @@ fn check_pat(pat_kind: &PatKind<'_>) -> CharRange { fn check_range(start: &Expr<'_>, end: &Expr<'_>) -> CharRange { if let ExprKind::Lit(start_lit) = &start.kind - && let ExprKind::Lit(end_lit) = &end.kind { + && let ExprKind::Lit(end_lit) = &end.kind + { match (&start_lit.node, &end_lit.node) { (Char('a'), Char('z')) | (Byte(b'a'), Byte(b'z')) => CharRange::LowerChar, (Char('A'), Char('Z')) | (Byte(b'A'), Byte(b'Z')) => CharRange::UpperChar, diff --git a/clippy_lints/src/manual_let_else.rs b/clippy_lints/src/manual_let_else.rs index 86bbdb4ea199..170a040d4ae8 100644 --- a/clippy_lints/src/manual_let_else.rs +++ b/clippy_lints/src/manual_let_else.rs @@ -1,10 +1,12 @@ use crate::question_mark::{QuestionMark, QUESTION_MARK}; +use clippy_config::msrvs; +use clippy_config::types::MatchLintBehaviour; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::IfLetOrMatch; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::{Descend, Visitable}; -use clippy_utils::{is_lint_allowed, msrvs, pat_and_expr_can_be_question_mark, peel_blocks}; +use clippy_utils::{is_lint_allowed, pat_and_expr_can_be_question_mark, peel_blocks}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_expr, Visitor}; @@ -14,7 +16,6 @@ use rustc_middle::lint::in_external_macro; use rustc_session::declare_tool_lint; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; -use serde::Deserialize; use std::ops::ControlFlow; use std::slice; @@ -30,14 +31,14 @@ declare_clippy_lint! { /// /// ### Example /// - /// ```rust + /// ```no_run /// # let w = Some(0); /// let v = if let Some(v) = w { v } else { return }; /// ``` /// /// Could be written: /// - /// ```rust + /// ```no_run /// # fn main () { /// # let w = Some(0); /// let Some(v) = w else { return }; @@ -55,21 +56,20 @@ impl<'tcx> QuestionMark { return; } - if let StmtKind::Local(local) = stmt.kind && - let Some(init) = local.init && - local.els.is_none() && - local.ty.is_none() && - init.span.eq_ctxt(stmt.span) && - let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init) + if let StmtKind::Local(local) = stmt.kind + && let Some(init) = local.init + && local.els.is_none() + && local.ty.is_none() + && init.span.eq_ctxt(stmt.span) + && let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init) { match if_let_or_match { IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else) => { - if - let Some(ident_map) = expr_simple_identity_map(local.pat, let_pat, if_then) && - let Some(if_else) = if_else && - expr_diverges(cx, if_else) && - let qm_allowed = is_lint_allowed(cx, QUESTION_MARK, stmt.hir_id) && - (qm_allowed || pat_and_expr_can_be_question_mark(cx, let_pat, if_else).is_none()) + if let Some(ident_map) = expr_simple_identity_map(local.pat, let_pat, if_then) + && let Some(if_else) = if_else + && expr_diverges(cx, if_else) + && let qm_allowed = is_lint_allowed(cx, QUESTION_MARK, stmt.hir_id) + && (qm_allowed || pat_and_expr_can_be_question_mark(cx, let_pat, if_else).is_none()) { emit_manual_let_else(cx, stmt.span, if_let_expr, &ident_map, let_pat, if_else); } @@ -95,7 +95,9 @@ impl<'tcx> QuestionMark { .iter() .enumerate() .find(|(_, arm)| expr_diverges(cx, arm.body) && pat_allowed_for_else(cx, arm.pat, check_types)); - let Some((idx, diverging_arm)) = diverging_arm_opt else { return; }; + let Some((idx, diverging_arm)) = diverging_arm_opt else { + return; + }; // If the non-diverging arm is the first one, its pattern can be reused in a let/else statement. // However, if it arrives in second position, its pattern may cover some cases already covered // by the diverging one. @@ -105,7 +107,7 @@ impl<'tcx> QuestionMark { } let pat_arm = &arms[1 - idx]; let Some(ident_map) = expr_simple_identity_map(local.pat, pat_arm.pat, pat_arm.body) else { - return + return; }; emit_manual_let_else(cx, stmt.span, match_expr, &ident_map, pat_arm.pat, diverging_arm.body); @@ -216,8 +218,8 @@ fn replace_in_pattern( let fields = fields .iter() .map(|fld| { - if let PatKind::Binding(_, _, name, None) = fld.pat.kind && - let Some(pat_to_put) = ident_map.get(&name.name) + if let PatKind::Binding(_, _, name, None) = fld.pat.kind + && let Some(pat_to_put) = ident_map.get(&name.name) { let (sn_fld_name, _) = snippet_with_context(cx, fld.ident.span, span.ctxt(), "", app); let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), "", app); @@ -463,8 +465,8 @@ fn expr_simple_identity_map<'a, 'hir>( } let mut ident_map = FxHashMap::default(); for (sub_pat, path) in sub_pats.iter().zip(paths.iter()) { - if let ExprKind::Path(QPath::Resolved(_ty, path)) = path.kind && - let [path_seg] = path.segments + if let ExprKind::Path(QPath::Resolved(_ty, path)) = path.kind + && let [path_seg] = path.segments { let ident = path_seg.ident; if !pat_bindings.remove(&ident) { @@ -477,10 +479,3 @@ fn expr_simple_identity_map<'a, 'hir>( } Some(ident_map) } - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize)] -pub enum MatchLintBehaviour { - AllTypes, - WellKnownTypes, - Never, -} diff --git a/clippy_lints/src/manual_main_separator_str.rs b/clippy_lints/src/manual_main_separator_str.rs index c292bbe4e934..23f47c86fcce 100644 --- a/clippy_lints/src/manual_main_separator_str.rs +++ b/clippy_lints/src/manual_main_separator_str.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::{is_trait_method, match_def_path, paths, peel_hir_expr_refs}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; @@ -19,11 +19,11 @@ declare_clippy_lint! { /// an extra memory allocation. /// /// ### Example - /// ```rust + /// ```no_run /// let s: &str = &std::path::MAIN_SEPARATOR.to_string(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let s: &str = std::path::MAIN_SEPARATOR_STR; /// ``` #[clippy::version = "1.70.0"] @@ -47,27 +47,27 @@ impl_lint_pass!(ManualMainSeparatorStr => [MANUAL_MAIN_SEPARATOR_STR]); impl LateLintPass<'_> for ManualMainSeparatorStr { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - if self.msrv.meets(msrvs::PATH_MAIN_SEPARATOR_STR) && - let (target, _) = peel_hir_expr_refs(expr) && - is_trait_method(cx, target, sym::ToString) && - let ExprKind::MethodCall(path, receiver, &[], _) = target.kind && - 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 && - match_def_path(cx, receiver_def_id, &paths::PATH_MAIN_SEPARATOR) && - let ty::Ref(_, ty, Mutability::Not) = cx.typeck_results().expr_ty_adjusted(expr).kind() && - ty.is_str() - { - span_lint_and_sugg( - cx, - MANUAL_MAIN_SEPARATOR_STR, - expr.span, - "taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String`", - "replace with", - "std::path::MAIN_SEPARATOR_STR".to_owned(), - Applicability::MachineApplicable, - ); - } + if self.msrv.meets(msrvs::PATH_MAIN_SEPARATOR_STR) + && let (target, _) = peel_hir_expr_refs(expr) + && is_trait_method(cx, target, sym::ToString) + && let ExprKind::MethodCall(path, receiver, &[], _) = target.kind + && 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 + && match_def_path(cx, receiver_def_id, &paths::PATH_MAIN_SEPARATOR) + && let ty::Ref(_, ty, Mutability::Not) = cx.typeck_results().expr_ty_adjusted(expr).kind() + && ty.is_str() + { + span_lint_and_sugg( + cx, + MANUAL_MAIN_SEPARATOR_STR, + expr.span, + "taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String`", + "replace with", + "std::path::MAIN_SEPARATOR_STR".to_owned(), + Applicability::MachineApplicable, + ); + } } extract_msrv_attr!(LateContext); diff --git a/clippy_lints/src/manual_non_exhaustive.rs b/clippy_lints/src/manual_non_exhaustive.rs index c12727c4a28c..fc8f23630013 100644 --- a/clippy_lints/src/manual_non_exhaustive.rs +++ b/clippy_lints/src/manual_non_exhaustive.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::is_doc_hidden; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_opt; use rustc_ast::ast::{self, VisibilityKind}; use rustc_ast::attr; @@ -22,7 +22,7 @@ declare_clippy_lint! { /// and allows possible optimizations when applied to enums. /// /// ### Example - /// ```rust + /// ```no_run /// struct S { /// pub a: i32, /// pub b: i32, @@ -39,7 +39,7 @@ declare_clippy_lint! { /// struct T(pub i32, pub i32, ()); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// #[non_exhaustive] /// struct S { /// pub a: i32, @@ -138,7 +138,7 @@ impl EarlyLintPass for ManualNonExhaustiveStruct { ); } diag.span_help(field.span, "remove this field"); - } + }, ); } } diff --git a/clippy_lints/src/manual_range_patterns.rs b/clippy_lints/src/manual_range_patterns.rs index 90557b555608..d24bfe182244 100644 --- a/clippy_lints/src/manual_range_patterns.rs +++ b/clippy_lints/src/manual_range_patterns.rs @@ -22,12 +22,12 @@ declare_clippy_lint! { /// in order to support negative numbers. /// /// ### Example - /// ```rust + /// ```no_run /// let x = 6; /// let foo = matches!(x, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let x = 6; /// let foo = matches!(x, 1..=10); /// ``` diff --git a/clippy_lints/src/manual_rem_euclid.rs b/clippy_lints/src/manual_rem_euclid.rs index 0e89ca132ef9..bc8372fbd418 100644 --- a/clippy_lints/src/manual_rem_euclid.rs +++ b/clippy_lints/src/manual_rem_euclid.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{constant_full_int, FullInt}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::{in_constant, path_to_local}; use rustc_errors::Applicability; @@ -18,12 +18,12 @@ declare_clippy_lint! { /// It's simpler and more readable. /// /// ### Example - /// ```rust + /// ```no_run /// let x: i32 = 24; /// let rem = ((x % 4) + 4) % 4; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let x: i32 = 24; /// let rem = x.rem_euclid(4); /// ``` @@ -76,30 +76,31 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid { // Also ensures the const is nonzero since zero can't be a divisor && const1 == const2 && const2 == const3 && let Some(hir_id) = path_to_local(expr3) - && let Some(Node::Pat(_)) = cx.tcx.hir().find(hir_id) { - // Apply only to params or locals with annotated types - match cx.tcx.hir().find_parent(hir_id) { - Some(Node::Param(..)) => (), - Some(Node::Local(local)) => { - let Some(ty) = local.ty else { return }; - if matches!(ty.kind, TyKind::Infer) { - return; - } + && let Some(Node::Pat(_)) = cx.tcx.hir().find(hir_id) + { + // Apply only to params or locals with annotated types + match cx.tcx.hir().find_parent(hir_id) { + Some(Node::Param(..)) => (), + Some(Node::Local(local)) => { + let Some(ty) = local.ty else { return }; + if matches!(ty.kind, TyKind::Infer) { + return; } - _ => return, - }; + }, + _ => return, + }; - let mut app = Applicability::MachineApplicable; - let rem_of = snippet_with_context(cx, expr3.span, ctxt, "_", &mut app).0; - span_lint_and_sugg( - cx, - MANUAL_REM_EUCLID, - expr.span, - "manual `rem_euclid` implementation", - "consider using", - format!("{rem_of}.rem_euclid({const1})"), - app, - ); + let mut app = Applicability::MachineApplicable; + let rem_of = snippet_with_context(cx, expr3.span, ctxt, "_", &mut app).0; + span_lint_and_sugg( + cx, + MANUAL_REM_EUCLID, + expr.span, + "manual `rem_euclid` implementation", + "consider using", + format!("{rem_of}.rem_euclid({const1})"), + app, + ); } } diff --git a/clippy_lints/src/manual_retain.rs b/clippy_lints/src/manual_retain.rs index f923413f4348..2f8682d04181 100644 --- a/clippy_lints/src/manual_retain.rs +++ b/clippy_lints/src/manual_retain.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item}; use clippy_utils::{get_parent_expr, match_def_path, paths, SpanlessEq}; @@ -35,13 +35,13 @@ declare_clippy_lint! { /// ### Why is this bad? /// `.retain()` is simpler and avoids needless allocation. /// ### Example - /// ```rust + /// ```no_run /// let mut vec = vec![0, 1, 2]; /// vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect(); /// vec = vec.into_iter().filter(|x| x % 2 == 0).collect(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let mut vec = vec![0, 1, 2]; /// vec.retain(|x| x % 2 == 0); /// ``` @@ -97,7 +97,8 @@ fn check_into_iter( && let Some(into_iter_def_id) = cx.typeck_results().type_dependent_def_id(into_iter_expr.hir_id) && Some(into_iter_def_id) == cx.tcx.lang_items().into_iter_fn() && match_acceptable_type(cx, left_expr, msrv) - && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) { + && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) + { suggest(cx, parent_expr, left_expr, target_expr); } } @@ -120,7 +121,8 @@ fn check_iter( && let Some(iter_expr_def_id) = cx.typeck_results().type_dependent_def_id(iter_expr.hir_id) && match_acceptable_def_path(cx, iter_expr_def_id) && match_acceptable_type(cx, left_expr, msrv) - && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) { + && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) + { suggest(cx, parent_expr, left_expr, filter_expr); } } @@ -144,33 +146,35 @@ fn check_to_owned( && match_def_path(cx, chars_expr_def_id, &paths::STR_CHARS) && let ty = cx.typeck_results().expr_ty(str_expr).peel_refs() && is_type_lang_item(cx, ty, hir::LangItem::String) - && SpanlessEq::new(cx).eq_expr(left_expr, str_expr) { + && SpanlessEq::new(cx).eq_expr(left_expr, str_expr) + { suggest(cx, parent_expr, left_expr, filter_expr); } } fn suggest(cx: &LateContext<'_>, parent_expr: &hir::Expr<'_>, left_expr: &hir::Expr<'_>, filter_expr: &hir::Expr<'_>) { if let hir::ExprKind::MethodCall(_, _, [closure], _) = filter_expr.kind - && let hir::ExprKind::Closure(&hir::Closure { body, ..}) = closure.kind + && let hir::ExprKind::Closure(&hir::Closure { body, .. }) = closure.kind && let filter_body = cx.tcx.hir().body(body) && let [filter_params] = filter_body.params && let Some(sugg) = match filter_params.pat.kind { - hir::PatKind::Binding(_, _, filter_param_ident, None) => { - Some(format!("{}.retain(|{filter_param_ident}| {})", snippet(cx, left_expr.span, ".."), snippet(cx, filter_body.value.span, ".."))) - }, - hir::PatKind::Tuple([key_pat, value_pat], _) => { - make_sugg(cx, key_pat, value_pat, left_expr, filter_body) - }, - hir::PatKind::Ref(pat, _) => { - match pat.kind { - hir::PatKind::Binding(_, _, filter_param_ident, None) => { - Some(format!("{}.retain(|{filter_param_ident}| {})", snippet(cx, left_expr.span, ".."), snippet(cx, filter_body.value.span, ".."))) - }, - _ => None - } + hir::PatKind::Binding(_, _, filter_param_ident, None) => Some(format!( + "{}.retain(|{filter_param_ident}| {})", + snippet(cx, left_expr.span, ".."), + snippet(cx, filter_body.value.span, "..") + )), + hir::PatKind::Tuple([key_pat, value_pat], _) => make_sugg(cx, key_pat, value_pat, left_expr, filter_body), + hir::PatKind::Ref(pat, _) => match pat.kind { + hir::PatKind::Binding(_, _, filter_param_ident, None) => Some(format!( + "{}.retain(|{filter_param_ident}| {})", + snippet(cx, left_expr.span, ".."), + snippet(cx, filter_body.value.span, "..") + )), + _ => None, }, - _ => None - } { + _ => None, + } + { span_lint_and_sugg( cx, MANUAL_RETAIN, @@ -178,7 +182,7 @@ fn suggest(cx: &LateContext<'_>, parent_expr: &hir::Expr<'_>, left_expr: &hir::E "this expression can be written more simply using `.retain()`", "consider calling `.retain()` instead", sugg, - Applicability::MachineApplicable + Applicability::MachineApplicable, ); } } diff --git a/clippy_lints/src/manual_slice_size_calculation.rs b/clippy_lints/src/manual_slice_size_calculation.rs index f97600b53e4d..3b97d165998e 100644 --- a/clippy_lints/src/manual_slice_size_calculation.rs +++ b/clippy_lints/src/manual_slice_size_calculation.rs @@ -22,12 +22,12 @@ declare_clippy_lint! { /// * Less turbofishing /// /// ### Example - /// ```rust + /// ```no_run /// # let data : &[i32] = &[1, 2, 3]; /// let newlen = data.len() * std::mem::size_of::(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let data : &[i32] = &[1, 2, 3]; /// let newlen = std::mem::size_of_val(data); /// ``` diff --git a/clippy_lints/src/manual_string_new.rs b/clippy_lints/src/manual_string_new.rs index c20d7959fc4a..f8afae0e1f51 100644 --- a/clippy_lints/src/manual_string_new.rs +++ b/clippy_lints/src/manual_string_new.rs @@ -19,12 +19,12 @@ declare_clippy_lint! { /// be confusing. /// /// ### Example - /// ```rust + /// ```no_run /// let a = "".to_string(); /// let b: String = "".into(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let a = String::new(); /// let b = String::new(); /// ``` @@ -65,9 +65,9 @@ impl LateLintPass<'_> for ManualStringNew { /// Checks if an expression's kind corresponds to an empty &str. fn is_expr_kind_empty_str(expr_kind: &ExprKind<'_>) -> bool { - if let ExprKind::Lit(lit) = expr_kind && - let LitKind::Str(value, _) = lit.node && - value == symbol::kw::Empty + if let ExprKind::Lit(lit) = expr_kind + && let LitKind::Str(value, _) = lit.node + && value == symbol::kw::Empty { return true; } @@ -110,23 +110,22 @@ fn parse_call(cx: &LateContext<'_>, span: Span, func: &Expr<'_>, args: &[Expr<'_ if let ExprKind::Path(qpath) = &func.kind { if let QPath::TypeRelative(_, _) = qpath { // String::from(...) or String::try_from(...) - if let QPath::TypeRelative(ty, path_seg) = qpath && - [sym::from, sym::try_from].contains(&path_seg.ident.name) && - let TyKind::Path(qpath) = &ty.kind && - let QPath::Resolved(_, path) = qpath && - let [path_seg] = path.segments && - path_seg.ident.name == sym::String && - is_expr_kind_empty_str(arg_kind) + if let QPath::TypeRelative(ty, path_seg) = qpath + && [sym::from, sym::try_from].contains(&path_seg.ident.name) + && let TyKind::Path(qpath) = &ty.kind + && let QPath::Resolved(_, path) = qpath + && let [path_seg] = path.segments + && path_seg.ident.name == sym::String + && is_expr_kind_empty_str(arg_kind) { warn_then_suggest(cx, span); } } else if let QPath::Resolved(_, path) = qpath { // From::from(...) or TryFrom::try_from(...) - if let [path_seg1, path_seg2] = path.segments && - is_expr_kind_empty_str(arg_kind) && ( - (path_seg1.ident.name == sym::From && path_seg2.ident.name == sym::from) || - (path_seg1.ident.name == sym::TryFrom && path_seg2.ident.name == sym::try_from) - ) + if let [path_seg1, path_seg2] = path.segments + && is_expr_kind_empty_str(arg_kind) + && ((path_seg1.ident.name == sym::From && path_seg2.ident.name == sym::from) + || (path_seg1.ident.name == sym::TryFrom && path_seg2.ident.name == sym::try_from)) { warn_then_suggest(cx, span); } diff --git a/clippy_lints/src/manual_strip.rs b/clippy_lints/src/manual_strip.rs index 201bb56efcdd..9a9e6af50849 100644 --- a/clippy_lints/src/manual_strip.rs +++ b/clippy_lints/src/manual_strip.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then}; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use clippy_utils::usage::mutated_variables; use clippy_utils::{eq_expr_value, higher, match_def_path, paths}; @@ -27,14 +27,14 @@ declare_clippy_lint! { /// used by `str::{starts,ends}_with` and in the slicing. /// /// ### Example - /// ```rust + /// ```no_run /// let s = "hello, world!"; /// if s.starts_with("hello, ") { /// assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!"); /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let s = "hello, world!"; /// if let Some(end) = s.strip_prefix("hello, ") { /// assert_eq!(end.to_uppercase(), "WORLD!"); diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs index f0a0f482af29..766beb980a58 100644 --- a/clippy_lints/src/map_unit_fn.rs +++ b/clippy_lints/src/map_unit_fn.rs @@ -21,7 +21,7 @@ declare_clippy_lint! { /// an if let statement /// /// ### Example - /// ```rust + /// ```no_run /// # fn do_stuff() -> Option { Some(String::new()) } /// # fn log_err_msg(foo: String) -> Option { Some(foo) } /// # fn format_msg(foo: String) -> String { String::new() } @@ -33,7 +33,7 @@ declare_clippy_lint! { /// /// The correct use would be: /// - /// ```rust + /// ```no_run /// # fn do_stuff() -> Option { Some(String::new()) } /// # fn log_err_msg(foo: String) -> Option { Some(foo) } /// # fn format_msg(foo: String) -> String { String::new() } @@ -63,7 +63,7 @@ declare_clippy_lint! { /// an if let statement /// /// ### Example - /// ```rust + /// ```no_run /// # fn do_stuff() -> Result { Ok(String::new()) } /// # fn log_err_msg(foo: String) -> Result { Ok(foo) } /// # fn format_msg(foo: String) -> String { String::new() } @@ -75,7 +75,7 @@ declare_clippy_lint! { /// /// The correct use would be: /// - /// ```rust + /// ```no_run /// # fn do_stuff() -> Result { Ok(String::new()) } /// # fn log_err_msg(foo: String) -> Result { Ok(foo) } /// # fn format_msg(foo: String) -> String { String::new() } diff --git a/clippy_lints/src/matches/manual_filter.rs b/clippy_lints/src/matches/manual_filter.rs index e0181a4757c0..cdb51c33aaf1 100644 --- a/clippy_lints/src/matches/manual_filter.rs +++ b/clippy_lints/src/matches/manual_filter.rs @@ -99,12 +99,20 @@ pub(super) fn check_match<'tcx>( ) { let ty = cx.typeck_results().expr_ty(expr); if is_type_diagnostic_item(cx, ty, sym::Option) - && let [first_arm, second_arm] = arms - && first_arm.guard.is_none() - && second_arm.guard.is_none() - { - check(cx, expr, scrutinee, first_arm.pat, first_arm.body, Some(second_arm.pat), second_arm.body); - } + && let [first_arm, second_arm] = arms + && first_arm.guard.is_none() + && second_arm.guard.is_none() + { + check( + cx, + expr, + scrutinee, + first_arm.pat, + first_arm.body, + Some(second_arm.pat), + second_arm.body, + ); + } } pub(super) fn check_if_let<'tcx>( diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs index b5ab94b3a2f8..dea46d4d3607 100644 --- a/clippy_lints/src/matches/mod.rs +++ b/clippy_lints/src/matches/mod.rs @@ -24,7 +24,7 @@ mod single_match; mod try_err; mod wild_in_or_pats; -use clippy_utils::msrvs::{self, Msrv}; +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::source::{snippet_opt, walk_span_to_context}; use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, tokenize_with_text}; use rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat}; @@ -48,7 +48,7 @@ declare_clippy_lint! { /// Just readability – `if let` nests less than a `match`. /// /// ### Example - /// ```rust + /// ```no_run /// # fn bar(stool: &str) {} /// # let x = Some("abc"); /// match x { @@ -58,7 +58,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # fn bar(stool: &str) {} /// # let x = Some("abc"); /// if let Some(ref foo) = x { @@ -85,7 +85,7 @@ declare_clippy_lint! { /// ### Example /// Using `match`: /// - /// ```rust + /// ```no_run /// # fn bar(foo: &usize) {} /// # let other_ref: usize = 1; /// # let x: Option<&usize> = Some(&1); @@ -97,7 +97,7 @@ declare_clippy_lint! { /// /// Using `if let` with `else`: /// - /// ```rust + /// ```no_run /// # fn bar(foo: &usize) {} /// # let other_ref: usize = 1; /// # let x: Option<&usize> = Some(&1); @@ -155,7 +155,7 @@ declare_clippy_lint! { /// It makes the code less readable. /// /// ### Example - /// ```rust + /// ```no_run /// # fn foo() {} /// # fn bar() {} /// let condition: bool = true; @@ -165,7 +165,7 @@ declare_clippy_lint! { /// } /// ``` /// Use if/else instead: - /// ```rust + /// ```no_run /// # fn foo() {} /// # fn bar() {} /// let condition: bool = true; @@ -190,7 +190,7 @@ declare_clippy_lint! { /// less obvious. /// /// ### Example - /// ```rust + /// ```no_run /// let x = 5; /// match x { /// 1..=10 => println!("1 ... 10"), @@ -214,7 +214,7 @@ declare_clippy_lint! { /// catching all exceptions in java with `catch(Exception)` /// /// ### Example - /// ```rust + /// ```no_run /// let x: Result = Ok(3); /// match x { /// Ok(_) => println!("ok"), @@ -236,7 +236,7 @@ declare_clippy_lint! { /// Using `as_ref()` or `as_mut()` instead is shorter. /// /// ### Example - /// ```rust + /// ```no_run /// let x: Option<()> = None; /// /// let r: Option<&()> = match x { @@ -246,7 +246,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let x: Option<()> = None; /// /// let r: Option<&()> = x.as_ref(); @@ -269,7 +269,7 @@ declare_clippy_lint! { /// variants, and also may not use correct path to enum if it's not present in the current scope. /// /// ### Example - /// ```rust + /// ```no_run /// # enum Foo { A(usize), B(usize) } /// # let x = Foo::B(1); /// match x { @@ -279,7 +279,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # enum Foo { A(usize), B(usize) } /// # let x = Foo::B(1); /// match x { @@ -305,7 +305,7 @@ declare_clippy_lint! { /// if it's not present in the current scope. /// /// ### Example - /// ```rust + /// ```no_run /// # enum Foo { A, B, C } /// # let x = Foo::B; /// match x { @@ -316,7 +316,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # enum Foo { A, B, C } /// # let x = Foo::B; /// match x { @@ -340,7 +340,7 @@ declare_clippy_lint! { /// It makes the code less readable, especially to spot wildcard pattern use in match arm. /// /// ### Example - /// ```rust + /// ```no_run /// # let s = "foo"; /// match s { /// "a" => {}, @@ -349,7 +349,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let s = "foo"; /// match s { /// "a" => {}, @@ -371,7 +371,7 @@ declare_clippy_lint! { /// Just readability – `let` doesn't nest, whereas a `match` does. /// /// ### Example - /// ```rust + /// ```no_run /// enum Wrapper { /// Data(i32), /// } @@ -384,7 +384,7 @@ declare_clippy_lint! { /// ``` /// /// The correct use would be: - /// ```rust + /// ```no_run /// enum Wrapper { /// Data(i32), /// } @@ -410,7 +410,7 @@ declare_clippy_lint! { /// is actually binding temporary value, bringing a 'dropped while borrowed' error. /// /// ### Example - /// ```rust + /// ```no_run /// # let a = 1; /// # let b = 2; /// match (a, b) { @@ -421,7 +421,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let a = 1; /// # let b = 2; /// let (c, d) = (a, b); @@ -441,7 +441,7 @@ declare_clippy_lint! { /// matching all enum variants explicitly. /// /// ### Example - /// ```rust + /// ```no_run /// # struct A { a: i32 } /// let a = A { a: 5 }; /// @@ -452,7 +452,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # struct A { a: i32 } /// # let a = A { a: 5 }; /// match a { @@ -484,7 +484,7 @@ declare_clippy_lint! { /// drop order. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::task::Poll; /// # use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; /// if let Ok(_) = Ok::(42) {} @@ -503,7 +503,7 @@ declare_clippy_lint! { /// /// The more idiomatic use would be: /// - /// ```rust + /// ```no_run /// # use std::task::Poll; /// # use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; /// if Ok::(42).is_ok() {} @@ -535,7 +535,7 @@ declare_clippy_lint! { /// `cfg` attributes that remove an arm evaluating to `false`. /// /// ### Example - /// ```rust + /// ```no_run /// let x = Some(5); /// /// let a = match x { @@ -551,7 +551,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let x = Some(5); /// let a = matches!(x, Some(0)); /// ``` @@ -664,7 +664,7 @@ declare_clippy_lint! { /// It is unnecessarily verbose and complex. /// /// ### Example - /// ```rust + /// ```no_run /// fn func(opt: Option>) { /// let n = match opt { /// Some(n) => match n { @@ -676,7 +676,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn func(opt: Option>) { /// let n = match opt { /// Some(Ok(n)) => n, @@ -698,7 +698,7 @@ declare_clippy_lint! { /// Concise code helps focusing on behavior instead of boilerplate. /// /// ### Example - /// ```rust + /// ```no_run /// let foo: Option = None; /// match foo { /// Some(v) => v, @@ -707,7 +707,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let foo: Option = None; /// foo.unwrap_or(1); /// ``` @@ -761,7 +761,7 @@ declare_clippy_lint! { /// The arm is unreachable, which is likely a mistake /// /// ### Example - /// ```rust + /// ```no_run /// # let text = "Foo"; /// match &*text.to_ascii_lowercase() { /// "foo" => {}, @@ -770,7 +770,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let text = "Foo"; /// match &*text.to_ascii_lowercase() { /// "foo" => {}, @@ -823,7 +823,7 @@ declare_clippy_lint! { /// println!("All done!"); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::sync::Mutex; /// # struct State {} /// # impl State { @@ -861,7 +861,7 @@ declare_clippy_lint! { /// always return), it is more clear to write `return Err(x)`. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo(fail: bool) -> Result { /// if fail { /// Err("failed")?; @@ -871,7 +871,7 @@ declare_clippy_lint! { /// ``` /// Could be written: /// - /// ```rust + /// ```no_run /// fn foo(fail: bool) -> Result { /// if fail { /// return Err("failed".into()); @@ -893,14 +893,14 @@ declare_clippy_lint! { /// Using the `map` method is clearer and more concise. /// /// ### Example - /// ```rust + /// ```no_run /// match Some(0) { /// Some(x) => Some(x + 1), /// None => None, /// }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// Some(0).map(|x| x + 1); /// ``` #[clippy::version = "1.52.0"] @@ -917,7 +917,7 @@ declare_clippy_lint! { /// Using the `filter` method is clearer and more concise. /// /// ### Example - /// ```rust + /// ```no_run /// match Some(0) { /// Some(x) => if x % 2 == 0 { /// Some(x) @@ -928,7 +928,7 @@ declare_clippy_lint! { /// }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// Some(0).filter(|&x| x % 2 == 0); /// ``` #[clippy::version = "1.66.0"] diff --git a/clippy_lints/src/matches/redundant_guards.rs b/clippy_lints/src/matches/redundant_guards.rs index 0efeeacc9d97..4a44d596a46d 100644 --- a/clippy_lints/src/matches/redundant_guards.rs +++ b/clippy_lints/src/matches/redundant_guards.rs @@ -27,8 +27,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) { arm, Arm { pat: Pat { - kind: PatKind::Wild, - .. + kind: PatKind::Wild, .. }, .. }, @@ -42,14 +41,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) { (PatKind::Ref(..), None) | (_, Some(_)) => continue, _ => arm.pat.span, }; - emit_redundant_guards( - cx, - outer_arm, - if_expr.span, - pat_span, - &binding, - arm.guard, - ); + emit_redundant_guards(cx, outer_arm, if_expr.span, pat_span, &binding, arm.guard); } // `Some(x) if let Some(2) = x` else if let Guard::IfLet(let_expr) = guard @@ -60,14 +52,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) { (PatKind::Ref(..), None) | (_, Some(_)) => continue, _ => let_expr.pat.span, }; - emit_redundant_guards( - cx, - outer_arm, - let_expr.span, - pat_span, - &binding, - None, - ); + emit_redundant_guards(cx, outer_arm, let_expr.span, pat_span, &binding, None); } // `Some(x) if x == Some(2)` // `Some(x) if Some(2) == x` @@ -93,14 +78,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) { (ExprKind::AddrOf(..), None) | (_, Some(_)) => continue, _ => pat.span, }; - emit_redundant_guards( - cx, - outer_arm, - if_expr.span, - pat_span, - &binding, - None, - ); + emit_redundant_guards(cx, outer_arm, if_expr.span, pat_span, &binding, None); } } } @@ -116,7 +94,9 @@ fn get_pat_binding<'tcx>( guard_expr: &Expr<'_>, outer_arm: &Arm<'tcx>, ) -> Option { - if let Some(local) = path_to_local(guard_expr) && !is_local_used(cx, outer_arm.body, local) { + if let Some(local) = path_to_local(guard_expr) + && !is_local_used(cx, outer_arm.body, local) + { let mut span = None; let mut byref_ident = None; let mut multiple_bindings = false; @@ -223,10 +203,7 @@ fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Ctor(..), ..), ) }, - ExprKind::AddrOf(..) - | ExprKind::Array(..) - | ExprKind::Tup(..) - | ExprKind::Struct(..) => true, + ExprKind::AddrOf(..) | ExprKind::Array(..) | ExprKind::Tup(..) | ExprKind::Struct(..) => true, ExprKind::Lit(lit) if !matches!(lit.node, LitKind::Float(..)) => true, _ => false, } { diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs index 6b05c6bfffdc..48efd0230175 100644 --- a/clippy_lints/src/matches/single_match.rs +++ b/clippy_lints/src/matches/single_match.rs @@ -20,8 +20,7 @@ fn empty_arm_has_comment(cx: &LateContext<'_>, span: Span) -> bool { if let Some(ff) = get_source_text(cx, span) && let Some(text) = ff.as_str() { - text.as_bytes().windows(2) - .any(|w| w == b"//" || w == b"/*") + text.as_bytes().windows(2).any(|w| w == b"//" || w == b"/*") } else { false } @@ -51,7 +50,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: // block with 2+ statements or 1 expr and 1+ statement Some(els) } else { - // not a block or an emtpy block w/ comments, don't lint + // not a block or an empty block w/ comments, don't lint return; }; diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index 8a921d4af165..c6a1b45a9faf 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; 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::source::{snippet, snippet_with_applicability}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::is_non_aggregate_primitive_type; @@ -25,14 +25,14 @@ declare_clippy_lint! { /// `None`. /// /// ### Example - /// ```rust + /// ```no_run /// use std::mem; /// /// let mut an_option = Some(0); /// let replaced = mem::replace(&mut an_option, None); /// ``` /// Is better expressed with: - /// ```rust + /// ```no_run /// let mut an_option = Some(0); /// let taken = an_option.take(); /// ``` @@ -53,7 +53,7 @@ declare_clippy_lint! { /// observed in the case of a panic. /// /// ### Example - /// ``` + /// ```no_run /// use std::mem; ///# fn may_panic(v: Vec) -> Vec { v } /// @@ -84,12 +84,12 @@ declare_clippy_lint! { /// take the current value and replace it with the default value of that type. /// /// ### Example - /// ```rust + /// ```no_run /// let mut text = String::from("foo"); /// let replaced = std::mem::replace(&mut text, String::default()); /// ``` /// Is better expressed with: - /// ```rust + /// ```no_run /// let mut text = String::from("foo"); /// let taken = std::mem::take(&mut text); /// ``` diff --git a/clippy_lints/src/methods/bytes_nth.rs b/clippy_lints/src/methods/bytes_nth.rs index c5fc145b2890..baafb7030aa1 100644 --- a/clippy_lints/src/methods/bytes_nth.rs +++ b/clippy_lints/src/methods/bytes_nth.rs @@ -24,8 +24,9 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E let n = snippet_with_applicability(cx, n_arg.span, "..", &mut applicability); if let Some(parent) = clippy_utils::get_parent_expr(cx, expr) - && let Some((name, _, _, _, _)) = method_call(parent) - && name == "unwrap" { + && let Some((name, _, _, _, _)) = method_call(parent) + && name == "unwrap" + { span_lint_and_sugg( cx, BYTES_NTH, @@ -33,7 +34,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E &format!("called `.bytes().nth().unwrap()` on a `{caller_type}`"), "try", format!("{receiver}.as_bytes()[{n}]",), - applicability + applicability, ); } else { span_lint_and_sugg( @@ -42,8 +43,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E expr.span, &format!("called `.bytes().nth()` on a `{caller_type}`"), "try", - format!("{receiver}.as_bytes().get({n}).copied()"), - applicability + format!("{receiver}.as_bytes().get({n}).copied()"), + applicability, ); }; } diff --git a/clippy_lints/src/methods/cloned_instead_of_copied.rs b/clippy_lints/src/methods/cloned_instead_of_copied.rs index 4e6ec61f6a83..fcafa1622365 100644 --- a/clippy_lints/src/methods/cloned_instead_of_copied.rs +++ b/clippy_lints/src/methods/cloned_instead_of_copied.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::is_trait_method; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::{get_iterator_item_ty, is_copy}; use rustc_errors::Applicability; use rustc_hir::Expr; diff --git a/clippy_lints/src/methods/err_expect.rs b/clippy_lints/src/methods/err_expect.rs index 3d82441c0e6a..a8d4dd5e4f31 100644 --- a/clippy_lints/src/methods/err_expect.rs +++ b/clippy_lints/src/methods/err_expect.rs @@ -1,6 +1,6 @@ use super::ERR_EXPECT; +use clippy_config::msrvs::{self, Msrv}; 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 rustc_errors::Applicability; use rustc_lint::LateContext; diff --git a/clippy_lints/src/methods/filter_map.rs b/clippy_lints/src/methods/filter_map.rs index c9eaa185acce..22b67923e508 100644 --- a/clippy_lints/src/methods/filter_map.rs +++ b/clippy_lints/src/methods/filter_map.rs @@ -159,7 +159,7 @@ impl<'tcx> OffendingFilterExpr<'tcx> { OffendingFilterExpr::IsSome { .. } => CalledMethod::OptionIsSome, OffendingFilterExpr::IsOk { .. } => CalledMethod::ResultIsOk, OffendingFilterExpr::Matches { .. } => unreachable!("only IsSome and IsOk can get here"), - } + }, }) } else { None @@ -189,7 +189,8 @@ impl<'tcx> OffendingFilterExpr<'tcx> { // scrutinee variant_span variant_ident else_ let (scrutinee, else_, variant_ident, variant_span) = match higher::IfLetOrMatch::parse(cx, map_body.value) { - // For `if let` we want to check that the variant matching arm references the local created by its pattern + // For `if let` we want to check that the variant matching arm references the local created by + // its pattern Some(higher::IfLetOrMatch::IfLet(sc, pat, then, Some(else_))) if let Some((ident, span)) = expr_uses_local(pat, then) => { @@ -211,7 +212,10 @@ impl<'tcx> OffendingFilterExpr<'tcx> { && let Some(mac) = root_macro_call(else_.peel_blocks().span) && (is_panic(cx, mac.def_id) || cx.tcx.opt_item_name(mac.def_id) == Some(sym::unreachable)) { - Some(CheckResult::PatternMatching { variant_span, variant_ident }) + Some(CheckResult::PatternMatching { + variant_span, + variant_ident, + }) } else { None } @@ -228,18 +232,20 @@ impl<'tcx> OffendingFilterExpr<'tcx> { // .filter(|x| effect(x).is_some()).map(|x| effect(x).unwrap()) // vs. // .filter_map(|x| effect(x)) - // + // // the latter only calls `effect` once let side_effect_expr_span = receiver.can_have_side_effects().then_some(receiver.span); - if cx.tcx.is_diagnostic_item(sym::Option, recv_ty.did()) - && path.ident.name == sym!(is_some) - { - Some(Self::IsSome { receiver, side_effect_expr_span }) - } else if cx.tcx.is_diagnostic_item(sym::Result, recv_ty.did()) - && path.ident.name == sym!(is_ok) - { - Some(Self::IsOk { receiver, side_effect_expr_span }) + if cx.tcx.is_diagnostic_item(sym::Option, recv_ty.did()) && path.ident.name == sym!(is_some) { + Some(Self::IsSome { + receiver, + side_effect_expr_span, + }) + } else if cx.tcx.is_diagnostic_item(sym::Result, recv_ty.did()) && path.ident.name == sym!(is_ok) { + Some(Self::IsOk { + receiver, + side_effect_expr_span, + }) } else { None } diff --git a/clippy_lints/src/methods/filter_map_bool_then.rs b/clippy_lints/src/methods/filter_map_bool_then.rs index 33657254965c..9950c4428551 100644 --- a/clippy_lints/src/methods/filter_map_bool_then.rs +++ b/clippy_lints/src/methods/filter_map_bool_then.rs @@ -54,7 +54,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: & "use `filter` then `map` instead", format!( "filter(|&{param_snippet}| {derefs}{filter}).map(|{param_snippet}| {map})", - derefs="*".repeat(needed_derefs) + derefs = "*".repeat(needed_derefs) ), Applicability::MachineApplicable, ); diff --git a/clippy_lints/src/methods/filter_map_next.rs b/clippy_lints/src/methods/filter_map_next.rs index 3f89e5931487..f94fe221833d 100644 --- a/clippy_lints/src/methods/filter_map_next.rs +++ b/clippy_lints/src/methods/filter_map_next.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; use clippy_utils::is_trait_method; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use rustc_errors::Applicability; use rustc_hir as hir; diff --git a/clippy_lints/src/methods/format_collect.rs b/clippy_lints/src/methods/format_collect.rs index 1f8863f85218..3e5162ef4580 100644 --- a/clippy_lints/src/methods/format_collect.rs +++ b/clippy_lints/src/methods/format_collect.rs @@ -24,10 +24,16 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, map_arg: &Expr<'_>, m && let Some(mac) = root_macro_call_first_node(cx, value) && is_format_macro(cx, mac.def_id) { - span_lint_and_then(cx, FORMAT_COLLECT, expr.span, "use of `format!` to build up a string from an iterator", |diag| { - diag.span_help(map_span, "call `fold` instead") - .span_help(value.span.source_callsite(), "... and use the `write!` macro here") - .note("this can be written more efficiently by appending to a `String` directly"); - }); + span_lint_and_then( + cx, + FORMAT_COLLECT, + expr.span, + "use of `format!` to build up a string from an iterator", + |diag| { + diag.span_help(map_span, "call `fold` instead") + .span_help(value.span.source_callsite(), "... and use the `write!` macro here") + .note("this can be written more efficiently by appending to a `String` directly"); + }, + ); } } diff --git a/clippy_lints/src/methods/get_first.rs b/clippy_lints/src/methods/get_first.rs index e7b4564c651e..2e1dd3ec649b 100644 --- a/clippy_lints/src/methods/get_first.rs +++ b/clippy_lints/src/methods/get_first.rs @@ -1,11 +1,13 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; +use clippy_utils::ty::is_type_diagnostic_item; use if_chain::if_chain; use rustc_ast::LitKind; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; use rustc_span::source_map::Spanned; +use rustc_span::sym; use super::GET_FIRST; @@ -18,20 +20,34 @@ pub(super) fn check<'tcx>( if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if cx.tcx.type_of(impl_id).instantiate_identity().is_slice(); + let identity = cx.tcx.type_of(impl_id).instantiate_identity(); if let hir::ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = arg.kind; then { - let mut app = Applicability::MachineApplicable; - let slice_name = snippet_with_applicability(cx, recv.span, "..", &mut app); - span_lint_and_sugg( - cx, - GET_FIRST, - expr.span, - &format!("accessing first element with `{slice_name}.get(0)`"), - "try", - format!("{slice_name}.first()"), - app, - ); + if identity.is_slice() { + let mut app = Applicability::MachineApplicable; + let slice_name = snippet_with_applicability(cx, recv.span, "..", &mut app); + span_lint_and_sugg( + cx, + GET_FIRST, + expr.span, + &format!("accessing first element with `{slice_name}.get(0)`"), + "try", + format!("{slice_name}.first()"), + app, + ); + } else if is_type_diagnostic_item(cx, identity, sym::VecDeque){ + let mut app = Applicability::MachineApplicable; + let slice_name = snippet_with_applicability(cx, recv.span, "..", &mut app); + span_lint_and_sugg( + cx, + GET_FIRST, + expr.span, + &format!("accessing first element with `{slice_name}.get(0)`"), + "try", + format!("{slice_name}.front()"), + app, + ); + } } } } diff --git a/clippy_lints/src/methods/get_unwrap.rs b/clippy_lints/src/methods/get_unwrap.rs index a8f090d1de17..afdcb3b65492 100644 --- a/clippy_lints/src/methods/get_unwrap.rs +++ b/clippy_lints/src/methods/get_unwrap.rs @@ -43,9 +43,9 @@ pub(super) fn check<'tcx>( // by not requiring an explicit reference let needs_ref = if let Some(parent) = get_parent_expr(cx, expr) && let hir::ExprKind::Unary(hir::UnOp::Deref, _) - | hir::ExprKind::MethodCall(..) - | hir::ExprKind::Field(..) - | hir::ExprKind::Index(..) = parent.kind + | hir::ExprKind::MethodCall(..) + | hir::ExprKind::Field(..) + | hir::ExprKind::Index(..) = parent.kind { if let hir::ExprKind::Unary(hir::UnOp::Deref, _) = parent.kind { // if the user explicitly dereferences the result, we can adjust diff --git a/clippy_lints/src/methods/is_digit_ascii_radix.rs b/clippy_lints/src/methods/is_digit_ascii_radix.rs index 120f3d5f42c7..e963950960ae 100644 --- a/clippy_lints/src/methods/is_digit_ascii_radix.rs +++ b/clippy_lints/src/methods/is_digit_ascii_radix.rs @@ -1,9 +1,9 @@ //! Lint for `c.is_digit(10)` use super::IS_DIGIT_ASCII_RADIX; +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{constant_full_int, FullInt}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use rustc_errors::Applicability; use rustc_hir::Expr; diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs index b44a2716dde1..625325d4cf5d 100644 --- a/clippy_lints/src/methods/iter_kv_map.rs +++ b/clippy_lints/src/methods/iter_kv_map.rs @@ -3,9 +3,8 @@ use super::ITER_KV_MAP; use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_sugg, span_lint_and_then}; use clippy_utils::source::{snippet, snippet_with_applicability}; -use clippy_utils::sugg; use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::visitors::is_local_used; +use clippy_utils::{pat_is_wild, sugg}; use rustc_hir::{BindingAnnotation, Body, BorrowKind, ByRef, Expr, ExprKind, Mutability, Pat, PatKind}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty; @@ -84,13 +83,3 @@ pub(super) fn check<'tcx>( } } } - -/// Returns `true` if the pattern is a `PatWild`, or is an ident prefixed with `_` -/// that is not locally used. -fn pat_is_wild<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx PatKind<'_>, body: &'tcx Expr<'_>) -> bool { - match *pat { - PatKind::Wild => true, - PatKind::Binding(_, id, ident, None) if ident.as_str().starts_with('_') => !is_local_used(cx, body, id), - _ => false, - } -} diff --git a/clippy_lints/src/methods/iter_out_of_bounds.rs b/clippy_lints/src/methods/iter_out_of_bounds.rs index 99ea7f03df4e..29e69b111de6 100644 --- a/clippy_lints/src/methods/iter_out_of_bounds.rs +++ b/clippy_lints/src/methods/iter_out_of_bounds.rs @@ -51,7 +51,7 @@ fn get_iterator_length<'tcx>(cx: &LateContext<'tcx>, iter: &'tcx Expr<'tcx>) -> Some(0) } else if cx.tcx.is_diagnostic_item(sym::IterOnce, did) { Some(1) - } else { + } else { None } } diff --git a/clippy_lints/src/methods/iter_overeager_cloned.rs b/clippy_lints/src/methods/iter_overeager_cloned.rs index a49dd98db871..eac6df0545ff 100644 --- a/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -60,9 +60,15 @@ pub(super) fn check<'tcx>( } if let Op::NeedlessMove(_, expr) = op { - let rustc_hir::ExprKind::Closure(closure) = expr.kind else { return } ; - let body @ Body { params: [p], .. } = cx.tcx.hir().body(closure.body) else { return }; - let mut delegate = MoveDelegate {used_move : HirIdSet::default()}; + let rustc_hir::ExprKind::Closure(closure) = expr.kind else { + return; + }; + let body @ Body { params: [p], .. } = cx.tcx.hir().body(closure.body) else { + return; + }; + let mut delegate = MoveDelegate { + used_move: HirIdSet::default(), + }; let infcx = cx.tcx.infer_ctxt().build(); ExprUseVisitor::new( @@ -77,7 +83,7 @@ pub(super) fn check<'tcx>( let mut to_be_discarded = false; p.pat.walk(|it| { - if delegate.used_move.contains(&it.hir_id){ + if delegate.used_move.contains(&it.hir_id) { to_be_discarded = true; return false; } @@ -87,8 +93,8 @@ pub(super) fn check<'tcx>( | PatKind::Ref(_, Mutability::Mut) => { to_be_discarded = true; false - } - _ => { true } + }, + _ => true, } }); @@ -99,46 +105,42 @@ pub(super) fn check<'tcx>( let (lint, msg, trailing_clone) = match op { Op::RmCloned | Op::NeedlessMove(_, _) => (REDUNDANT_CLONE, "unneeded cloning of iterator items", ""), - Op::LaterCloned | Op::FixClosure(_, _) => (ITER_OVEREAGER_CLONED, "unnecessarily eager cloning of iterator items", ".cloned()"), + Op::LaterCloned | Op::FixClosure(_, _) => ( + ITER_OVEREAGER_CLONED, + "unnecessarily eager cloning of iterator items", + ".cloned()", + ), }; - span_lint_and_then( - cx, - lint, - expr.span, - msg, - |diag| { - match op { - Op::RmCloned | Op::LaterCloned => { - let method_span = expr.span.with_lo(cloned_call.span.hi()); - if let Some(mut snip) = snippet_opt(cx, method_span) { - snip.push_str(trailing_clone); - let replace_span = expr.span.with_lo(cloned_recv.span.hi()); - diag.span_suggestion(replace_span, "try", snip, Applicability::MachineApplicable); - } - } - Op::FixClosure(name, predicate_expr) => { - if let Some(predicate) = snippet_opt(cx, predicate_expr.span) { - let new_closure = if let ExprKind::Closure(_) = predicate_expr.kind { - predicate.replacen('|', "|&", 1) - } else { - format!("|&x| {predicate}(x)") - }; - let snip = format!(".{name}({new_closure}).cloned()" ); - let replace_span = expr.span.with_lo(cloned_recv.span.hi()); - diag.span_suggestion(replace_span, "try", snip, Applicability::MachineApplicable); - } - } - Op::NeedlessMove(_, _) => { - let method_span = expr.span.with_lo(cloned_call.span.hi()); - if let Some(snip) = snippet_opt(cx, method_span) { - let replace_span = expr.span.with_lo(cloned_recv.span.hi()); - diag.span_suggestion(replace_span, "try", snip, Applicability::MaybeIncorrect); - } - } + span_lint_and_then(cx, lint, expr.span, msg, |diag| match op { + Op::RmCloned | Op::LaterCloned => { + let method_span = expr.span.with_lo(cloned_call.span.hi()); + if let Some(mut snip) = snippet_opt(cx, method_span) { + snip.push_str(trailing_clone); + let replace_span = expr.span.with_lo(cloned_recv.span.hi()); + diag.span_suggestion(replace_span, "try", snip, Applicability::MachineApplicable); } - } - ); + }, + Op::FixClosure(name, predicate_expr) => { + if let Some(predicate) = snippet_opt(cx, predicate_expr.span) { + let new_closure = if let ExprKind::Closure(_) = predicate_expr.kind { + predicate.replacen('|', "|&", 1) + } else { + format!("|&x| {predicate}(x)") + }; + let snip = format!(".{name}({new_closure}).cloned()"); + let replace_span = expr.span.with_lo(cloned_recv.span.hi()); + diag.span_suggestion(replace_span, "try", snip, Applicability::MachineApplicable); + } + }, + Op::NeedlessMove(_, _) => { + let method_span = expr.span.with_lo(cloned_call.span.hi()); + if let Some(snip) = snippet_opt(cx, method_span) { + let replace_span = expr.span.with_lo(cloned_recv.span.hi()); + diag.span_suggestion(replace_span, "try", snip, Applicability::MaybeIncorrect); + } + }, + }); } } diff --git a/clippy_lints/src/methods/manual_try_fold.rs b/clippy_lints/src/methods/manual_try_fold.rs index dabed0affcf4..51145afda7f4 100644 --- a/clippy_lints/src/methods/manual_try_fold.rs +++ b/clippy_lints/src/methods/manual_try_fold.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::is_from_proc_macro; -use clippy_utils::msrvs::{Msrv, ITERATOR_TRY_FOLD}; use clippy_utils::source::snippet_opt; use clippy_utils::ty::implements_trait; use rustc_errors::Applicability; @@ -21,7 +21,7 @@ pub(super) fn check<'tcx>( msrv: &Msrv, ) { if !in_external_macro(cx.sess(), fold_span) - && msrv.meets(ITERATOR_TRY_FOLD) + && msrv.meets(msrvs::ITERATOR_TRY_FOLD) && let init_ty = cx.typeck_results().expr_ty(init) && let Some(try_trait) = cx.tcx.lang_items().try_trait() && implements_trait(cx, init_ty, try_trait, &[]) @@ -44,7 +44,7 @@ pub(super) fn check<'tcx>( fold_span, "usage of `Iterator::fold` on a type that implements `Try`", "use `try_fold` instead", - format!("try_fold({init_snip}, {args_snip} ...)", ), + format!("try_fold({init_snip}, {args_snip} ...)",), Applicability::HasPlaceholders, ); } diff --git a/clippy_lints/src/methods/map_clone.rs b/clippy_lints/src/methods/map_clone.rs index 880efe60c1a3..e0f8cb1b955f 100644 --- a/clippy_lints/src/methods/map_clone.rs +++ b/clippy_lints/src/methods/map_clone.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::{is_copy, is_type_diagnostic_item}; use clippy_utils::{is_diag_trait_item, peel_blocks}; diff --git a/clippy_lints/src/methods/map_unwrap_or.rs b/clippy_lints/src/methods/map_unwrap_or.rs index e70a1bc98799..cb81b3919bfd 100644 --- a/clippy_lints/src/methods/map_unwrap_or.rs +++ b/clippy_lints/src/methods/map_unwrap_or.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::usage::mutated_variables; diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index a935aea5075d..a71a136eba57 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -99,6 +99,7 @@ mod suspicious_to_owned; mod type_id_on_box; mod uninit_assumed_init; mod unit_hash; +mod unnecessary_fallible_conversions; mod unnecessary_filter_map; mod unnecessary_fold; mod unnecessary_iter_cloned; @@ -112,13 +113,14 @@ mod useless_asref; mod utils; mod vec_resize_to_zero; mod verbose_file_reads; +mod waker_clone_wake; mod wrong_self_convention; mod zst_offset; use bind_instead_of_map::BindInsteadOfMap; +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item}; use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty}; use if_chain::if_chain; @@ -142,11 +144,11 @@ declare_clippy_lint! { /// implements `Copy`. /// /// ### Example - /// ```rust + /// ```no_run /// [1, 2, 3].iter().cloned(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// [1, 2, 3].iter().copied(); /// ``` #[clippy::version = "1.53.0"] @@ -165,14 +167,14 @@ declare_clippy_lint! { /// with repetitive code. /// /// ### Example - /// ```rust + /// ```no_run /// let hello = "hesuo worpd" /// .replace('s', "l") /// .replace("u", "l") /// .replace('p', "l"); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let hello = "hesuo worpd".replace(['s', 'u', 'p'], "l"); /// ``` #[clippy::version = "1.65.0"] @@ -194,14 +196,14 @@ declare_clippy_lint! { /// A code that relies on that side-effect could fail. /// /// ### Examples - /// ```rust + /// ```no_run /// # let vec = vec!["string".to_string()]; /// vec.iter().cloned().take(10); /// vec.iter().cloned().last(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let vec = vec!["string".to_string()]; /// vec.iter().take(10).cloned(); /// vec.iter().last().cloned(); @@ -222,11 +224,11 @@ declare_clippy_lint! { /// `Option` is used to produce 0 or 1 items. /// /// ### Example - /// ```rust + /// ```no_run /// let nums: Vec = ["1", "2", "whee!"].iter().flat_map(|x| x.parse().ok()).collect(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let nums: Vec = ["1", "2", "whee!"].iter().filter_map(|x| x.parse().ok()).collect(); /// ``` #[clippy::version = "1.53.0"] @@ -254,7 +256,7 @@ declare_clippy_lint! { /// where they may get displayed. Activate this lint to do just that. /// /// ### Examples - /// ```rust + /// ```no_run /// # let option = Some(1); /// # let result: Result = Ok(1); /// option.unwrap(); @@ -262,7 +264,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let option = Some(1); /// # let result: Result = Ok(1); /// option.expect("more helpful message"); @@ -293,14 +295,14 @@ declare_clippy_lint! { /// It is better to write the value directly without the indirection. /// /// ### Examples - /// ```rust + /// ```no_run /// let val1 = Some(1).unwrap(); /// let val2 = Ok::<_, ()>(1).unwrap(); /// let val3 = Err::<(), _>(1).unwrap_err(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let val1 = 1; /// let val2 = 1; /// let val3 = 1; @@ -363,7 +365,7 @@ declare_clippy_lint! { /// them. /// /// ### Example - /// ```rust + /// ```no_run /// struct X; /// impl X { /// fn add(&self, other: &X) -> X { @@ -412,7 +414,7 @@ declare_clippy_lint! { /// mutable reference to a `as_..` function. /// /// ### Example - /// ```rust + /// ```no_run /// # struct X; /// impl X { /// fn as_str(self) -> &'static str { @@ -439,13 +441,13 @@ declare_clippy_lint! { /// The error type needs to implement `Debug` /// /// ### Example - /// ```rust + /// ```no_run /// # let x = Ok::<_, ()>(()); /// x.ok().expect("why did I do this again?"); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let x = Ok::<_, ()>(()); /// x.expect("why did I do this again?"); /// ``` @@ -496,7 +498,7 @@ declare_clippy_lint! { /// heuristic to try to identify such cases. However, the heuristic can produce false negatives. /// /// ### Examples - /// ```rust + /// ```no_run /// # let x = Some(1); /// # let mut map = std::collections::HashMap::::new(); /// x.unwrap_or(Default::default()); @@ -504,7 +506,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let x = Some(1); /// # let mut map = std::collections::HashMap::::new(); /// x.unwrap_or_default(); @@ -529,7 +531,7 @@ declare_clippy_lint! { /// The order of the arguments is not in execution order /// /// ### Examples - /// ```rust + /// ```no_run /// # let option = Some(1); /// # let result: Result = Ok(1); /// # fn some_function(foo: ()) -> usize { 1 } @@ -539,7 +541,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let option = Some(1); /// # let result: Result = Ok(1); /// # fn some_function(foo: ()) -> usize { 1 } @@ -565,13 +567,13 @@ declare_clippy_lint! { /// The order of the arguments is not in execution order. /// /// ### Example - /// ```rust + /// ```no_run /// # let opt = Some(1); /// opt.map_or(None, |a| Some(a + 1)); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let opt = Some(1); /// opt.and_then(|a| Some(a + 1)); /// ``` @@ -590,13 +592,13 @@ declare_clippy_lint! { /// `_.ok()`. /// /// ### Example - /// ```rust + /// ```no_run /// # let r: Result = Ok(1); /// assert_eq!(Some(1), r.map_or(None, Some)); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let r: Result = Ok(1); /// assert_eq!(Some(1), r.ok()); /// ``` @@ -616,7 +618,7 @@ declare_clippy_lint! { /// `_.map(|x| y)` or `_.map_err(|x| y)`. /// /// ### Example - /// ```rust + /// ```no_run /// # fn opt() -> Option<&'static str> { Some("42") } /// # fn res() -> Result<&'static str, &'static str> { Ok("42") } /// let _ = opt().and_then(|s| Some(s.len())); @@ -626,7 +628,7 @@ declare_clippy_lint! { /// /// The correct use would be: /// - /// ```rust + /// ```no_run /// # fn opt() -> Option<&'static str> { Some("42") } /// # fn res() -> Result<&'static str, &'static str> { Ok("42") } /// let _ = opt().map(|s| s.len()); @@ -648,13 +650,13 @@ declare_clippy_lint! { /// `_.find(_)`. /// /// ### Example - /// ```rust + /// ```no_run /// # let vec = vec![1]; /// vec.iter().filter(|x| **x == 0).next(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let vec = vec![1]; /// vec.iter().find(|x| **x == 0); /// ``` @@ -673,13 +675,13 @@ declare_clippy_lint! { /// `_.find(!condition)`. /// /// ### Example - /// ```rust + /// ```no_run /// # let vec = vec![1]; /// vec.iter().skip_while(|x| **x == 0).next(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let vec = vec![1]; /// vec.iter().find(|x| **x != 0); /// ``` @@ -698,7 +700,7 @@ declare_clippy_lint! { /// `_.flat_map(_)` for `Iterator` or `_.and_then(_)` for `Option` /// /// ### Example - /// ```rust + /// ```no_run /// let vec = vec![vec![1]]; /// let opt = Some(5); /// @@ -707,7 +709,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let vec = vec![vec![1]]; /// # let opt = Some(5); /// vec.iter().flat_map(|x| x.iter()); @@ -729,7 +731,7 @@ declare_clippy_lint! { /// less performant. /// /// ### Example - /// ```rust + /// ```no_run /// # #![allow(unused)] /// (0_i32..10) /// .filter(|n| n.checked_add(1).is_some()) @@ -737,7 +739,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # #[allow(unused)] /// (0_i32..10).filter_map(|n| n.checked_add(1)); /// ``` @@ -757,14 +759,14 @@ declare_clippy_lint! { /// less performant. /// /// ### Example - /// ```rust + /// ```no_run /// (0_i32..10) /// .find(|n| n.checked_add(1).is_some()) /// .map(|n| n.checked_add(1).unwrap()); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// (0_i32..10).find_map(|n| n.checked_add(1)); /// ``` #[clippy::version = "1.51.0"] @@ -782,12 +784,12 @@ declare_clippy_lint! { /// `_.find_map(_)`. /// /// ### Example - /// ```rust + /// ```no_run /// (0..3).filter_map(|x| if x == 2 { Some(x) } else { None }).next(); /// ``` /// Can be written as /// - /// ```rust + /// ```no_run /// (0..3).find_map(|x| if x == 2 { Some(x) } else { None }); /// ``` #[clippy::version = "1.36.0"] @@ -804,12 +806,12 @@ declare_clippy_lint! { /// Readability, this can be written more concisely by using `flatten`. /// /// ### Example - /// ```rust + /// ```no_run /// # let iter = vec![vec![0]].into_iter(); /// iter.flat_map(|x| x); /// ``` /// Can be written as - /// ```rust + /// ```no_run /// # let iter = vec![vec![0]].into_iter(); /// iter.flatten(); /// ``` @@ -830,7 +832,7 @@ declare_clippy_lint! { /// * `!_.any(_)`, or `!_.contains(_)` for `is_none()`. /// /// ### Example - /// ```rust + /// ```no_run /// # #![allow(unused)] /// let vec = vec![1]; /// vec.iter().find(|x| **x == 0).is_some(); @@ -839,7 +841,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let vec = vec![1]; /// vec.iter().any(|x| *x == 0); /// @@ -862,13 +864,13 @@ declare_clippy_lint! { /// `_.starts_with(_)`. /// /// ### Example - /// ```rust + /// ```no_run /// let name = "foo"; /// if name.chars().next() == Some('_') {}; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let name = "foo"; /// if name.starts_with('_') {}; /// ``` @@ -897,13 +899,13 @@ declare_clippy_lint! { /// actually expensive to call or not. /// /// ### Example - /// ```rust + /// ```no_run /// # let foo = Some(String::new()); /// foo.unwrap_or(String::from("empty")); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let foo = Some(String::new()); /// foo.unwrap_or_else(|| String::from("empty")); /// ``` @@ -921,7 +923,7 @@ declare_clippy_lint! { /// You should use `.unwrap_or(…)` instead for clarity. /// /// ### Example - /// ```rust + /// ```no_run /// # let fallback = "fallback"; /// // Result /// # type Error = &'static str; @@ -933,7 +935,7 @@ declare_clippy_lint! { /// let value = option.or(Some(fallback)).unwrap(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let fallback = "fallback"; /// // Result /// # let result: Result<&str, &str> = Err("error"); @@ -962,7 +964,7 @@ declare_clippy_lint! { /// change the semantics of the program, but you shouldn't rely on that anyway. /// /// ### Example - /// ```rust + /// ```no_run /// # let foo = Some(String::new()); /// # let err_code = "418"; /// # let err_msg = "I'm a teapot"; @@ -975,7 +977,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let foo = Some(String::new()); /// # let err_code = "418"; /// # let err_msg = "I'm a teapot"; @@ -996,7 +998,7 @@ declare_clippy_lint! { /// generics, not for using the `clone` method on a concrete type. /// /// ### Example - /// ```rust + /// ```no_run /// 42u64.clone(); /// ``` #[clippy::version = "pre 1.29.0"] @@ -1017,7 +1019,7 @@ declare_clippy_lint! { /// data. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::rc::Rc; /// let x = Rc::new(1); /// @@ -1025,7 +1027,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # use std::rc::Rc; /// # let x = Rc::new(1); /// Rc::clone(&x); @@ -1047,7 +1049,7 @@ declare_clippy_lint! { /// facilities. /// /// ### Example - /// ```rust + /// ```no_run /// // Generic implementation for `T: Display` is used (slow) /// ["foo", "bar"].iter().map(|s| s.to_string()); /// @@ -1070,7 +1072,7 @@ declare_clippy_lint! { /// /// ### Example /// In an impl block: - /// ```rust + /// ```no_run /// # struct Foo; /// # struct NotAFoo; /// impl Foo { @@ -1080,7 +1082,7 @@ declare_clippy_lint! { /// } /// ``` /// - /// ```rust + /// ```no_run /// # struct Foo; /// struct Bar(Foo); /// impl Foo { @@ -1091,7 +1093,7 @@ declare_clippy_lint! { /// } /// ``` /// - /// ```rust + /// ```no_run /// # struct Foo; /// # struct FooError; /// impl Foo { @@ -1103,14 +1105,14 @@ declare_clippy_lint! { /// ``` /// /// Or in a trait definition: - /// ```rust + /// ```no_run /// pub trait Trait { /// // Bad. The type name must contain `Self` /// fn new(); /// } /// ``` /// - /// ```rust + /// ```no_run /// pub trait Trait { /// // Good. Return type contains `Self` /// fn new() -> Self; @@ -1178,11 +1180,11 @@ declare_clippy_lint! { /// automatically does this without suspicious-looking `unwrap` calls. /// /// ### Example - /// ```rust + /// ```no_run /// let _ = std::iter::empty::>().filter(Option::is_some).map(Option::unwrap); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let _ = std::iter::empty::>().flatten(); /// ``` #[clippy::version = "1.53.0"] @@ -1201,7 +1203,7 @@ declare_clippy_lint! { /// but is more readable. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::collections::HashSet; /// # let mut s = HashSet::new(); /// # s.insert(1); @@ -1209,7 +1211,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # use std::collections::HashSet; /// # let mut s = HashSet::new(); /// # s.insert(1); @@ -1231,13 +1233,13 @@ declare_clippy_lint! { /// readable. /// /// ### Example - /// ```rust + /// ```no_run /// let some_vec = vec![0, 1, 2, 3]; /// let bad_vec = some_vec.iter().nth(3); /// let bad_slice = &some_vec[..].iter().nth(3); /// ``` /// The correct use would be: - /// ```rust + /// ```no_run /// let some_vec = vec![0, 1, 2, 3]; /// let bad_vec = some_vec.get(3); /// let bad_slice = &some_vec[..].get(3); @@ -1256,13 +1258,13 @@ declare_clippy_lint! { /// `.nth(x)` is cleaner /// /// ### Example - /// ```rust + /// ```no_run /// let some_vec = vec![0, 1, 2, 3]; /// let bad_vec = some_vec.iter().skip(3).next(); /// let bad_slice = &some_vec[..].iter().skip(3).next(); /// ``` /// The correct use would be: - /// ```rust + /// ```no_run /// let some_vec = vec![0, 1, 2, 3]; /// let bad_vec = some_vec.iter().nth(3); /// let bad_slice = &some_vec[..].iter().nth(3); @@ -1281,13 +1283,13 @@ declare_clippy_lint! { /// `.into_iter()` is simpler with better performance. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::collections::HashSet; /// let mut foo = vec![0, 1, 2, 3]; /// let bar: HashSet = foo.drain(..).collect(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::collections::HashSet; /// let foo = vec![0, 1, 2, 3]; /// let bar: HashSet = foo.into_iter().collect(); @@ -1315,13 +1317,13 @@ declare_clippy_lint! { /// `x.get(index).unwrap()` instead of `x[index]`. /// /// ### Example - /// ```rust + /// ```no_run /// let x = vec![2, 3, 5]; /// let last_element = x.get(x.len() - 1); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let x = vec![2, 3, 5]; /// let last_element = x.last(); /// ``` @@ -1351,13 +1353,13 @@ declare_clippy_lint! { /// trait. /// /// ### Example - /// ```rust + /// ```no_run /// let mut some_vec = vec![0, 1, 2, 3]; /// let last = some_vec.get(3).unwrap(); /// *some_vec.get_mut(0).unwrap() = 1; /// ``` /// The correct use would be: - /// ```rust + /// ```no_run /// let mut some_vec = vec![0, 1, 2, 3]; /// let last = some_vec[3]; /// some_vec[0] = 1; @@ -1376,7 +1378,7 @@ declare_clippy_lint! { /// Using `append` instead of `extend` is more concise and faster /// /// ### Example - /// ```rust + /// ```no_run /// let mut a = vec![1, 2, 3]; /// let mut b = vec![4, 5, 6]; /// @@ -1384,7 +1386,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let mut a = vec![1, 2, 3]; /// let mut b = vec![4, 5, 6]; /// @@ -1405,7 +1407,7 @@ declare_clippy_lint! { /// `.push_str(s)` is clearer /// /// ### Example - /// ```rust + /// ```no_run /// let abc = "abc"; /// let def = String::from("def"); /// let mut s = String::new(); @@ -1413,7 +1415,7 @@ declare_clippy_lint! { /// s.extend(def.chars()); /// ``` /// The correct use would be: - /// ```rust + /// ```no_run /// let abc = "abc"; /// let def = String::from("def"); /// let mut s = String::new(); @@ -1435,12 +1437,12 @@ declare_clippy_lint! { /// `.to_vec()` is clearer /// /// ### Example - /// ```rust + /// ```no_run /// let s = [1, 2, 3, 4, 5]; /// let s2: Vec = s[..].iter().cloned().collect(); /// ``` /// The better use would be: - /// ```rust + /// ```no_run /// let s = [1, 2, 3, 4, 5]; /// let s2: Vec = s.to_vec(); /// ``` @@ -1460,13 +1462,13 @@ declare_clippy_lint! { /// `_.ends_with(_)`. /// /// ### Example - /// ```rust + /// ```no_run /// # let name = "_"; /// name.chars().last() == Some('_') || name.chars().next_back() == Some('-'); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let name = "_"; /// name.ends_with('_') || name.ends_with('-'); /// ``` @@ -1485,13 +1487,13 @@ declare_clippy_lint! { /// The call is unnecessary. /// /// ### Example - /// ```rust + /// ```no_run /// # fn do_stuff(x: &[i32]) {} /// let x: &[i32] = &[1, 2, 3, 4, 5]; /// do_stuff(x.as_ref()); /// ``` /// The correct use would be: - /// ```rust + /// ```no_run /// # fn do_stuff(x: &[i32]) {} /// let x: &[i32] = &[1, 2, 3, 4, 5]; /// do_stuff(x); @@ -1512,13 +1514,13 @@ declare_clippy_lint! { /// Readability. /// /// ### Example - /// ```rust + /// ```no_run /// # #[allow(unused)] /// (0..3).fold(false, |acc, x| acc || x > 2); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// (0..3).any(|x| x > 2); /// ``` #[clippy::version = "pre 1.29.0"] @@ -1538,14 +1540,14 @@ declare_clippy_lint! { /// operation is being performed. /// /// ### Example - /// ```rust + /// ```no_run /// let _ = (0..3).filter_map(|x| if x > 2 { Some(x) } else { None }); /// /// // As there is no transformation of the argument this could be written as: /// let _ = (0..3).filter(|&x| x > 2); /// ``` /// - /// ```rust + /// ```no_run /// let _ = (0..4).filter_map(|x| Some(x + 1)); /// /// // As there is no conditional check on the argument this could be written as: @@ -1568,14 +1570,14 @@ declare_clippy_lint! { /// operation is being performed. /// /// ### Example - /// ```rust + /// ```no_run /// let _ = (0..3).find_map(|x| if x > 2 { Some(x) } else { None }); /// /// // As there is no transformation of the argument this could be written as: /// let _ = (0..3).find(|&x| x > 2); /// ``` /// - /// ```rust + /// ```no_run /// let _ = (0..4).find_map(|x| Some(x + 1)); /// /// // As there is no conditional check on the argument this could be written as: @@ -1598,13 +1600,13 @@ declare_clippy_lint! { /// `iter_mut` directly. /// /// ### Example - /// ```rust + /// ```no_run /// # let vec = vec![3, 4, 5]; /// (&vec).into_iter(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let vec = vec![3, 4, 5]; /// (&vec).iter(); /// ``` @@ -1625,7 +1627,7 @@ declare_clippy_lint! { /// completion, you can just use `for_each` instead. /// /// ### Example - /// ```rust + /// ```no_run /// let _ = (0..3).map(|x| x + 2).count(); /// ``` #[clippy::version = "1.39.0"] @@ -1647,7 +1649,7 @@ declare_clippy_lint! { /// data, but those are not yet rigorously defined. /// /// ### Example - /// ```rust + /// ```no_run /// // Beware the UB /// use std::mem::MaybeUninit; /// @@ -1656,7 +1658,7 @@ declare_clippy_lint! { /// /// Note that the following is OK: /// - /// ```rust + /// ```no_run /// use std::mem::MaybeUninit; /// /// let _: [MaybeUninit; 5] = unsafe { @@ -1677,7 +1679,7 @@ declare_clippy_lint! { /// These can be written simply with `saturating_add/sub` methods. /// /// ### Example - /// ```rust + /// ```no_run /// # let y: u32 = 0; /// # let x: u32 = 100; /// let add = x.checked_add(y).unwrap_or(u32::MAX); @@ -1686,7 +1688,7 @@ declare_clippy_lint! { /// /// can be written using dedicated methods for saturating addition/subtraction as: /// - /// ```rust + /// ```no_run /// # let y: u32 = 0; /// # let x: u32 = 100; /// let add = x.saturating_add(y); @@ -1707,7 +1709,7 @@ declare_clippy_lint! { /// This is a no-op, and likely unintended /// /// ### Example - /// ```rust + /// ```no_run /// unsafe { (&() as *const ()).offset(1) }; /// ``` #[clippy::version = "1.41.0"] @@ -1727,7 +1729,7 @@ declare_clippy_lint! { /// symlink in windows. Using `!FileType::is_dir()` is a better way to that intention. /// /// ### Example - /// ```rust + /// ```no_run /// # || { /// let metadata = std::fs::metadata("foo.txt")?; /// let filetype = metadata.file_type(); @@ -1741,7 +1743,7 @@ declare_clippy_lint! { /// /// should be written as: /// - /// ```rust + /// ```no_run /// # || { /// let metadata = std::fs::metadata("foo.txt")?; /// let filetype = metadata.file_type(); @@ -1767,13 +1769,13 @@ declare_clippy_lint! { /// `_.as_deref()`. /// /// ### Example - /// ```rust + /// ```no_run /// # let opt = Some("".to_string()); /// opt.as_ref().map(String::as_str) /// # ; /// ``` /// Can be written as - /// ```rust + /// ```no_run /// # let opt = Some("".to_string()); /// opt.as_deref() /// # ; @@ -1792,14 +1794,14 @@ declare_clippy_lint! { /// These can be shortened into `.get()` /// /// ### Example - /// ```rust + /// ```no_run /// # let a = [1, 2, 3]; /// # let b = vec![1, 2, 3]; /// a[2..].iter().next(); /// b.iter().next(); /// ``` /// should be written as: - /// ```rust + /// ```no_run /// # let a = [1, 2, 3]; /// # let b = vec![1, 2, 3]; /// a.get(2); @@ -1820,14 +1822,14 @@ declare_clippy_lint! { /// It's less clear that we are pushing a single character. /// /// ### Example - /// ```rust + /// ```no_run /// # let mut string = String::new(); /// string.insert_str(0, "R"); /// string.push_str("R"); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let mut string = String::new(); /// string.insert(0, 'R'); /// string.push('R'); @@ -1860,14 +1862,14 @@ declare_clippy_lint! { /// side effects. Eagerly evaluating them can change the semantics of the program. /// /// ### Example - /// ```rust + /// ```no_run /// // example code where clippy issues a warning /// let opt: Option = None; /// /// opt.unwrap_or_else(|| 42); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let opt: Option = None; /// /// opt.unwrap_or(42); @@ -1886,11 +1888,11 @@ declare_clippy_lint! { /// Using `try_for_each` instead is more readable and idiomatic. /// /// ### Example - /// ```rust + /// ```no_run /// (0..3).map(|t| Err(t)).collect::>(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// (0..3).try_for_each(|t| Err(t)); /// ``` #[clippy::version = "1.49.0"] @@ -1909,7 +1911,7 @@ declare_clippy_lint! { /// [FromIterator documentation](https://doc.rust-lang.org/std/iter/trait.FromIterator.html) /// /// ### Example - /// ```rust + /// ```no_run /// let five_fives = std::iter::repeat(5).take(5); /// /// let v = Vec::from_iter(five_fives); @@ -1917,7 +1919,7 @@ declare_clippy_lint! { /// assert_eq!(v, vec![5, 5, 5, 5, 5]); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let five_fives = std::iter::repeat(5).take(5); /// /// let v: Vec = five_fives.collect(); @@ -1939,7 +1941,7 @@ declare_clippy_lint! { /// inside `inspect` at the beginning of the closure in `for_each`. /// /// ### Example - /// ```rust + /// ```no_run /// [1,2,3,4,5].iter() /// .inspect(|&x| println!("inspect the number: {}", x)) /// .for_each(|&x| { @@ -1947,7 +1949,7 @@ declare_clippy_lint! { /// }); /// ``` /// Can be written as - /// ```rust + /// ```no_run /// [1,2,3,4,5].iter() /// .for_each(|&x| { /// println!("inspect the number: {}", x); @@ -1968,12 +1970,12 @@ declare_clippy_lint! { /// Readability, this can be written more concisely by using `flatten`. /// /// ### Example - /// ```rust + /// ```no_run /// # let iter = vec![Some(1)].into_iter(); /// iter.filter_map(|x| x); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let iter = vec![Some(1)].into_iter(); /// iter.flatten(); /// ``` @@ -1991,12 +1993,12 @@ declare_clippy_lint! { /// It can be written more concisely without the call to `map`. /// /// ### Example - /// ```rust + /// ```no_run /// let x = [1, 2, 3]; /// let y: Vec<_> = x.iter().map(|x| x).map(|x| 2*x).collect(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let x = [1, 2, 3]; /// let y: Vec<_> = x.iter().map(|x| 2*x).collect(); /// ``` @@ -2015,13 +2017,13 @@ declare_clippy_lint! { /// readable. /// /// ### Example - /// ```rust + /// ```no_run /// # #[allow(unused)] /// "Hello".bytes().nth(3); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # #[allow(unused)] /// "Hello".as_bytes().get(3); /// ``` @@ -2040,13 +2042,13 @@ declare_clippy_lint! { /// to why we are calling `to_vec` on something that is already a `Vec` or calling `to_owned` on something that is already owned. /// /// ### Example - /// ```rust + /// ```no_run /// let a = vec![1, 2, 3]; /// let b = a.to_vec(); /// let c = a.to_owned(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let a = vec![1, 2, 3]; /// let b = a.clone(); /// let c = a.clone(); @@ -2066,7 +2068,7 @@ declare_clippy_lint! { /// readable. /// /// ### Example - /// ```rust + /// ```no_run /// # #![allow(unused)] /// let some_vec = vec![0, 1, 2, 3]; /// @@ -2075,7 +2077,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let some_vec = vec![0, 1, 2, 3]; /// /// some_vec.len(); @@ -2104,7 +2106,7 @@ declare_clippy_lint! { /// was the original intent, using `into_owned` instead. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::borrow::Cow; /// let s = "Hello world!"; /// let cow = Cow::Borrowed(s); @@ -2113,7 +2115,7 @@ declare_clippy_lint! { /// assert!(matches!(data, Cow::Borrowed(_))) /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::borrow::Cow; /// let s = "Hello world!"; /// let cow = Cow::Borrowed(s); @@ -2122,7 +2124,7 @@ declare_clippy_lint! { /// assert!(matches!(data, Cow::Borrowed(_))) /// ``` /// or - /// ```rust + /// ```no_run /// # use std::borrow::Cow; /// let s = "Hello world!"; /// let cow = Cow::Borrowed(s); @@ -2146,7 +2148,7 @@ declare_clippy_lint! { /// likely to be intended as a different number. /// /// ### Example - /// ```rust + /// ```no_run /// # let s = ""; /// for x in s.splitn(1, ":") { /// // .. @@ -2154,7 +2156,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let s = ""; /// for x in s.splitn(2, ":") { /// // .. @@ -2174,12 +2176,12 @@ declare_clippy_lint! { /// These are both harder to read, as well as less performant. /// /// ### Example - /// ```rust + /// ```no_run /// let x: String = std::iter::repeat('x').take(10).collect(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let x: String = "x".repeat(10); /// ``` #[clippy::version = "1.54.0"] @@ -2231,13 +2233,13 @@ declare_clippy_lint! { /// The function `split` is simpler and there is no performance difference in these cases, considering /// that both functions return a lazy iterator. /// ### Example - /// ```rust + /// ```no_run /// let str = "key=value=add"; /// let _ = str.splitn(3, '=').next().unwrap(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let str = "key=value=add"; /// let _ = str.split('=').next().unwrap(); /// ``` @@ -2261,13 +2263,13 @@ declare_clippy_lint! { /// [#8148](https://github.com/rust-lang/rust-clippy/issues/8148). /// /// ### Example - /// ```rust + /// ```no_run /// let path = std::path::Path::new("x"); /// foo(&path.to_string_lossy().to_string()); /// fn foo(s: &str) {} /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let path = std::path::Path::new("x"); /// foo(&path.to_string_lossy()); /// fn foo(s: &str) {} @@ -2286,13 +2288,13 @@ declare_clippy_lint! { /// `.collect::()` is more concise and might be more performant /// /// ### Example - /// ```rust + /// ```no_run /// let vector = vec!["hello", "world"]; /// let output = vector.iter().map(|item| item.to_uppercase()).collect::>().join(""); /// println!("{}", output); /// ``` /// The correct use would be: - /// ```rust + /// ```no_run /// let vector = vec!["hello", "world"]; /// let output = vector.iter().map(|item| item.to_uppercase()).collect::(); /// println!("{}", output); @@ -2319,13 +2321,13 @@ declare_clippy_lint! { /// Redundant code and improving readability. /// /// ### Example - /// ```rust + /// ```no_run /// let a = Some(&1); /// let b = a.as_deref(); // goes from Option<&i32> to Option<&i32> /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let a = Some(&1); /// let b = a; /// ``` @@ -2345,13 +2347,13 @@ declare_clippy_lint! { /// `is_digit(..)` is slower and requires specifying the radix. /// /// ### Example - /// ```rust + /// ```no_run /// let c: char = '6'; /// c.is_digit(10); /// c.is_digit(16); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let c: char = '6'; /// c.is_ascii_digit(); /// c.is_ascii_hexdigit(); @@ -2371,12 +2373,12 @@ declare_clippy_lint! { /// In this case the modification is useless as it's a temporary that cannot be read from afterwards. /// /// ### Example - /// ```rust + /// ```no_run /// let x = Some(3); /// x.as_ref().take(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let x = Some(3); /// x.as_ref(); /// ``` @@ -2394,7 +2396,7 @@ declare_clippy_lint! { /// It's either a mistake or confusing. /// /// ### Example - /// ```rust + /// ```no_run /// "1234".replace("12", "12"); /// "1234".replacen("12", "12", 1); /// ``` @@ -2417,12 +2419,12 @@ declare_clippy_lint! { /// to account for similar patterns. /// /// ### Example - /// ```rust + /// ```no_run /// let x = true; /// x.then_some("a").unwrap_or("b"); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let x = true; /// if x { "a" } else { "b" }; /// ``` @@ -2444,12 +2446,12 @@ declare_clippy_lint! { /// /// ### Example /// - /// ```rust + /// ```no_run /// let a = [123].iter(); /// let b = Some(123).into_iter(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::iter; /// let a = iter::once(&123); /// let b = iter::once(123); @@ -2475,13 +2477,13 @@ declare_clippy_lint! { /// /// ### Example /// - /// ```rust + /// ```no_run /// use std::{slice, option}; /// let a: slice::Iter = [].iter(); /// let f: option::IntoIter = None.into_iter(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::iter; /// let a: iter::Empty = iter::empty(); /// let b: iter::Empty = iter::empty(); @@ -2511,7 +2513,7 @@ declare_clippy_lint! { /// faster in those cases. /// /// ### Example - /// ```rust + /// ```no_run /// # let vec = vec![1_u8]; /// let count = vec.iter().filter(|x| **x == 0u8).count(); /// ``` @@ -2537,12 +2539,12 @@ declare_clippy_lint! { /// `str::len()`. /// /// ### Example - /// ```rust + /// ```no_run /// "hello".bytes().count(); /// String::from("hello").bytes().count(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// "hello".len(); /// String::from("hello").len(); /// ``` @@ -2561,13 +2563,13 @@ declare_clippy_lint! { /// `ends_with` is case-sensitive and may not detect files with a valid extension. /// /// ### Example - /// ```rust + /// ```no_run /// fn is_rust_file(filename: &str) -> bool { /// filename.ends_with(".rs") /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn is_rust_file(filename: &str) -> bool { /// let filename = std::path::Path::new(filename); /// filename.extension() @@ -2590,13 +2592,13 @@ declare_clippy_lint! { /// result. /// /// ### Example - /// ```rust + /// ```no_run /// let x = vec![2, 3, 5]; /// let first_element = x.get(0); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let x = vec![2, 3, 5]; /// let first_element = x.first(); /// ``` @@ -2616,13 +2618,13 @@ declare_clippy_lint! { /// Concise code helps focusing on behavior instead of boilerplate. /// /// ### Examples - /// ```rust + /// ```no_run /// let foo: Option = None; /// foo.map_or(Err("error"), |v| Ok(v)); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let foo: Option = None; /// foo.ok_or("error"); /// ``` @@ -2642,7 +2644,7 @@ declare_clippy_lint! { /// Readability, this can be written more concisely /// /// ### Example - /// ```rust + /// ```no_run /// let x = vec![42, 43]; /// let y = x.iter(); /// let z = y.map(|i| *i); @@ -2650,7 +2652,7 @@ declare_clippy_lint! { /// /// The correct use would be: /// - /// ```rust + /// ```no_run /// let x = vec![42, 43]; /// let y = x.iter(); /// let z = y.cloned(); @@ -2670,7 +2672,7 @@ declare_clippy_lint! { /// /// ### Example /// Before: - /// ```rust + /// ```no_run /// use std::fmt; /// /// #[derive(Debug)] @@ -2772,7 +2774,7 @@ declare_clippy_lint! { /// guarantee. /// /// ### Example - /// ```rust + /// ```no_run /// use std::sync::{Arc, Mutex}; /// /// let mut value_rc = Arc::new(Mutex::new(42_u8)); @@ -2782,7 +2784,7 @@ declare_clippy_lint! { /// *value += 1; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::sync::{Arc, Mutex}; /// /// let mut value_rc = Arc::new(Mutex::new(42_u8)); @@ -2807,7 +2809,7 @@ declare_clippy_lint! { /// necessary. I don't know the worst case. /// /// ### Example - /// ```rust + /// ```no_run /// use std::fs::OpenOptions; /// /// OpenOptions::new().read(true).truncate(true); @@ -2828,7 +2830,7 @@ declare_clippy_lint! { /// previous defined path. /// /// ### Example - /// ```rust + /// ```no_run /// use std::path::PathBuf; /// /// let mut x = PathBuf::from("/foo"); @@ -2837,7 +2839,7 @@ declare_clippy_lint! { /// ``` /// Could be written: /// - /// ```rust + /// ```no_run /// use std::path::PathBuf; /// /// let mut x = PathBuf::from("/foo"); @@ -2859,13 +2861,13 @@ declare_clippy_lint! { /// The code is better expressed with `.enumerate()`. /// /// ### Example - /// ```rust + /// ```no_run /// # let x = vec![1]; /// let _ = x.iter().zip(0..x.len()); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let x = vec![1]; /// let _ = x.iter().enumerate(); /// ``` @@ -2890,13 +2892,13 @@ declare_clippy_lint! { /// the string is the intention behind this, `clone()` should be used. /// /// ### Example - /// ```rust + /// ```no_run /// fn main() { /// let x = String::from("hello world").repeat(1); /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn main() { /// let x = String::from("hello world").clone(); /// } @@ -2930,12 +2932,12 @@ declare_clippy_lint! { /// issue linked above. /// /// ### Example - /// ```rust + /// ```no_run /// let mut vec = vec![2, 1, 3]; /// vec.sort(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let mut vec = vec![2, 1, 3]; /// vec.sort_unstable(); /// ``` @@ -2963,7 +2965,7 @@ declare_clippy_lint! { /// assert_eq!(any_box.type_id(), TypeId::of::()); // ⚠️ this fails! /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::any::{Any, TypeId}; /// /// let any_box: Box = Box::new(42_i32); @@ -2984,7 +2986,7 @@ declare_clippy_lint! { /// Hashing a unit value doesn't do anything as the implementation of `Hash` for `()` is a no-op. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::hash::Hash; /// # use std::collections::hash_map::DefaultHasher; /// # enum Foo { Empty, WithValue(u8) } @@ -2997,7 +2999,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::hash::Hash; /// # use std::collections::hash_map::DefaultHasher; /// # enum Foo { Empty, WithValue(u8) } @@ -3030,14 +3032,14 @@ declare_clippy_lint! { /// imported by a use statement, then it will need to be added manually. /// /// ### Example - /// ```rust + /// ```no_run /// # struct A; /// # impl A { fn foo(&self) {} } /// # let mut vec: Vec = Vec::new(); /// vec.sort_by(|a, b| a.foo().cmp(&b.foo())); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # struct A; /// # impl A { fn foo(&self) {} } /// # let mut vec: Vec = Vec::new(); @@ -3057,12 +3059,12 @@ declare_clippy_lint! { /// This is probably an argument inversion mistake. /// /// ### Example - /// ```rust + /// ```no_run /// vec![1, 2, 3, 4, 5].resize(0, 5) /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// vec![1, 2, 3, 4, 5].clear() /// ``` #[clippy::version = "1.46.0"] @@ -3111,14 +3113,14 @@ declare_clippy_lint! { /// /// ### Example /// - /// ``` + /// ```no_run /// # use std::collections::HashMap; /// let map: HashMap = HashMap::new(); /// let values = map.iter().map(|(_, value)| value).collect::>(); /// ``` /// /// Use instead: - /// ``` + /// ```no_run /// # use std::collections::HashMap; /// let map: HashMap = HashMap::new(); /// let values = map.values().collect::>(); @@ -3184,14 +3186,14 @@ declare_clippy_lint! { /// this exact scenario. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::io; /// fn foo(t: &mut T) { /// t.seek(io::SeekFrom::Start(0)); /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::io; /// fn foo(t: &mut T) { /// t.rewind(); @@ -3213,12 +3215,12 @@ declare_clippy_lint! { /// when this allocation may not be needed. /// /// ### Example - /// ```rust + /// ```no_run /// # let iterator = vec![1].into_iter(); /// let len = iterator.collect::>().len(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let iterator = vec![1].into_iter(); /// let len = iterator.count(); /// ``` @@ -3241,11 +3243,11 @@ declare_clippy_lint! { /// which is likely not what was intended. /// /// ### Example - /// ```rust + /// ```no_run /// std::process::Command::new("echo").arg("-n hello").spawn().unwrap(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap(); /// ``` #[clippy::version = "1.69.0"] @@ -3264,12 +3266,12 @@ declare_clippy_lint! { /// Calling `.clear()` also makes the intent clearer. /// /// ### Example - /// ```rust + /// ```no_run /// let mut v = vec![1, 2, 3]; /// v.drain(..); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let mut v = vec![1, 2, 3]; /// v.clear(); /// ``` @@ -3287,12 +3289,12 @@ declare_clippy_lint! { /// `.next_back()` is cleaner. /// /// ### Example - /// ```rust + /// ```no_run /// # let foo = [0; 10]; /// foo.iter().rev().next(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let foo = [0; 10]; /// foo.iter().next_back(); /// ``` @@ -3320,13 +3322,13 @@ declare_clippy_lint! { /// to keep the capacity on the original `Vec`. /// /// ### Example - /// ```rust + /// ```no_run /// fn remove_all(v: &mut Vec) -> Vec { /// v.drain(..).collect() /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::mem; /// fn remove_all(v: &mut Vec) -> Vec { /// mem::take(v) @@ -3354,11 +3356,11 @@ declare_clippy_lint! { /// desirable in those cases. /// /// ### Example - /// ```rust + /// ```no_run /// vec![1, 2, 3].iter().fold(Some(0i32), |sum, i| sum?.checked_add(*i)); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// vec![1, 2, 3].iter().try_fold(0i32, |sum, i| sum.checked_add(*i)); /// ``` #[clippy::version = "1.72.0"] @@ -3410,12 +3412,12 @@ declare_clippy_lint! { /// for situations where that additional performance is absolutely necessary. /// /// ### Example - /// ```rust + /// ```no_run /// # let c = 'c'; /// "\\.+*?()|[]{}^$#&-~".chars().any(|x| x == c); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let c = 'c'; /// matches!(c, '\\' | '.' | '+' | '*' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); /// ``` @@ -3439,13 +3441,13 @@ declare_clippy_lint! { /// so it can be safely ignored or unwrapped. /// /// ### Example - /// ```rust + /// ```no_run /// fn hex_encode(bytes: &[u8]) -> String { /// bytes.iter().map(|b| format!("{b:02X}")).collect() /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::fmt::Write; /// fn hex_encode(bytes: &[u8]) -> String { /// bytes.iter().fold(String::new(), |mut output, b| { @@ -3469,7 +3471,7 @@ declare_clippy_lint! { /// nothing. If not, the call should be removed. /// /// ### Example - /// ```rust + /// ```no_run /// let v = vec![1, 2, 3]; /// let x = v.iter().skip(0).collect::>(); /// let y = v.iter().collect::>(); @@ -3495,13 +3497,13 @@ declare_clippy_lint! { /// This can create differing behavior, so better safe than sorry. /// /// ### Example - /// ```rust + /// ```no_run /// # fn really_expensive_fn(i: i32) -> i32 { i } /// # let v = vec![]; /// _ = v.into_iter().filter_map(|i| (i % 2 == 0).then(|| really_expensive_fn(i))); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # fn really_expensive_fn(i: i32) -> i32 { i } /// # let v = vec![]; /// _ = v.into_iter().filter(|i| i % 2 == 0).map(|i| really_expensive_fn(i)); @@ -3521,7 +3523,7 @@ declare_clippy_lint! { /// can access the lock while this writer is active. /// /// ### Example - /// ```rust + /// ```no_run /// use std::sync::RwLock; /// fn assert_is_zero(lock: &RwLock) { /// let num = lock.write().unwrap(); @@ -3530,7 +3532,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// use std::sync::RwLock; /// fn assert_is_zero(lock: &RwLock) { /// let num = lock.read().unwrap(); @@ -3554,11 +3556,11 @@ declare_clippy_lint! { /// This is most likely not what the user intended to do. /// /// ### Example - /// ```rust + /// ```no_run /// for _ in [1, 2, 3].iter().take(4) {} /// ``` /// Use instead: - /// ```rust + /// ```no_run /// for _ in [1, 2, 3].iter() {} /// ``` #[clippy::version = "1.74.0"] @@ -3587,14 +3589,14 @@ declare_clippy_lint! { /// therefore ignored. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::path::Path; /// fn is_markdown(path: &Path) -> bool { /// path.ends_with(".md") /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::path::Path; /// fn is_markdown(path: &Path) -> bool { /// path.extension().is_some_and(|ext| ext == "md") @@ -3614,14 +3616,14 @@ declare_clippy_lint! { /// The `as_str()` conversion is pointless and can be removed for simplicity and cleanliness. /// /// ### Example - /// ```rust + /// ```no_run /// # #![allow(unused)] /// let owned_string = "This is a string".to_owned(); /// owned_string.as_str().as_bytes(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # #![allow(unused)] /// let owned_string = "This is a string".to_owned(); /// owned_string.as_bytes(); @@ -3632,6 +3634,55 @@ declare_clippy_lint! { "`as_str` used to call a method on `str` that is also available on `String`" } +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of `waker.clone().wake()` + /// + /// ### Why is this bad? + /// Cloning the waker is not necessary, `wake_by_ref()` enables the same operation + /// without extra cloning/dropping. + /// + /// ### Example + /// ```rust,ignore + /// waker.clone().wake(); + /// ``` + /// Should be written + /// ```rust,ignore + /// waker.wake_by_ref(); + /// ``` + #[clippy::version = "1.75.0"] + pub WAKER_CLONE_WAKE, + perf, + "cloning a `Waker` only to wake it" +} + +declare_clippy_lint! { + /// ### What it does + /// Checks for calls to `TryInto::try_into` and `TryFrom::try_from` when their infallible counterparts + /// could be used. + /// + /// ### Why is this bad? + /// In those cases, the `TryInto` and `TryFrom` trait implementation is a blanket impl that forwards + /// to `Into` or `From`, which always succeeds. + /// The returned `Result<_, Infallible>` requires error handling to get the contained value + /// even though the conversion can never fail. + /// + /// ### Example + /// ```rust + /// let _: Result = 1i32.try_into(); + /// let _: Result = <_>::try_from(1i32); + /// ``` + /// Use `from`/`into` instead: + /// ```rust + /// let _: i64 = 1i32.into(); + /// let _: i64 = <_>::from(1i32); + /// ``` + #[clippy::version = "1.75.0"] + pub UNNECESSARY_FALLIBLE_CONVERSIONS, + style, + "calling the `try_from` and `try_into` trait methods when `From`/`Into` is implemented" +} + pub struct Methods { avoid_breaking_exported_api: bool, msrv: Msrv, @@ -3777,6 +3828,8 @@ impl_lint_pass!(Methods => [ ITER_OUT_OF_BOUNDS, PATH_ENDS_WITH_EXT, REDUNDANT_AS_STR, + WAKER_CLONE_WAKE, + UNNECESSARY_FALLIBLE_CONVERSIONS, ]); /// Extracts a method call name, args, and `Span` of the method name. @@ -3803,6 +3856,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { match expr.kind { hir::ExprKind::Call(func, args) => { from_iter_instead_of_collect::check(cx, expr, args, func); + unnecessary_fallible_conversions::check_function(cx, expr, func); }, hir::ExprKind::MethodCall(method_call, receiver, args, _) => { let method_span = method_call.ident.span; @@ -3878,21 +3932,21 @@ impl<'tcx> LateLintPass<'tcx> for Methods { } if sig.decl.implicit_self.has_implicit_self() - && !(self.avoid_breaking_exported_api + && !(self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(impl_item.owner_id.def_id)) - && let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir().body(id)).next() - && let Some(first_arg_ty) = first_arg_ty_opt - { - wrong_self_convention::check( - cx, - name, - self_ty, - first_arg_ty, - first_arg.pat.span, - implements_trait, - false - ); - } + && let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir().body(id)).next() + && let Some(first_arg_ty) = first_arg_ty_opt + { + wrong_self_convention::check( + cx, + name, + self_ty, + first_arg_ty, + first_arg.pat.span, + implements_trait, + false, + ); + } } // if this impl block implements a trait, lint in trait definition instead @@ -3977,10 +4031,16 @@ impl Methods { }, ("all", [arg]) => { if let Some(("cloned", recv2, [], _, _)) = method_call(recv) { - iter_overeager_cloned::check(cx, expr, recv, recv2, - iter_overeager_cloned::Op::NeedlessMove(name, arg), false); + iter_overeager_cloned::check( + cx, + expr, + recv, + recv2, + iter_overeager_cloned::Op::NeedlessMove(name, arg), + false, + ); } - } + }, ("and_then", [arg]) => { let biom_option_linted = bind_instead_of_map::OptionAndThenSome::check(cx, expr, recv, arg); let biom_result_linted = bind_instead_of_map::ResultAndThenOk::check(cx, expr, recv, arg); @@ -3988,24 +4048,35 @@ impl Methods { unnecessary_lazy_eval::check(cx, expr, recv, arg, "and"); } }, - ("any", [arg]) => { - match method_call(recv) { - Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::NeedlessMove(name, arg), false), - Some(("chars", recv, _, _, _)) if let ExprKind::Closure(arg) = arg.kind - && let body = cx.tcx.hir().body(arg.body) - && let [param] = body.params => { - string_lit_chars_any::check(cx, expr, recv, param, peel_blocks(body.value), &self.msrv); - } - _ => {} - } - } + ("any", [arg]) => match method_call(recv) { + Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( + cx, + expr, + recv, + recv2, + iter_overeager_cloned::Op::NeedlessMove(name, arg), + false, + ), + Some(("chars", recv, _, _, _)) + if let ExprKind::Closure(arg) = arg.kind + && let body = cx.tcx.hir().body(arg.body) + && let [param] = body.params => + { + string_lit_chars_any::check(cx, expr, recv, param, peel_blocks(body.value), &self.msrv); + }, + _ => {}, + }, ("arg", [arg]) => { suspicious_command_arg_space::check(cx, recv, arg, span); - } + }, ("as_deref" | "as_deref_mut", []) => { needless_option_as_deref::check(cx, expr, recv, name); }, - ("as_bytes" | "is_empty", []) => if let Some(("as_str", recv, [], as_str_span, _)) = method_call(recv) { redundant_as_str::check(cx, expr, recv, as_str_span, span); }, + ("as_bytes" | "is_empty", []) => { + if let Some(("as_str", recv, [], as_str_span, _)) = method_call(recv) { + redundant_as_str::check(cx, expr, recv, as_str_span, span); + } + }, ("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv), ("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv), ("assume_init", []) => uninit_assumed_init::check(cx, expr, recv), @@ -4027,12 +4098,14 @@ impl Methods { }, Some(("drain", recv, args, ..)) => { drain_collect::check(cx, args, expr, recv); - } + }, _ => {}, } }, ("count", []) if is_trait_method(cx, expr, sym::Iterator) => match method_call(recv) { - Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::RmCloned , false), + Some(("cloned", recv2, [], _, _)) => { + iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::RmCloned, false); + }, Some((name2 @ ("into_iter" | "iter" | "iter_mut"), recv2, [], _, _)) => { iter_count::check(cx, expr, recv2, name2); }, @@ -4060,7 +4133,9 @@ impl Methods { ("expect", [_]) => { match method_call(recv) { Some(("ok", recv, [], _, _)) => ok_expect::check(cx, expr, recv), - Some(("err", recv, [], err_span, _)) => err_expect::check(cx, expr, recv, span, err_span, &self.msrv), + Some(("err", recv, [], err_span, _)) => { + err_expect::check(cx, expr, recv, span, err_span, &self.msrv); + }, _ => unwrap_expect_used::check( cx, expr, @@ -4087,13 +4162,19 @@ impl Methods { string_extend_chars::check(cx, expr, recv, arg); extend_with_drain::check(cx, expr, recv, arg); }, - (name @ ( "filter" | "find" ) , [arg]) => { + (name @ ("filter" | "find"), [arg]) => { if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) { // if `arg` has side-effect, the semantic will change - iter_overeager_cloned::check(cx, expr, recv, recv2, - iter_overeager_cloned::Op::FixClosure(name, arg), false); + iter_overeager_cloned::check( + cx, + expr, + recv, + recv2, + iter_overeager_cloned::Op::FixClosure(name, arg), + false, + ); } - } + }, ("filter_map", [arg]) => { unnecessary_filter_map::check(cx, expr, arg, name); filter_map_bool_then::check(cx, expr, arg, call_span); @@ -4107,20 +4188,34 @@ impl Methods { flat_map_option::check(cx, expr, arg, span); }, ("flatten", []) => match method_call(recv) { - Some(("map", recv, [map_arg], map_span, _)) => map_flatten::check(cx, expr, recv, map_arg, map_span), - Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::LaterCloned , true), + Some(("map", recv, [map_arg], map_span, _)) => { + map_flatten::check(cx, expr, recv, map_arg, map_span); + }, + Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( + cx, + expr, + recv, + recv2, + iter_overeager_cloned::Op::LaterCloned, + true, + ), _ => {}, }, ("fold", [init, acc]) => { manual_try_fold::check(cx, expr, init, acc, call_span, &self.msrv); unnecessary_fold::check(cx, expr, init, acc, span); }, - ("for_each", [arg]) => { - match method_call(recv) { - Some(("inspect", _, [_], span2, _)) => inspect_for_each::check(cx, expr, span2), - Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::NeedlessMove(name, arg), false), - _ => {} - } + ("for_each", [arg]) => match method_call(recv) { + Some(("inspect", _, [_], span2, _)) => inspect_for_each::check(cx, expr, span2), + Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( + cx, + expr, + recv, + recv2, + iter_overeager_cloned::Op::NeedlessMove(name, arg), + false, + ), + _ => {}, }, ("get", [arg]) => { get_first::check(cx, expr, recv, arg); @@ -4144,8 +4239,14 @@ impl Methods { }, ("last", []) => { if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) { - iter_overeager_cloned::check(cx, expr, recv, recv2, - iter_overeager_cloned::Op::LaterCloned , false); + iter_overeager_cloned::check( + cx, + expr, + recv, + recv2, + iter_overeager_cloned::Op::LaterCloned, + false, + ); } }, ("lock", []) => { @@ -4155,14 +4256,23 @@ impl Methods { if name == "map" { map_clone::check(cx, expr, recv, m_arg, &self.msrv); match method_call(recv) { - Some((map_name @ ("iter" | "into_iter"), recv2, _, _, _)) => iter_kv_map::check(cx, map_name, expr, recv2, m_arg), - Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::NeedlessMove(name, m_arg), false), - _ => {} + Some((map_name @ ("iter" | "into_iter"), recv2, _, _, _)) => { + iter_kv_map::check(cx, map_name, expr, recv2, m_arg); + }, + Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( + cx, + expr, + recv, + recv2, + iter_overeager_cloned::Op::NeedlessMove(name, m_arg), + false, + ), + _ => {}, } } else { map_err_ignore::check(cx, expr, m_arg); } - if let Some((name, recv2, args, span2,_)) = method_call(recv) { + if let Some((name, recv2, args, span2, _)) = method_call(recv) { match (name, args) { ("as_mut", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, &self.msrv), ("as_ref", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, &self.msrv), @@ -4184,20 +4294,34 @@ impl Methods { ("next", []) => { if let Some((name2, recv2, args2, _, _)) = method_call(recv) { match (name2, args2) { - ("cloned", []) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::LaterCloned, false), + ("cloned", []) => iter_overeager_cloned::check( + cx, + expr, + recv, + recv2, + iter_overeager_cloned::Op::LaterCloned, + false, + ), ("filter", [arg]) => filter_next::check(cx, expr, recv2, arg), ("filter_map", [arg]) => filter_map_next::check(cx, expr, recv2, arg, &self.msrv), ("iter", []) => iter_next_slice::check(cx, expr, recv2), ("skip", [arg]) => iter_skip_next::check(cx, expr, recv2, arg), ("skip_while", [_]) => skip_while_next::check(cx, expr), - ("rev", [])=> manual_next_back::check(cx, expr, recv, recv2), + ("rev", []) => manual_next_back::check(cx, expr, recv, recv2), _ => {}, } } }, ("nth", [n_arg]) => match method_call(recv) { Some(("bytes", recv2, [], _, _)) => bytes_nth::check(cx, expr, recv2, n_arg), - Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::LaterCloned , false), + Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( + cx, + expr, + recv, + recv2, + iter_overeager_cloned::Op::LaterCloned, + false, + ), Some(("iter", recv2, [], _, _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, false), Some(("iter_mut", recv2, [], _, _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, true), _ => iter_nth_zero::check(cx, expr, recv, n_arg), @@ -4222,7 +4346,7 @@ impl Methods { }, ("read_line", [arg]) => { read_line_without_trim::check(cx, expr, recv, arg); - } + }, ("repeat", [arg]) => { repeat_once::check(cx, expr, recv, arg); }, @@ -4253,10 +4377,16 @@ impl Methods { iter_out_of_bounds::check_skip(cx, expr, recv, arg); if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) { - iter_overeager_cloned::check(cx, expr, recv, recv2, - iter_overeager_cloned::Op::LaterCloned , false); + iter_overeager_cloned::check( + cx, + expr, + recv, + recv2, + iter_overeager_cloned::Op::LaterCloned, + false, + ); } - } + }, ("sort", []) => { stable_sort_primitive::check(cx, expr, recv); }, @@ -4281,8 +4411,14 @@ impl Methods { ("take", [arg]) => { iter_out_of_bounds::check_take(cx, expr, recv, arg); if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) { - iter_overeager_cloned::check(cx, expr, recv, recv2, - iter_overeager_cloned::Op::LaterCloned, false); + iter_overeager_cloned::check( + cx, + expr, + recv, + recv2, + iter_overeager_cloned::Op::LaterCloned, + false, + ); } }, ("take", []) => needless_option_take::check(cx, expr, recv), @@ -4292,6 +4428,9 @@ impl Methods { } unnecessary_lazy_eval::check(cx, expr, recv, arg, "then_some"); }, + ("try_into", []) if is_trait_method(cx, expr, sym::TryInto) => { + unnecessary_fallible_conversions::check_method(cx, expr); + }, ("to_owned", []) => { if !suspicious_to_owned::check(cx, expr, recv) { implicit_clone::check(cx, name, expr, recv); @@ -4302,7 +4441,7 @@ impl Methods { }, ("type_id", []) => { type_id_on_box::check(cx, recv, expr.span); - } + }, ("unwrap", []) => { match method_call(recv) { Some(("get", recv, [get_arg], _, _)) => { @@ -4354,7 +4493,7 @@ impl Methods { }, ("unwrap_or_default" | "unwrap_unchecked" | "unwrap_err_unchecked", []) => { unnecessary_literal_unwrap::check(cx, expr, recv, name, args); - } + }, ("unwrap_or_else", [u_arg]) => { match method_call(recv) { Some(("map", recv, [map_arg], _, _)) @@ -4365,9 +4504,12 @@ impl Methods { } unnecessary_literal_unwrap::check(cx, expr, recv, name, args); }, + ("wake", []) => { + waker_clone_wake::check(cx, expr, recv); + }, ("write", []) => { readonly_write_lock::check(cx, expr, recv); - } + }, ("zip", [arg]) => { if let ExprKind::MethodCall(name, iter_recv, [], _) = recv.kind && name.ident.name == sym::iter diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index dbd965d65060..2ef71be3217f 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -17,7 +17,7 @@ use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, AssocKind, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty}; use rustc_span::symbol::Ident; -use rustc_span::{sym, Span, Symbol}; +use rustc_span::{sym, Span}; const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed"; @@ -87,21 +87,17 @@ pub(super) fn check<'tcx>( } }, Node::Local(l) => { - if let PatKind::Binding(BindingAnnotation::NONE | BindingAnnotation::MUT, id, _, None) - = l.pat.kind + if let PatKind::Binding(BindingAnnotation::NONE | BindingAnnotation::MUT, id, _, None) = l.pat.kind && let ty = cx.typeck_results().expr_ty(collect_expr) - && [sym::Vec, sym::VecDeque, sym::BinaryHeap, sym::LinkedList].into_iter() + && [sym::Vec, sym::VecDeque, sym::BinaryHeap, sym::LinkedList] + .into_iter() .any(|item| is_type_diagnostic_item(cx, ty, item)) && let iter_ty = cx.typeck_results().expr_ty(iter_expr) && let Some(block) = get_enclosing_block(cx, l.hir_id) && let Some(iter_calls) = detect_iter_and_into_iters(block, id, cx, get_captured_ids(cx, iter_ty)) && let [iter_call] = &*iter_calls { - let mut used_count_visitor = UsedCountVisitor { - cx, - id, - count: 0, - }; + let mut used_count_visitor = UsedCountVisitor { cx, id, count: 0 }; walk_block(&mut used_count_visitor, block); if used_count_visitor.count > 1 { return; @@ -117,13 +113,11 @@ pub(super) fn check<'tcx>( span, NEEDLESS_COLLECT_MSG, |diag| { - let iter_replacement = format!("{}{}", Sugg::hir(cx, iter_expr, ".."), iter_call.get_iter_method(cx)); + let iter_replacement = + format!("{}{}", Sugg::hir(cx, iter_expr, ".."), iter_call.get_iter_method(cx)); diag.multipart_suggestion( iter_call.get_suggestion_text(), - vec![ - (l.span, String::new()), - (iter_call.span, iter_replacement) - ], + vec![(l.span, String::new()), (iter_call.span, iter_replacement)], Applicability::MaybeIncorrect, ); }, @@ -175,11 +169,12 @@ fn check_collect_into_intoiterator<'tcx>( .into_iter() .filter_map(|p| { if let ClauseKind::Trait(t) = p.kind().skip_binder() - && cx.tcx.is_diagnostic_item(sym::IntoIterator,t.trait_ref.def_id) { - Some(t.self_ty()) - } else { - None - } + && cx.tcx.is_diagnostic_item(sym::IntoIterator, t.trait_ref.def_id) + { + Some(t.self_ty()) + } else { + None + } }) .any(|ty| ty == inputs[arg_idx]) { @@ -207,14 +202,13 @@ fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool { /// Checks if `::Item` is the same as `::Item` fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: Ty<'tcx>) -> bool { - let item = Symbol::intern("Item"); if let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator) && let Some(into_iter_trait) = cx.tcx.get_diagnostic_item(sym::IntoIterator) - && let Some(iter_item_ty) = make_normalized_projection(cx.tcx, cx.param_env, iter_trait, item, [iter_ty]) - && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, item, [collect_ty]) + && let Some(iter_item_ty) = make_normalized_projection(cx.tcx, cx.param_env, iter_trait, sym::Item, [iter_ty]) + && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, sym::Item, [collect_ty]) && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions( cx.param_env, - Ty::new_projection(cx.tcx,into_iter_item_proj.def_id, into_iter_item_proj.args) + Ty::new_projection(cx.tcx, into_iter_item_proj.def_id, into_iter_item_proj.args), ) { iter_item_ty == into_iter_item_ty @@ -233,11 +227,14 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) - && let [_, search_ty] = *sig.skip_binder().inputs() && let ty::Ref(_, search_ty, Mutability::Not) = *cx.tcx.erase_late_bound_regions(sig.rebind(search_ty)).kind() && let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator) - && let Some(iter_item) = cx.tcx - .associated_items(iter_trait) - .find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait) + && let Some(iter_item) = cx.tcx.associated_items(iter_trait).find_by_name_and_kind( + cx.tcx, + Ident::with_dummy_span(sym::Item), + AssocKind::Type, + iter_trait, + ) && let args = cx.tcx.mk_args(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) - && let proj_ty = Ty::new_projection(cx.tcx,iter_item.def_id, args) + && let proj_ty = Ty::new_projection(cx.tcx, iter_item.def_id, args) && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty) { item_ty == EarlyBinder::bind(search_ty).instantiate(cx.tcx, cx.typeck_results().node_args(call_id)) diff --git a/clippy_lints/src/methods/option_as_ref_deref.rs b/clippy_lints/src/methods/option_as_ref_deref.rs index d0c27f9631f7..7b81d4571b24 100644 --- a/clippy_lints/src/methods/option_as_ref_deref.rs +++ b/clippy_lints/src/methods/option_as_ref_deref.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{match_def_path, path_to_local_id, paths, peel_blocks}; diff --git a/clippy_lints/src/methods/option_map_unwrap_or.rs b/clippy_lints/src/methods/option_map_unwrap_or.rs index fcbe005fb286..ebb0a7b562d2 100644 --- a/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::{is_copy, is_type_diagnostic_item}; use rustc_data_structures::fx::FxHashSet; diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs index 942f3bd79a61..b942346d5c3f 100644 --- a/clippy_lints/src/methods/or_fun_call.rs +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -235,10 +235,10 @@ fn closure_body_returns_empty_to_string(cx: &LateContext<'_>, e: &hir::Expr<'_>) let body = cx.tcx.hir().body(body); if body.params.is_empty() - && let hir::Expr{ kind, .. } = &body.value - && let hir::ExprKind::MethodCall(hir::PathSegment {ident, ..}, self_arg, _, _) = kind + && let hir::Expr { kind, .. } = &body.value + && let hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, self_arg, _, _) = kind && ident.name == sym::to_string - && let hir::Expr{ kind, .. } = self_arg + && let hir::Expr { kind, .. } = self_arg && let hir::ExprKind::Lit(lit) = kind && let ast::LitKind::Str(symbol::kw::Empty, _) = lit.node { diff --git a/clippy_lints/src/methods/path_ends_with_ext.rs b/clippy_lints/src/methods/path_ends_with_ext.rs index 3347c8c16201..094ead9f4ad8 100644 --- a/clippy_lints/src/methods/path_ends_with_ext.rs +++ b/clippy_lints/src/methods/path_ends_with_ext.rs @@ -1,7 +1,6 @@ use super::PATH_ENDS_WITH_EXT; +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs; -use clippy_utils::msrvs::Msrv; use clippy_utils::source::snippet; use clippy_utils::ty::is_type_diagnostic_item; use rustc_ast::{LitKind, StrStyle}; @@ -47,7 +46,7 @@ pub(super) fn check( "this looks like a failed attempt at checking for the file extension", "try", sugg, - Applicability::MaybeIncorrect + Applicability::MaybeIncorrect, ); } } diff --git a/clippy_lints/src/methods/read_line_without_trim.rs b/clippy_lints/src/methods/read_line_without_trim.rs index 81f9e2a77fce..3b903ec5cdb1 100644 --- a/clippy_lints/src/methods/read_line_without_trim.rs +++ b/clippy_lints/src/methods/read_line_without_trim.rs @@ -46,9 +46,12 @@ pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr< span, "calling `.parse()` without trimming the trailing newline character", |diag| { - diag.span_note(call.span, "call to `.read_line()` here, \ + diag.span_note( + call.span, + "call to `.read_line()` here, \ which leaves a trailing newline character in the buffer, \ - which in turn will cause `.parse()` to fail"); + which in turn will cause `.parse()` to fail", + ); diag.span_suggestion( expr.span, @@ -56,7 +59,7 @@ pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr< format!("{local_snippet}.trim_end()"), Applicability::MachineApplicable, ); - } + }, ); } diff --git a/clippy_lints/src/methods/readonly_write_lock.rs b/clippy_lints/src/methods/readonly_write_lock.rs index e3ec921da0ce..1184dd4525a7 100644 --- a/clippy_lints/src/methods/readonly_write_lock.rs +++ b/clippy_lints/src/methods/readonly_write_lock.rs @@ -26,13 +26,18 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, receiver && let parent = cx.tcx.hir().get_parent(unwrap_call_expr.hir_id) && let Node::Local(local) = parent && let Some(mir) = enclosing_mir(cx.tcx, expr.hir_id) - && let Some((local, _)) = mir.local_decls.iter_enumerated().find(|(_, decl)| { - local.span.contains(decl.source_info.span) - }) - && let Some(usages) = visit_local_usage(&[local], mir, Location { - block: START_BLOCK, - statement_index: 0, - }) + && let Some((local, _)) = mir + .local_decls + .iter_enumerated() + .find(|(_, decl)| local.span.contains(decl.source_info.span)) + && let Some(usages) = visit_local_usage( + &[local], + mir, + Location { + block: START_BLOCK, + statement_index: 0, + }, + ) && let [usage] = usages.as_slice() { let writer_never_mutated = usage.local_consume_or_mutate_locs.is_empty(); @@ -45,7 +50,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, receiver "this write lock is used only for reading", "consider using a read lock instead", format!("{}.read()", snippet(cx, receiver.span, "")), - Applicability::MaybeIncorrect // write lock might be intentional for enforcing exclusiveness + Applicability::MaybeIncorrect, // write lock might be intentional for enforcing exclusiveness ); } } diff --git a/clippy_lints/src/methods/seek_from_current.rs b/clippy_lints/src/methods/seek_from_current.rs index 4ea87027a9e6..63d41677feed 100644 --- a/clippy_lints/src/methods/seek_from_current.rs +++ b/clippy_lints/src/methods/seek_from_current.rs @@ -33,15 +33,17 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &' } fn arg_is_seek_from_current<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool { - if let ExprKind::Call(f, args) = expr.kind && - let ExprKind::Path(ref path) = f.kind && - let Some(def_id) = cx.qpath_res(path, f.hir_id).opt_def_id() && - match_def_path(cx, def_id, &paths::STD_IO_SEEK_FROM_CURRENT) { + if let ExprKind::Call(f, args) = expr.kind + && let ExprKind::Path(ref path) = f.kind + && let Some(def_id) = cx.qpath_res(path, f.hir_id).opt_def_id() + && match_def_path(cx, def_id, &paths::STD_IO_SEEK_FROM_CURRENT) + { // check if argument of `SeekFrom::Current` is `0` - if args.len() == 1 && - let ExprKind::Lit(lit) = args[0].kind && - let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node { - return true + if args.len() == 1 + && let ExprKind::Lit(lit) = args[0].kind + && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node + { + return true; } } diff --git a/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs b/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs index 50d4de7a6800..9f38460357ba 100644 --- a/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs +++ b/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs @@ -23,15 +23,15 @@ pub(super) fn check<'tcx>( return; } - if let Some(seek_trait_id) = cx.tcx.get_diagnostic_item(sym::IoSeek) && - implements_trait(cx, ty, seek_trait_id, &[]) && - let ExprKind::Call(func, args1) = arg.kind && - let ExprKind::Path(ref path) = func.kind && - let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id() && - match_def_path(cx, def_id, &paths::STD_IO_SEEKFROM_START) && - args1.len() == 1 && - let ExprKind::Lit(lit) = args1[0].kind && - let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node + if let Some(seek_trait_id) = cx.tcx.get_diagnostic_item(sym::IoSeek) + && implements_trait(cx, ty, seek_trait_id, &[]) + && let ExprKind::Call(func, args1) = arg.kind + && let ExprKind::Path(ref path) = func.kind + && let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id() + && match_def_path(cx, def_id, &paths::STD_IO_SEEKFROM_START) + && args1.len() == 1 + && let ExprKind::Lit(lit) = args1[0].kind + && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node { let method_call_span = expr.span.with_lo(name_span.lo()); span_lint_and_then( diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs index 7016ad0a80f1..9da61bca52c8 100644 --- a/clippy_lints/src/methods/str_splitn.rs +++ b/clippy_lints/src/methods/str_splitn.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::usage::local_used_after_expr; use clippy_utils::visitors::{for_each_expr_with_closures, Descend}; @@ -115,7 +115,7 @@ fn check_manual_split_once( /// checks for /// -/// ``` +/// ```no_run /// let mut iter = "a.b.c".splitn(2, '.'); /// let a = iter.next(); /// let b = iter.next(); @@ -133,13 +133,11 @@ fn check_manual_split_once_indirect( && let PatKind::Binding(BindingAnnotation::MUT, iter_binding_id, iter_ident, None) = local.pat.kind && let (iter_stmt_id, Node::Stmt(_)) = parents.next()? && let (_, Node::Block(enclosing_block)) = parents.next()? - && let mut stmts = enclosing_block .stmts .iter() .skip_while(|stmt| stmt.hir_id != iter_stmt_id) .skip(1) - && let first = indirect_usage(cx, stmts.next()?, iter_binding_id, ctxt)? && let second = indirect_usage(cx, stmts.next()?, iter_binding_id, ctxt)? && first.unwrap_kind == second.unwrap_kind @@ -173,18 +171,8 @@ fn check_manual_split_once_indirect( ); let remove_msg = format!("remove the `{iter_ident}` usages"); - diag.span_suggestion( - first.span, - remove_msg.clone(), - "", - app, - ); - diag.span_suggestion( - second.span, - remove_msg, - "", - app, - ); + diag.span_suggestion(first.span, remove_msg.clone(), "", app); + diag.span_suggestion(second.span, remove_msg, "", app); }); } diff --git a/clippy_lints/src/methods/string_lit_chars_any.rs b/clippy_lints/src/methods/string_lit_chars_any.rs index 70da6ad58bdc..5f6f027a3b59 100644 --- a/clippy_lints/src/methods/string_lit_chars_any.rs +++ b/clippy_lints/src/methods/string_lit_chars_any.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{Msrv, MATCHES_MACRO}; use clippy_utils::source::snippet_opt; use clippy_utils::{is_from_proc_macro, is_trait_method, path_to_local}; use itertools::Itertools; @@ -19,7 +19,7 @@ pub(super) fn check<'tcx>( body: &Expr<'_>, msrv: &Msrv, ) { - if msrv.meets(MATCHES_MACRO) + if msrv.meets(msrvs::MATCHES_MACRO) && is_trait_method(cx, expr, sym::Iterator) && let PatKind::Binding(_, arg, _, _) = param.pat.kind && let ExprKind::Lit(lit_kind) = recv.kind @@ -52,7 +52,7 @@ pub(super) fn check<'tcx>( format!("matches!({scrutinee_snip}, {pat_snip})"), Applicability::MachineApplicable, ); - } + }, ); } } diff --git a/clippy_lints/src/methods/suspicious_command_arg_space.rs b/clippy_lints/src/methods/suspicious_command_arg_space.rs index 8959e2c1d75f..b2c5987e43d2 100644 --- a/clippy_lints/src/methods/suspicious_command_arg_space.rs +++ b/clippy_lints/src/methods/suspicious_command_arg_space.rs @@ -25,13 +25,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, recv: &'tcx hir::Expr<'_>, arg |diag: &mut Diagnostic| { diag.multipart_suggestion_verbose( "consider splitting the argument", - vec![ - (span, "args".to_string()), - (arg.span, format!("[{arg1:?}, {arg2:?}]")), - ], + vec![(span, "args".to_string()), (arg.span, format!("[{arg1:?}, {arg2:?}]"))], Applicability::MaybeIncorrect, ); - } + }, ); } } diff --git a/clippy_lints/src/methods/type_id_on_box.rs b/clippy_lints/src/methods/type_id_on_box.rs index 3404bdfe79be..4917936a9322 100644 --- a/clippy_lints/src/methods/type_id_on_box.rs +++ b/clippy_lints/src/methods/type_id_on_box.rs @@ -44,11 +44,11 @@ pub(super) fn check(cx: &LateContext<'_>, receiver: &Expr<'_>, call_span: Span) diag.note( "this returns the type id of the literal type `Box` instead of the \ - type id of the boxed value, which is most likely not what you want" + type id of the boxed value, which is most likely not what you want", ) .note( "if this is intentional, use `TypeId::of::>()` instead, \ - which makes it more clear" + which makes it more clear", ) .span_suggestion( receiver.span, diff --git a/clippy_lints/src/methods/unnecessary_fallible_conversions.rs b/clippy_lints/src/methods/unnecessary_fallible_conversions.rs new file mode 100644 index 000000000000..bb32b1bb7fc4 --- /dev/null +++ b/clippy_lints/src/methods/unnecessary_fallible_conversions.rs @@ -0,0 +1,122 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::get_parent_expr; +use clippy_utils::ty::implements_trait; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_span::{sym, Span}; + +use super::UNNECESSARY_FALLIBLE_CONVERSIONS; + +/// What function is being called and whether that call is written as a method call or a function +/// call +#[derive(Copy, Clone)] +#[expect(clippy::enum_variant_names)] +enum FunctionKind { + /// `T::try_from(U)` + TryFromFunction, + /// `t.try_into()` + TryIntoMethod, + /// `U::try_into(t)` + TryIntoFunction, +} + +fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &Expr<'_>, + node_args: ty::GenericArgsRef<'tcx>, + kind: FunctionKind, + primary_span: Span, +) { + if let &[self_ty, other_ty] = node_args.as_slice() + // useless_conversion already warns `T::try_from(T)`, so ignore it here + && self_ty != other_ty + && let Some(self_ty) = self_ty.as_type() + && let Some(from_into_trait) = cx.tcx.get_diagnostic_item(match kind { + FunctionKind::TryFromFunction => sym::From, + FunctionKind::TryIntoMethod | FunctionKind::TryIntoFunction => sym::Into, + }) + // If `T: TryFrom` and `T: From` both exist, then that means that the `TryFrom` + // _must_ be from the blanket impl and cannot have been manually implemented + // (else there would be conflicting impls, even with #![feature(spec)]), so we don't even need to check + // what `>::Error` is: it's always `Infallible` + && implements_trait(cx, self_ty, from_into_trait, &[other_ty]) + { + let parent_unwrap_call = get_parent_expr(cx, expr).and_then(|parent| { + if let ExprKind::MethodCall(path, .., span) = parent.kind + && let sym::unwrap | sym::expect = path.ident.name + { + Some(span) + } else { + None + } + }); + + let (sugg, span, applicability) = match kind { + FunctionKind::TryIntoMethod if let Some(unwrap_span) = parent_unwrap_call => { + // Extend the span to include the unwrap/expect call: + // `foo.try_into().expect("..")` + // ^^^^^^^^^^^^^^^^^^^^^^^ + // + // `try_into().unwrap()` specifically can be trivially replaced with just `into()`, + // so that can be machine-applicable + + ( + "into()", + primary_span.with_hi(unwrap_span.hi()), + Applicability::MachineApplicable, + ) + }, + FunctionKind::TryFromFunction => ("From::from", primary_span, Applicability::Unspecified), + FunctionKind::TryIntoFunction => ("Into::into", primary_span, Applicability::Unspecified), + FunctionKind::TryIntoMethod => ("into", primary_span, Applicability::Unspecified), + }; + + span_lint_and_sugg( + cx, + UNNECESSARY_FALLIBLE_CONVERSIONS, + span, + "use of a fallible conversion when an infallible one could be used", + "use", + sugg.into(), + applicability, + ); + } +} + +/// Checks method call exprs: +/// - `0i32.try_into()` +pub(super) fn check_method(cx: &LateContext<'_>, expr: &Expr<'_>) { + if let ExprKind::MethodCall(path, ..) = expr.kind { + check( + cx, + expr, + cx.typeck_results().node_args(expr.hir_id), + FunctionKind::TryIntoMethod, + path.ident.span, + ); + } +} + +/// Checks function call exprs: +/// - `>::try_from(0i32)` +/// - `<_ as TryInto>::try_into(0i32)` +pub(super) fn check_function(cx: &LateContext<'_>, expr: &Expr<'_>, callee: &Expr<'_>) { + if let ExprKind::Path(ref qpath) = callee.kind + && let Some(item_def_id) = cx.qpath_res(qpath, callee.hir_id).opt_def_id() + && let Some(trait_def_id) = cx.tcx.trait_of_item(item_def_id) + { + check( + cx, + expr, + cx.typeck_results().node_args(callee.hir_id), + match cx.tcx.get_diagnostic_name(trait_def_id) { + Some(sym::TryFrom) => FunctionKind::TryFromFunction, + Some(sym::TryInto) => FunctionKind::TryIntoFunction, + _ => return, + }, + callee.span, + ); + } +} diff --git a/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/clippy_lints/src/methods/unnecessary_literal_unwrap.rs index 3e19d72ec912..a1125d70db39 100644 --- a/clippy_lints/src/methods/unnecessary_literal_unwrap.rs +++ b/clippy_lints/src/methods/unnecessary_literal_unwrap.rs @@ -81,7 +81,7 @@ pub(super) fn check( { suggs.extend([ (block.span.shrink_to_lo().to(expr.span.shrink_to_lo()), String::new()), - (expr.span.shrink_to_hi().to(block.span.shrink_to_hi()), String::new()) + (expr.span.shrink_to_hi().to(block.span.shrink_to_hi()), String::new()), ]); } Some(suggs) diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs index 50d6f3b7e55f..772686d93dd7 100644 --- a/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -1,7 +1,7 @@ use super::implicit_clone::is_clone_like; use super::unnecessary_iter_cloned::{self, is_into_iter}; +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_opt; use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs}; use clippy_utils::visitors::find_all_ret_expressions; @@ -382,10 +382,10 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< Node::Block(..) => continue, Node::Item(item) => { if let ItemKind::Fn(_, _, body_id) = &item.kind - && let output_ty = return_ty(cx, item.owner_id) - && let inherited = Inherited::new(cx.tcx, item.owner_id.def_id) - && let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, item.owner_id.def_id) - && fn_ctxt.can_coerce(ty, output_ty) + && let output_ty = return_ty(cx, item.owner_id) + && let inherited = Inherited::new(cx.tcx, item.owner_id.def_id) + && let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, item.owner_id.def_id) + && fn_ctxt.can_coerce(ty, output_ty) { if has_lifetime(output_ty) && has_lifetime(ty) { return false; @@ -393,12 +393,15 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< let body = cx.tcx.hir().body(*body_id); let body_expr = &body.value; let mut count = 0; - return find_all_ret_expressions(cx, body_expr, |_| { count += 1; count <= 1 }); + return find_all_ret_expressions(cx, body_expr, |_| { + count += 1; + count <= 1 + }); } - } + }, Node::Expr(parent_expr) => { - if let Some((callee_def_id, call_generic_args, recv, call_args)) - = get_callee_generic_args_and_args(cx, parent_expr) + if let Some((callee_def_id, call_generic_args, recv, call_args)) = + get_callee_generic_args_and_args(cx, parent_expr) { // FIXME: the `instantiate_identity()` below seems incorrect, since we eventually // call `tcx.try_instantiate_and_normalize_erasing_regions` further down @@ -420,40 +423,49 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< return false; } - let mut trait_predicates = cx.tcx.param_env(callee_def_id) - .caller_bounds().iter().filter(|predicate| { - if let ClauseKind::Trait(trait_predicate) - = predicate.kind().skip_binder() - && trait_predicate.trait_ref.self_ty() == *param_ty - { - true - } else { - false - } - }); + let mut trait_predicates = + cx.tcx + .param_env(callee_def_id) + .caller_bounds() + .iter() + .filter(|predicate| { + if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() + && trait_predicate.trait_ref.self_ty() == *param_ty + { + true + } else { + false + } + }); - let new_subst = cx.tcx.mk_args_from_iter( - call_generic_args.iter() - .enumerate() - .map(|(i, t)| - if i == (*param_index as usize) { - GenericArg::from(ty) - } else { - t - })); + let new_subst = cx + .tcx + .mk_args_from_iter(call_generic_args.iter().enumerate().map(|(i, t)| { + if i == (*param_index as usize) { + GenericArg::from(ty) + } else { + t + } + })); if trait_predicates.any(|predicate| { let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, new_subst); let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate); - !cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation) + !cx.tcx + .infer_ctxt() + .build() + .predicate_must_hold_modulo_regions(&obligation) }) { return false; } let output_ty = fn_sig.output(); if output_ty.contains(*param_ty) { - if let Ok(new_ty) = cx.tcx.try_instantiate_and_normalize_erasing_regions( - new_subst, cx.param_env, EarlyBinder::bind(output_ty)) { + if let Ok(new_ty) = cx.tcx.try_instantiate_and_normalize_erasing_regions( + new_subst, + cx.param_env, + EarlyBinder::bind(output_ty), + ) { expr = parent_expr; ty = new_ty; continue; @@ -515,10 +527,11 @@ fn is_to_string_on_string_like<'a>( && let GenericArgKind::Type(ty) = generic_arg.unpack() && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref) && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef) - && (cx.get_associated_type(ty, deref_trait_id, "Target") == Some(cx.tcx.types.str_) || - implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()])) { - true - } else { - false - } + && (cx.get_associated_type(ty, deref_trait_id, "Target") == Some(cx.tcx.types.str_) + || implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()])) + { + true + } else { + false + } } diff --git a/clippy_lints/src/methods/waker_clone_wake.rs b/clippy_lints/src/methods/waker_clone_wake.rs new file mode 100644 index 000000000000..da66632d55f5 --- /dev/null +++ b/clippy_lints/src/methods/waker_clone_wake.rs @@ -0,0 +1,32 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_with_applicability; +use clippy_utils::{is_trait_method, match_def_path, paths}; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_span::sym; + +use super::WAKER_CLONE_WAKE; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) { + let ty = cx.typeck_results().expr_ty(recv); + + if let Some(did) = ty.ty_adt_def() + && match_def_path(cx, did.did(), &paths::WAKER) + && let ExprKind::MethodCall(_, waker_ref, &[], _) = recv.kind + && is_trait_method(cx, recv, sym::Clone) + { + let mut applicability = Applicability::MachineApplicable; + let snippet = snippet_with_applicability(cx, waker_ref.span.source_callsite(), "..", &mut applicability); + + span_lint_and_sugg( + cx, + WAKER_CLONE_WAKE, + expr.span, + "cloning a `Waker` only to wake it", + "replace with", + format!("{snippet}.wake_by_ref()"), + applicability, + ); + } +} diff --git a/clippy_lints/src/min_ident_chars.rs b/clippy_lints/src/min_ident_chars.rs index c79a1a7b9d42..4ad12e899fe2 100644 --- a/clippy_lints/src/min_ident_chars.rs +++ b/clippy_lints/src/min_ident_chars.rs @@ -107,13 +107,17 @@ impl Visitor<'_> for IdentVisitor<'_, '_> { let str = ident.as_str(); if conf.is_ident_too_short(cx, str, ident.span) { - if let Node::Item(item) = node && let ItemKind::Use(..) = item.kind { + if let Node::Item(item) = node + && let ItemKind::Use(..) = item.kind + { return; } // `struct Awa(T)` // ^ if let Node::PathSegment(path) = node { - if let Res::Def(def_kind, ..) = path.res && let DefKind::TyParam = def_kind { + if let Res::Def(def_kind, ..) = path.res + && let DefKind::TyParam = def_kind + { return; } if matches!(path.res, Res::PrimTy(..)) || path.res.opt_def_id().is_some_and(|def_id| !def_id.is_local()) diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 9c8b47fb3032..01eace6c48c5 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -41,12 +41,12 @@ declare_clippy_lint! { /// dereferences, e.g., changing `*x` to `x` within the function. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo(ref _x: u8) {} /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// fn foo(_x: &u8) {} /// ``` #[clippy::version = "pre 1.29.0"] @@ -70,7 +70,7 @@ declare_clippy_lint! { /// macro, it has been allowed in the mean time. /// /// ### Example - /// ```rust + /// ```no_run /// let _x = 0; /// let y = _x + 1; // Here we are using `_x`, even though it has a leading /// // underscore. We should rename `_x` to `x` @@ -263,7 +263,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass { ), |diag| { diag.span_note(definition_span, format!("`{name}` is defined here")); - } + }, ); } } diff --git a/clippy_lints/src/misc_early/mod.rs b/clippy_lints/src/misc_early/mod.rs index b226b8781237..f758cbb47fc2 100644 --- a/clippy_lints/src/misc_early/mod.rs +++ b/clippy_lints/src/misc_early/mod.rs @@ -28,7 +28,7 @@ declare_clippy_lint! { /// the fields that are actually bound. /// /// ### Example - /// ```rust + /// ```no_run /// # struct Foo { /// # a: i32, /// # b: i32, @@ -43,7 +43,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # struct Foo { /// # a: i32, /// # b: i32, @@ -71,12 +71,12 @@ declare_clippy_lint! { /// It affects code readability. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo(a: i32, _a: i32) {} /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// fn bar(a: i32, _b: i32) {} /// ``` #[clippy::version = "pre 1.29.0"] @@ -94,7 +94,7 @@ declare_clippy_lint! { /// decremented. /// /// ### Example - /// ```rust + /// ```no_run /// let mut x = 3; /// --x; /// ``` @@ -113,14 +113,14 @@ declare_clippy_lint! { /// It looks confusing. /// /// ### Example - /// ```rust + /// ```no_run /// # let _ = /// 0x1a9BAcD /// # ; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let _ = /// 0x1A9BACD /// # ; @@ -142,14 +142,14 @@ declare_clippy_lint! { /// Suffix style should be consistent. /// /// ### Example - /// ```rust + /// ```no_run /// # let _ = /// 123832i32 /// # ; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let _ = /// 123832_i32 /// # ; @@ -170,14 +170,14 @@ declare_clippy_lint! { /// Suffix style should be consistent. /// /// ### Example - /// ```rust + /// ```no_run /// # let _ = /// 123832_i32 /// # ; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let _ = /// 123832i32 /// # ; @@ -202,7 +202,7 @@ declare_clippy_lint! { /// ### Example /// /// In Rust: - /// ```rust + /// ```no_run /// fn main() { /// let a = 0123; /// println!("{}", a); @@ -258,7 +258,7 @@ declare_clippy_lint! { /// bindings. /// /// ### Example - /// ```rust + /// ```no_run /// # let v = Some("abc"); /// match v { /// Some(x) => (), @@ -267,7 +267,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let v = Some("abc"); /// match v { /// Some(x) => (), @@ -295,7 +295,7 @@ declare_clippy_lint! { /// can match that element as well. /// /// ### Example - /// ```rust + /// ```no_run /// # struct TupleStruct(u32, u32, u32); /// # let t = TupleStruct(1, 2, 3); /// match t { @@ -305,7 +305,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # struct TupleStruct(u32, u32, u32); /// # let t = TupleStruct(1, 2, 3); /// match t { diff --git a/clippy_lints/src/mismatching_type_param_order.rs b/clippy_lints/src/mismatching_type_param_order.rs index 28e041dee0db..0d79ece087f5 100644 --- a/clippy_lints/src/mismatching_type_param_order.rs +++ b/clippy_lints/src/mismatching_type_param_order.rs @@ -24,7 +24,7 @@ declare_clippy_lint! { /// ignored. /// /// ### Example - /// ```rust + /// ```no_run /// struct Foo { /// x: A, /// y: B, @@ -33,7 +33,7 @@ declare_clippy_lint! { /// impl Foo {} /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct Foo { /// x: A, /// y: B, diff --git a/clippy_lints/src/missing_assert_message.rs b/clippy_lints/src/missing_assert_message.rs index 136947a2c8cd..4e00215c5cba 100644 --- a/clippy_lints/src/missing_assert_message.rs +++ b/clippy_lints/src/missing_assert_message.rs @@ -27,14 +27,14 @@ declare_clippy_lint! { /// don't provide any extra information. /// /// ### Example - /// ```rust + /// ```no_run /// # struct Service { ready: bool } /// fn call(service: Service) { /// assert!(service.ready); /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # struct Service { ready: bool } /// fn call(service: Service) { /// assert!(service.ready, "`service.poll_ready()` must be called first to ensure that service is ready to receive requests"); diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index 08fec2b8ec82..dccf72d3c84c 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -43,14 +43,14 @@ declare_clippy_lint! { /// about the length of a slice, but this lint will not detect that. /// /// ### Example - /// ```rust + /// ```no_run /// fn sum(v: &[u8]) -> u8 { /// // 4 bounds checks /// v[0] + v[1] + v[2] + v[3] /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn sum(v: &[u8]) -> u8 { /// assert!(v.len() > 4); /// // no bounds checks @@ -200,9 +200,13 @@ impl<'hir> IndexEntry<'hir> { /// E.g. for `5` this returns `Some(5)`, for `..5` this returns `Some(4)`, /// for `..=5` this returns `Some(5)` fn upper_index_expr(expr: &Expr<'_>) -> Option { - if let ExprKind::Lit(lit) = &expr.kind && let LitKind::Int(index, _) = lit.node { + if let ExprKind::Lit(lit) = &expr.kind + && let LitKind::Int(index, _) = lit.node + { Some(index as usize) - } else if let Some(higher::Range { end: Some(end), limits, .. }) = higher::Range::hir(expr) + } else if let Some(higher::Range { + end: Some(end), limits, .. + }) = higher::Range::hir(expr) && let ExprKind::Lit(lit) = &end.kind && let LitKind::Int(index @ 1.., _) = lit.node { @@ -228,7 +232,12 @@ fn check_index<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Unh if let Some(entry) = entry { match entry { - IndexEntry::StrayAssert { asserted_len, comparison, assert_span, slice } => { + IndexEntry::StrayAssert { + asserted_len, + comparison, + assert_span, + slice, + } => { *entry = IndexEntry::AssertWithIndex { highest_index: index, asserted_len: *asserted_len, @@ -238,8 +247,12 @@ fn check_index<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Unh comparison: *comparison, }; }, - IndexEntry::IndexWithoutAssert { highest_index, indexes, .. } - | IndexEntry::AssertWithIndex { highest_index, indexes, .. } => { + IndexEntry::IndexWithoutAssert { + highest_index, indexes, .. + } + | IndexEntry::AssertWithIndex { + highest_index, indexes, .. + } => { indexes.push(expr.span); *highest_index = (*highest_index).max(index); }, diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index f598a65d2e48..97522cbe6cea 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::qualify_min_const_fn::is_min_const_fn; use clippy_utils::ty::has_drop; use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, trait_ref_of_method}; @@ -27,7 +27,7 @@ declare_clippy_lint! { /// /// Also, the lint only runs one pass over the code. Consider these two non-const functions: /// - /// ```rust + /// ```no_run /// fn a() -> i32 { /// 0 /// } @@ -42,7 +42,7 @@ declare_clippy_lint! { /// /// If you are marking a public function with `const`, removing it again will break API compatibility. /// ### Example - /// ```rust + /// ```no_run /// # struct Foo { /// # random_number: usize, /// # } @@ -55,7 +55,7 @@ declare_clippy_lint! { /// /// Could be a const fn: /// - /// ```rust + /// ```no_run /// # struct Foo { /// # random_number: usize, /// # } diff --git a/clippy_lints/src/missing_enforced_import_rename.rs b/clippy_lints/src/missing_enforced_import_rename.rs index fc088710e429..16ff98a5922c 100644 --- a/clippy_lints/src/missing_enforced_import_rename.rs +++ b/clippy_lints/src/missing_enforced_import_rename.rs @@ -1,6 +1,6 @@ +use clippy_config::types::Rename; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_opt; - use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::def::Res; @@ -10,8 +10,6 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::Symbol; -use crate::utils::conf::Rename; - declare_clippy_lint! { /// ### What it does /// Checks for imports that do not rename the item as specified diff --git a/clippy_lints/src/missing_fields_in_debug.rs b/clippy_lints/src/missing_fields_in_debug.rs index d205237a5915..95f9df4e42a4 100644 --- a/clippy_lints/src/missing_fields_in_debug.rs +++ b/clippy_lints/src/missing_fields_in_debug.rs @@ -40,7 +40,7 @@ declare_clippy_lint! { /// making it much less likely to accidentally forget to update the `Debug` impl when adding a new variant. /// /// ### Example - /// ```rust + /// ```no_run /// use std::fmt; /// struct Foo { /// data: String, @@ -57,7 +57,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::fmt; /// struct Foo { /// data: String, diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index 93f6025c71d6..0346d80c676b 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -21,7 +21,7 @@ declare_clippy_lint! { /// then opt out for specific methods where this might not make sense. /// /// ### Example - /// ```rust + /// ```no_run /// pub fn foo() {} // missing #[inline] /// fn ok() {} // ok /// #[inline] pub fn bar() {} // ok diff --git a/clippy_lints/src/missing_trait_methods.rs b/clippy_lints/src/missing_trait_methods.rs index 1adecd2caaca..ad5f45a32808 100644 --- a/clippy_lints/src/missing_trait_methods.rs +++ b/clippy_lints/src/missing_trait_methods.rs @@ -21,7 +21,7 @@ declare_clippy_lint! { /// Indicates that a method is missing. /// /// ### Example - /// ```rust + /// ```no_run /// trait Trait { /// fn required(); /// @@ -35,7 +35,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// trait Trait { /// fn required(); /// diff --git a/clippy_lints/src/mixed_read_write_in_expression.rs b/clippy_lints/src/mixed_read_write_in_expression.rs index e87aea263d48..215161b04c7c 100644 --- a/clippy_lints/src/mixed_read_write_in_expression.rs +++ b/clippy_lints/src/mixed_read_write_in_expression.rs @@ -22,7 +22,7 @@ declare_clippy_lint! { /// order, or which is correct for any evaluation order. /// /// ### Example - /// ```rust + /// ```no_run /// let mut x = 0; /// /// let a = { @@ -33,7 +33,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let mut x = 0; /// let tmp = { /// x = 1; diff --git a/clippy_lints/src/multi_assignments.rs b/clippy_lints/src/multi_assignments.rs index 81eb1a085aea..b42dce7a13a3 100644 --- a/clippy_lints/src/multi_assignments.rs +++ b/clippy_lints/src/multi_assignments.rs @@ -13,12 +13,12 @@ declare_clippy_lint! { /// where such assignments return a copy of the assigned value. /// /// ### Example - /// ```rust + /// ```no_run ///# let (a, b); /// a = b = 42; /// ``` /// Use instead: - /// ```rust + /// ```no_run ///# let (a, b); /// b = 42; /// a = b; diff --git a/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 2c42a7a3676a..d4f8008aeced 100644 --- a/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -22,7 +22,7 @@ declare_clippy_lint! { /// elimination of unnecessary unsafe blocks through refactoring. /// /// ### Example - /// ```rust + /// ```no_run /// /// Reads a `char` from the given pointer. /// /// /// /// # Safety @@ -36,7 +36,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// /// Reads a `char` from the given pointer. /// /// /// /// # Safety diff --git a/clippy_lints/src/mut_key.rs b/clippy_lints/src/mut_key.rs index 5878f899541a..683ff859d377 100644 --- a/clippy_lints/src/mut_key.rs +++ b/clippy_lints/src/mut_key.rs @@ -47,7 +47,7 @@ declare_clippy_lint! { /// [#6745](https://github.com/rust-lang/rust-clippy/issues/6745). /// /// ### Example - /// ```rust + /// ```no_run /// use std::cmp::{PartialEq, Eq}; /// use std::collections::HashSet; /// use std::hash::{Hash, Hasher}; diff --git a/clippy_lints/src/mut_mut.rs b/clippy_lints/src/mut_mut.rs index 64d8333a093b..6989504a4a9a 100644 --- a/clippy_lints/src/mut_mut.rs +++ b/clippy_lints/src/mut_mut.rs @@ -17,7 +17,7 @@ declare_clippy_lint! { /// misunderstanding of references. /// /// ### Example - /// ```rust + /// ```no_run /// # let mut y = 1; /// let x = &mut &mut y; /// ``` diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs index 01b850cdb113..4f8e244222d8 100644 --- a/clippy_lints/src/mut_reference.rs +++ b/clippy_lints/src/mut_reference.rs @@ -15,14 +15,14 @@ declare_clippy_lint! { /// the value. Also the code misleads about the intent of the call site. /// /// ### Example - /// ```rust + /// ```no_run /// # let mut vec = Vec::new(); /// # let mut value = 5; /// vec.push(&mut value); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let mut vec = Vec::new(); /// # let value = 5; /// vec.push(&value); diff --git a/clippy_lints/src/mutex_atomic.rs b/clippy_lints/src/mutex_atomic.rs index 99394b9e5fba..9d8c06cd0770 100644 --- a/clippy_lints/src/mutex_atomic.rs +++ b/clippy_lints/src/mutex_atomic.rs @@ -29,14 +29,14 @@ declare_clippy_lint! { /// for waiting before a critical section. /// /// ### Example - /// ```rust + /// ```no_run /// # let y = true; /// # use std::sync::Mutex; /// let x = Mutex::new(&y); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let y = true; /// # use std::sync::atomic::AtomicBool; /// let x = AtomicBool::new(y); @@ -62,13 +62,13 @@ declare_clippy_lint! { /// for waiting before a critical section. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::sync::Mutex; /// let x = Mutex::new(0usize); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # use std::sync::atomic::AtomicUsize; /// let x = AtomicUsize::new(0usize); /// ``` diff --git a/clippy_lints/src/needless_arbitrary_self_type.rs b/clippy_lints/src/needless_arbitrary_self_type.rs index 5457eeec4eac..97e8f1c030ad 100644 --- a/clippy_lints/src/needless_arbitrary_self_type.rs +++ b/clippy_lints/src/needless_arbitrary_self_type.rs @@ -15,7 +15,7 @@ declare_clippy_lint! { /// Increases the amount and decreases the readability of code /// /// ### Example - /// ```rust + /// ```no_run /// enum ValType { /// I32, /// I64, @@ -35,7 +35,7 @@ declare_clippy_lint! { /// /// Could be rewritten as /// - /// ```rust + /// ```no_run /// enum ValType { /// I32, /// I64, diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index f6b87b071b94..02c177c92274 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -32,7 +32,7 @@ declare_clippy_lint! { /// shorter code. /// /// ### Example - /// ```rust + /// ```no_run /// # let x = true; /// if x { /// false @@ -43,7 +43,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let x = true; /// !x /// # ; @@ -207,9 +207,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool { _ => (), } } - if let Some((lhs_a, a)) = fetch_assign(then) && - let Some((lhs_b, b)) = fetch_assign(r#else) && - SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b) + if let Some((lhs_a, a)) = fetch_assign(then) + && let Some((lhs_b, b)) = fetch_assign(r#else) + && SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b) { let mut applicability = Applicability::MachineApplicable; let cond = Sugg::hir_with_applicability(cx, cond, "..", &mut applicability); @@ -226,7 +226,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool { "this if-then-else expression assigns a bool literal", "you can reduce it to", sugg, - applicability + applicability, ); } } diff --git a/clippy_lints/src/needless_borrowed_ref.rs b/clippy_lints/src/needless_borrowed_ref.rs index 11bf9e9ca170..fdb91f0dc0d6 100644 --- a/clippy_lints/src/needless_borrowed_ref.rs +++ b/clippy_lints/src/needless_borrowed_ref.rs @@ -13,7 +13,7 @@ declare_clippy_lint! { /// This pattern has no effect in almost all cases. /// /// ### Example - /// ```rust + /// ```no_run /// let mut v = Vec::::new(); /// v.iter_mut().filter(|&ref a| a.is_empty()); /// @@ -21,7 +21,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let mut v = Vec::::new(); /// v.iter_mut().filter(|a| a.is_empty()); /// diff --git a/clippy_lints/src/needless_borrows_for_generic_args.rs b/clippy_lints/src/needless_borrows_for_generic_args.rs index d55c77a92b15..dcfb109a4c49 100644 --- a/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::mir::{enclosing_mir, expr_local, local_assignments, used_exactly_once, PossibleBorrowerMap}; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::is_copy; use clippy_utils::{expr_use_ctxt, peel_n_hir_expr_refs, DefinedTy, ExprUseNode}; @@ -36,7 +36,7 @@ declare_clippy_lint! { /// in such a case can change the semantics of the code. /// /// ### Example - /// ```rust + /// ```no_run /// fn f(_: impl AsRef) {} /// /// let x = "foo"; @@ -44,7 +44,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// fn f(_: impl AsRef) {} /// /// let x = "foo"; @@ -87,18 +87,24 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> { && let ty::Param(ty) = *ty.value.skip_binder().kind() && let Some((hir_id, fn_id, i)) = match use_cx.node { ExprUseNode::MethodArg(_, _, 0) => None, - ExprUseNode::MethodArg(hir_id, None, i) => { - cx.typeck_results().type_dependent_def_id(hir_id).map(|id| (hir_id, id, i)) - }, - ExprUseNode::FnArg(&Expr { kind: ExprKind::Path(ref p), hir_id, .. }, i) - if !path_has_args(p) => match cx.typeck_results().qpath_res(p, hir_id) { - Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) => { - Some((hir_id, id, i)) + ExprUseNode::MethodArg(hir_id, None, i) => cx + .typeck_results() + .type_dependent_def_id(hir_id) + .map(|id| (hir_id, id, i)), + ExprUseNode::FnArg( + &Expr { + kind: ExprKind::Path(ref p), + hir_id, + .. }, + i, + ) if !path_has_args(p) => match cx.typeck_results().qpath_res(p, hir_id) { + Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) => Some((hir_id, id, i)), _ => None, }, _ => None, - } && let count = needless_borrow_count( + } + && let count = needless_borrow_count( cx, &mut self.possible_borrowers, fn_id, @@ -107,7 +113,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> { ty, expr, &self.msrv, - ) && count != 0 + ) + && count != 0 { span_lint_and_then( cx, @@ -119,7 +126,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> { let snip_span = peel_n_hir_expr_refs(expr, count).0.span; let snip = snippet_with_context(cx, snip_span, expr.span.ctxt(), "..", &mut app).0; diag.span_suggestion(expr.span, "change this to", snip.into_owned(), app); - } + }, ); } } @@ -245,7 +252,9 @@ fn needless_borrow_count<'tcx>( predicates.iter().all(|predicate| { if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() - && cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id) + && cx + .tcx + .is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id) && let ty::Param(param_ty) = trait_predicate.self_ty().kind() && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].unpack() && ty.is_array() @@ -308,13 +317,13 @@ fn is_mixed_projection_predicate<'tcx>( match projection_ty.self_ty().kind() { ty::Alias(ty::Projection, inner_projection_ty) => { projection_ty = *inner_projection_ty; - } + }, ty::Param(param_ty) => { return (param_ty.index as usize) >= generics.parent_count; - } + }, _ => { return false; - } + }, } } } else { diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index 377cbef7b99e..cb2738947d49 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -55,7 +55,7 @@ declare_clippy_lint! { /// statement within the THEN block and omitting the else block completely. /// /// ### Example - /// ```rust + /// ```no_run /// # fn condition() -> bool { false } /// # fn update_condition() {} /// # let x = false; @@ -72,7 +72,7 @@ declare_clippy_lint! { /// /// Could be rewritten as /// - /// ```rust + /// ```no_run /// # fn condition() -> bool { false } /// # fn update_condition() {} /// # let x = false; @@ -87,7 +87,7 @@ declare_clippy_lint! { /// /// As another example, the following code /// - /// ```rust + /// ```no_run /// # fn waiting() -> bool { false } /// loop { /// if waiting() { @@ -100,7 +100,7 @@ declare_clippy_lint! { /// ``` /// Could be rewritten as /// - /// ```rust + /// ```no_run /// # fn waiting() -> bool { false } /// loop { /// if waiting() { @@ -408,7 +408,7 @@ fn check_and_warn(cx: &EarlyContext<'_>, expr: &ast::Expr) { /// till a non-whitespace character is found. e.g., the string. If no closing `}` is present, the /// string will be preserved. /// -/// ```rust +/// ```no_run /// { /// let x = 5; /// } diff --git a/clippy_lints/src/needless_else.rs b/clippy_lints/src/needless_else.rs index 0c1fe881fc10..d881c13f84ad 100644 --- a/clippy_lints/src/needless_else.rs +++ b/clippy_lints/src/needless_else.rs @@ -13,7 +13,7 @@ declare_clippy_lint! { /// An empty else branch does nothing and can be removed. /// /// ### Example - /// ```rust + /// ```no_run ///# fn check() -> bool { true } /// if check() { /// println!("Check successful!"); @@ -21,7 +21,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run ///# fn check() -> bool { true } /// if check() { /// println!("Check successful!"); diff --git a/clippy_lints/src/needless_for_each.rs b/clippy_lints/src/needless_for_each.rs index 98bf122fab74..086c8e6fffe1 100644 --- a/clippy_lints/src/needless_for_each.rs +++ b/clippy_lints/src/needless_for_each.rs @@ -25,14 +25,14 @@ declare_clippy_lint! { /// But when none of these apply, a simple `for` loop is more idiomatic. /// /// ### Example - /// ```rust + /// ```no_run /// let v = vec![0, 1, 2]; /// v.iter().for_each(|elem| { /// println!("{}", elem); /// }) /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let v = vec![0, 1, 2]; /// for elem in v.iter() { /// println!("{}", elem); diff --git a/clippy_lints/src/needless_late_init.rs b/clippy_lints/src/needless_late_init.rs index 948454d13ae7..c8888c744b66 100644 --- a/clippy_lints/src/needless_late_init.rs +++ b/clippy_lints/src/needless_late_init.rs @@ -22,7 +22,7 @@ declare_clippy_lint! { /// Assigning in the `let` statement is less repetitive. /// /// ### Example - /// ```rust + /// ```no_run /// let a; /// a = 1; /// @@ -41,7 +41,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let a = 1; /// /// let b = match 3 { diff --git a/clippy_lints/src/needless_parens_on_range_literals.rs b/clippy_lints/src/needless_parens_on_range_literals.rs index d17a383e8829..7bbf1fb4cd9a 100644 --- a/clippy_lints/src/needless_parens_on_range_literals.rs +++ b/clippy_lints/src/needless_parens_on_range_literals.rs @@ -20,7 +20,7 @@ declare_clippy_lint! { /// /// ### Example /// - /// ```rust + /// ```no_run /// for i in (0)..10 { /// println!("{i}"); /// } @@ -28,7 +28,7 @@ declare_clippy_lint! { /// /// Use instead: /// - /// ```rust + /// ```no_run /// for i in 0..10 { /// println!("{i}"); /// } @@ -46,9 +46,9 @@ fn snippet_enclosed_in_parenthesis(snippet: &str) -> bool { } fn check_for_parens(cx: &LateContext<'_>, e: &Expr<'_>, is_start: bool) { - if is_start && - let ExprKind::Lit(literal) = e.kind && - let ast::LitKind::Float(_sym, ast::LitFloatType::Unsuffixed) = literal.node + if is_start + && let ExprKind::Lit(literal) = e.kind + && let ast::LitKind::Float(_sym, ast::LitFloatType::Unsuffixed) = literal.node { // don't check floating point literals on the start expression of a range return; diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index 1d5874f6feac..d610ba520a48 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -37,13 +37,13 @@ declare_clippy_lint! { /// opportunities for parallelization. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo(y: &mut i32) -> i32 { /// 12 + *y /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn foo(y: &i32) -> i32 { /// 12 + *y /// } @@ -225,7 +225,10 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { if let PatKind::Binding(_, canonical_id, ..) = arg.pat.kind && !mutably_used_vars.contains(&canonical_id) { - self.fn_def_ids_to_maybe_unused_mut.entry(fn_def_id).or_default().push(input); + self.fn_def_ids_to_maybe_unused_mut + .entry(fn_def_id) + .or_default() + .push(input); } } } @@ -520,7 +523,11 @@ impl<'tcx> Visitor<'tcx> for FnNeedsMutVisitor<'_, 'tcx> { // #11182; do not lint if mutability is required elsewhere if let Node::Expr(expr) = cx.tcx.hir().get(hir_id) && let Some(parent) = get_parent_node(cx.tcx, expr.hir_id) - && let ty::FnDef(def_id, _) = cx.tcx.typeck(cx.tcx.hir().enclosing_body_owner(hir_id)).expr_ty(expr).kind() + && let ty::FnDef(def_id, _) = cx + .tcx + .typeck(cx.tcx.hir().enclosing_body_owner(hir_id)) + .expr_ty(expr) + .kind() && let Some(def_id) = def_id.as_local() { if let Node::Expr(e) = parent diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index f3c0d616473f..8fa461ac12c7 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -43,13 +43,13 @@ declare_clippy_lint! { /// (by using `Borrow` trait, for example), depending on how the function is used. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo(v: Vec) { /// assert_eq!(v.len(), 42); /// } /// ``` /// should be - /// ```rust + /// ```no_run /// fn foo(v: &[i32]) { /// assert_eq!(v.len(), 42); /// } diff --git a/clippy_lints/src/needless_question_mark.rs b/clippy_lints/src/needless_question_mark.rs index b3a2060d6ac9..074c9fef1b2d 100644 --- a/clippy_lints/src/needless_question_mark.rs +++ b/clippy_lints/src/needless_question_mark.rs @@ -4,7 +4,7 @@ use clippy_utils::source::snippet; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{CoroutineSource, Block, Body, CoroutineKind, Expr, ExprKind, LangItem, MatchSource, QPath}; +use rustc_hir::{Block, Body, CoroutineKind, CoroutineSource, Expr, ExprKind, LangItem, MatchSource, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -16,7 +16,7 @@ declare_clippy_lint! { /// There's no reason to use `?` to short-circuit when execution of the body will end there anyway. /// /// ### Example - /// ```rust + /// ```no_run /// struct TO { /// magic: Option, /// } @@ -35,7 +35,7 @@ declare_clippy_lint! { /// /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct TO { /// magic: Option, /// } diff --git a/clippy_lints/src/needless_update.rs b/clippy_lints/src/needless_update.rs index 0bd29d1776b2..f8888d368788 100644 --- a/clippy_lints/src/needless_update.rs +++ b/clippy_lints/src/needless_update.rs @@ -17,7 +17,7 @@ declare_clippy_lint! { /// somewhere), and make the code less readable. /// /// ### Example - /// ```rust + /// ```no_run /// # struct Point { /// # x: i32, /// # y: i32, diff --git a/clippy_lints/src/neg_cmp_op_on_partial_ord.rs b/clippy_lints/src/neg_cmp_op_on_partial_ord.rs index a022fc156fca..56c67406d6fd 100644 --- a/clippy_lints/src/neg_cmp_op_on_partial_ord.rs +++ b/clippy_lints/src/neg_cmp_op_on_partial_ord.rs @@ -18,7 +18,7 @@ declare_clippy_lint! { /// especially easy to miss if the operator based comparison result is negated. /// /// ### Example - /// ```rust + /// ```no_run /// let a = 1.0; /// let b = f64::NAN; /// @@ -26,7 +26,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// use std::cmp::Ordering; /// # let a = 1.0; /// # let b = f64::NAN; diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index aee184252fbf..3a28e511fdda 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -23,7 +23,7 @@ declare_clippy_lint! { /// readable. /// /// ### Example - /// ```rust + /// ```no_run /// 0; /// ``` #[clippy::version = "pre 1.29.0"] @@ -103,11 +103,16 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool { && final_stmt.hir_id == stmt.hir_id { let expr_ty = cx.typeck_results().expr_ty(expr); - let mut ret_ty = cx.tcx.fn_sig(item.owner_id).instantiate_identity().output().skip_binder(); + let mut ret_ty = cx + .tcx + .fn_sig(item.owner_id) + .instantiate_identity() + .output() + .skip_binder(); // Remove `impl Future` to get `T` - if cx.tcx.ty_is_opaque_future(ret_ty) && - let Some(true_ret_ty) = cx.tcx.infer_ctxt().build().get_impl_future_output_ty(ret_ty) + if cx.tcx.ty_is_opaque_future(ret_ty) + && let Some(true_ret_ty) = cx.tcx.infer_ctxt().build().get_impl_future_output_ty(ret_ty) { ret_ty = true_ret_ty; } diff --git a/clippy_lints/src/no_mangle_with_rust_abi.rs b/clippy_lints/src/no_mangle_with_rust_abi.rs index 8fd9ae351a0d..04d750148921 100644 --- a/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -18,13 +18,13 @@ declare_clippy_lint! { /// Rust ABI can break this at any point. /// /// ### Example - /// ```rust + /// ```no_run /// #[no_mangle] /// fn example(arg_one: u32, arg_two: usize) {} /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// #[no_mangle] /// extern "C" fn example(arg_one: u32, arg_two: usize) {} /// ``` @@ -48,7 +48,8 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { && let Some((fn_attrs, _)) = snippet.split_once("fn") && !fn_attrs.contains("extern") { - let sugg_span = fn_sig.span + let sugg_span = fn_sig + .span .with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len())) .shrink_to_lo(); diff --git a/clippy_lints/src/non_canonical_impls.rs b/clippy_lints/src/non_canonical_impls.rs index 0e4b6aa1b7d2..9689f63a0135 100644 --- a/clippy_lints/src/non_canonical_impls.rs +++ b/clippy_lints/src/non_canonical_impls.rs @@ -64,7 +64,7 @@ declare_clippy_lint! { /// in `Some`. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::cmp::Ordering; /// #[derive(Eq, PartialEq)] /// struct A(u32); @@ -84,7 +84,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::cmp::Ordering; /// #[derive(Eq, PartialEq)] /// struct A(u32); @@ -131,12 +131,7 @@ impl LateLintPass<'_> for NonCanonicalImpls { if cx.tcx.is_diagnostic_item(sym::Clone, trait_impl.def_id) && let Some(copy_def_id) = cx.tcx.get_diagnostic_item(sym::Copy) - && implements_trait( - cx, - trait_impl.self_ty(), - copy_def_id, - &[], - ) + && implements_trait(cx, trait_impl.self_ty(), copy_def_id, &[]) { if impl_item.ident.name == sym::clone { if block.stmts.is_empty() @@ -144,7 +139,8 @@ impl LateLintPass<'_> for NonCanonicalImpls { && let ExprKind::Unary(UnOp::Deref, deref) = expr.kind && let ExprKind::Path(qpath) = deref.kind && last_path_segment(&qpath).ident.name == kw::SelfLower - {} else { + { + } else { span_lint_and_sugg( cx, NON_CANONICAL_CLONE_IMPL, @@ -197,10 +193,13 @@ impl LateLintPass<'_> for NonCanonicalImpls { && is_res_lang_ctor(cx, cx.qpath_res(some_path, *some_hir_id), LangItem::OptionSome) // Fix #11178, allow `Self::cmp(self, ..)` too && self_cmp_call(cx, cmp_expr, impl_item.owner_id.def_id, &mut needs_fully_qualified) - {} else { + { + } else { // If `Self` and `Rhs` are not the same type, bail. This makes creating a valid // suggestion tons more complex. - if let [lhs, rhs, ..] = trait_impl.args.as_slice() && lhs != rhs { + if let [lhs, rhs, ..] = trait_impl.args.as_slice() + && lhs != rhs + { return; } @@ -238,12 +237,8 @@ impl LateLintPass<'_> for NonCanonicalImpls { ], }; - diag.multipart_suggestion( - "change this to", - suggs, - Applicability::Unspecified, - ); - } + diag.multipart_suggestion("change this to", suggs, Applicability::Unspecified); + }, ); } } diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 613afa46a912..54cec066ba10 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -58,7 +58,7 @@ declare_clippy_lint! { /// [#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and /// /// ### Example - /// ```rust + /// ```no_run /// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; /// /// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12); @@ -67,7 +67,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; /// static STATIC_ATOM: AtomicUsize = AtomicUsize::new(15); /// STATIC_ATOM.store(9, SeqCst); @@ -105,7 +105,7 @@ declare_clippy_lint! { /// [#3825](https://github.com/rust-lang/rust-clippy/issues/3825) /// /// ### Example - /// ```rust + /// ```no_run /// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; /// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12); /// @@ -114,7 +114,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; /// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12); /// diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs index d562047cbf15..182d3747f784 100644 --- a/clippy_lints/src/non_expressive_names.rs +++ b/clippy_lints/src/non_expressive_names.rs @@ -63,7 +63,7 @@ declare_clippy_lint! { /// descriptive name. /// /// ### Example - /// ```rust + /// ```no_run /// let _1 = 1; /// let ___1 = 1; /// let __1___2 = 11; diff --git a/clippy_lints/src/nonstandard_macro_braces.rs b/clippy_lints/src/nonstandard_macro_braces.rs index bd194b93584e..11c3a5417b55 100644 --- a/clippy_lints/src/nonstandard_macro_braces.rs +++ b/clippy_lints/src/nonstandard_macro_braces.rs @@ -1,6 +1,4 @@ -use std::fmt; -use std::hash::{Hash, Hasher}; - +use clippy_config::types::MacroMatcher; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_opt; use if_chain::if_chain; @@ -12,7 +10,6 @@ use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::Span; -use serde::{de, Deserialize}; declare_clippy_lint! { /// ### What it does @@ -23,11 +20,11 @@ declare_clippy_lint! { /// doesn't give you a semicolon in item position, which can be unexpected. /// /// ### Example - /// ```rust + /// ```no_run /// vec!{1, 2, 3}; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// vec![1, 2, 3]; /// ``` #[clippy::version = "1.55.0"] @@ -36,8 +33,6 @@ declare_clippy_lint! { "check consistent use of braces in macro" } -const BRACES: &[(&str, &str)] = &[("(", ")"), ("{", "}"), ("[", "]")]; - /// The (callsite span, (open brace, close brace), source snippet) type MacroInfo<'a> = (Span, &'a (String, String), String); @@ -195,81 +190,3 @@ macro_rules! macro_matcher { }; } pub(crate) use macro_matcher; - -#[derive(Clone, Debug)] -pub struct MacroMatcher { - name: String, - braces: (String, String), -} - -impl Hash for MacroMatcher { - fn hash(&self, state: &mut H) { - self.name.hash(state); - } -} - -impl PartialEq for MacroMatcher { - fn eq(&self, other: &Self) -> bool { - self.name == other.name - } -} -impl Eq for MacroMatcher {} - -impl<'de> Deserialize<'de> for MacroMatcher { - fn deserialize(deser: D) -> Result - where - D: de::Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(field_identifier, rename_all = "lowercase")] - enum Field { - Name, - Brace, - } - struct MacVisitor; - impl<'de> de::Visitor<'de> for MacVisitor { - type Value = MacroMatcher; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("struct MacroMatcher") - } - - fn visit_map(self, mut map: V) -> Result - where - V: de::MapAccess<'de>, - { - let mut name = None; - let mut brace: Option = None; - while let Some(key) = map.next_key()? { - match key { - Field::Name => { - if name.is_some() { - return Err(de::Error::duplicate_field("name")); - } - name = Some(map.next_value()?); - }, - Field::Brace => { - if brace.is_some() { - return Err(de::Error::duplicate_field("brace")); - } - brace = Some(map.next_value()?); - }, - } - } - let name = name.ok_or_else(|| de::Error::missing_field("name"))?; - let brace = brace.ok_or_else(|| de::Error::missing_field("brace"))?; - Ok(MacroMatcher { - name, - braces: BRACES - .iter() - .find(|b| b.0 == brace) - .map(|(o, c)| ((*o).to_owned(), (*c).to_owned())) - .ok_or_else(|| de::Error::custom(format!("expected one of `(`, `{{`, `[` found `{brace}`")))?, - }) - } - } - - const FIELDS: &[&str] = &["name", "brace"]; - deser.deserialize_struct("MacroMatcher", FIELDS, MacVisitor) - } -} diff --git a/clippy_lints/src/octal_escapes.rs b/clippy_lints/src/octal_escapes.rs index 6d3865080a68..0faf4ce3d3e6 100644 --- a/clippy_lints/src/octal_escapes.rs +++ b/clippy_lints/src/octal_escapes.rs @@ -32,13 +32,13 @@ declare_clippy_lint! { /// can see it. /// /// ### Example - /// ```rust + /// ```no_run /// let one = "\033[1m Bold? \033[0m"; // \033 intended as escape /// let two = "\033\0"; // \033 intended as null-3-3 /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let one = "\x1b[1mWill this be bold?\x1b[0m"; /// let two = "\x0033\x00"; /// ``` diff --git a/clippy_lints/src/only_used_in_recursion.rs b/clippy_lints/src/only_used_in_recursion.rs index f0f8d510c7e2..ef7b367649f8 100644 --- a/clippy_lints/src/only_used_in_recursion.rs +++ b/clippy_lints/src/only_used_in_recursion.rs @@ -30,7 +30,7 @@ declare_clippy_lint! { /// /// In some cases, this would not catch all useless arguments. /// - /// ```rust + /// ```no_run /// fn foo(a: usize, b: usize) -> usize { /// let f = |x| x + 1; /// @@ -53,7 +53,7 @@ declare_clippy_lint! { /// Also, when you recurse the function name with path segments, it is not possible to detect. /// /// ### Example - /// ```rust + /// ```no_run /// fn f(a: usize, b: usize) -> usize { /// if a == 0 { /// 1 @@ -66,7 +66,7 @@ declare_clippy_lint! { /// # } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn f(a: usize) -> usize { /// if a == 0 { /// 1 @@ -244,7 +244,10 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { })) => { #[allow(trivial_casts)] if let Some(Node::Item(item)) = get_parent_node(cx.tcx, owner_id.into()) - && let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::instantiate_identity) + && let Some(trait_ref) = cx + .tcx + .impl_trait_ref(item.owner_id) + .map(EarlyBinder::instantiate_identity) && let Some(trait_item_id) = cx.tcx.associated_item(owner_id).trait_item_def_id { ( @@ -288,8 +291,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { // Recursive call. Track which index the parameter is used in. ExprKind::Call(callee, args) if path_def_id(cx, callee).map_or(false, |id| { - id == param.fn_id - && has_matching_args(param.fn_kind, typeck.node_args(callee.hir_id)) + id == param.fn_id && has_matching_args(param.fn_kind, typeck.node_args(callee.hir_id)) }) => { if let Some(idx) = args.iter().position(|arg| arg.hir_id == child_id) { @@ -299,8 +301,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { }, ExprKind::MethodCall(_, receiver, args, _) if typeck.type_dependent_def_id(parent.hir_id).map_or(false, |id| { - id == param.fn_id - && has_matching_args(param.fn_kind, typeck.node_args(parent.hir_id)) + id == param.fn_id && has_matching_args(param.fn_kind, typeck.node_args(parent.hir_id)) }) => { if let Some(idx) = iter::once(receiver).chain(args).position(|arg| arg.hir_id == child_id) { @@ -336,8 +337,8 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { // Only allow field accesses without auto-deref ExprKind::Field(..) if typeck.adjustments().get(child_id).is_none() => { e = parent; - continue - } + continue; + }, _ => (), }, _ => (), diff --git a/clippy_lints/src/operators/arithmetic_side_effects.rs b/clippy_lints/src/operators/arithmetic_side_effects.rs index a10aa65e5948..4e8631eefa1d 100644 --- a/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -71,7 +71,7 @@ impl ArithmeticSideEffects { rhs_has_allowed_ty || rhs_from_specific.contains("*") } { - true + true } else if let Some(rhs_from_glob) = self.allowed_binary.get("*") { rhs_from_glob.contains(rhs_ty_string_elem) } else { @@ -144,8 +144,10 @@ impl ArithmeticSideEffects { /// like `i32::MAX` or constant references like `N` from `const N: i32 = 1;`, fn literal_integer(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option { let actual = peel_hir_expr_unary(expr).0; - if let hir::ExprKind::Lit(lit) = actual.kind && let ast::LitKind::Int(n, _) = lit.node { - return Some(n) + if let hir::ExprKind::Lit(lit) = actual.kind + && let ast::LitKind::Int(n, _) = lit.node + { + return Some(n); } if let Some(Constant::Int(n)) = constant(cx, cx.typeck_results(), expr) { return Some(n); @@ -317,7 +319,9 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects { let body_owner_kind = cx.tcx.hir().body_owner_kind(body_owner_def_id); if let hir::BodyOwnerKind::Const { .. } | hir::BodyOwnerKind::Static(_) = body_owner_kind { let body_span = cx.tcx.hir().span_with_body(body_owner); - if let Some(span) = self.const_span && span.contains(body_span) { + if let Some(span) = self.const_span + && span.contains(body_span) + { return; } self.const_span = Some(body_span); @@ -327,7 +331,9 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects { fn check_body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { let body_owner = cx.tcx.hir().body_owner(body.id()); let body_span = cx.tcx.hir().span(body_owner); - if let Some(span) = self.const_span && span.contains(body_span) { + if let Some(span) = self.const_span + && span.contains(body_span) + { return; } self.const_span = None; diff --git a/clippy_lints/src/operators/eq_op.rs b/clippy_lints/src/operators/eq_op.rs index 88d566318414..fd3502ad878c 100644 --- a/clippy_lints/src/operators/eq_op.rs +++ b/clippy_lints/src/operators/eq_op.rs @@ -8,13 +8,14 @@ use rustc_lint::LateContext; use super::EQ_OP; pub(crate) fn check_assert<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { - if let Some((macro_call, macro_name)) - = first_node_macro_backtrace(cx, e).find_map(|macro_call| { - let name = cx.tcx.item_name(macro_call.def_id); - matches!(name.as_str(), "assert_eq" | "assert_ne" | "debug_assert_eq" | "debug_assert_ne") - .then(|| (macro_call, name)) - }) - && let Some((lhs, rhs, _)) = find_assert_eq_args(cx, e, macro_call.expn) + if let Some((macro_call, macro_name)) = first_node_macro_backtrace(cx, e).find_map(|macro_call| { + let name = cx.tcx.item_name(macro_call.def_id); + matches!( + name.as_str(), + "assert_eq" | "assert_ne" | "debug_assert_eq" | "debug_assert_ne" + ) + .then(|| (macro_call, name)) + }) && let Some((lhs, rhs, _)) = find_assert_eq_args(cx, e, macro_call.expn) && eq_expr_value(cx, lhs, rhs) && macro_call.is_local() && !is_in_test_function(cx.tcx, e.hir_id) @@ -42,7 +43,9 @@ pub(crate) fn check<'tcx>( e.span, &format!("equal expressions as operands to `{}`", op.as_str()), |diag| { - if let BinOpKind::Ne = op && cx.typeck_results().expr_ty(left).is_floating_point() { + if let BinOpKind::Ne = op + && cx.typeck_results().expr_ty(left).is_floating_point() + { diag.note("if you intended to check if the operand is NaN, use `.is_nan()` instead"); } }, diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 6b247cf5f6ae..ee79ea276892 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -48,7 +48,7 @@ declare_clippy_lint! { /// like `#[cfg(target_pointer_width = "64")] ..` instead. /// /// ### Example - /// ```rust + /// ```no_run /// let vec: Vec = Vec::new(); /// if vec.len() <= 0 {} /// if 100 > i32::MAX {} @@ -76,7 +76,7 @@ declare_clippy_lint! { /// desirable to explicitly call checked, wrapping or saturating arithmetic methods. /// /// #### Example - /// ```rust + /// ```no_run /// // `n` can be any number, including `i32::MAX`. /// fn foo(n: i32) -> i32 { /// n + 1 @@ -105,7 +105,7 @@ declare_clippy_lint! { /// can be useful to rule out floating-point numbers. /// /// ### Example - /// ```rust + /// ```no_run /// # let a = 0.0; /// a + 1.0; /// ``` @@ -128,7 +128,7 @@ declare_clippy_lint! { /// implementations that differ from the regular `Op` impl. /// /// ### Example - /// ```rust + /// ```no_run /// let mut a = 5; /// let b = 0; /// // ... @@ -137,7 +137,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let mut a = 5; /// let b = 0; /// // ... @@ -165,7 +165,7 @@ declare_clippy_lint! { /// written as `a = a op a op b` as it's less confusing. /// /// ### Example - /// ```rust + /// ```no_run /// let mut a = 5; /// let b = 2; /// // ... @@ -205,7 +205,7 @@ declare_clippy_lint! { /// test-case for this lint. /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 1; /// if (x & 1 == 2) { } /// ``` @@ -238,7 +238,7 @@ declare_clippy_lint! { /// uncommon). /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 1; /// if (x | 1 > 3) { } /// ``` @@ -261,7 +261,7 @@ declare_clippy_lint! { /// llvm generates better code for `x & 15 == 0` on x86 /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 1; /// if x & 0b1111 == 0 { } /// ``` @@ -280,7 +280,7 @@ declare_clippy_lint! { /// Readability. /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 1; /// # let y = 2; /// if x == y || x < y {} @@ -288,7 +288,7 @@ declare_clippy_lint! { /// /// Use instead: /// - /// ```rust + /// ```no_run /// # let x = 1; /// # let y = 2; /// if x <= y {} @@ -308,7 +308,7 @@ declare_clippy_lint! { /// which is probably not the programmer's intention /// /// ### Example - /// ```rust + /// ```no_run /// # let status_code = 200; /// if status_code <= 400 && status_code > 500 {} /// ``` @@ -328,7 +328,7 @@ declare_clippy_lint! { /// different value entirely. /// /// ### Example - /// ```rust + /// ```no_run /// # let status_code = 200; /// if status_code <= 400 && status_code < 500 {} /// ``` @@ -348,7 +348,7 @@ declare_clippy_lint! { /// `Duration::subsec_millis()` than to calculate them. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::time::Duration; /// # let duration = Duration::new(5, 0); /// let micros = duration.subsec_nanos() / 1_000; @@ -356,7 +356,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # use std::time::Duration; /// # let duration = Duration::new(5, 0); /// let micros = duration.subsec_micros(); @@ -384,7 +384,7 @@ declare_clippy_lint! { /// calls. We may introduce a list of known pure functions in the future. /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 1; /// if x + 1 == x + 1 {} /// @@ -434,7 +434,7 @@ declare_clippy_lint! { /// corrected /// /// ### Example - /// ```rust + /// ```no_run /// let x = 1; /// 0 / x; /// 0 * x; @@ -462,13 +462,13 @@ declare_clippy_lint! { /// with an allow. /// /// ### Example - /// ```rust + /// ```no_run /// pub fn is_roughly_equal(a: f32, b: f32) -> bool { /// (a - b) < f32::EPSILON /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// pub fn is_roughly_equal(a: f32, b: f32) -> bool { /// (a - b).abs() < f32::EPSILON /// } @@ -488,7 +488,7 @@ declare_clippy_lint! { /// meaning. So it just obscures what's going on. Delete it mercilessly. /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 1; /// x / 1 + 0 * 1 - 0 | 0; /// ``` @@ -508,13 +508,13 @@ declare_clippy_lint! { /// remainder. /// /// ### Example - /// ```rust + /// ```no_run /// let x = 3 / 2; /// println!("{}", x); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let x = 3f32 / 2f32; /// println!("{}", x); /// ``` @@ -535,14 +535,14 @@ declare_clippy_lint! { /// needlessly consuming code and heap space. /// /// ### Example - /// ```rust + /// ```no_run /// # let x = "foo"; /// # let y = String::from("foo"); /// if x.to_owned() == y {} /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let x = "foo"; /// # let y = String::from("foo"); /// if x == y {} @@ -566,7 +566,7 @@ declare_clippy_lint! { /// guide](http://www.floating-point-gui.de/errors/comparison). /// /// ### Example - /// ```rust + /// ```no_run /// let x = 1.2331f64; /// let y = 1.2332f64; /// @@ -575,7 +575,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let x = 1.2331f64; /// # let y = 1.2332f64; /// let error_margin = f64::EPSILON; // Use an epsilon for comparison @@ -603,7 +603,7 @@ declare_clippy_lint! { /// guide](http://www.floating-point-gui.de/errors/comparison). /// /// ### Example - /// ```rust + /// ```no_run /// let x: f64 = 1.0; /// const ONE: f64 = 1.00; /// @@ -611,7 +611,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let x: f64 = 1.0; /// # const ONE: f64 = 1.00; /// let error_margin = f64::EPSILON; // Use an epsilon for comparison @@ -638,7 +638,7 @@ declare_clippy_lint! { /// contest, it's probably a bad idea. Use something more underhanded. /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 1; /// let a = x % 1; /// let a = x % -1; @@ -662,7 +662,7 @@ declare_clippy_lint! { /// For example, in Rust `17 % -3 = 2`, but in Python `17 % -3 = -1`. /// /// ### Example - /// ```rust + /// ```no_run /// let x = -17 % 3; /// ``` #[clippy::version = "1.42.0"] @@ -685,12 +685,12 @@ declare_clippy_lint! { /// determination is quite conservative. /// /// ### Example - /// ```rust + /// ```no_run /// let (x,y) = (true, false); /// if x & !y {} // where both x and y are booleans /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let (x,y) = (true, false); /// if x && !y {} /// ``` @@ -710,14 +710,14 @@ declare_clippy_lint! { /// comparing the values they point to. /// /// ### Example - /// ```rust + /// ```no_run /// let a = &[1, 2, 3]; /// let b = &[1, 2, 3]; /// /// assert!(a as *const _ as usize == b as *const _ as usize); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let a = &[1, 2, 3]; /// let b = &[1, 2, 3]; /// @@ -742,7 +742,7 @@ declare_clippy_lint! { /// indexing operations they are assumed not to have any side effects. /// /// ### Example - /// ```rust + /// ```no_run /// struct Event { /// x: i32, /// } @@ -753,7 +753,7 @@ declare_clippy_lint! { /// ``` /// /// Should be: - /// ```rust + /// ```no_run /// struct Event { /// x: i32, /// } diff --git a/clippy_lints/src/option_env_unwrap.rs b/clippy_lints/src/option_env_unwrap.rs index 9c7f7e1cd7f8..7792efe6acd0 100644 --- a/clippy_lints/src/option_env_unwrap.rs +++ b/clippy_lints/src/option_env_unwrap.rs @@ -46,16 +46,19 @@ impl EarlyLintPass for OptionEnvUnwrap { ); } - if let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &expr.kind && - matches!(seg.ident.name, sym::expect | sym::unwrap) { - if let ExprKind::Call(caller, _) = &receiver.kind && + if let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &expr.kind + && matches!(seg.ident.name, sym::expect | sym::unwrap) + { + if let ExprKind::Call(caller, _) = &receiver.kind && // If it exists, it will be ::core::option::Option::Some("").unwrap() (A method call in the HIR) - is_direct_expn_of(caller.span, "option_env").is_some() { - lint(cx, expr.span); - } else if let ExprKind::Path(_, caller) = &receiver.kind && // If it doesn't exist, it will be ::core::option::Option::None::<&'static str>.unwrap() (A path in the HIR) - is_direct_expn_of(caller.span, "option_env").is_some() { - lint(cx, expr.span); - } - } + is_direct_expn_of(caller.span, "option_env").is_some() + { + lint(cx, expr.span); + } else if let ExprKind::Path(_, caller) = &receiver.kind && // If it doesn't exist, it will be ::core::option::Option::None::<&'static str>.unwrap() (A path in the HIR) + is_direct_expn_of(caller.span, "option_env").is_some() + { + lint(cx, expr.span); + } + } } } diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index a7a7f4fd8fa2..d7cbbe13a261 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -32,7 +32,7 @@ declare_clippy_lint! { /// this lint will not be raised. /// /// ### Example - /// ```rust + /// ```no_run /// # let optional: Option = Some(0); /// # fn do_complicated_function() -> u32 { 5 }; /// let _ = if let Some(foo) = optional { @@ -54,7 +54,7 @@ declare_clippy_lint! { /// /// should be /// - /// ```rust + /// ```no_run /// # let optional: Option = Some(0); /// # fn do_complicated_function() -> u32 { 5 }; /// let _ = optional.map_or(5, |foo| foo); @@ -165,6 +165,12 @@ fn try_get_option_occurrence<'tcx>( } let mut app = Applicability::Unspecified; + + let (none_body, is_argless_call) = match none_body.kind { + ExprKind::Call(call_expr, []) if !none_body.span.from_expansion() => (call_expr, true), + _ => (none_body, false), + }; + return Some(OptionOccurrence { option: format_option_in_sugg( Sugg::hir_with_context(cx, cond_expr, ctxt, "..", &mut app), @@ -178,7 +184,7 @@ fn try_get_option_occurrence<'tcx>( ), none_expr: format!( "{}{}", - if method_sugg == "map_or" { "" } else if is_result { "|_| " } else { "|| "}, + if method_sugg == "map_or" || is_argless_call { "" } else if is_result { "|_| " } else { "|| "}, Sugg::hir_with_context(cx, none_body, ctxt, "..", &mut app), ), }); @@ -234,7 +240,7 @@ fn try_convert_match<'tcx>( if let [first_arm, second_arm] = arms && first_arm.guard.is_none() && second_arm.guard.is_none() - { + { return if is_none_or_err_arm(cx, second_arm) { Some((first_arm.pat, first_arm.body, second_arm.body)) } else if is_none_or_err_arm(cx, first_arm) { diff --git a/clippy_lints/src/overflow_check_conditional.rs b/clippy_lints/src/overflow_check_conditional.rs index 6dabbd480311..38cd5043adc7 100644 --- a/clippy_lints/src/overflow_check_conditional.rs +++ b/clippy_lints/src/overflow_check_conditional.rs @@ -14,7 +14,7 @@ declare_clippy_lint! { /// Rust. Users can use functions like `overflowing_*` and `wrapping_*` instead. /// /// ### Example - /// ```rust + /// ```no_run /// # let a = 1; /// # let b = 2; /// a + b < a; diff --git a/clippy_lints/src/panic_in_result_fn.rs b/clippy_lints/src/panic_in_result_fn.rs index a049427d85d9..6a760f9fe64a 100644 --- a/clippy_lints/src/panic_in_result_fn.rs +++ b/clippy_lints/src/panic_in_result_fn.rs @@ -22,14 +22,14 @@ declare_clippy_lint! { /// Functions called from a function returning a `Result` may invoke a panicking macro. This is not checked. /// /// ### Example - /// ```rust + /// ```no_run /// fn result_with_panic() -> Result /// { /// panic!("error"); /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn result_without_panic() -> Result { /// Err(String::from("error")) /// } diff --git a/clippy_lints/src/panic_unimplemented.rs b/clippy_lints/src/panic_unimplemented.rs index a72aefe91c12..f4f1f6ddb3f2 100644 --- a/clippy_lints/src/panic_unimplemented.rs +++ b/clippy_lints/src/panic_unimplemented.rs @@ -9,7 +9,7 @@ declare_clippy_lint! { /// Checks for usage of `panic!`. /// /// ### Why is this bad? - /// `panic!` will stop the execution of the executable + /// `panic!` will stop the execution of the executable. /// /// ### Example /// ```no_run @@ -26,7 +26,7 @@ declare_clippy_lint! { /// Checks for usage of `unimplemented!`. /// /// ### Why is this bad? - /// This macro should not be present in production code + /// This macro should not be present in production code. /// /// ### Example /// ```no_run @@ -43,12 +43,17 @@ declare_clippy_lint! { /// Checks for usage of `todo!`. /// /// ### Why is this bad? - /// This macro should not be present in production code + /// The `todo!` macro is often used for unfinished code, and it causes + /// code to panic. It should not be present in production code. /// /// ### Example /// ```no_run /// todo!(); /// ``` + /// Finish the implementation, or consider marking it as explicitly unimplemented. + /// ```no_run + /// unimplemented!(); + /// ``` #[clippy::version = "1.40.0"] pub TODO, restriction, @@ -60,7 +65,7 @@ declare_clippy_lint! { /// Checks for usage of `unreachable!`. /// /// ### Why is this bad? - /// This macro can cause code to panic + /// This macro can cause code to panic. /// /// ### Example /// ```no_run diff --git a/clippy_lints/src/partial_pub_fields.rs b/clippy_lints/src/partial_pub_fields.rs index f60d9d65b120..99ba55b6b310 100644 --- a/clippy_lints/src/partial_pub_fields.rs +++ b/clippy_lints/src/partial_pub_fields.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// * Data: relatively simple objects which group a bunch of related attributes together. /// /// ### Example - /// ```rust + /// ```no_run /// pub struct Color { /// pub r: u8, /// pub g: u8, @@ -24,7 +24,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// pub struct Color { /// pub r: u8, /// pub g: u8, diff --git a/clippy_lints/src/partialeq_ne_impl.rs b/clippy_lints/src/partialeq_ne_impl.rs index a8c4823fe538..68d3d00ac16d 100644 --- a/clippy_lints/src/partialeq_ne_impl.rs +++ b/clippy_lints/src/partialeq_ne_impl.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// re-implement it. /// /// ### Example - /// ```rust + /// ```no_run /// struct Foo; /// /// impl PartialEq for Foo { diff --git a/clippy_lints/src/partialeq_to_none.rs b/clippy_lints/src/partialeq_to_none.rs index d9f5d1642d76..11e9a2bc3946 100644 --- a/clippy_lints/src/partialeq_to_none.rs +++ b/clippy_lints/src/partialeq_to_none.rs @@ -21,13 +21,13 @@ declare_clippy_lint! { /// way relies on `T: PartialEq` to do the comparison, which is unneeded. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo(f: Option) -> &'static str { /// if f != None { "yay" } else { "nay" } /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn foo(f: Option) -> &'static str { /// if f.is_some() { "yay" } else { "nay" } /// } diff --git a/clippy_lints/src/pass_by_ref_or_value.rs b/clippy_lints/src/pass_by_ref_or_value.rs index 41513647f054..4d7a055dae17 100644 --- a/clippy_lints/src/pass_by_ref_or_value.rs +++ b/clippy_lints/src/pass_by_ref_or_value.rs @@ -58,12 +58,12 @@ declare_clippy_lint! { /// /// ### Example /// - /// ```rust + /// ```no_run /// fn foo(v: &u32) {} /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// fn foo(v: u32) {} /// ``` #[clippy::version = "pre 1.29.0"] @@ -86,7 +86,7 @@ declare_clippy_lint! { /// `memcpy`, which can be expensive. /// /// ### Example - /// ```rust + /// ```no_run /// #[derive(Clone, Copy)] /// struct TooLarge([u8; 2048]); /// @@ -94,7 +94,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # #[derive(Clone, Copy)] /// # struct TooLarge([u8; 2048]); /// fn foo(v: &TooLarge) {} @@ -208,7 +208,10 @@ impl<'tcx> PassByRefOrValue { cx, TRIVIALLY_COPY_PASS_BY_REF, input.span, - &format!("this argument ({size} byte) is passed by reference, but would be more efficient if passed by value (limit: {} byte)", self.ref_min_size), + &format!( + "this argument ({size} byte) is passed by reference, but would be more efficient if passed by value (limit: {} byte)", + self.ref_min_size + ), "consider passing by value instead", value_type, Applicability::Unspecified, diff --git a/clippy_lints/src/permissions_set_readonly_false.rs b/clippy_lints/src/permissions_set_readonly_false.rs index f3089d716ff1..b98005d59224 100644 --- a/clippy_lints/src/permissions_set_readonly_false.rs +++ b/clippy_lints/src/permissions_set_readonly_false.rs @@ -14,7 +14,7 @@ declare_clippy_lint! { /// On Unix platforms this results in the file being world writable, /// equivalent to `chmod a+w `. /// ### Example - /// ```rust + /// ```no_run /// use std::fs::File; /// let f = File::create("foo.txt").unwrap(); /// let metadata = f.metadata().unwrap(); @@ -43,9 +43,11 @@ impl<'tcx> LateLintPass<'tcx> for PermissionsSetReadonlyFalse { "call to `set_readonly` with argument `false`", |diag| { diag.note("on Unix platforms this results in the file being world writable"); - diag.help("you can set the desired permissions using `PermissionsExt`. For more information, see\n\ - https://doc.rust-lang.org/std/os/unix/fs/trait.PermissionsExt.html"); - } + diag.help( + "you can set the desired permissions using `PermissionsExt`. For more information, see\n\ + https://doc.rust-lang.org/std/os/unix/fs/trait.PermissionsExt.html", + ); + }, ); } } diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 310051efc508..945b78185d97 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -289,10 +289,7 @@ fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { | sym::ptr_write_volatile | sym::slice_from_raw_parts | sym::slice_from_raw_parts_mut => &[0], - sym::ptr_copy - | sym::ptr_copy_nonoverlapping - | sym::ptr_swap - | sym::ptr_swap_nonoverlapping => &[0, 1], + sym::ptr_copy | sym::ptr_copy_nonoverlapping | sym::ptr_swap | sym::ptr_swap_nonoverlapping => &[0, 1], _ => return, }; @@ -416,7 +413,6 @@ impl<'tcx> DerefTy<'tcx> { } } -#[expect(clippy::too_many_lines)] fn check_fn_args<'cx, 'tcx: 'cx>( cx: &'cx LateContext<'tcx>, fn_sig: ty::FnSig<'tcx>, @@ -438,104 +434,93 @@ fn check_fn_args<'cx, 'tcx: 'cx>( && let [.., name] = path.segments && cx.tcx.item_name(adt.did()) == name.ident.name { - let emission_id = params.get(i).map_or(hir_ty.hir_id, |param| param.hir_id); - let (method_renames, deref_ty) = match cx.tcx.get_diagnostic_name(adt.did()) { - Some(sym::Vec) => ( - [("clone", ".to_owned()")].as_slice(), - DerefTy::Slice( - name.args - .and_then(|args| args.args.first()) - .and_then(|arg| if let GenericArg::Type(ty) = arg { - Some(ty.span) - } else { - None - }), - args.type_at(0), - ), - ), - _ if Some(adt.did()) == cx.tcx.lang_items().string() => ( - [("clone", ".to_owned()"), ("as_str", "")].as_slice(), - DerefTy::Str, - ), - Some(sym::PathBuf) => ( - [("clone", ".to_path_buf()"), ("as_path", "")].as_slice(), - DerefTy::Path, - ), - Some(sym::Cow) if mutability == Mutability::Not => { - if let Some((lifetime, ty)) = name.args - .and_then(|args| { - if let [GenericArg::Lifetime(lifetime), ty] = args.args { - return Some((lifetime, ty)); - } + let emission_id = params.get(i).map_or(hir_ty.hir_id, |param| param.hir_id); + let (method_renames, deref_ty) = match cx.tcx.get_diagnostic_name(adt.did()) { + Some(sym::Vec) => ( + [("clone", ".to_owned()")].as_slice(), + DerefTy::Slice( + name.args.and_then(|args| args.args.first()).and_then(|arg| { + if let GenericArg::Type(ty) = arg { + Some(ty.span) + } else { None - }) - { - if !lifetime.is_anonymous() - && fn_sig.output() - .walk() - .filter_map(|arg| { - arg.as_region().and_then(|lifetime| { - match lifetime.kind() { - ty::ReEarlyBound(r) => Some(r.def_id), - ty::ReLateBound(_, r) => r.kind.get_id(), - ty::ReFree(r) => r.bound_region.get_id(), - ty::ReStatic - | ty::ReVar(_) - | ty::RePlaceholder(_) - | ty::ReErased - | ty::ReError(_) => None, - } - }) - }) - .any(|def_id| { - matches!( - lifetime.res, - LifetimeName::Param(param_def_id) if def_id - .as_local() - .is_some_and(|def_id| def_id == param_def_id), - ) - }) - { - // `&Cow<'a, T>` when the return type uses 'a is okay - return None; } - - let ty_name = - snippet_opt(cx, ty.span()).unwrap_or_else(|| args.type_at(1).to_string()); - - span_lint_hir_and_then( - cx, - PTR_ARG, - emission_id, - hir_ty.span, - "using a reference to `Cow` is not recommended", - |diag| { - diag.span_suggestion( - hir_ty.span, - "change this to", - format!("&{}{ty_name}", mutability.prefix_str()), - Applicability::Unspecified, - ); - } - ); + }), + args.type_at(0), + ), + ), + _ if Some(adt.did()) == cx.tcx.lang_items().string() => { + ([("clone", ".to_owned()"), ("as_str", "")].as_slice(), DerefTy::Str) + }, + Some(sym::PathBuf) => ([("clone", ".to_path_buf()"), ("as_path", "")].as_slice(), DerefTy::Path), + Some(sym::Cow) if mutability == Mutability::Not => { + if let Some((lifetime, ty)) = name.args.and_then(|args| { + if let [GenericArg::Lifetime(lifetime), ty] = args.args { + return Some((lifetime, ty)); + } + None + }) { + if !lifetime.is_anonymous() + && fn_sig + .output() + .walk() + .filter_map(|arg| { + arg.as_region().and_then(|lifetime| match lifetime.kind() { + ty::ReEarlyBound(r) => Some(r.def_id), + ty::ReLateBound(_, r) => r.kind.get_id(), + ty::ReFree(r) => r.bound_region.get_id(), + ty::ReStatic + | ty::ReVar(_) + | ty::RePlaceholder(_) + | ty::ReErased + | ty::ReError(_) => None, + }) + }) + .any(|def_id| { + matches!( + lifetime.res, + LifetimeName::Param(param_def_id) if def_id + .as_local() + .is_some_and(|def_id| def_id == param_def_id), + ) + }) + { + // `&Cow<'a, T>` when the return type uses 'a is okay + return None; } - return None; - }, - _ => return None, - }; - return Some(PtrArg { - idx: i, - emission_id, - span: hir_ty.span, - ty_did: adt.did(), - ty_name: name.ident.name, - method_renames, - ref_prefix: RefPrefix { - lt: *lt, - mutability, - }, - deref_ty, - }); + + let ty_name = snippet_opt(cx, ty.span()).unwrap_or_else(|| args.type_at(1).to_string()); + + span_lint_hir_and_then( + cx, + PTR_ARG, + emission_id, + hir_ty.span, + "using a reference to `Cow` is not recommended", + |diag| { + diag.span_suggestion( + hir_ty.span, + "change this to", + format!("&{}{ty_name}", mutability.prefix_str()), + Applicability::Unspecified, + ); + }, + ); + } + return None; + }, + _ => return None, + }; + return Some(PtrArg { + idx: i, + emission_id, + span: hir_ty.span, + ty_did: adt.did(), + ty_name: name.ident.name, + method_renames, + ref_prefix: RefPrefix { lt: *lt, mutability }, + deref_ty, + }); } None }) diff --git a/clippy_lints/src/ptr_offset_with_cast.rs b/clippy_lints/src/ptr_offset_with_cast.rs index 20e032d4b010..66d869bc45a0 100644 --- a/clippy_lints/src/ptr_offset_with_cast.rs +++ b/clippy_lints/src/ptr_offset_with_cast.rs @@ -17,7 +17,7 @@ declare_clippy_lint! { /// cast by using the `add` method instead. /// /// ### Example - /// ```rust + /// ```no_run /// let vec = vec![b'a', b'b', b'c']; /// let ptr = vec.as_ptr(); /// let offset = 1_usize; @@ -29,7 +29,7 @@ declare_clippy_lint! { /// /// Could be written: /// - /// ```rust + /// ```no_run /// let vec = vec![b'a', b'b', b'c']; /// let ptr = vec.as_ptr(); /// let offset = 1_usize; diff --git a/clippy_lints/src/pub_use.rs b/clippy_lints/src/pub_use.rs index 9d2b0cedb60a..316a72988aab 100644 --- a/clippy_lints/src/pub_use.rs +++ b/clippy_lints/src/pub_use.rs @@ -14,7 +14,7 @@ declare_clippy_lint! { /// unintentional exports or to encourage placing exported items directly in public modules /// /// ### Example - /// ```rust + /// ```no_run /// pub mod outer { /// mod inner { /// pub struct Test {} @@ -25,7 +25,7 @@ declare_clippy_lint! { /// use outer::Test; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// pub mod outer { /// pub struct Test {} /// } @@ -41,16 +41,17 @@ declare_lint_pass!(PubUse => [PUB_USE]); impl EarlyLintPass for PubUse { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { - if let ItemKind::Use(_) = item.kind && - let VisibilityKind::Public = item.vis.kind { - span_lint_and_help( - cx, - PUB_USE, - item.span, - "using `pub use`", - None, - "move the exported item to a public module instead", - ); - } + if let ItemKind::Use(_) = item.kind + && let VisibilityKind::Public = item.vis.kind + { + span_lint_and_help( + cx, + PUB_USE, + item.span, + "using `pub use`", + None, + "move the exported item to a public module instead", + ); + } } } diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index 734ca2914f5d..b133635e8835 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -1,7 +1,8 @@ -use crate::manual_let_else::{MatchLintBehaviour, MANUAL_LET_ELSE}; +use crate::manual_let_else::MANUAL_LET_ELSE; use crate::question_mark_used::QUESTION_MARK_USED; +use clippy_config::msrvs::Msrv; +use clippy_config::types::MatchLintBehaviour; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::Msrv; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{ @@ -97,16 +98,23 @@ enum IfBlockType<'hir> { } fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) { - if let StmtKind::Local(Local { pat, init: Some(init_expr), els: Some(els), .. }) = stmt.kind && - let Block { stmts: &[], expr: Some(els), .. } = els && - let Some(inner_pat) = pat_and_expr_can_be_question_mark(cx, pat, els) + if let StmtKind::Local(Local { + pat, + init: Some(init_expr), + els: Some(els), + .. + }) = stmt.kind + && let Block { + stmts: &[], + expr: Some(els), + .. + } = els + && let Some(inner_pat) = pat_and_expr_can_be_question_mark(cx, pat, els) { let mut applicability = Applicability::MaybeIncorrect; let init_expr_str = snippet_with_applicability(cx, init_expr.span, "..", &mut applicability); let receiver_str = snippet_with_applicability(cx, inner_pat.span, "..", &mut applicability); - let sugg = format!( - "let {receiver_str} = {init_expr_str}?;", - ); + let sugg = format!("let {receiver_str} = {init_expr_str}?;",); span_lint_and_sugg( cx, QUESTION_MARK, diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index 3287675a82de..ffd49de3820a 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then}; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{snippet, snippet_opt, snippet_with_applicability}; use clippy_utils::sugg::Sugg; use clippy_utils::{get_parent_expr, higher, in_constant, is_integer_const, path_to_local}; @@ -39,7 +39,7 @@ declare_clippy_lint! { /// ([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)). /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 0; /// # let y = 1; /// for i in x..(y+1) { @@ -48,7 +48,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let x = 0; /// # let y = 1; /// for i in x..=y { @@ -77,7 +77,7 @@ declare_clippy_lint! { /// ([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)). /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 0; /// # let y = 1; /// for i in x..=(y-1) { @@ -86,7 +86,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let x = 0; /// # let y = 1; /// for i in x..y { @@ -118,7 +118,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn main() { /// (0..=10).rev().for_each(|x| println!("{}", x)); /// @@ -142,14 +142,14 @@ declare_clippy_lint! { /// failure modes (such as fencepost errors or using `||` instead of `&&`). /// /// ### Example - /// ```rust + /// ```no_run /// // given /// let x = 6; /// /// assert!(x >= 3 && x < 8); /// ``` /// Use instead: - /// ```rust + /// ```no_run ///# let x = 6; /// assert!((3..8).contains(&x)); /// ``` diff --git a/clippy_lints/src/raw_strings.rs b/clippy_lints/src/raw_strings.rs index c951d9a4a09d..391c77dbf902 100644 --- a/clippy_lints/src/raw_strings.rs +++ b/clippy_lints/src/raw_strings.rs @@ -20,11 +20,11 @@ declare_clippy_lint! { /// idiomatic than a string literal, so it's opt-in. /// /// ### Example - /// ```rust + /// ```no_run /// let r = r"Hello, world!"; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let r = "Hello, world!"; /// ``` #[clippy::version = "1.72.0"] @@ -41,11 +41,11 @@ declare_clippy_lint! { /// necessary. /// /// ### Example - /// ```rust + /// ```no_run /// let r = r###"Hello, "world"!"###; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let r = r#"Hello, "world"!"#; /// ``` #[clippy::version = "1.72.0"] diff --git a/clippy_lints/src/rc_clone_in_vec_init.rs b/clippy_lints/src/rc_clone_in_vec_init.rs index bd0ca66b7618..59ce289e7d2b 100644 --- a/clippy_lints/src/rc_clone_in_vec_init.rs +++ b/clippy_lints/src/rc_clone_in_vec_init.rs @@ -21,13 +21,13 @@ declare_clippy_lint! { /// than different instances. /// /// ### Example - /// ```rust + /// ```no_run /// let v = vec![std::sync::Arc::new("some data".to_string()); 100]; /// // or /// let v = vec![std::rc::Rc::new("some data".to_string()); 100]; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// // Initialize each value separately: /// let mut data = Vec::with_capacity(100); /// for _ in 0..100 { diff --git a/clippy_lints/src/read_zero_byte_vec.rs b/clippy_lints/src/read_zero_byte_vec.rs index 2bf90815caad..b27d4cc6e4f8 100644 --- a/clippy_lints/src/read_zero_byte_vec.rs +++ b/clippy_lints/src/read_zero_byte_vec.rs @@ -24,7 +24,7 @@ declare_clippy_lint! { /// a zero-byte read would allocate a `Vec` for it. /// /// ### Example - /// ```rust + /// ```no_run /// use std::io; /// fn foo(mut f: F) { /// let mut data = Vec::with_capacity(100); @@ -32,7 +32,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::io; /// fn foo(mut f: F) { /// let mut data = Vec::with_capacity(100); @@ -42,7 +42,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.63.0"] pub READ_ZERO_BYTE_VEC, - correctness, + nursery, "checks for reads into a zero-length `Vec`" } declare_lint_pass!(ReadZeroByteVec => [READ_ZERO_BYTE_VEC]); @@ -59,7 +59,10 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec { { let visitor = |expr: &Expr<'_>| { if let ExprKind::MethodCall(path, _, [arg], _) = expr.kind - && let PathSegment { ident: read_or_read_exact, .. } = *path + && let PathSegment { + ident: read_or_read_exact, + .. + } = *path && matches!(read_or_read_exact.as_str(), "read" | "read_exact") && let ExprKind::AddrOf(_, hir::Mutability::Mut, inner) = arg.kind && let ExprKind::Path(QPath::Resolved(None, inner_path)) = inner.kind @@ -72,15 +75,14 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec { } }; - let (read_found, next_stmt_span) = - if let Some(next_stmt) = block.stmts.get(idx + 1) { + let (read_found, next_stmt_span) = if let Some(next_stmt) = block.stmts.get(idx + 1) { // case { .. stmt; stmt; .. } (for_each_expr(next_stmt, visitor).is_some(), next_stmt.span) } else if let Some(e) = block.expr { // case { .. stmt; expr } (for_each_expr(e, visitor).is_some(), e.span) } else { - return + return; }; if read_found && !next_stmt_span.from_expansion() { @@ -93,13 +95,14 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec { next_stmt_span, "reading zero byte data to `Vec`", "try", - format!("{}.resize({len}, 0); {}", + format!( + "{}.resize({len}, 0); {}", ident.as_str(), snippet(cx, next_stmt_span, "..") ), applicability, ); - } + }, VecInitKind::WithExprCapacity(hir_id) => { let e = cx.tcx.hir().expect_expr(hir_id); span_lint_and_sugg( @@ -108,14 +111,15 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec { next_stmt_span, "reading zero byte data to `Vec`", "try", - format!("{}.resize({}, 0); {}", + format!( + "{}.resize({}, 0); {}", ident.as_str(), snippet(cx, e.span, ".."), snippet(cx, next_stmt_span, "..") ), applicability, ); - } + }, _ => { span_lint( cx, @@ -123,8 +127,7 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec { next_stmt_span, "reading zero byte data to `Vec`", ); - - } + }, } } } diff --git a/clippy_lints/src/redundant_async_block.rs b/clippy_lints/src/redundant_async_block.rs index bf9bdacba5b9..90297ca8bb61 100644 --- a/clippy_lints/src/redundant_async_block.rs +++ b/clippy_lints/src/redundant_async_block.rs @@ -5,7 +5,7 @@ use clippy_utils::peel_blocks; use clippy_utils::source::{snippet, walk_span_to_context}; use clippy_utils::visitors::for_each_expr; use rustc_errors::Applicability; -use rustc_hir::{CoroutineSource, Closure, CoroutineKind, Expr, ExprKind, MatchSource}; +use rustc_hir::{Closure, CoroutineKind, CoroutineSource, Expr, ExprKind, MatchSource}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::UpvarCapture; @@ -19,7 +19,7 @@ declare_clippy_lint! { /// It is simpler and more efficient to use the future directly. /// /// ### Example - /// ```rust + /// ```no_run /// let f = async { /// 1 + 2 /// }; @@ -28,7 +28,7 @@ declare_clippy_lint! { /// }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let f = async { /// 1 + 2 /// }; @@ -69,12 +69,11 @@ impl<'tcx> LateLintPass<'tcx> for RedundantAsyncBlock { /// If `expr` is a desugared `async` block, return the original expression if it does not capture /// any variable by ref. fn desugar_async_block<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { - if let ExprKind::Closure(Closure { body, def_id, .. }) = expr.kind && - let body = cx.tcx.hir().body(*body) && - matches!(body.coroutine_kind, Some(CoroutineKind::Async(CoroutineSource::Block))) + if let ExprKind::Closure(Closure { body, def_id, .. }) = expr.kind + && let body = cx.tcx.hir().body(*body) + && matches!(body.coroutine_kind, Some(CoroutineKind::Async(CoroutineSource::Block))) { - cx - .typeck_results() + cx.typeck_results() .closure_min_captures .get(def_id) .map_or(true, |m| { @@ -93,12 +92,13 @@ fn desugar_async_block<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Op /// If `expr` is a desugared `.await`, return the original expression if it does not come from a /// macro expansion. fn desugar_await<'tcx>(expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { - if let ExprKind::Match(match_value, _, MatchSource::AwaitDesugar) = expr.kind && - let ExprKind::Call(_, [into_future_arg]) = match_value.kind && - let ctxt = expr.span.ctxt() && - for_each_expr(into_future_arg, |e| - walk_span_to_context(e.span, ctxt) - .map_or(ControlFlow::Break(()), |_| ControlFlow::Continue(()))).is_none() + if let ExprKind::Match(match_value, _, MatchSource::AwaitDesugar) = expr.kind + && let ExprKind::Call(_, [into_future_arg]) = match_value.kind + && let ctxt = expr.span.ctxt() + && for_each_expr(into_future_arg, |e| { + walk_span_to_context(e.span, ctxt).map_or(ControlFlow::Break(()), |_| ControlFlow::Continue(())) + }) + .is_none() { Some(into_future_arg) } else { diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index 2c0086b09813..ef14e68967e4 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -37,7 +37,7 @@ declare_clippy_lint! { /// False-negatives: analysis performed by this lint is conservative and limited. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::path::Path; /// # #[derive(Clone)] /// # struct Foo; diff --git a/clippy_lints/src/redundant_closure_call.rs b/clippy_lints/src/redundant_closure_call.rs index c18237e887db..e679fab5323d 100644 --- a/clippy_lints/src/redundant_closure_call.rs +++ b/clippy_lints/src/redundant_closure_call.rs @@ -23,12 +23,12 @@ declare_clippy_lint! { /// complexity. /// /// ### Example - /// ```rust + /// ```no_run /// let a = (|| 42)(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let a = 42; /// ``` #[clippy::version = "pre 1.29.0"] @@ -98,11 +98,15 @@ fn find_innermost_closure<'tcx>( && steps > 0 { expr = body.value; - data = Some((body.value, closure.fn_decl, if is_async_closure(body) { - ty::Asyncness::Yes - } else { - ty::Asyncness::No - })); + data = Some(( + body.value, + closure.fn_decl, + if is_async_closure(body) { + ty::Asyncness::Yes + } else { + ty::Asyncness::No + }, + )); steps -= 1; } @@ -154,7 +158,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { |diag| { if fn_decl.inputs.is_empty() { let mut applicability = Applicability::MachineApplicable; - let mut hint = Sugg::hir_with_context(cx, body, full_expr.span.ctxt(), "..", &mut applicability); + let mut hint = + Sugg::hir_with_context(cx, body, full_expr.span.ctxt(), "..", &mut applicability); if coroutine_kind.is_async() && let hir::ExprKind::Closure(closure) = body.kind @@ -173,10 +178,10 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { full_expr.span, "try doing something like", hint.maybe_par(), - applicability + applicability, ); } - } + }, ); } } diff --git a/clippy_lints/src/redundant_else.rs b/clippy_lints/src/redundant_else.rs index 73088ce1a87e..221aa317e5d4 100644 --- a/clippy_lints/src/redundant_else.rs +++ b/clippy_lints/src/redundant_else.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// Some may prefer to keep the `else` block for clarity. /// /// ### Example - /// ```rust + /// ```no_run /// fn my_func(count: u32) { /// if count == 0 { /// print!("Nothing to do"); @@ -27,7 +27,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn my_func(count: u32) { /// if count == 0 { /// print!("Nothing to do"); diff --git a/clippy_lints/src/redundant_field_names.rs b/clippy_lints/src/redundant_field_names.rs index 61bff4a0e38d..b8e606df737c 100644 --- a/clippy_lints/src/redundant_field_names.rs +++ b/clippy_lints/src/redundant_field_names.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use rustc_ast::ast::{Expr, ExprKind}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; @@ -16,7 +16,7 @@ declare_clippy_lint! { /// the field name is redundant. /// /// ### Example - /// ```rust + /// ```no_run /// let bar: u8 = 123; /// /// struct Foo { diff --git a/clippy_lints/src/redundant_locals.rs b/clippy_lints/src/redundant_locals.rs index a1a0e8f35208..6bc0d06183f3 100644 --- a/clippy_lints/src/redundant_locals.rs +++ b/clippy_lints/src/redundant_locals.rs @@ -20,7 +20,7 @@ declare_clippy_lint! { /// Note that although these bindings do not affect your code's meaning, they _may_ affect `rustc`'s stack allocation. /// /// ### Example - /// ```rust + /// ```no_run /// let a = 0; /// let a = a; /// @@ -29,7 +29,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let a = 0; /// // no redefinition with the same name /// diff --git a/clippy_lints/src/redundant_pub_crate.rs b/clippy_lints/src/redundant_pub_crate.rs index c2a8db7df038..03673eb27f8f 100644 --- a/clippy_lints/src/redundant_pub_crate.rs +++ b/clippy_lints/src/redundant_pub_crate.rs @@ -18,14 +18,14 @@ declare_clippy_lint! { /// module's visibility. /// /// ### Example - /// ```rust + /// ```no_run /// mod internal { /// pub(crate) fn internal_fn() { } /// } /// ``` /// This function is not visible outside the module and it can be declared with `pub` or /// private visibility - /// ```rust + /// ```no_run /// mod internal { /// pub fn internal_fn() { } /// } diff --git a/clippy_lints/src/redundant_slicing.rs b/clippy_lints/src/redundant_slicing.rs index 4abfa0fc35c6..7adbd67912c0 100644 --- a/clippy_lints/src/redundant_slicing.rs +++ b/clippy_lints/src/redundant_slicing.rs @@ -51,12 +51,12 @@ declare_clippy_lint! { /// Some people may prefer to dereference rather than slice. /// /// ### Example - /// ```rust + /// ```no_run /// let vec = vec![1, 2, 3]; /// let slice = &vec[..]; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let vec = vec![1, 2, 3]; /// let slice = &*vec; /// ``` diff --git a/clippy_lints/src/redundant_static_lifetimes.rs b/clippy_lints/src/redundant_static_lifetimes.rs index ed42a422b4b5..a70b831a80cf 100644 --- a/clippy_lints/src/redundant_static_lifetimes.rs +++ b/clippy_lints/src/redundant_static_lifetimes.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use rustc_ast::ast::{ConstItem, Item, ItemKind, StaticItem, Ty, TyKind}; use rustc_errors::Applicability; diff --git a/clippy_lints/src/redundant_type_annotations.rs b/clippy_lints/src/redundant_type_annotations.rs index 1d4fdb43a0b9..f6af9cac3def 100644 --- a/clippy_lints/src/redundant_type_annotations.rs +++ b/clippy_lints/src/redundant_type_annotations.rs @@ -24,11 +24,11 @@ declare_clippy_lint! { /// - `Path` to anything else than a primitive type. /// /// ### Example - /// ```rust + /// ```no_run /// let foo: String = String::new(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let foo = String::new(); /// ``` #[clippy::version = "1.72.0"] @@ -145,8 +145,8 @@ impl LateLintPass<'_> for RedundantTypeAnnotations { hir::ExprKind::Call(init_call, _) => { if let hir::TyKind::Path(ty_path) = &ty.kind && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path - - && is_redundant_in_func_call(cx, resolved_path_ty.res, init_call) { + && is_redundant_in_func_call(cx, resolved_path_ty.res, init_call) + { span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation"); } }, @@ -164,11 +164,11 @@ impl LateLintPass<'_> for RedundantTypeAnnotations { && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path && let Some(func_ty) = func_hir_id_to_func_ty(cx, init.hir_id) && let Some(return_type) = func_ty_to_return_type(cx, func_ty) - && is_same_type(cx, resolved_path_ty.res, if is_ref { - return_type.peel_refs() - } else { - return_type - }) + && is_same_type( + cx, + resolved_path_ty.res, + if is_ref { return_type.peel_refs() } else { return_type }, + ) { span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation"); } @@ -177,10 +177,8 @@ impl LateLintPass<'_> for RedundantTypeAnnotations { hir::ExprKind::Path(init_path) => { // TODO: check for non primty if let Some(primty) = extract_primty(&ty.kind) - && let hir::QPath::TypeRelative(init_ty, _) = init_path && let Some(primty_init) = extract_primty(&init_ty.kind) - && primty == primty_init { span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation"); @@ -205,8 +203,8 @@ impl LateLintPass<'_> for RedundantTypeAnnotations { }, LitKind::Err => (), } - } - _ => () + }, + _ => (), } }; } diff --git a/clippy_lints/src/ref_patterns.rs b/clippy_lints/src/ref_patterns.rs index b1530eed1c11..8b3dabde9bee 100644 --- a/clippy_lints/src/ref_patterns.rs +++ b/clippy_lints/src/ref_patterns.rs @@ -10,12 +10,12 @@ declare_clippy_lint! { /// The `ref` keyword can be confusing for people unfamiliar with it, and often /// it is more concise to use `&` instead. /// ### Example - /// ```rust + /// ```no_run /// let opt = Some(5); /// if let Some(ref foo) = opt {} /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let opt = Some(5); /// if let Some(foo) = &opt {} /// ``` @@ -29,7 +29,7 @@ declare_lint_pass!(RefPatterns => [REF_PATTERNS]); impl EarlyLintPass for RefPatterns { fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &Pat) { if let PatKind::Ident(BindingAnnotation::REF, _, _) = pat.kind - && !pat.span.from_expansion() + && !pat.span.from_expansion() { span_lint_and_help( cx, diff --git a/clippy_lints/src/reserve_after_initialization.rs b/clippy_lints/src/reserve_after_initialization.rs index 0c8c904e3745..1975946c6e6c 100644 --- a/clippy_lints/src/reserve_after_initialization.rs +++ b/clippy_lints/src/reserve_after_initialization.rs @@ -18,18 +18,18 @@ declare_clippy_lint! { /// The `Vec::with_capacity` constructor is less complex. /// /// ### Example - /// ```rust + /// ```no_run /// let mut v: Vec = vec![]; /// v.reserve(10); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let mut v: Vec = Vec::with_capacity(10); /// ``` #[clippy::version = "1.73.0"] pub RESERVE_AFTER_INITIALIZATION, complexity, - "`reserve` called immediatly after `Vec` creation" + "`reserve` called immediately after `Vec` creation" } impl_lint_pass!(ReserveAfterInitialization => [RESERVE_AFTER_INITIALIZATION]); @@ -74,15 +74,24 @@ impl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization { && let PatKind::Binding(BindingAnnotation::MUT, id, _, None) = local.pat.kind && !in_external_macro(cx.sess(), local.span) && let Some(init) = get_vec_init_kind(cx, init_expr) - && !matches!(init, VecInitKind::WithExprCapacity(_) | VecInitKind::WithConstCapacity(_)) + && !matches!( + init, + VecInitKind::WithExprCapacity(_) | VecInitKind::WithConstCapacity(_) + ) { self.searcher = Some(VecReserveSearcher { local_id: id, err_span: local.span, - init_part: snippet(cx, local.span.shrink_to_lo() - .to(init_expr.span.source_callsite().shrink_to_lo()), "..") - .into_owned(), - space_hint: String::new() + init_part: snippet( + cx, + local + .span + .shrink_to_lo() + .to(init_expr.span.source_callsite().shrink_to_lo()), + "..", + ) + .into_owned(), + space_hint: String::new(), }); } } @@ -94,15 +103,21 @@ impl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization { && let Res::Local(id) = path.res && !in_external_macro(cx.sess(), expr.span) && let Some(init) = get_vec_init_kind(cx, right) - && !matches!(init, VecInitKind::WithExprCapacity(_) | VecInitKind::WithConstCapacity(_)) + && !matches!( + init, + VecInitKind::WithExprCapacity(_) | VecInitKind::WithConstCapacity(_) + ) { self.searcher = Some(VecReserveSearcher { local_id: id, err_span: expr.span, - init_part: snippet(cx, left.span.shrink_to_lo() - .to(right.span.source_callsite().shrink_to_lo()), "..") - .into_owned(), // see `assign_expression` test - space_hint: String::new() + init_part: snippet( + cx, + left.span.shrink_to_lo().to(right.span.source_callsite().shrink_to_lo()), + "..", + ) + .into_owned(), // see `assign_expression` test + space_hint: String::new(), }); } } @@ -118,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization { self.searcher = Some(VecReserveSearcher { err_span: searcher.err_span.to(stmt.span), space_hint: snippet(cx, space_hint.span, "..").into_owned(), - .. searcher + ..searcher }); } else { searcher.display_err(cx); diff --git a/clippy_lints/src/return_self_not_must_use.rs b/clippy_lints/src/return_self_not_must_use.rs index bccf421e8f3b..245029a066db 100644 --- a/clippy_lints/src/return_self_not_must_use.rs +++ b/clippy_lints/src/return_self_not_must_use.rs @@ -26,7 +26,7 @@ declare_clippy_lint! { /// if it was added on constructors for example. /// /// ### Example - /// ```rust + /// ```no_run /// pub struct Bar; /// impl Bar { /// // Missing attribute @@ -37,7 +37,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # { /// // It's better to have the `#[must_use]` attribute on the method like this: /// pub struct Bar; diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index d6b9a49d2fe0..72235a954ba8 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::source::{snippet_opt, snippet_with_context}; +use clippy_utils::sugg::has_enclosing_paren; use clippy_utils::visitors::{for_each_expr_with_closures, Descend}; use clippy_utils::{fn_def_id, is_from_proc_macro, path_to_local_id, span_find_starting_semi}; use core::ops::ControlFlow; @@ -34,14 +35,14 @@ declare_clippy_lint! { /// bound without first assigning it to a let-binding. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo() -> String { /// let x = String::new(); /// x /// } /// ``` /// instead, use - /// ``` + /// ```no_run /// fn foo() -> String { /// String::new() /// } @@ -61,13 +62,13 @@ declare_clippy_lint! { /// more rusty. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo(x: usize) -> usize { /// return x; /// } /// ``` /// simplify to - /// ```rust + /// ```no_run /// fn foo(x: usize) -> usize { /// x /// } @@ -213,6 +214,9 @@ impl<'tcx> LateLintPass<'tcx> for Return { if let Some(mut snippet) = snippet_opt(cx, initexpr.span) { if !cx.typeck_results().expr_adjustments(retexpr).is_empty() { + if !has_enclosing_paren(&snippet) { + snippet = format!("({snippet})"); + } snippet.push_str(" as _"); } err.multipart_suggestion( diff --git a/clippy_lints/src/same_name_method.rs b/clippy_lints/src/same_name_method.rs index a37e2772d355..fd1f3d3903ac 100644 --- a/clippy_lints/src/same_name_method.rs +++ b/clippy_lints/src/same_name_method.rs @@ -18,7 +18,7 @@ declare_clippy_lint! { /// Confusing. /// /// ### Example - /// ```rust + /// ```no_run /// trait T { /// fn foo(&self) {} /// } @@ -120,9 +120,10 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { } }; - for impl_item_ref in (*items).iter().filter(|impl_item_ref| { - matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. }) - }) { + for impl_item_ref in (*items) + .iter() + .filter(|impl_item_ref| matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. })) + { let method_name = impl_item_ref.ident.name; methods_in_trait.remove(&method_name); check_trait_method(method_name, impl_item_ref.span); @@ -133,9 +134,10 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { } }, None => { - for impl_item_ref in (*items).iter().filter(|impl_item_ref| { - matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. }) - }) { + for impl_item_ref in (*items) + .iter() + .filter(|impl_item_ref| matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. })) + { let method_name = impl_item_ref.ident.name; let impl_span = impl_item_ref.span; let hir_id = impl_item_ref.id.hir_id(); diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs index 88f295c72ebd..b0601bba4aff 100644 --- a/clippy_lints/src/semicolon_block.rs +++ b/clippy_lints/src/semicolon_block.rs @@ -19,13 +19,13 @@ declare_clippy_lint! { /// /// ### Example /// - /// ```rust + /// ```no_run /// # fn f(_: u32) {} /// # let x = 0; /// unsafe { f(x) }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # fn f(_: u32) {} /// # let x = 0; /// unsafe { f(x); } @@ -48,13 +48,13 @@ declare_clippy_lint! { /// /// ### Example /// - /// ```rust + /// ```no_run /// # fn f(_: u32) {} /// # let x = 0; /// unsafe { f(x); } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # fn f(_: u32) {} /// # let x = 0; /// unsafe { f(x) }; diff --git a/clippy_lints/src/semicolon_if_nothing_returned.rs b/clippy_lints/src/semicolon_if_nothing_returned.rs index c9547cd95dca..ccf8b9977056 100644 --- a/clippy_lints/src/semicolon_if_nothing_returned.rs +++ b/clippy_lints/src/semicolon_if_nothing_returned.rs @@ -17,13 +17,13 @@ declare_clippy_lint! { /// code, it doesn't require a change in previous last line. /// /// ### Example - /// ```rust + /// ```no_run /// fn main() { /// println!("Hello world") /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn main() { /// println!("Hello world"); /// } diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 78418b223924..41c10b34a424 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -21,13 +21,13 @@ declare_clippy_lint! { /// lint to `Warn`. /// /// ### Example - /// ```rust + /// ```no_run /// # let x = 1; /// let x = &x; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let x = 1; /// let y = &x; // use different variable name /// ``` @@ -49,12 +49,12 @@ declare_clippy_lint! { /// the code. /// /// ### Example - /// ```rust + /// ```no_run /// let x = 2; /// let x = x + 1; /// ``` /// use different variable name: - /// ```rust + /// ```no_run /// let x = 2; /// let y = x + 1; /// ``` @@ -77,7 +77,7 @@ declare_clippy_lint! { /// names to bindings or introducing more scopes to contain the bindings. /// /// ### Example - /// ```rust + /// ```no_run /// # let y = 1; /// # let z = 2; /// let x = y; @@ -85,7 +85,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let y = 1; /// # let z = 2; /// let x = y; diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs index 4b248c9c7900..57bcee1a8719 100644 --- a/clippy_lints/src/significant_drop_tightening.rs +++ b/clippy_lints/src/significant_drop_tightening.rs @@ -236,9 +236,13 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx fn manage_has_expensive_expr_after_last_attr(&mut self) { let has_expensive_stmt = match self.ap.curr_stmt.kind { hir::StmtKind::Expr(expr) if is_inexpensive_expr(expr) => false, - hir::StmtKind::Local(local) if let Some(expr) = local.init - && let hir::ExprKind::Path(_) = expr.kind => false, - _ => true + hir::StmtKind::Local(local) + if let Some(expr) = local.init + && let hir::ExprKind::Path(_) = expr.kind => + { + false + }, + _ => true, }; if has_expensive_stmt { for apa in self.ap.apas.values_mut() { @@ -292,8 +296,7 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'o && { if let Some(local_hir_id) = path_to_local(expr) { local_hir_id == hir_id - } - else { + } else { true } } @@ -306,8 +309,7 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'o let expr_or_init = expr_or_init(self.cx, expr); if let hir::ExprKind::MethodCall(_, local_expr, _, span) = expr_or_init.kind { local_expr.span.to(span) - } - else { + } else { expr_or_init.span } }, @@ -317,8 +319,12 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'o modify_apa_params(&mut apa); let _ = self.ap.apas.insert(hir_id, apa); } else { - let Some(hir_id) = path_to_local(expr) else { return; }; - let Some(apa) = self.ap.apas.get_mut(&hir_id) else { return; }; + let Some(hir_id) = path_to_local(expr) else { + return; + }; + let Some(apa) = self.ap.apas.get_mut(&hir_id) else { + return; + }; match self.ap.curr_stmt.kind { hir::StmtKind::Local(local) => { if let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind { @@ -437,19 +443,20 @@ fn has_drop(expr: &hir::Expr<'_>, first_bind_ident: &Ident, lcx: &LateContext<'_ { let has_ident = |local_expr: &hir::Expr<'_>| { if let hir::ExprKind::Path(hir::QPath::Resolved(_, arg_path)) = &local_expr.kind - && let [first_arg_ps, .. ] = arg_path.segments + && let [first_arg_ps, ..] = arg_path.segments && &first_arg_ps.ident == first_bind_ident { true - } - else { + } else { false } }; if has_ident(first_arg) { return true; } - if let hir::ExprKind::Tup(value) = &first_arg.kind && value.iter().any(has_ident) { + if let hir::ExprKind::Tup(value) = &first_arg.kind + && value.iter().any(has_ident) + { return true; } } diff --git a/clippy_lints/src/single_call_fn.rs b/clippy_lints/src/single_call_fn.rs index 7bbe98e0a7f9..ae81e1198af2 100644 --- a/clippy_lints/src/single_call_fn.rs +++ b/clippy_lints/src/single_call_fn.rs @@ -23,7 +23,7 @@ declare_clippy_lint! { /// Note: If this lint is used, prepare to allow this a lot. /// /// ### Example - /// ```rust + /// ```no_run /// pub fn a(t: &T) /// where /// T: AsRef, @@ -37,7 +37,7 @@ declare_clippy_lint! { /// /// ``` /// Use instead: - /// ```rust + /// ```no_run /// pub fn a(t: &T) /// where /// T: AsRef, diff --git a/clippy_lints/src/single_char_lifetime_names.rs b/clippy_lints/src/single_char_lifetime_names.rs index 3dc995e2fa57..74ee8ce2de72 100644 --- a/clippy_lints/src/single_char_lifetime_names.rs +++ b/clippy_lints/src/single_char_lifetime_names.rs @@ -22,13 +22,13 @@ declare_clippy_lint! { /// be obvious or, rarely, expressible in one character. /// /// ### Example - /// ```rust + /// ```no_run /// struct DiagnosticCtx<'a> { /// source: &'a str, /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct DiagnosticCtx<'src> { /// source: &'src str, /// } diff --git a/clippy_lints/src/single_range_in_vec_init.rs b/clippy_lints/src/single_range_in_vec_init.rs index 321c89889887..099743d229d1 100644 --- a/clippy_lints/src/single_range_in_vec_init.rs +++ b/clippy_lints/src/single_range_in_vec_init.rs @@ -21,11 +21,11 @@ declare_clippy_lint! { /// the end of the range to be the length instead. /// /// ### Example - /// ```rust + /// ```no_run /// let x = [0..200]; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// // If it was intended to include every element in the range... /// let x = (0..200).collect::>(); /// // ...Or if 200 was meant to be the len diff --git a/clippy_lints/src/size_of_ref.rs b/clippy_lints/src/size_of_ref.rs index 89ac8cd8ca97..7de029b7b942 100644 --- a/clippy_lints/src/size_of_ref.rs +++ b/clippy_lints/src/size_of_ref.rs @@ -19,7 +19,7 @@ declare_clippy_lint! { /// the reference. /// /// ### Example - /// ```rust + /// ```no_run /// struct Foo { /// buffer: [u8], /// } @@ -35,7 +35,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct Foo { /// buffer: [u8], /// } diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index 2278e41be375..2244eab96ca8 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -31,7 +31,7 @@ declare_clippy_lint! { /// The `resize` call first allocates memory (since `Vec::new()` did not), and only *then* zero-initializes it. /// /// ### Example - /// ```rust + /// ```no_run /// # use core::iter::repeat; /// # let len = 4; /// let mut vec1 = Vec::new(); @@ -45,7 +45,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # let len = 4; /// let mut vec1 = vec![0; len]; /// let mut vec2 = vec![0; len]; diff --git a/clippy_lints/src/std_instead_of_core.rs b/clippy_lints/src/std_instead_of_core.rs index b7396535eedf..d07a44770cc7 100644 --- a/clippy_lints/src/std_instead_of_core.rs +++ b/clippy_lints/src/std_instead_of_core.rs @@ -22,11 +22,11 @@ declare_clippy_lint! { /// migrating to become `no_std` compatible. /// /// ### Example - /// ```rust + /// ```no_run /// use std::hash::Hasher; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use core::hash::Hasher; /// ``` #[clippy::version = "1.64.0"] @@ -47,11 +47,11 @@ declare_clippy_lint! { /// for crates migrating to become `no_std` compatible. /// /// ### Example - /// ```rust + /// ```no_run /// use std::vec::Vec; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # extern crate alloc; /// use alloc::vec::Vec; /// ``` @@ -73,12 +73,12 @@ declare_clippy_lint! { /// is also useful for crates migrating to become `no_std` compatible. /// /// ### Example - /// ```rust + /// ```no_run /// # extern crate alloc; /// use alloc::slice::from_ref; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use core::slice::from_ref; /// ``` #[clippy::version = "1.64.0"] @@ -106,16 +106,8 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { { let (lint, used_mod, replace_with) = match first_segment.ident.name { sym::std => match cx.tcx.crate_name(def_id.krate) { - sym::core => ( - STD_INSTEAD_OF_CORE, - "std", - "core", - ), - sym::alloc => ( - STD_INSTEAD_OF_ALLOC, - "std", - "alloc", - ), + sym::core => (STD_INSTEAD_OF_CORE, "std", "core"), + sym::alloc => (STD_INSTEAD_OF_ALLOC, "std", "alloc"), _ => { self.prev_span = path.span; return; @@ -123,11 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { }, sym::alloc => { if cx.tcx.crate_name(def_id.krate) == sym::core { - ( - ALLOC_INSTEAD_OF_CORE, - "alloc", - "core", - ) + (ALLOC_INSTEAD_OF_CORE, "alloc", "core") } else { self.prev_span = path.span; return; @@ -143,7 +131,8 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { &format!("used import from `{used_mod}` instead of `{replace_with}`"), &format!("consider importing the item from `{replace_with}`"), replace_with.to_string(), - Applicability::MachineApplicable); + Applicability::MachineApplicable, + ); self.prev_span = path.span; } } diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 76f463fff7dc..a44adc938559 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -26,7 +26,7 @@ declare_clippy_lint! { /// `.push_str(_)` method is more readable. /// /// ### Example - /// ```rust + /// ```no_run /// let mut x = "Hello".to_owned(); /// x = x + ", World"; /// @@ -58,13 +58,13 @@ declare_clippy_lint! { /// particular lint `allow` by default. /// /// ### Example - /// ```rust + /// ```no_run /// let x = "Hello".to_owned(); /// x + ", World"; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let mut x = "Hello".to_owned(); /// x.push_str(", World"); /// ``` @@ -106,12 +106,12 @@ declare_clippy_lint! { /// more readable than a function call. /// /// ### Example - /// ```rust + /// ```no_run /// let bstr = "a byte string".as_bytes(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let bstr = b"a byte string"; /// ``` #[clippy::version = "pre 1.29.0"] @@ -231,12 +231,12 @@ declare_clippy_lint! { /// It's unnecessary, the string can be used directly. /// /// ### Example - /// ```rust + /// ```no_run /// std::str::from_utf8(&"Hello World!".as_bytes()[6..11]).unwrap(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// &"Hello World!"[6..11]; /// ``` #[clippy::version = "1.50.0"] @@ -387,12 +387,12 @@ declare_clippy_lint! { /// expressed with `.to_owned()`. /// /// ### Example - /// ```rust + /// ```no_run /// // example code where clippy issues a warning /// let _ = "str".to_string(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// // example code which does not raise clippy warning /// let _ = "str".to_owned(); /// ``` @@ -435,13 +435,13 @@ declare_clippy_lint! { /// When called on a `String` it only clones the `String`, which can be better expressed with `.clone()`. /// /// ### Example - /// ```rust + /// ```no_run /// // example code where clippy issues a warning /// let msg = String::from("Hello World"); /// let _ = msg.to_string(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// // example code which does not raise clippy warning /// let msg = String::from("Hello World"); /// let _ = msg.clone(); @@ -483,11 +483,11 @@ declare_clippy_lint! { /// `split_whitespace` already ignores leading and trailing whitespace. /// /// ### Example - /// ```rust + /// ```no_run /// " A B C ".trim().split_whitespace(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// " A B C ".split_whitespace(); /// ``` #[clippy::version = "1.62.0"] diff --git a/clippy_lints/src/suspicious_doc_comments.rs b/clippy_lints/src/suspicious_doc_comments.rs index 8be4ec3dc64c..0abc199da164 100644 --- a/clippy_lints/src/suspicious_doc_comments.rs +++ b/clippy_lints/src/suspicious_doc_comments.rs @@ -32,7 +32,7 @@ declare_clippy_lint! { /// /// ### Example /// In this example, the doc comment is attached to the *function*, rather than the *module*. - /// ```rust + /// ```no_run /// pub mod util { /// ///! This module contains utility functions. /// @@ -41,7 +41,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// pub mod util { /// //! This module contains utility functions. /// diff --git a/clippy_lints/src/suspicious_operation_groupings.rs b/clippy_lints/src/suspicious_operation_groupings.rs index 7dff37a2b8ff..bb8cde5b94d1 100644 --- a/clippy_lints/src/suspicious_operation_groupings.rs +++ b/clippy_lints/src/suspicious_operation_groupings.rs @@ -28,7 +28,7 @@ declare_clippy_lint! { /// unusual that happens to look like a typo. /// /// ### Example - /// ```rust + /// ```no_run /// struct Vec3 { /// x: f64, /// y: f64, @@ -45,7 +45,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # struct Vec3 { /// # x: f64, /// # y: f64, diff --git a/clippy_lints/src/suspicious_xor_used_as_pow.rs b/clippy_lints/src/suspicious_xor_used_as_pow.rs index 39cd289b67ad..4340c23f8303 100644 --- a/clippy_lints/src/suspicious_xor_used_as_pow.rs +++ b/clippy_lints/src/suspicious_xor_used_as_pow.rs @@ -14,11 +14,11 @@ declare_clippy_lint! { /// ### Why is this bad? /// It's most probably a typo and may lead to unexpected behaviours. /// ### Example - /// ```rust + /// ```no_run /// let x = 3_i32 ^ 4_i32; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let x = 3_i32.pow(4); /// ``` #[clippy::version = "1.67.0"] @@ -38,21 +38,18 @@ impl LateLintPass<'_> for ConfusingXorAndPow { && let ExprKind::Lit(lit_right) = &right.kind && matches!(lit_right.node, LitKind::Int(..) | LitKind::Float(..)) && matches!(lit_left.node, LitKind::Int(..) | LitKind::Float(..)) - && NumericLiteral::from_lit_kind(&snippet(cx, lit_right.span, ".."), &lit_right.node).is_some_and(|x| x.is_decimal()) - { - span_lint_and_sugg( - cx, - SUSPICIOUS_XOR_USED_AS_POW, - expr.span, - "`^` is not the exponentiation operator", - "did you mean to write", - format!( - "{}.pow({})", - lit_left.node, - lit_right.node - ), - Applicability::MaybeIncorrect, - ); - } + && NumericLiteral::from_lit_kind(&snippet(cx, lit_right.span, ".."), &lit_right.node) + .is_some_and(|x| x.is_decimal()) + { + span_lint_and_sugg( + cx, + SUSPICIOUS_XOR_USED_AS_POW, + expr.span, + "`^` is not the exponentiation operator", + "did you mean to write", + format!("{}.pow({})", lit_left.node, lit_right.node), + Applicability::MaybeIncorrect, + ); + } } } diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index 548fabb8b736..660e6835e46a 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -25,7 +25,7 @@ declare_clippy_lint! { /// without deinitializing or copying either variable. /// /// ### Example - /// ```rust + /// ```no_run /// let mut a = 42; /// let mut b = 1337; /// @@ -34,7 +34,7 @@ declare_clippy_lint! { /// a = t; /// ``` /// Use std::mem::swap(): - /// ```rust + /// ```no_run /// let mut a = 1; /// let mut b = 2; /// std::mem::swap(&mut a, &mut b); @@ -53,14 +53,14 @@ declare_clippy_lint! { /// This looks like a failed attempt to swap. /// /// ### Example - /// ```rust + /// ```no_run /// # let mut a = 1; /// # let mut b = 2; /// a = b; /// b = a; /// ``` /// If swapping is intended, use `swap()` instead: - /// ```rust + /// ```no_run /// # let mut a = 1; /// # let mut b = 2; /// std::mem::swap(&mut a, &mut b); @@ -232,7 +232,7 @@ fn is_same(cx: &LateContext<'_>, lhs: ExprOrIdent<'_>, rhs: &Expr<'_>) -> bool { } else { false } - } + }, } } diff --git a/clippy_lints/src/swap_ptr_to_ref.rs b/clippy_lints/src/swap_ptr_to_ref.rs index 4bfbe3bf37e7..6a6c94425d1d 100644 --- a/clippy_lints/src/swap_ptr_to_ref.rs +++ b/clippy_lints/src/swap_ptr_to_ref.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// other. This would then lead to undefined behavior. /// /// ### Example - /// ```rust + /// ```no_run /// unsafe fn swap(x: &[*mut u32], y: &[*mut u32]) { /// for (&x, &y) in x.iter().zip(y) { /// core::mem::swap(&mut *x, &mut *y); @@ -24,7 +24,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// unsafe fn swap(x: &[*mut u32], y: &[*mut u32]) { /// for (&x, &y) in x.iter().zip(y) { /// core::ptr::swap(x, y); @@ -58,9 +58,14 @@ impl LateLintPass<'_> for SwapPtrToRef { let mut app = Applicability::MachineApplicable; let snip1 = snippet_with_context(cx, arg1_span.unwrap_or(arg1.span), ctxt, "..", &mut app).0; let snip2 = snippet_with_context(cx, arg2_span.unwrap_or(arg2.span), ctxt, "..", &mut app).0; - diag.span_suggestion(e.span, "use ptr::swap", format!("core::ptr::swap({snip1}, {snip2})"), app); + diag.span_suggestion( + e.span, + "use ptr::swap", + format!("core::ptr::swap({snip1}, {snip2})"), + app, + ); } - } + }, ); } } @@ -73,7 +78,10 @@ fn is_ptr_to_ref(cx: &LateContext<'_>, e: &Expr<'_>, ctxt: SyntaxContext) -> (bo && let ExprKind::Unary(UnOp::Deref, derefed_expr) = borrowed_expr.kind && cx.typeck_results().expr_ty(derefed_expr).is_unsafe_ptr() { - (true, (borrowed_expr.span.ctxt() == ctxt || derefed_expr.span.ctxt() == ctxt).then_some(derefed_expr.span)) + ( + true, + (borrowed_expr.span.ctxt() == ctxt || derefed_expr.span.ctxt() == ctxt).then_some(derefed_expr.span), + ) } else { (false, None) } diff --git a/clippy_lints/src/tabs_in_doc_comments.rs b/clippy_lints/src/tabs_in_doc_comments.rs index e223aea297fc..71b6fef16bab 100644 --- a/clippy_lints/src/tabs_in_doc_comments.rs +++ b/clippy_lints/src/tabs_in_doc_comments.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// display settings of the author and reader differ. /// /// ### Example - /// ```rust + /// ```no_run /// /// /// /// Struct to hold two strings: /// /// - first one @@ -34,7 +34,7 @@ declare_clippy_lint! { /// ``` /// /// Will be converted to: - /// ```rust + /// ```no_run /// /// /// /// Struct to hold two strings: /// /// - first one diff --git a/clippy_lints/src/temporary_assignment.rs b/clippy_lints/src/temporary_assignment.rs index b6b653f6610d..c717ccc35a6b 100644 --- a/clippy_lints/src/temporary_assignment.rs +++ b/clippy_lints/src/temporary_assignment.rs @@ -14,7 +14,7 @@ declare_clippy_lint! { /// updated, why not write the structure you want in the first place? /// /// ### Example - /// ```rust + /// ```no_run /// (0, 0).0 = 1 /// ``` #[clippy::version = "pre 1.29.0"] diff --git a/clippy_lints/src/tests_outside_test_module.rs b/clippy_lints/src/tests_outside_test_module.rs index b356666d852a..0cfb1c1253c6 100644 --- a/clippy_lints/src/tests_outside_test_module.rs +++ b/clippy_lints/src/tests_outside_test_module.rs @@ -15,7 +15,7 @@ declare_clippy_lint! { /// The idiomatic (and more performant) way of writing tests is inside a testing module (flagged with `#[cfg(test)]`), /// having test functions outside of this module is confusing and may lead to them being "hidden". /// ### Example - /// ```rust + /// ```no_run /// #[test] /// fn my_cool_test() { /// // [...] @@ -28,7 +28,7 @@ declare_clippy_lint! { /// /// ``` /// Use instead: - /// ```rust + /// ```no_run /// #[cfg(test)] /// mod tests { /// #[test] diff --git a/clippy_lints/src/to_digit_is_some.rs b/clippy_lints/src/to_digit_is_some.rs index f1b703fde0e6..a171d225f1e4 100644 --- a/clippy_lints/src/to_digit_is_some.rs +++ b/clippy_lints/src/to_digit_is_some.rs @@ -17,13 +17,13 @@ declare_clippy_lint! { /// more straight forward to use the dedicated `is_digit` method. /// /// ### Example - /// ```rust + /// ```no_run /// # let c = 'c'; /// # let radix = 10; /// let is_digit = c.to_digit(radix).is_some(); /// ``` /// can be written as: - /// ``` + /// ```no_run /// # let c = 'c'; /// # let radix = 10; /// let is_digit = c.is_digit(radix); diff --git a/clippy_lints/src/trailing_empty_array.rs b/clippy_lints/src/trailing_empty_array.rs index bb9da3a20470..87181adc24b0 100644 --- a/clippy_lints/src/trailing_empty_array.rs +++ b/clippy_lints/src/trailing_empty_array.rs @@ -13,7 +13,7 @@ declare_clippy_lint! { /// Zero-sized arrays aren't very useful in Rust itself, so such a struct is likely being created to pass to C code or in some other situation where control over memory layout matters (for example, in conjunction with manual allocation to make it easy to compute the offset of the array). Either way, `#[repr(C)]` (or another `repr` attribute) is needed. /// /// ### Example - /// ```rust + /// ```no_run /// struct RarelyUseful { /// some_field: u32, /// last: [u32; 0], @@ -21,7 +21,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// #[repr(C)] /// struct MoreOftenUseful { /// some_field: usize, diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index 6db330dfa617..f065d215e489 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{snippet, snippet_opt, snippet_with_applicability}; use clippy_utils::{is_from_proc_macro, SpanlessEq, SpanlessHash}; use core::hash::{Hash, Hasher}; @@ -27,12 +27,12 @@ declare_clippy_lint! { /// less readable than combining the bounds /// /// ### Example - /// ```rust + /// ```no_run /// pub fn foo(t: T) where T: Copy, T: Clone {} /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// pub fn foo(t: T) where T: Copy + Clone {} /// ``` #[clippy::version = "1.38.0"] @@ -51,12 +51,12 @@ declare_clippy_lint! { /// less readable than specifying them only once. /// /// ### Example - /// ```rust + /// ```no_run /// fn func(arg: T) where T: Clone + Default {} /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # mod hidden { /// fn func(arg: T) {} /// # } @@ -66,19 +66,19 @@ declare_clippy_lint! { /// fn func(arg: T) where T: Clone + Default {} /// ``` /// - /// ```rust + /// ```no_run /// fn foo(bar: T) {} /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn foo(bar: T) {} /// ``` /// - /// ```rust + /// ```no_run /// fn foo(bar: T) where T: Default + Default {} /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn foo(bar: T) where T: Default {} /// ``` #[clippy::version = "1.47.0"] diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 0dc30f7a9355..6eec40cb5295 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -17,8 +17,8 @@ mod useless_transmute; mod utils; mod wrong_transmute; +use clippy_config::msrvs::Msrv; use clippy_utils::in_constant; -use clippy_utils::msrvs::Msrv; use if_chain::if_chain; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; @@ -78,12 +78,12 @@ declare_clippy_lint! { /// /// ### Example /// - /// ```rust + /// ```no_run /// # let p: *const [i32] = &[]; /// unsafe { std::mem::transmute::<*const [i32], *const [u16]>(p) }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # let p: *const [i32] = &[]; /// p as *const [u16]; /// ``` @@ -159,7 +159,7 @@ declare_clippy_lint! { /// [`from_u32_unchecked`]: https://doc.rust-lang.org/std/char/fn.from_u32_unchecked.html /// /// ### Example - /// ```rust + /// ```no_run /// let x = 1_u32; /// unsafe { /// let _: char = std::mem::transmute(x); // where x: u32 @@ -193,7 +193,7 @@ declare_clippy_lint! { /// [`from_utf8_unchecked`]: https://doc.rust-lang.org/std/str/fn.from_utf8_unchecked.html /// /// ### Example - /// ```rust + /// ```no_run /// let b: &[u8] = &[1_u8, 2_u8]; /// unsafe { /// let _: &str = std::mem::transmute(b); // where b: &[u8] @@ -216,7 +216,7 @@ declare_clippy_lint! { /// This might result in an invalid in-memory representation of a `bool`. /// /// ### Example - /// ```rust + /// ```no_run /// let x = 1_u8; /// unsafe { /// let _: bool = std::mem::transmute(x); // where x: u8 @@ -240,7 +240,7 @@ declare_clippy_lint! { /// and safe. /// /// ### Example - /// ```rust + /// ```no_run /// unsafe { /// let _: f32 = std::mem::transmute(1_u32); // where x: u32 /// } @@ -264,12 +264,12 @@ declare_clippy_lint! { /// elsewhere. `new_unchecked` only works for the appropriate types instead. /// /// ### Example - /// ```rust + /// ```no_run /// # use core::num::NonZeroU32; /// let _non_zero: NonZeroU32 = unsafe { std::mem::transmute(123) }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use core::num::NonZeroU32; /// let _non_zero = unsafe { NonZeroU32::new_unchecked(123) }; /// ``` @@ -288,7 +288,7 @@ declare_clippy_lint! { /// and safe. /// /// ### Example - /// ```rust + /// ```no_run /// unsafe { /// let _: u32 = std::mem::transmute(1f32); /// } @@ -311,7 +311,7 @@ declare_clippy_lint! { /// is intuitive and safe. /// /// ### Example - /// ```rust + /// ```no_run /// unsafe { /// let x: [u8; 8] = std::mem::transmute(1i64); /// } @@ -335,7 +335,7 @@ declare_clippy_lint! { /// written as casts. /// /// ### Example - /// ```rust + /// ```no_run /// let ptr = &1u32 as *const u32; /// unsafe { /// // pointer-to-pointer transmute @@ -366,7 +366,7 @@ declare_clippy_lint! { /// collection, so we just lint the ones that come with `std`. /// /// ### Example - /// ```rust + /// ```no_run /// // different size, therefore likely out-of-bounds memory access /// // You absolutely do not want this in your code! /// unsafe { @@ -376,7 +376,7 @@ declare_clippy_lint! { /// /// You must always iterate, map and collect the values: /// - /// ```rust + /// ```no_run /// vec![2_u16].into_iter().map(u32::from).collect::>(); /// ``` #[clippy::version = "1.40.0"] @@ -398,12 +398,12 @@ declare_clippy_lint! { /// [#8496](https://github.com/rust-lang/rust-clippy/issues/8496) for more details. /// /// ### Example - /// ```rust + /// ```no_run /// struct Foo(u32, T); /// let _ = unsafe { core::mem::transmute::, Foo>(Foo(0u32, 0u32)) }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// #[repr(C)] /// struct Foo(u32, T); /// let _ = unsafe { core::mem::transmute::, Foo>(Foo(0u32, 0u32)) }; @@ -427,7 +427,7 @@ declare_clippy_lint! { /// call, aren't detectable yet. /// /// ### Example - /// ```rust + /// ```no_run /// let null_ref: &u64 = unsafe { std::mem::transmute(0 as *const u64) }; /// ``` #[clippy::version = "1.35.0"] @@ -451,11 +451,11 @@ declare_clippy_lint! { /// call, aren't detectable yet. /// /// ### Example - /// ```rust + /// ```no_run /// let null_fn: fn() = unsafe { std::mem::transmute( std::ptr::null::<()>() ) }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let null_fn: Option = None; /// ``` #[clippy::version = "1.68.0"] diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs index 6bdb9aa5a26d..4ab3afbe7143 100644 --- a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs +++ b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs @@ -1,6 +1,6 @@ use super::TRANSMUTE_PTR_TO_REF; +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg; use rustc_errors::Applicability; diff --git a/clippy_lints/src/transmute/transmute_undefined_repr.rs b/clippy_lints/src/transmute/transmute_undefined_repr.rs index c61eb0a93112..7c2223ca3ab7 100644 --- a/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -98,17 +98,17 @@ pub(super) fn check<'tcx>( }, (ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty)) if from_ty != to_ty => { - let same_adt_did = if let (ty::Adt(from_def, from_subs), ty::Adt(to_def, to_subs)) - = (from_ty.kind(), to_ty.kind()) - && from_def == to_def - { - if same_except_params(from_subs, to_subs) { - return false; - } - Some(from_def.did()) - } else { - None - }; + let same_adt_did = if let (ty::Adt(from_def, from_subs), ty::Adt(to_def, to_subs)) = + (from_ty.kind(), to_ty.kind()) + && from_def == to_def + { + if same_except_params(from_subs, to_subs) { + return false; + } + Some(from_def.did()) + } else { + None + }; span_lint_and_then( cx, TRANSMUTE_UNDEFINED_REPR, diff --git a/clippy_lints/src/transmute/transmuting_null.rs b/clippy_lints/src/transmute/transmuting_null.rs index 770914e99e16..471bd44b5d5e 100644 --- a/clippy_lints/src/transmute/transmuting_null.rs +++ b/clippy_lints/src/transmute/transmuting_null.rs @@ -16,8 +16,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t } // Catching transmute over constants that resolve to `null`. - if let ExprKind::Path(ref _qpath) = arg.kind && - let Some(Constant::RawPtr(0)) = constant(cx, cx.typeck_results(), arg) + if let ExprKind::Path(ref _qpath) = arg.kind + && let Some(Constant::RawPtr(0)) = constant(cx, cx.typeck_results(), arg) { span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG); return true; @@ -25,15 +25,17 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t // Catching: // `std::mem::transmute(0 as *const i32)` - if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind && is_integer_literal(inner_expr, 0) { + if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind + && is_integer_literal(inner_expr, 0) + { span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG); return true; } // Catching: // `std::mem::transmute(std::ptr::null::())` - if let ExprKind::Call(func1, []) = arg.kind && - is_path_diagnostic_item(cx, func1, sym::ptr_null) + if let ExprKind::Call(func1, []) = arg.kind + && is_path_diagnostic_item(cx, func1, sym::ptr_null) { span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG); return true; diff --git a/clippy_lints/src/tuple_array_conversions.rs b/clippy_lints/src/tuple_array_conversions.rs index c12519d723c0..642e39e8270e 100644 --- a/clippy_lints/src/tuple_array_conversions.rs +++ b/clippy_lints/src/tuple_array_conversions.rs @@ -1,5 +1,5 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::visitors::for_each_local_use_after_expr; use clippy_utils::{is_from_proc_macro, path_to_local}; use itertools::Itertools; diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 788678a63b76..781e0aa22edb 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -64,7 +64,7 @@ declare_clippy_lint! { /// 1st comment). /// /// ### Example - /// ```rust + /// ```no_run /// struct X { /// values: Vec>, /// } @@ -72,7 +72,7 @@ declare_clippy_lint! { /// /// Better: /// - /// ```rust + /// ```no_run /// struct X { /// values: Vec, /// } @@ -97,7 +97,7 @@ declare_clippy_lint! { /// consider a custom `enum` instead, with clear names for each case. /// /// ### Example - /// ```rust + /// ```no_run /// fn get_data() -> Option> { /// None /// } @@ -105,7 +105,7 @@ declare_clippy_lint! { /// /// Better: /// - /// ```rust + /// ```no_run /// pub enum Contents { /// Data(Vec), // Was Some(Some(Vec)) /// NotYetFetched, // Was Some(None) @@ -152,7 +152,7 @@ declare_clippy_lint! { /// `LinkedList` makes sense are few and far between, but they can still happen. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::collections::LinkedList; /// let x: LinkedList = LinkedList::new(); /// ``` @@ -197,14 +197,14 @@ declare_clippy_lint! { /// `Arc>`, `Arc>`, `Box<&T>`, `Box>`, `Box>`, `Box>`, add an unnecessary level of indirection. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::rc::Rc; /// fn foo(bar: Rc<&usize>) {} /// ``` /// /// Better: /// - /// ```rust + /// ```no_run /// fn foo(bar: &usize) {} /// ``` #[clippy::version = "1.44.0"] @@ -258,7 +258,7 @@ declare_clippy_lint! { /// using a `type` definition to simplify them. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::rc::Rc; /// struct Foo { /// inner: Rc>>>, diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index 6193fdeb433a..32aebdd8c0f7 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -44,14 +44,14 @@ declare_clippy_lint! { /// and bugs. /// /// ### Example - /// ```rust + /// ```no_run /// use std::ptr::NonNull; /// let a = &mut 42; /// /// let ptr = unsafe { NonNull::new_unchecked(a) }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::ptr::NonNull; /// let a = &mut 42; /// @@ -72,7 +72,7 @@ declare_clippy_lint! { /// describe safety invariants. /// /// ### Example - /// ```rust + /// ```no_run /// use std::ptr::NonNull; /// let a = &mut 42; /// @@ -80,7 +80,7 @@ declare_clippy_lint! { /// let ptr = NonNull::new(a).unwrap(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::ptr::NonNull; /// let a = &mut 42; /// @@ -638,7 +638,9 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option { fn span_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool { let source_map = cx.sess().source_map(); let ctxt = span.ctxt(); - if ctxt.is_root() && let Some(search_span) = get_body_search_span(cx) { + if ctxt.is_root() + && let Some(search_span) = get_body_search_span(cx) + { if let Ok(unsafe_line) = source_map.lookup_line(span.lo()) && let Some(body_span) = walk_span_to_context(search_span, SyntaxContext::root()) && let Ok(body_line) = source_map.lookup_line(body_span.lo()) @@ -648,11 +650,13 @@ fn span_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool { // Get the text from the start of function body to the unsafe block. // fn foo() { some_stuff; unsafe { stuff }; other_stuff; } // ^-------------^ - body_line.line < unsafe_line.line && text_has_safety_comment( - src, - &unsafe_line.sf.lines()[body_line.line + 1..=unsafe_line.line], - unsafe_line.sf.start_pos, - ).is_some() + body_line.line < unsafe_line.line + && text_has_safety_comment( + src, + &unsafe_line.sf.lines()[body_line.line + 1..=unsafe_line.line], + unsafe_line.sf.start_pos, + ) + .is_some() } else { // Problem getting source text. Pretend a comment was found. true diff --git a/clippy_lints/src/unicode.rs b/clippy_lints/src/unicode.rs index e275bfd37b00..37bf2a352518 100644 --- a/clippy_lints/src/unicode.rs +++ b/clippy_lints/src/unicode.rs @@ -39,12 +39,12 @@ declare_clippy_lint! { /// requirements, activating this lint could be useful. /// /// ### Example - /// ```rust + /// ```no_run /// let x = String::from("€"); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let x = String::from("\u{20ac}"); /// ``` #[clippy::version = "pre 1.29.0"] diff --git a/clippy_lints/src/unit_return_expecting_ord.rs b/clippy_lints/src/unit_return_expecting_ord.rs index de4b8738e35b..e76cc65fd46a 100644 --- a/clippy_lints/src/unit_return_expecting_ord.rs +++ b/clippy_lints/src/unit_return_expecting_ord.rs @@ -25,7 +25,7 @@ declare_clippy_lint! { /// way of specifying this without triggering needless_return lint /// /// ### Example - /// ```rust + /// ```no_run /// let mut twins = vec![(1, 1), (2, 2)]; /// twins.sort_by_key(|x| { x.1; }); /// ``` diff --git a/clippy_lints/src/unit_types/let_unit_value.rs b/clippy_lints/src/unit_types/let_unit_value.rs index e7915953d85b..ef67f4b04b5a 100644 --- a/clippy_lints/src/unit_types/let_unit_value.rs +++ b/clippy_lints/src/unit_types/let_unit_value.rs @@ -24,7 +24,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) { && expr_needs_inferred_result(cx, init) { if !matches!(local.pat.kind, PatKind::Wild) - && !matches!(local.pat.kind, PatKind::Tuple([], ddpos) if ddpos.as_opt_usize().is_none()) + && !matches!(local.pat.kind, PatKind::Tuple([], ddpos) if ddpos.as_opt_usize().is_none()) { span_lint_and_then( cx, @@ -43,7 +43,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) { } } else { if let ExprKind::Match(_, _, MatchSource::AwaitDesugar) = init.kind { - return + return; } span_lint_and_then( @@ -55,12 +55,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) { if let Some(expr) = &local.init { let mut app = Applicability::MachineApplicable; let snip = snippet_with_context(cx, expr.span, local.span.ctxt(), "()", &mut app).0; - diag.span_suggestion( - local.span, - "omit the `let` binding", - format!("{snip};"), - app, - ); + diag.span_suggestion(local.span, "omit the `let` binding", format!("{snip};"), app); } }, ); diff --git a/clippy_lints/src/unit_types/mod.rs b/clippy_lints/src/unit_types/mod.rs index 546242ebd9a4..884c6ca4d313 100644 --- a/clippy_lints/src/unit_types/mod.rs +++ b/clippy_lints/src/unit_types/mod.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// binding one is kind of pointless. /// /// ### Example - /// ```rust + /// ```no_run /// let x = { /// 1; /// }; @@ -38,7 +38,7 @@ declare_clippy_lint! { /// adds semicolons at the end of the operands. /// /// ### Example - /// ```rust + /// ```no_run /// # fn foo() {}; /// # fn bar() {}; /// # fn baz() {}; @@ -51,7 +51,7 @@ declare_clippy_lint! { /// } /// ``` /// is equal to - /// ```rust + /// ```no_run /// # fn foo() {}; /// # fn bar() {}; /// # fn baz() {}; @@ -63,7 +63,7 @@ declare_clippy_lint! { /// ``` /// /// For asserts: - /// ```rust + /// ```no_run /// # fn foo() {}; /// # fn bar() {}; /// assert_eq!({ foo(); }, { bar(); }); diff --git a/clippy_lints/src/unnamed_address.rs b/clippy_lints/src/unnamed_address.rs index 996e7edf5573..e7355f92304d 100644 --- a/clippy_lints/src/unnamed_address.rs +++ b/clippy_lints/src/unnamed_address.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// the same address after being merged together. /// /// ### Example - /// ```rust + /// ```no_run /// type F = fn(); /// fn a() {} /// let f: F = a; diff --git a/clippy_lints/src/unnecessary_box_returns.rs b/clippy_lints/src/unnecessary_box_returns.rs index ed2ef506381f..ca159eb4d5fd 100644 --- a/clippy_lints/src/unnecessary_box_returns.rs +++ b/clippy_lints/src/unnecessary_box_returns.rs @@ -22,13 +22,13 @@ declare_clippy_lint! { /// `Box` been dropped. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo() -> Box { /// Box::new(String::from("Hello, world!")) /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn foo() -> String { /// String::from("Hello, world!") /// } diff --git a/clippy_lints/src/unnecessary_map_on_constructor.rs b/clippy_lints/src/unnecessary_map_on_constructor.rs index 894de0d85c1e..9107b2b99b88 100644 --- a/clippy_lints/src/unnecessary_map_on_constructor.rs +++ b/clippy_lints/src/unnecessary_map_on_constructor.rs @@ -9,18 +9,18 @@ use rustc_span::sym; declare_clippy_lint! { /// ### What it does - /// Suggest removing the use of a may (or map_err) method when an Option or Result is being construted. + /// Suggest removing the use of a may (or map_err) method when an Option or Result is being constructed. /// /// ### Why is this bad? /// It introduces unnecessary complexity. In this case the function can be used directly and /// construct the Option or Result from the output. /// /// ### Example - /// ```rust + /// ```no_run /// Some(4).map(i32::swap_bytes); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// Some(i32::swap_bytes(4)); /// ``` #[clippy::version = "1.73.0"] @@ -36,19 +36,20 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor { return; } if let hir::ExprKind::MethodCall(path, recv, args, ..) = expr.kind - && let Some(sym::Option | sym::Result) = get_type_diagnostic_name(cx, cx.typeck_results().expr_ty(recv)){ - let (constructor_path, constructor_item) = - if let hir::ExprKind::Call(constructor, constructor_args) = recv.kind - && let hir::ExprKind::Path(constructor_path) = constructor.kind - && let Some(arg) = constructor_args.first() - { - if constructor.span.from_expansion() || arg.span.from_expansion() { - return; - } - (constructor_path, arg) - } else { + && let Some(sym::Option | sym::Result) = get_type_diagnostic_name(cx, cx.typeck_results().expr_ty(recv)) + { + let (constructor_path, constructor_item) = if let hir::ExprKind::Call(constructor, constructor_args) = + recv.kind + && let hir::ExprKind::Path(constructor_path) = constructor.kind + && let Some(arg) = constructor_args.first() + { + if constructor.span.from_expansion() || arg.span.from_expansion() { return; - }; + } + (constructor_path, arg) + } else { + return; + }; let constructor_symbol = match constructor_path { hir::QPath::Resolved(_, path) => { if let Some(path_segment) = path.segments.last() { @@ -82,7 +83,10 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor { cx, UNNECESSARY_MAP_ON_CONSTRUCTOR, expr.span, - &format!("unnecessary {} on constructor {constructor_snippet}(_)", path.ident.name), + &format!( + "unnecessary {} on constructor {constructor_snippet}(_)", + path.ident.name + ), "try", format!("{constructor_snippet}({fun_snippet}({constructor_arg_snippet}))"), applicability, diff --git a/clippy_lints/src/unnecessary_owned_empty_strings.rs b/clippy_lints/src/unnecessary_owned_empty_strings.rs index 57a4a429e129..28ea02e4d9a1 100644 --- a/clippy_lints/src/unnecessary_owned_empty_strings.rs +++ b/clippy_lints/src/unnecessary_owned_empty_strings.rs @@ -20,11 +20,11 @@ declare_clippy_lint! { /// This results in longer and less readable code /// /// ### Example - /// ```rust + /// ```no_run /// vec!["1", "2", "3"].join(&String::new()); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// vec!["1", "2", "3"].join(""); /// ``` #[clippy::version = "1.62.0"] diff --git a/clippy_lints/src/unnecessary_self_imports.rs b/clippy_lints/src/unnecessary_self_imports.rs index 397633f533b2..a1083a0a68e5 100644 --- a/clippy_lints/src/unnecessary_self_imports.rs +++ b/clippy_lints/src/unnecessary_self_imports.rs @@ -19,11 +19,11 @@ declare_clippy_lint! { /// to detect this scenario and that is why it is a restriction lint. /// /// ### Example - /// ```rust + /// ```no_run /// use std::io::{self}; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// use std::io; /// ``` #[clippy::version = "1.53.0"] diff --git a/clippy_lints/src/unnecessary_struct_initialization.rs b/clippy_lints/src/unnecessary_struct_initialization.rs index f4111186c642..c35a2afab48e 100644 --- a/clippy_lints/src/unnecessary_struct_initialization.rs +++ b/clippy_lints/src/unnecessary_struct_initialization.rs @@ -15,14 +15,14 @@ declare_clippy_lint! { /// Readability suffers from unnecessary struct building. /// /// ### Example - /// ```rust + /// ```no_run /// struct S { s: String } /// /// let a = S { s: String::from("Hello, world!") }; /// let b = S { ..a }; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct S { s: String } /// /// let a = S { s: String::from("Hello, world!") }; @@ -42,9 +42,9 @@ declare_lint_pass!(UnnecessaryStruct => [UNNECESSARY_STRUCT_INITIALIZATION]); impl LateLintPass<'_> for UnnecessaryStruct { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { if let ExprKind::Struct(_, &[], Some(base)) = expr.kind { - if let Some(parent) = get_parent_expr(cx, expr) && - let parent_ty = cx.typeck_results().expr_ty_adjusted(parent) && - parent_ty.is_any_ptr() + if let Some(parent) = get_parent_expr(cx, expr) + && let parent_ty = cx.typeck_results().expr_ty_adjusted(parent) + && parent_ty.is_any_ptr() { if is_copy(cx, cx.typeck_results().expr_ty(expr)) && path_to_local(base).is_some() { // When the type implements `Copy`, a reference to the new struct works on the @@ -59,9 +59,9 @@ impl LateLintPass<'_> for UnnecessaryStruct { } // TODO: do not propose to replace *XX if XX is not Copy - if let ExprKind::Unary(UnOp::Deref, target) = base.kind && - matches!(target.kind, ExprKind::Path(..)) && - !is_copy(cx, cx.typeck_results().expr_ty(expr)) + if let ExprKind::Unary(UnOp::Deref, target) = base.kind + && matches!(target.kind, ExprKind::Path(..)) + && !is_copy(cx, cx.typeck_results().expr_ty(expr)) { // `*base` cannot be used instead of the struct in the general case if it is not Copy. return; @@ -81,8 +81,8 @@ impl LateLintPass<'_> for UnnecessaryStruct { } fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - if let Some(hir_id) = path_to_local(expr) && - let Node::Pat(pat) = cx.tcx.hir().get(hir_id) + if let Some(hir_id) = path_to_local(expr) + && let Node::Pat(pat) = cx.tcx.hir().get(hir_id) { matches!(pat.kind, PatKind::Binding(BindingAnnotation::MUT, ..)) } else { diff --git a/clippy_lints/src/unnecessary_wraps.rs b/clippy_lints/src/unnecessary_wraps.rs index f34f8d0e3538..ab8de17b091f 100644 --- a/clippy_lints/src/unnecessary_wraps.rs +++ b/clippy_lints/src/unnecessary_wraps.rs @@ -26,7 +26,7 @@ declare_clippy_lint! { /// fit some external requirement. /// /// ### Example - /// ```rust + /// ```no_run /// fn get_cool_number(a: bool, b: bool) -> Option { /// if a && b { /// return Some(50); @@ -39,7 +39,7 @@ declare_clippy_lint! { /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn get_cool_number(a: bool, b: bool) -> i32 { /// if a && b { /// return 50; diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index 766a54814516..8ff088a208f2 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -1,8 +1,8 @@ #![allow(clippy::wildcard_imports, clippy::enum_glob_use)] +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_maybe_qself, eq_pat, eq_path}; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::over; use rustc_ast::mut_visit::*; use rustc_ast::ptr::P; @@ -29,13 +29,13 @@ declare_clippy_lint! { /// In the example above, `Some` is repeated, which unnecessarily complicates the pattern. /// /// ### Example - /// ```rust + /// ```no_run /// fn main() { /// if let Some(0) | Some(2) = Some(0) {} /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// fn main() { /// if let Some(0 | 2) = Some(0) {} /// } diff --git a/clippy_lints/src/unused_async.rs b/clippy_lints/src/unused_async.rs index 3649f8792ae5..aea72c798be7 100644 --- a/clippy_lints/src/unused_async.rs +++ b/clippy_lints/src/unused_async.rs @@ -19,7 +19,7 @@ declare_clippy_lint! { /// causes runtime overhead and hassle for the caller. /// /// ### Example - /// ```rust + /// ```no_run /// async fn get_random_number() -> i64 { /// 4 // Chosen by fair dice roll. Guaranteed to be random. /// } @@ -27,7 +27,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// fn get_random_number_improved() -> i64 { /// 4 // Chosen by fair dice roll. Guaranteed to be random. /// } diff --git a/clippy_lints/src/unused_peekable.rs b/clippy_lints/src/unused_peekable.rs index db91beec0efa..0473ecaabeb5 100644 --- a/clippy_lints/src/unused_peekable.rs +++ b/clippy_lints/src/unused_peekable.rs @@ -18,7 +18,7 @@ declare_clippy_lint! { /// or just a leftover after a refactor. /// /// ### Example - /// ```rust + /// ```no_run /// let collection = vec![1, 2, 3]; /// let iter = collection.iter().peekable(); /// @@ -28,7 +28,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let collection = vec![1, 2, 3]; /// let iter = collection.iter(); /// @@ -85,8 +85,8 @@ impl<'tcx> LateLintPass<'tcx> for UnusedPeekable { ident.span, "`peek` never called on `Peekable` iterator", None, - "consider removing the call to `peekable`" - ); + "consider removing the call to `peekable`", + ); } } } @@ -131,11 +131,7 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> { // If the Peekable is passed to a function, stop ExprKind::Call(_, args) => { if let Some(func_did) = fn_def_id(self.cx, expr) - && let Some(into_iter_did) = self - .cx - .tcx - .lang_items() - .into_iter_fn() + && let Some(into_iter_did) = self.cx.tcx.lang_items().into_iter_fn() && func_did == into_iter_did { // Probably a for loop desugar, stop searching diff --git a/clippy_lints/src/unused_rounding.rs b/clippy_lints/src/unused_rounding.rs index 097568cd1f70..fbb36bea0682 100644 --- a/clippy_lints/src/unused_rounding.rs +++ b/clippy_lints/src/unused_rounding.rs @@ -16,11 +16,11 @@ declare_clippy_lint! { /// This is unnecessary and confusing to the reader. Doing this is probably a mistake. /// /// ### Example - /// ```rust + /// ```no_run /// let x = 1f32.ceil(); /// ``` /// Use instead: - /// ```rust + /// ```no_run /// let x = 1f32; /// ``` #[clippy::version = "1.63.0"] @@ -31,18 +31,21 @@ declare_clippy_lint! { declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]); fn is_useless_rounding<'a>(cx: &EarlyContext<'_>, expr: &'a Expr) -> Option<(&'a str, String)> { - if let ExprKind::MethodCall(box MethodCall { seg:name_ident, receiver, .. }) = &expr.kind + if let ExprKind::MethodCall(box MethodCall { + seg: name_ident, + receiver, + .. + }) = &expr.kind && let method_name = name_ident.ident.name.as_str() && (method_name == "ceil" || method_name == "round" || method_name == "floor") && let ExprKind::Lit(token_lit) = &receiver.kind && token_lit.is_semantic_float() - && let Ok(f) = token_lit.symbol.as_str().replace('_', "").parse::() { - (f.fract() == 0.0).then(|| - (method_name, snippet(cx, receiver.span, "..").to_string()) - ) - } else { - None - } + && let Ok(f) = token_lit.symbol.as_str().replace('_', "").parse::() + { + (f.fract() == 0.0).then(|| (method_name, snippet(cx, receiver.span, "..").to_string())) + } else { + None + } } impl EarlyLintPass for UnusedRounding { diff --git a/clippy_lints/src/unused_unit.rs b/clippy_lints/src/unused_unit.rs index 95e74718d806..ae844673b158 100644 --- a/clippy_lints/src/unused_unit.rs +++ b/clippy_lints/src/unused_unit.rs @@ -19,13 +19,13 @@ declare_clippy_lint! { /// statement look like a function call. /// /// ### Example - /// ```rust + /// ```no_run /// fn return_unit() -> () { /// () /// } /// ``` /// is equivalent to - /// ```rust + /// ```no_run /// fn return_unit() {} /// ``` #[clippy::version = "1.31.0"] diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index 9a0d83d83f1f..e52cfb29fe54 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -26,7 +26,7 @@ declare_clippy_lint! { /// Using `if let` or `match` is more idiomatic. /// /// ### Example - /// ```rust + /// ```no_run /// # let option = Some(0); /// # fn do_something_with(_x: usize) {} /// if option.is_some() { @@ -36,7 +36,7 @@ declare_clippy_lint! { /// /// Could be written: /// - /// ```rust + /// ```no_run /// # let option = Some(0); /// # fn do_something_with(_x: usize) {} /// if let Some(value) = option { @@ -61,7 +61,7 @@ declare_clippy_lint! { /// So something like `let x: Option<()> = None; x.unwrap();` will not be recognized. /// /// ### Example - /// ```rust + /// ```no_run /// # let option = Some(0); /// # fn do_something_with(_x: usize) {} /// if option.is_none() { diff --git a/clippy_lints/src/unwrap_in_result.rs b/clippy_lints/src/unwrap_in_result.rs index 3a1845425a25..21592abbf168 100644 --- a/clippy_lints/src/unwrap_in_result.rs +++ b/clippy_lints/src/unwrap_in_result.rs @@ -22,7 +22,7 @@ declare_clippy_lint! { /// /// ### Example /// Before: - /// ```rust + /// ```no_run /// fn divisible_by_3(i_str: String) -> Result<(), String> { /// let i = i_str /// .parse::() @@ -37,7 +37,7 @@ declare_clippy_lint! { /// ``` /// /// After: - /// ```rust + /// ```no_run /// fn divisible_by_3(i_str: String) -> Result<(), String> { /// let i = i_str /// .parse::() diff --git a/clippy_lints/src/upper_case_acronyms.rs b/clippy_lints/src/upper_case_acronyms.rs index 4df1e3299ed9..de6a75b79fcf 100644 --- a/clippy_lints/src/upper_case_acronyms.rs +++ b/clippy_lints/src/upper_case_acronyms.rs @@ -26,11 +26,11 @@ declare_clippy_lint! { /// the letters in the second acronym. /// /// ### Example - /// ```rust + /// ```no_run /// struct HTTPResponse; /// ``` /// Use instead: - /// ```rust + /// ```no_run /// struct HttpResponse; /// ``` #[clippy::version = "1.51.0"] diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index f10ed4b3d419..c3fe16ad5c3e 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -1,6 +1,6 @@ +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::is_from_proc_macro; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::same_type_and_consts; use if_chain::if_chain; use rustc_data_structures::fx::FxHashSet; @@ -31,7 +31,7 @@ declare_clippy_lint! { /// - Unaddressed false negative in fn bodies of trait implementations /// /// ### Example - /// ```rust + /// ```no_run /// struct Foo; /// impl Foo { /// fn new() -> Foo { @@ -40,7 +40,7 @@ declare_clippy_lint! { /// } /// ``` /// could be - /// ```rust + /// ```no_run /// struct Foo; /// impl Foo { /// fn new() -> Self { diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index 3cc91838c000..28f1d487eb5f 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -26,13 +26,13 @@ declare_clippy_lint! { /// Redundant code. /// /// ### Example - /// ```rust + /// ```no_run /// // format!() returns a `String` /// let s: String = format!("hello").into(); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let s: String = format!("hello"); /// ``` #[clippy::version = "1.45.0"] @@ -215,20 +215,19 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { did, args, cx.typeck_results().node_args(recv.hir_id), - MethodOrFunction::Function + MethodOrFunction::Function, )) - } + }, ExprKind::MethodCall(.., args, _) => { - cx.typeck_results().type_dependent_def_id(parent.hir_id) - .map(|did| { - return ( - did, - args, - cx.typeck_results().node_args(parent.hir_id), - MethodOrFunction::Method - ); - }) - } + cx.typeck_results().type_dependent_def_id(parent.hir_id).map(|did| { + return ( + did, + args, + cx.typeck_results().node_args(parent.hir_id), + MethodOrFunction::Method, + ); + }) + }, _ => None, }; @@ -244,7 +243,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { into_iter_did, cx.typeck_results().expr_ty(into_iter_recv), param.index, - node_args + node_args, ) && self.expn_depth == 0 { @@ -255,26 +254,38 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { let plural = if depth == 0 { "" } else { "s" }; let mut applicability = Applicability::MachineApplicable; - let sugg = snippet_with_applicability(cx, into_iter_recv.span.source_callsite(), "", &mut applicability).into_owned(); - span_lint_and_then(cx, USELESS_CONVERSION, e.span, "explicit call to `.into_iter()` in function argument accepting `IntoIterator`", |diag| { - diag.span_suggestion( - e.span, - format!("consider removing the `.into_iter()`{plural}"), - sugg, - applicability, - ); - diag.span_note(span, "this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`"); - }); + let sugg = snippet_with_applicability( + cx, + into_iter_recv.span.source_callsite(), + "", + &mut applicability, + ) + .into_owned(); + span_lint_and_then( + cx, + USELESS_CONVERSION, + e.span, + "explicit call to `.into_iter()` in function argument accepting `IntoIterator`", + |diag| { + diag.span_suggestion( + e.span, + format!("consider removing the `.into_iter()`{plural}"), + sugg, + applicability, + ); + diag.span_note(span, "this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`"); + }, + ); // Early return to avoid linting again with contradicting suggestions return; } } - if let Some(id) = path_to_local(recv) && - let Node::Pat(pat) = cx.tcx.hir().get(id) && - let PatKind::Binding(ann, ..) = pat.kind && - ann != BindingAnnotation::MUT + if let Some(id) = path_to_local(recv) + && let Node::Pat(pat) = cx.tcx.hir().get(id) + && let PatKind::Binding(ann, ..) = pat.kind + && ann != BindingAnnotation::MUT { // Do not remove .into_iter() applied to a non-mutable local variable used in // a larger expression context as it would differ in mutability. diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index aecb0c6dbfa1..ce93aea21360 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -10,12 +10,12 @@ use rustc_hir::{ ArrayLen, BindingAnnotation, Closure, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_session::declare_lint_pass; use rustc_span::symbol::{Ident, Symbol}; use std::cell::Cell; use std::fmt::{Display, Formatter, Write as _}; -declare_clippy_lint! { +declare_lint_pass!( /// ### What it does /// Generates clippy code that detects the offending pattern /// @@ -47,12 +47,8 @@ declare_clippy_lint! { /// // report your lint here /// } /// ``` - pub LINT_AUTHOR, - internal_warn, - "helper for writing lints" -} - -declare_lint_pass!(Author => [LINT_AUTHOR]); + Author => [] +); /// Writes a line of output with indentation added macro_rules! out { diff --git a/clippy_lints/src/utils/dump_hir.rs b/clippy_lints/src/utils/dump_hir.rs index 092041aecf29..b108951978f3 100644 --- a/clippy_lints/src/utils/dump_hir.rs +++ b/clippy_lints/src/utils/dump_hir.rs @@ -2,9 +2,9 @@ use clippy_utils::get_attr; use hir::TraitItem; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_session::declare_lint_pass; -declare_clippy_lint! { +declare_lint_pass!( /// ### What it does /// It formats the attached node with `{:#?}` and writes the result to the /// standard output. This is intended for debugging. @@ -19,12 +19,8 @@ declare_clippy_lint! { /// input as u64 /// } /// ``` - pub DUMP_HIR, - internal_warn, - "helper to dump info about code" -} - -declare_lint_pass!(DumpHir => [DUMP_HIR]); + DumpHir => [] +); impl<'tcx> LateLintPass<'tcx> for DumpHir { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { diff --git a/clippy_lints/src/utils/format_args_collector.rs b/clippy_lints/src/utils/format_args_collector.rs index 94a9a7c241bb..58e66c9f9b95 100644 --- a/clippy_lints/src/utils/format_args_collector.rs +++ b/clippy_lints/src/utils/format_args_collector.rs @@ -5,27 +5,20 @@ use rustc_ast::{Crate, Expr, ExprKind, FormatArgs}; use rustc_data_structures::fx::FxHashMap; use rustc_lexer::{tokenize, TokenKind}; use rustc_lint::{EarlyContext, EarlyLintPass}; -use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_session::impl_lint_pass; use rustc_span::{hygiene, Span}; use std::iter::once; use std::mem; use std::rc::Rc; -declare_clippy_lint! { - /// ### What it does - /// Collects [`rustc_ast::FormatArgs`] so that future late passes can call - /// [`clippy_utils::macros::find_format_args`] - pub FORMAT_ARGS_COLLECTOR, - internal_warn, - "collects `format_args` AST nodes for use in later lints" -} - +/// Collects [`rustc_ast::FormatArgs`] so that future late passes can call +/// [`clippy_utils::macros::find_format_args`] #[derive(Default)] pub struct FormatArgsCollector { format_args: FxHashMap>, } -impl_lint_pass!(FormatArgsCollector => [FORMAT_ARGS_COLLECTOR]); +impl_lint_pass!(FormatArgsCollector => []); impl EarlyLintPass for FormatArgsCollector { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index e222a5448c9c..ddcb9f27c6c0 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -1,5 +1,4 @@ pub mod almost_standard_lint_formulation; -pub mod clippy_lints_internal; pub mod collapsible_calls; pub mod compiler_lint_functions; pub mod if_chain_style; @@ -11,3 +10,4 @@ pub mod msrv_attr_impl; pub mod outer_expn_data_pass; pub mod produce_ice; pub mod unnecessary_def_path; +pub mod unsorted_clippy_utils_paths; diff --git a/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs b/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs index 570a88a0ed2b..d78f67c05f00 100644 --- a/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs +++ b/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs @@ -11,7 +11,7 @@ declare_clippy_lint! { /// Checks if lint formulations have a standardized format. /// /// ### Why is this bad? - /// It's not neccessarily bad, but we try to enforce a standard in Clippy. + /// It's not necessarily bad, but we try to enforce a standard in Clippy. /// /// ### Example /// `Checks for use...` can be written as `Checks for usage...` . diff --git a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index bbb5ade8b9f3..00e352961bd3 100644 --- a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -153,8 +153,9 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass { let fields; if is_lint_ref_ty { if let ExprKind::AddrOf(_, _, inner_exp) = expr.kind - && let ExprKind::Struct(_, struct_fields, _) = inner_exp.kind { - fields = struct_fields; + && let ExprKind::Struct(_, struct_fields, _) = inner_exp.kind + { + fields = struct_fields; } else { return; } diff --git a/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/clippy_lints/src/utils/internal_lints/metadata_collector.rs index c8600badf18e..51abe0c1dc36 100644 --- a/clippy_lints/src/utils/internal_lints/metadata_collector.rs +++ b/clippy_lints/src/utils/internal_lints/metadata_collector.rs @@ -9,7 +9,7 @@ use crate::renamed_lints::RENAMED_LINTS; use crate::utils::internal_lints::lint_without_lint_pass::{extract_clippy_version_value, is_lint_ref_type}; -use crate::utils::{collect_configs, ClippyConfiguration}; +use clippy_config::{get_configuration_metadata, ClippyConfiguration}; use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::{match_type, walk_ptrs_ty_depth}; @@ -40,8 +40,6 @@ use std::process::Command; const JSON_OUTPUT_FILE: &str = "../util/gh-pages/lints.json"; /// This is the markdown output file of the lint collector. const MARKDOWN_OUTPUT_FILE: &str = "../book/src/lint_configuration.md"; -/// These lints are excluded from the export. -const BLACK_LISTED_LINTS: &[&str] = &["lint_author", "dump_hir", "internal_metadata_collector"]; /// These groups will be ignored by the lint group matcher. This is useful for collections like /// `clippy::all` const IGNORED_LINT_GROUPS: [&str; 1] = ["clippy::all"]; @@ -121,7 +119,7 @@ declare_clippy_lint! { /// ### Example output /// ```json,ignore /// { - /// "id": "internal_metadata_collector", + /// "id": "metadata_collector", /// "id_span": { /// "path": "clippy_lints/src/utils/internal_lints/metadata_collector.rs", /// "line": 1 @@ -131,12 +129,12 @@ declare_clippy_lint! { /// } /// ``` #[clippy::version = "1.56.0"] - pub INTERNAL_METADATA_COLLECTOR, - internal_warn, + pub METADATA_COLLECTOR, + internal, "A busy bee collection metadata about lints" } -impl_lint_pass!(MetadataCollector => [INTERNAL_METADATA_COLLECTOR]); +impl_lint_pass!(MetadataCollector => [METADATA_COLLECTOR]); #[allow(clippy::module_name_repetitions)] #[derive(Debug, Clone)] @@ -155,7 +153,7 @@ impl MetadataCollector { Self { lints: BinaryHeap::::default(), applicability_info: FxHashMap::::default(), - config: collect_configs(), + config: get_configuration_metadata(), clippy_project_root: std::env::current_dir() .expect("failed to get current dir") .ancestors() @@ -528,16 +526,6 @@ impl Serialize for ApplicabilityInfo { } } -impl fmt::Display for ClippyConfiguration { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result { - writeln!( - f, - "* `{}`: `{}`(defaults to `{}`): {}", - self.name, self.config_type, self.default, self.doc - ) - } -} - // ================================================================== // Lint pass // ================================================================== @@ -560,7 +548,6 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector { if is_lint_ref_type(cx, ty); // disallow check let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase(); - if !BLACK_LISTED_LINTS.contains(&lint_name.as_str()); // metadata extraction if let Some((group, level)) = get_lint_group_and_level_or_lint(cx, &lint_name, item); if let Some(mut raw_docs) = extract_attr_docs_or_lint(cx, item); @@ -585,7 +572,6 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector { if is_deprecated_lint(cx, ty); // disallow check let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase(); - if !BLACK_LISTED_LINTS.contains(&lint_name.as_str()); // Metadata the little we can get from a deprecated lint if let Some(raw_docs) = extract_attr_docs_or_lint(cx, item); then { @@ -841,7 +827,7 @@ fn collect_renames(lints: &mut Vec) { fn lint_collection_error_item(cx: &LateContext<'_>, item: &Item<'_>, message: &str) { span_lint( cx, - INTERNAL_METADATA_COLLECTOR, + METADATA_COLLECTOR, item.ident.span, &format!("metadata collection error for `{}`: {message}", item.ident.name), ); diff --git a/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs index a3acb8f1762d..81be04659b9f 100644 --- a/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs +++ b/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs @@ -270,7 +270,8 @@ fn read_mir_alloc_def_path<'tcx>(cx: &LateContext<'tcx>, alloc: &'tcx Allocation if let GlobalAlloc::Memory(alloc) = cx.tcx.global_alloc(alloc) { let alloc = alloc.inner(); str::from_utf8(alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len())) - .ok().map(ToOwned::to_owned) + .ok() + .map(ToOwned::to_owned) } else { None } diff --git a/clippy_lints/src/utils/internal_lints/clippy_lints_internal.rs b/clippy_lints/src/utils/internal_lints/unsorted_clippy_utils_paths.rs similarity index 85% rename from clippy_lints/src/utils/internal_lints/clippy_lints_internal.rs rename to clippy_lints/src/utils/internal_lints/unsorted_clippy_utils_paths.rs index da9514dd15ee..fd51bca9e5be 100644 --- a/clippy_lints/src/utils/internal_lints/clippy_lints_internal.rs +++ b/clippy_lints/src/utils/internal_lints/unsorted_clippy_utils_paths.rs @@ -5,21 +5,21 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { /// ### What it does - /// Checks for various things we like to keep tidy in clippy. + /// Checks that [`clippy_utils::paths`] is sorted lexically /// /// ### Why is this bad? /// We like to pretend we're an example of tidy code. /// /// ### Example /// Wrong ordering of the util::paths constants. - pub CLIPPY_LINTS_INTERNAL, + pub UNSORTED_CLIPPY_UTILS_PATHS, internal, "various things that will negatively affect your clippy experience" } -declare_lint_pass!(ClippyLintsInternal => [CLIPPY_LINTS_INTERNAL]); +declare_lint_pass!(UnsortedClippyUtilsPaths => [UNSORTED_CLIPPY_UTILS_PATHS]); -impl EarlyLintPass for ClippyLintsInternal { +impl EarlyLintPass for UnsortedClippyUtilsPaths { fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) { if let Some(utils) = krate.items.iter().find(|item| item.ident.name.as_str() == "utils") { if let ItemKind::Mod(_, ModKind::Loaded(ref items, ..)) = utils.kind { @@ -32,7 +32,7 @@ impl EarlyLintPass for ClippyLintsInternal { if *last_name > *name { span_lint( cx, - CLIPPY_LINTS_INTERNAL, + UNSORTED_CLIPPY_UTILS_PATHS, item.span, "this constant should be before the previous constant due to lexical \ ordering", diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 4fef8c0717d8..13e9ead9a57f 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -1,148 +1,5 @@ pub mod author; -pub mod conf; pub mod dump_hir; pub mod format_args_collector; #[cfg(feature = "internal")] pub mod internal_lints; -#[cfg(feature = "internal")] -use itertools::Itertools; - -/// Transforms a given `snake_case_string` to a tasty `kebab-case-string` -fn to_kebab(config_name: &str) -> String { - config_name.replace('_', "-") -} - -#[cfg(feature = "internal")] -const BOOK_CONFIGS_PATH: &str = "https://doc.rust-lang.org/clippy/lint_configuration.html"; - -// ================================================================== -// Configuration -// ================================================================== -#[derive(Debug, Clone, Default)] -pub struct ClippyConfiguration { - pub name: String, - #[allow(dead_code)] - config_type: &'static str, - pub default: String, - pub lints: Vec, - pub doc: String, - #[allow(dead_code)] - deprecation_reason: Option<&'static str>, -} - -impl ClippyConfiguration { - pub fn new( - name: &'static str, - config_type: &'static str, - default: String, - doc_comment: &'static str, - deprecation_reason: Option<&'static str>, - ) -> Self { - let (lints, doc) = parse_config_field_doc(doc_comment) - .unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string())); - - Self { - name: to_kebab(name), - lints, - doc, - config_type, - default, - deprecation_reason, - } - } - - #[cfg(feature = "internal")] - fn to_markdown_paragraph(&self) -> String { - format!( - "## `{}`\n{}\n\n**Default Value:** `{}` (`{}`)\n\n---\n**Affected lints:**\n{}\n\n", - self.name, - self.doc - .lines() - .map(|line| line.strip_prefix(" ").unwrap_or(line)) - .join("\n"), - self.default, - self.config_type, - self.lints - .iter() - .map(|name| name.to_string().split_whitespace().next().unwrap().to_string()) - .map(|name| format!("* [`{name}`](https://rust-lang.github.io/rust-clippy/master/index.html#{name})")) - .join("\n"), - ) - } - #[cfg(feature = "internal")] - fn to_markdown_link(&self) -> String { - format!("[`{}`]: {BOOK_CONFIGS_PATH}#{}", self.name, self.name) - } -} - -#[cfg(feature = "internal")] -fn collect_configs() -> Vec { - crate::utils::conf::metadata::get_configuration_metadata() -} - -/// This parses the field documentation of the config struct. -/// -/// ```rust, ignore -/// parse_config_field_doc(cx, "Lint: LINT_NAME_1, LINT_NAME_2. Papa penguin, papa penguin") -/// ``` -/// -/// Would yield: -/// ```rust, ignore -/// Some(["lint_name_1", "lint_name_2"], "Papa penguin, papa penguin") -/// ``` -fn parse_config_field_doc(doc_comment: &str) -> Option<(Vec, String)> { - const DOC_START: &str = " Lint: "; - if_chain! { - if doc_comment.starts_with(DOC_START); - if let Some(split_pos) = doc_comment.find('.'); - then { - let mut doc_comment = doc_comment.to_string(); - let mut documentation = doc_comment.split_off(split_pos); - - // Extract lints - doc_comment.make_ascii_lowercase(); - let lints: Vec = doc_comment - .split_off(DOC_START.len()) - .split(", ") - .map(str::to_string) - .collect(); - - // Format documentation correctly - // split off leading `.` from lint name list and indent for correct formatting - documentation = documentation.trim_start_matches('.').trim().replace("\n ", "\n "); - - Some((lints, documentation)) - } else { - None - } - } -} - -// Shamelessly stolen from find_all (https://github.com/nectariner/find_all) -pub trait FindAll: Iterator + Sized { - fn find_all

(&mut self, predicate: P) -> Option> - where - P: FnMut(&Self::Item) -> bool; -} - -impl FindAll for I -where - I: Iterator, -{ - fn find_all

(&mut self, mut predicate: P) -> Option> - where - P: FnMut(&Self::Item) -> bool, - { - let mut occurences = Vec::::default(); - for (index, element) in self.enumerate() { - if predicate(&element) { - occurences.push(index); - } - } - - match occurences.len() { - 0 => None, - _ => Some(occurences), - } - } -} diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index fc17e7c6d5aa..a9dd44afaf7a 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -1,8 +1,8 @@ use std::ops::ControlFlow; +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_copy; use clippy_utils::visitors::for_each_local_use_after_expr; @@ -33,14 +33,14 @@ declare_clippy_lint! { /// This is less efficient. /// /// ### Example - /// ```rust + /// ```no_run /// fn foo(_x: &[u8]) {} /// /// foo(&vec![1, 2]); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # fn foo(_x: &[u8]) {} /// foo(&[1, 2]); /// ``` @@ -110,14 +110,15 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec { } else { ControlFlow::Break(()) } - }).is_continue(); + }) + .is_continue(); if only_slice_uses { self.check_vec_macro( cx, &vec_args, expr.span.ctxt().outer_expn_data().call_site, - SuggestedType::Array + SuggestedType::Array, ); } } diff --git a/clippy_lints/src/vec_init_then_push.rs b/clippy_lints/src/vec_init_then_push.rs index 3fa51216c773..c8b9402f1ae4 100644 --- a/clippy_lints/src/vec_init_then_push.rs +++ b/clippy_lints/src/vec_init_then_push.rs @@ -30,13 +30,15 @@ declare_clippy_lint! { /// multiple `push` calls. /// /// ### Example - /// ```rust + /// ```no_run /// let mut v = Vec::new(); /// v.push(0); + /// v.push(1); + /// v.push(2); /// ``` /// Use instead: - /// ```rust - /// let v = vec![0]; + /// ```no_run + /// let v = vec![0, 1, 2]; /// ``` #[clippy::version = "1.51.0"] pub VEC_INIT_THEN_PUSH, @@ -209,7 +211,7 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush { found: searcher.found + 1, err_span: searcher.err_span.to(stmt.span), last_push_expr: expr.hir_id, - .. searcher + ..searcher }); } else { searcher.display_err(cx); diff --git a/clippy_lints/src/visibility.rs b/clippy_lints/src/visibility.rs index 496376520019..8abcc964b890 100644 --- a/clippy_lints/src/visibility.rs +++ b/clippy_lints/src/visibility.rs @@ -82,7 +82,9 @@ impl EarlyLintPass for Visibility { if !in_external_macro(cx.sess(), item.span) && let VisibilityKind::Restricted { path, shorthand, .. } = &item.vis.kind { - if **path == kw::SelfLower && let Some(false) = is_from_proc_macro(cx, item.vis.span) { + if **path == kw::SelfLower + && let Some(false) = is_from_proc_macro(cx, item.vis.span) + { span_lint_and_sugg( cx, NEEDLESS_PUB_SELF, diff --git a/clippy_lints/src/wildcard_imports.rs b/clippy_lints/src/wildcard_imports.rs index 70b83149ce1a..d88ede763980 100644 --- a/clippy_lints/src/wildcard_imports.rs +++ b/clippy_lints/src/wildcard_imports.rs @@ -24,7 +24,7 @@ declare_clippy_lint! { /// still around. /// /// ### Example - /// ```rust + /// ```no_run /// use std::cmp::Ordering::*; /// /// # fn foo(_: std::cmp::Ordering) {} @@ -32,7 +32,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// use std::cmp::Ordering; /// /// # fn foo(_: Ordering) {} diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index 855aefa70cb1..b6f942a90d3a 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -22,12 +22,12 @@ declare_clippy_lint! { /// You should use `println!()`, which is simpler. /// /// ### Example - /// ```rust + /// ```no_run /// println!(""); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// println!(); /// ``` #[clippy::version = "pre 1.29.0"] @@ -46,12 +46,12 @@ declare_clippy_lint! { /// newline. /// /// ### Example - /// ```rust + /// ```no_run /// # let name = "World"; /// print!("Hello {}!\n", name); /// ``` /// use println!() instead - /// ```rust + /// ```no_run /// # let name = "World"; /// println!("Hello {}!", name); /// ``` @@ -74,7 +74,7 @@ declare_clippy_lint! { /// Only catches `print!` and `println!` calls. /// /// ### Example - /// ```rust + /// ```no_run /// println!("Hello world!"); /// ``` #[clippy::version = "pre 1.29.0"] @@ -96,7 +96,7 @@ declare_clippy_lint! { /// Only catches `eprint!` and `eprintln!` calls. /// /// ### Example - /// ```rust + /// ```no_run /// eprintln!("Hello world!"); /// ``` #[clippy::version = "1.50.0"] @@ -115,7 +115,7 @@ declare_clippy_lint! { /// debugging Rust code. It should not be used in user-facing output. /// /// ### Example - /// ```rust + /// ```no_run /// # let foo = "bar"; /// println!("{:?}", foo); /// ``` @@ -135,11 +135,11 @@ declare_clippy_lint! { /// (i.e., just put the literal in the format string) /// /// ### Example - /// ```rust + /// ```no_run /// println!("{}", "foo"); /// ``` /// use the literal without formatting: - /// ```rust + /// ```no_run /// println!("foo"); /// ``` #[clippy::version = "pre 1.29.0"] @@ -157,14 +157,14 @@ declare_clippy_lint! { /// You should use `writeln!(buf)`, which is simpler. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::fmt::Write; /// # let mut buf = String::new(); /// writeln!(buf, ""); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # use std::fmt::Write; /// # let mut buf = String::new(); /// writeln!(buf); @@ -186,7 +186,7 @@ declare_clippy_lint! { /// newline. /// /// ### Example - /// ```rust + /// ```no_run /// # use std::fmt::Write; /// # let mut buf = String::new(); /// # let name = "World"; @@ -194,7 +194,7 @@ declare_clippy_lint! { /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # use std::fmt::Write; /// # let mut buf = String::new(); /// # let name = "World"; @@ -216,14 +216,14 @@ declare_clippy_lint! { /// (i.e., just put the literal in the format string) /// /// ### Example - /// ```rust + /// ```no_run /// # use std::fmt::Write; /// # let mut buf = String::new(); /// writeln!(buf, "{}", "foo"); /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// # use std::fmt::Write; /// # let mut buf = String::new(); /// writeln!(buf, "foo"); @@ -342,7 +342,10 @@ impl<'tcx> LateLintPass<'tcx> for Write { } fn is_debug_impl(cx: &LateContext<'_>, item: &Item<'_>) -> bool { - if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), .. }) = &item.kind + if let ItemKind::Impl(Impl { + of_trait: Some(trait_ref), + .. + }) = &item.kind && let Some(trait_id) = trait_ref.trait_def_id() { cx.tcx.is_diagnostic_item(sym::Debug, trait_id) @@ -508,7 +511,9 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) { _ => continue, }; - let Some(format_string_snippet) = snippet_opt(cx, format_args.span) else { continue }; + let Some(format_string_snippet) = snippet_opt(cx, format_args.span) else { + continue; + }; let format_string_is_raw = format_string_snippet.starts_with('r'); let replacement = match (format_string_is_raw, replace_raw) { @@ -537,7 +542,8 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) { if let Some(replacement) = replacement // `format!("{}", "a")`, `format!("{named}", named = "b") // ~~~~~ ~~~~~~~~~~~~~ - && let Some(removal_span) = format_arg_removal_span(format_args, index) { + && let Some(removal_span) = format_arg_removal_span(format_args, index) + { let replacement = escape_braces(&replacement, !format_string_is_raw && !replace_raw); suggestion.push((*placeholder_span, replacement)); suggestion.push((removal_span, String::new())); @@ -549,7 +555,8 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) { if !suggestion.is_empty() { for piece in &format_args.template { if let Some((span, index)) = positional_arg_piece_span(piece) - && suggestion.iter().all(|(s, _)| *s != span) { + && suggestion.iter().all(|(s, _)| *s != span) + { let decrement = replaced_position.iter().filter(|i| **i < index).count(); suggestion.push((span, format!("{{{}}}", index.saturating_sub(decrement)))); } diff --git a/clippy_lints/src/zero_div_zero.rs b/clippy_lints/src/zero_div_zero.rs index 9b3de35dbd3c..f2f0699ef489 100644 --- a/clippy_lints/src/zero_div_zero.rs +++ b/clippy_lints/src/zero_div_zero.rs @@ -13,12 +13,12 @@ declare_clippy_lint! { /// It's less readable than `f32::NAN` or `f64::NAN`. /// /// ### Example - /// ```rust + /// ```no_run /// let nan = 0.0f32 / 0.0; /// ``` /// /// Use instead: - /// ```rust + /// ```no_run /// let nan = f32::NAN; /// ``` #[clippy::version = "pre 1.29.0"] diff --git a/clippy_lints/src/zero_sized_map_values.rs b/clippy_lints/src/zero_sized_map_values.rs index 002304f8840b..fee100fe1ead 100644 --- a/clippy_lints/src/zero_sized_map_values.rs +++ b/clippy_lints/src/zero_sized_map_values.rs @@ -23,14 +23,14 @@ declare_clippy_lint! { /// * This lints the signature of public items /// /// ### Example - /// ```rust + /// ```no_run /// # use std::collections::HashMap; /// fn unique_words(text: &str) -> HashMap<&str, ()> { /// todo!(); /// } /// ``` /// Use instead: - /// ```rust + /// ```no_run /// # use std::collections::HashSet; /// fn unique_words(text: &str) -> HashSet<&str> { /// todo!(); diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index 90091ca927ae..c9b01a68f42d 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -5,15 +5,14 @@ edition = "2021" publish = false [dependencies] +clippy_config = { path = "../clippy_config" } arrayvec = { version = "0.7", default-features = false } if_chain = "1.0" itertools = "0.10.1" rustc-semver = "1.1" -serde = { version = "1.0" } [features] -deny-warnings = [] -internal = [] +deny-warnings = ["clippy_config/deny-warnings"] [package.metadata.rust-analyzer] # This crate uses #[feature(rustc_private)] diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index 6be8b8bb9169..3bac0626f885 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -292,7 +292,9 @@ fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) { (Pat::Str("#!["), Pat::Str("]")) }; - if let Some(ident) = attr.ident() && let Pat::Str(old_pat) = pat.0 { + if let Some(ident) = attr.ident() + && let Pat::Str(old_pat) = pat.0 + { // TODO: I feel like it's likely we can use `Cow` instead but this will require quite a bit of // refactoring // NOTE: This will likely have false positives, like `allow = 1` diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 50a73745acb8..b581a60de6e5 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -405,8 +405,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { && let Some(desired_field) = field_of_struct(*adt_def, self.lcx, *constant, field) { mir_to_const(self.lcx, desired_field) - } - else { + } else { result } }, @@ -462,11 +461,15 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { // Check if this constant is based on `cfg!(..)`, // which is NOT constant for our purposes. if let Some(node) = self.lcx.tcx.hir().get_if_local(def_id) - && let Node::Item(Item { kind: ItemKind::Const(.., body_id), .. }) = node - && let Node::Expr(Expr { kind: ExprKind::Lit(_), span, .. }) = self.lcx - .tcx - .hir() - .get(body_id.hir_id) + && let Node::Item(Item { + kind: ItemKind::Const(.., body_id), + .. + }) = node + && let Node::Expr(Expr { + kind: ExprKind::Lit(_), + span, + .. + }) = self.lcx.tcx.hir().get(body_id.hir_id) && is_direct_expn_of(*span, "cfg").is_some() { return None; @@ -531,7 +534,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { && let Some(src) = get_source_text(self.lcx, span.lo..expr_lo) && let Some(src) = src.as_str() { - use rustc_lexer::TokenKind::{Whitespace, LineComment, BlockComment, Semi, OpenBrace}; + use rustc_lexer::TokenKind::{BlockComment, LineComment, OpenBrace, Semi, Whitespace}; if !tokenize(src) .map(|t| t.kind) .filter(|t| !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi)) @@ -717,8 +720,7 @@ fn field_of_struct<'tcx>( && let Some(&(val, ty)) = dc.fields.get(field_idx) { Some(mir::Const::Val(val, ty)) - } - else { + } else { None } } diff --git a/clippy_utils/src/diagnostics.rs b/clippy_utils/src/diagnostics.rs index edd87546a5f8..76f5d680a986 100644 --- a/clippy_utils/src/diagnostics.rs +++ b/clippy_utils/src/diagnostics.rs @@ -193,7 +193,7 @@ pub fn span_lint_hir_and_then( /// | /// = note: `-D fold-any` implied by `-D warnings` /// ``` -#[cfg_attr(feature = "internal", allow(clippy::collapsible_span_lint_calls))] +#[expect(clippy::collapsible_span_lint_calls)] pub fn span_lint_and_sugg( cx: &T, lint: &'static Lint, diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 52214e733f1a..2a8b2ebd5fbd 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -1142,12 +1142,8 @@ fn eq_span_tokens( let pred = |t: &(_, _)| pred(t.0); let map = |(_, x)| x; - let ltok = tokenize_with_text(lsrc) - .filter(pred) - .map(map); - let rtok = tokenize_with_text(rsrc) - .filter(pred) - .map(map); + let ltok = tokenize_with_text(lsrc).filter(pred).map(map); + let rtok = tokenize_with_text(rsrc).filter(pred).map(map); ltok.eq(rtok) } else { // Unable to access the source. Conservatively assume the blocks aren't equal. diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 93b370228228..1181dfc0ef95 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -54,7 +54,6 @@ pub mod higher; mod hir_utils; pub mod macros; pub mod mir; -pub mod msrvs; pub mod numeric_literal; pub mod paths; pub mod ptr; @@ -144,7 +143,7 @@ macro_rules! extract_msrv_attr { /// instead. /// /// Examples: -/// ``` +/// ```no_run /// let abc = 1; /// // ^ output /// let def = abc; @@ -288,7 +287,7 @@ pub fn is_wild(pat: &Pat<'_>) -> bool { pub fn is_ty_alias(qpath: &QPath<'_>) -> bool { match *qpath { QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias | DefKind::AssocTy, ..)), - QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => { is_ty_alias(&qpath) }, + QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => is_ty_alias(&qpath), _ => false, } } @@ -699,7 +698,7 @@ pub fn get_trait_def_id(cx: &LateContext<'_>, path: &[&str]) -> Option { /// /// Use this if you want to find the `TraitRef` of the `Add` trait in this example: /// -/// ```rust +/// ```no_run /// struct Point(isize, isize); /// /// impl std::ops::Add for Point { @@ -864,8 +863,8 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { } fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: &Expr<'_>) -> bool { - if let ExprKind::Path(QPath::TypeRelative(ty, seg)) = from_func.kind && - seg.ident.name == sym::from + if let ExprKind::Path(QPath::TypeRelative(ty, seg)) = from_func.kind + && seg.ident.name == sym::from { match arg.kind { ExprKind::Lit(hir::Lit { @@ -874,12 +873,12 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: & }) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String), ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec), ExprKind::Repeat(_, ArrayLen::Body(len)) => { - if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind && - let LitKind::Int(v, _) = const_lit.node + if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind + && let LitKind::Int(v, _) = const_lit.node { - return v == 0 && is_path_diagnostic_item(cx, ty, sym::Vec); + return v == 0 && is_path_diagnostic_item(cx, ty, sym::Vec); } - } + }, _ => (), } } @@ -895,7 +894,7 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: & /// /// For example, given the following function: /// -/// ``` +/// ```no_run /// fn f<'a>(iter: &mut impl Iterator) { /// for item in iter { /// let s = item.1; @@ -1516,32 +1515,30 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti false } }); - let end_is_none_or_max = end.map_or(true, |end| { - match limits { - RangeLimits::Closed => { - if let rustc_ty::Adt(_, subst) = ty.kind() - && let bnd_ty = subst.type_at(0) - && let Some(max_val) = bnd_ty.numeric_max_val(cx.tcx) - && let Some(max_const) = mir_to_const(cx, Const::from_ty_const(max_val, cx.tcx)) - && let Some(end_const) = constant(cx, cx.typeck_results(), end) - { - end_const == max_const - } else { - false - } - }, - RangeLimits::HalfOpen => { - if let Some(container_path) = container_path - && let ExprKind::MethodCall(name, self_arg, [], _) = end.kind - && name.ident.name == sym::len - && let ExprKind::Path(QPath::Resolved(None, path)) = self_arg.kind - { - container_path.res == path.res - } else { - false - } - }, - } + let end_is_none_or_max = end.map_or(true, |end| match limits { + RangeLimits::Closed => { + if let rustc_ty::Adt(_, subst) = ty.kind() + && let bnd_ty = subst.type_at(0) + && let Some(max_val) = bnd_ty.numeric_max_val(cx.tcx) + && let Some(max_const) = mir_to_const(cx, Const::from_ty_const(max_val, cx.tcx)) + && let Some(end_const) = constant(cx, cx.typeck_results(), end) + { + end_const == max_const + } else { + false + } + }, + RangeLimits::HalfOpen => { + if let Some(container_path) = container_path + && let ExprKind::MethodCall(name, self_arg, [], _) = end.kind + && name.ident.name == sym::len + && let ExprKind::Path(QPath::Resolved(None, path)) = self_arg.kind + { + container_path.res == path.res + } else { + false + } + }, }); return start_is_none_or_min && end_is_none_or_max; } @@ -1609,7 +1606,7 @@ pub fn is_expn_of(mut span: Span, name: &str) -> Option { /// Returns the pre-expansion span if the span directly comes from an expansion /// of the macro `name`. /// The difference with [`is_expn_of`] is that in -/// ```rust +/// ```no_run /// # macro_rules! foo { ($name:tt!$args:tt) => { $name!$args } } /// # macro_rules! bar { ($e:expr) => { $e } } /// foo!(bar!(42)); @@ -2032,17 +2029,26 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { /// * `|x| return x` /// * `|x| { return x }` /// * `|x| { return x; }` +/// * `|(x, y)| (x, y)` /// /// Consider calling [`is_expr_untyped_identity_function`] or [`is_expr_identity_function`] instead. fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool { - let id = if_chain! { - if let [param] = func.params; - if let PatKind::Binding(_, id, _, _) = param.pat.kind; - then { - id - } else { - return false; + fn check_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr<'_>) -> bool { + match (pat.kind, expr.kind) { + (PatKind::Binding(_, id, _, _), _) => { + path_to_local_id(expr, id) && cx.typeck_results().expr_adjustments(expr).is_empty() + }, + (PatKind::Tuple(pats, dotdot), ExprKind::Tup(tup)) + if dotdot.as_opt_usize().is_none() && pats.len() == tup.len() => + { + pats.iter().zip(tup).all(|(pat, expr)| check_pat(cx, pat, expr)) + }, + _ => false, } + } + + let [param] = func.params else { + return false; }; let mut expr = func.value; @@ -2075,7 +2081,7 @@ fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool { } } }, - _ => return path_to_local_id(expr, id) && cx.typeck_results().expr_adjustments(expr).is_empty(), + _ => return check_pat(cx, param.pat, expr), } } } @@ -2093,7 +2099,8 @@ pub fn is_expr_untyped_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) }, ExprKind::Path(QPath::Resolved(_, path)) if path.segments.iter().all(|seg| seg.infer_args) - && let Some(did) = path.res.opt_def_id() => { + && let Some(did) = path.res.opt_def_id() => + { cx.tcx.is_diagnostic_item(sym::convert_identity, did) }, _ => false, @@ -2195,7 +2202,7 @@ pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { /// Check if parent of a hir node is a trait implementation block. /// For example, `f` in -/// ```rust +/// ```no_run /// # struct S; /// # trait Trait { fn f(); } /// impl Trait for S { @@ -2447,7 +2454,8 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym for id in tcx.hir().module_items(module) { if matches!(tcx.def_kind(id.owner_id), DefKind::Const) && let item = tcx.hir().item(id) - && let ItemKind::Const(ty, _generics, _body) = item.kind { + && let ItemKind::Const(ty, _generics, _body) = item.kind + { if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind { // We could also check for the type name `test::TestDescAndFn` if let Res::Def(DefKind::Struct, _) = path.res { @@ -2711,7 +2719,9 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> Optio let ctxt = e.span.ctxt(); walk_to_expr_usage(cx, e, &mut |parent, child_id| { // LocalTableInContext returns the wrong lifetime, so go use `expr_adjustments` instead. - if adjustments.is_empty() && let Node::Expr(e) = cx.tcx.hir().get(child_id) { + if adjustments.is_empty() + && let Node::Expr(e) = cx.tcx.hir().get(child_id) + { adjustments = cx.typeck_results().expr_adjustments(e); } match parent { @@ -2908,13 +2918,13 @@ pub fn pat_and_expr_can_be_question_mark<'a, 'hir>( pat: &'a Pat<'hir>, else_body: &Expr<'_>, ) -> Option<&'a Pat<'hir>> { - if let PatKind::TupleStruct(pat_path, [inner_pat], _) = pat.kind && - is_res_lang_ctor(cx, cx.qpath_res(&pat_path, pat.hir_id), OptionSome) && - !is_refutable(cx, inner_pat) && - let else_body = peel_blocks(else_body) && - let ExprKind::Ret(Some(ret_val)) = else_body.kind && - let ExprKind::Path(ret_path) = ret_val.kind && - is_res_lang_ctor(cx, cx.qpath_res(&ret_path, ret_val.hir_id), OptionNone) + if let PatKind::TupleStruct(pat_path, [inner_pat], _) = pat.kind + && is_res_lang_ctor(cx, cx.qpath_res(&pat_path, pat.hir_id), OptionSome) + && !is_refutable(cx, inner_pat) + && let else_body = peel_blocks(else_body) + && let ExprKind::Ret(Some(ret_val)) = else_body.kind + && let ExprKind::Path(ret_path) = ret_val.kind + && is_res_lang_ctor(cx, cx.qpath_res(&ret_path, ret_val.hir_id), OptionNone) { Some(inner_pat) } else { @@ -2952,3 +2962,15 @@ op_utils! { Shl ShlAssign Shr ShrAssign } + +/// Returns `true` if the pattern is a `PatWild`, or is an ident prefixed with `_` +/// that is not locally used. +pub fn pat_is_wild<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx PatKind<'_>, body: impl Visitable<'tcx>) -> bool { + match *pat { + PatKind::Wild => true, + PatKind::Binding(_, id, ident, None) if ident.as_str().starts_with('_') => { + !visitors::is_local_used(cx, body, id) + }, + _ => false, + } +} diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 4a20399e3649..5bca554378e7 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -4,16 +4,13 @@ //! Whenever possible, please consider diagnostic items over hardcoded paths. //! See for more information. -#[cfg(feature = "internal")] pub const APPLICABILITY: [&str; 2] = ["rustc_lint_defs", "Applicability"]; -#[cfg(feature = "internal")] pub const APPLICABILITY_VALUES: [[&str; 3]; 4] = [ ["rustc_lint_defs", "Applicability", "Unspecified"], ["rustc_lint_defs", "Applicability", "HasPlaceholders"], ["rustc_lint_defs", "Applicability", "MaybeIncorrect"], ["rustc_lint_defs", "Applicability", "MachineApplicable"], ]; -#[cfg(feature = "internal")] pub const DIAGNOSTIC_BUILDER: [&str; 3] = ["rustc_errors", "diagnostic_builder", "DiagnosticBuilder"]; pub const BINARYHEAP_ITER: [&str; 5] = ["alloc", "collections", "binary_heap", "BinaryHeap", "iter"]; pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "contains_key"]; @@ -25,9 +22,7 @@ pub const CORE_ITER_COPIED: [&str; 6] = ["core", "iter", "traits", "iterator", " pub const CORE_ITER_FILTER: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "filter"]; pub const CORE_RESULT_OK_METHOD: [&str; 4] = ["core", "result", "Result", "ok"]; pub const CSTRING_AS_C_STR: [&str; 5] = ["alloc", "ffi", "c_str", "CString", "as_c_str"]; -#[cfg(feature = "internal")] pub const EARLY_CONTEXT: [&str; 2] = ["rustc_lint", "EarlyContext"]; -#[cfg(feature = "internal")] pub const EARLY_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "EarlyLintPass"]; pub const F32_EPSILON: [&str; 4] = ["core", "f32", "", "EPSILON"]; pub const F64_EPSILON: [&str; 4] = ["core", "f64", "", "EPSILON"]; @@ -38,22 +33,15 @@ pub const FUTURES_IO_ASYNCWRITEEXT: [&str; 3] = ["futures_util", "io", "AsyncWri pub const HASHMAP_CONTAINS_KEY: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "contains_key"]; pub const HASHMAP_INSERT: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "insert"]; pub const HASHSET_ITER: [&str; 6] = ["std", "collections", "hash", "set", "HashSet", "iter"]; -#[cfg(feature = "internal")] pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"]; -#[cfg(feature = "internal")] pub const IDENT_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Ident", "as_str"]; pub const INSERT_STR: [&str; 4] = ["alloc", "string", "String", "insert_str"]; pub const ITERTOOLS_NEXT_TUPLE: [&str; 3] = ["itertools", "Itertools", "next_tuple"]; -#[cfg(feature = "internal")] pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"]; -#[cfg(feature = "internal")] pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"]; -#[cfg(feature = "internal")] pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"]; -#[cfg(feature = "internal")] pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"]; -#[cfg(feature = "internal")] -pub const MSRV: [&str; 3] = ["clippy_utils", "msrvs", "Msrv"]; +pub const MSRV: [&str; 3] = ["clippy_config", "msrvs", "Msrv"]; pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"]; pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"]; pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard"]; @@ -86,17 +74,11 @@ pub const STR_CHARS: [&str; 4] = ["core", "str", "", "chars"]; pub const STR_ENDS_WITH: [&str; 4] = ["core", "str", "", "ends_with"]; pub const STR_LEN: [&str; 4] = ["core", "str", "", "len"]; pub const STR_STARTS_WITH: [&str; 4] = ["core", "str", "", "starts_with"]; -#[cfg(feature = "internal")] pub const SYMBOL: [&str; 3] = ["rustc_span", "symbol", "Symbol"]; -#[cfg(feature = "internal")] pub const SYMBOL_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Symbol", "as_str"]; -#[cfg(feature = "internal")] pub const SYMBOL_INTERN: [&str; 4] = ["rustc_span", "symbol", "Symbol", "intern"]; -#[cfg(feature = "internal")] pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol", "to_ident_string"]; -#[cfg(feature = "internal")] pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"]; -#[cfg(feature = "internal")] pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"]; #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates pub const TOKIO_IO_ASYNCREADEXT: [&str; 5] = ["tokio", "io", "util", "async_read_ext", "AsyncReadExt"]; @@ -112,6 +94,7 @@ pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"]; pub const INSTANT_NOW: [&str; 4] = ["std", "time", "Instant", "now"]; pub const VEC_IS_EMPTY: [&str; 4] = ["alloc", "vec", "Vec", "is_empty"]; pub const VEC_POP: [&str; 4] = ["alloc", "vec", "Vec", "pop"]; +pub const WAKER: [&str; 4] = ["core", "task", "wake", "Waker"]; pub const OPTION_UNWRAP: [&str; 4] = ["core", "option", "Option", "unwrap"]; pub const OPTION_EXPECT: [&str; 4] = ["core", "option", "Option", "expect"]; #[expect(clippy::invalid_paths)] // not sure why it thinks this, it works so diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index ef0e2d3e1b3d..668ea9fcf3b4 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -3,7 +3,7 @@ // of terminologies might not be relevant in the context of Clippy. Note that its behavior might // differ from the time of `rustc` even if the name stays the same. -use crate::msrvs::Msrv; +use clippy_config::msrvs::Msrv; use hir::LangItem; use rustc_attr::StableSince; use rustc_const_eval::transform::check_consts::ConstCx; diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index 31cb421095ed..e72467edeeb0 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -70,9 +70,9 @@ pub fn expr_block( app: &mut Applicability, ) -> String { let (code, from_macro) = snippet_block_with_context(cx, expr.span, outer, default, indent_relative_to, app); - if !from_macro && - let ExprKind::Block(block, _) = expr.kind && - block.rules != BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) + if !from_macro + && let ExprKind::Block(block, _) = expr.kind + && block.rules != BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) { format!("{code}") } else { @@ -108,7 +108,7 @@ fn first_char_in_first_line(cx: &T, span: Span) -> Option StrIndex { /// Returns index of the first camel-case component of `s`. /// -/// ``` +/// ```no_run /// # use clippy_utils::str_utils::{camel_case_start, StrIndex}; /// assert_eq!(camel_case_start("AbcDef"), StrIndex::new(0, 0)); /// assert_eq!(camel_case_start("abcDef"), StrIndex::new(3, 3)); @@ -73,7 +73,7 @@ pub fn camel_case_start(s: &str) -> StrIndex { /// Returns `StrIndex` of the last camel-case component of `s[idx..]`. /// -/// ``` +/// ```no_run /// # use clippy_utils::str_utils::{camel_case_start_from_idx, StrIndex}; /// assert_eq!(camel_case_start_from_idx("AbcDef", 0), StrIndex::new(0, 0)); /// assert_eq!(camel_case_start_from_idx("AbcDef", 1), StrIndex::new(3, 3)); @@ -122,7 +122,7 @@ pub fn camel_case_start_from_idx(s: &str, start_idx: usize) -> StrIndex { /// Get the indexes of camel case components of a string `s` /// -/// ``` +/// ```no_run /// # use clippy_utils::str_utils::{camel_case_indices, StrIndex}; /// assert_eq!( /// camel_case_indices("AbcDef"), @@ -149,7 +149,7 @@ pub fn camel_case_indices(s: &str) -> Vec { /// Split camel case string into a vector of its components /// -/// ``` +/// ```no_run /// # use clippy_utils::str_utils::{camel_case_split, StrIndex}; /// assert_eq!(camel_case_split("AbcDef"), vec!["Abc", "Def"]); /// ``` @@ -181,7 +181,7 @@ impl StrCount { /// Returns the number of chars that match from the start /// -/// ``` +/// ```no_run /// # use clippy_utils::str_utils::{count_match_start, StrCount}; /// assert_eq!(count_match_start("hello_mouse", "hello_penguin"), StrCount::new(6, 6)); /// assert_eq!(count_match_start("hello_clippy", "bye_bugs"), StrCount::new(0, 0)); @@ -207,7 +207,7 @@ pub fn count_match_start(str1: &str, str2: &str) -> StrCount { /// Returns the number of chars and bytes that match from the end /// -/// ``` +/// ```no_run /// # use clippy_utils::str_utils::{count_match_end, StrCount}; /// assert_eq!(count_match_end("hello_cat", "bye_cat"), StrCount::new(4, 4)); /// assert_eq!(count_match_end("if_item_thing", "enum_value"), StrCount::new(0, 0)); @@ -237,7 +237,7 @@ pub fn count_match_end(str1: &str, str2: &str) -> StrCount { } /// Returns a `snake_case` version of the input -/// ``` +/// ```no_run /// use clippy_utils::str_utils::to_snake_case; /// assert_eq!(to_snake_case("AbcDef"), "abc_def"); /// assert_eq!(to_snake_case("ABCD"), "a_b_c_d"); @@ -260,7 +260,7 @@ pub fn to_snake_case(name: &str) -> String { s } /// Returns a `CamelCase` version of the input -/// ``` +/// ```no_run /// use clippy_utils::str_utils::to_camel_case; /// assert_eq!(to_camel_case("abc_def"), "AbcDef"); /// assert_eq!(to_camel_case("a_b_c_d"), "ABCD"); diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 836f8cc19168..de18fd1bc5ca 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -465,7 +465,10 @@ forward_binop_impls_to_ref!(impl Sub, sub for Sugg<'_>, type Output = Sugg<'stat impl Neg for Sugg<'_> { type Output = Sugg<'static>; fn neg(self) -> Sugg<'static> { - make_unop("-", self) + match &self { + Self::BinOp(AssocOp::As, ..) => Sugg::MaybeParen(format!("-({self})").into()), + _ => make_unop("-", self), + } } } diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 673b259523e1..7eff93881b26 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -890,7 +890,9 @@ pub fn for_each_top_level_late_bound_region( impl<'tcx, B, F: FnMut(BoundRegion) -> ControlFlow> TypeVisitor> for V { type BreakTy = B; fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow { - if let RegionKind::ReLateBound(idx, bound) = r.kind() && idx.as_u32() == self.index { + if let RegionKind::ReLateBound(idx, bound) = r.kind() + && idx.as_u32() == self.index + { (self.f)(bound) } else { ControlFlow::Continue(()) @@ -984,16 +986,16 @@ pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tc .iter() .try_fold(false, |found, p| { if let ty::ClauseKind::Trait(p) = p.kind().skip_binder() - && let ty::Param(self_ty) = p.trait_ref.self_ty().kind() - && ty.index == self_ty.index - { - // This should use `super_traits_of`, but that's a private function. - if p.trait_ref.def_id == fn_once_id { - return Some(true); - } else if p.trait_ref.def_id == fn_mut_id || p.trait_ref.def_id == fn_id { - return None; + && let ty::Param(self_ty) = p.trait_ref.self_ty().kind() + && ty.index == self_ty.index + { + // This should use `super_traits_of`, but that's a private function. + if p.trait_ref.def_id == fn_once_id { + return Some(true); + } else if p.trait_ref.def_id == fn_mut_id || p.trait_ref.def_id == fn_id { + return None; + } } - } Some(found) }) .unwrap_or(false) diff --git a/clippy_utils/src/ty/type_certainty/mod.rs b/clippy_utils/src/ty/type_certainty/mod.rs index 750646723260..76fa15e15880 100644 --- a/clippy_utils/src/ty/type_certainty/mod.rs +++ b/clippy_utils/src/ty/type_certainty/mod.rs @@ -267,7 +267,9 @@ fn path_segment_certainty( /// For at least some `QPath::TypeRelative`, the path segment's `res` can be `Res::Err`. /// `update_res` tries to fix the resolution when `parent_certainty` is `Certain(Some(..))`. fn update_res(cx: &LateContext<'_>, parent_certainty: Certainty, path_segment: &PathSegment<'_>) -> Option { - if path_segment.res == Res::Err && let Some(def_id) = parent_certainty.to_def_id() { + if path_segment.res == Res::Err + && let Some(def_id) = parent_certainty.to_def_id() + { let mut def_path = cx.get_def_path(def_id); def_path.push(path_segment.ident.name); let reses = def_path_res(cx, &def_path.iter().map(Symbol::as_str).collect::>()); diff --git a/declare_clippy_lint/src/lib.rs b/declare_clippy_lint/src/lib.rs index 0057256f659b..dc3037f66692 100644 --- a/declare_clippy_lint/src/lib.rs +++ b/declare_clippy_lint/src/lib.rs @@ -94,7 +94,7 @@ impl Parse for ClippyLint { /// /// # Example /// -/// ``` +/// ```ignore /// use rustc_session::declare_tool_lint; /// /// declare_clippy_lint! { @@ -136,28 +136,16 @@ pub fn declare_clippy_lint(input: TokenStream) -> TokenStream { "{}", match category.as_str() { "correctness" => "Deny", - "style" | "suspicious" | "complexity" | "perf" | "internal_warn" => "Warn", + "style" | "suspicious" | "complexity" | "perf" => "Warn", "pedantic" | "restriction" | "cargo" | "nursery" | "internal" => "Allow", _ => panic!("unknown category {category}"), }, ); - let info = if category == "internal_warn" { - None - } else { - let info_name = format_ident!("{name}_INFO"); - - (&mut category[0..1]).make_ascii_uppercase(); - let category_variant = format_ident!("{category}"); + let info_name = format_ident!("{name}_INFO"); - Some(quote! { - pub(crate) static #info_name: &'static crate::LintInfo = &crate::LintInfo { - lint: &#name, - category: crate::LintCategory::#category_variant, - explanation: #explanation, - }; - }) - }; + (&mut category[0..1]).make_ascii_uppercase(); + let category_variant = format_ident!("{category}"); let output = quote! { declare_tool_lint! { @@ -168,7 +156,11 @@ pub fn declare_clippy_lint(input: TokenStream) -> TokenStream { report_in_external_macro: true } - #info + pub(crate) static #info_name: &'static crate::LintInfo = &crate::LintInfo { + lint: &#name, + category: crate::LintCategory::#category_variant, + explanation: #explanation, + }; }; TokenStream::from(output) diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index 3a022b343a43..58cb42316fd2 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -523,7 +523,7 @@ fn gather_stats(clippy_warnings: &[ClippyWarning]) -> (String, HashMap<&String, .for_each(|wrn| *counter.entry(&wrn.lint_type).or_insert(0) += 1); // collect into a tupled list for sorting - let mut stats: Vec<(&&String, &usize)> = counter.iter().map(|(lint, count)| (lint, count)).collect(); + let mut stats: Vec<(&&String, &usize)> = counter.iter().collect(); // sort by "000{count} {clippy::lintname}" // to not have a lint with 200 and 2 warnings take the same spot stats.sort_by_key(|(lint, count)| format!("{count:0>4}, {lint}")); diff --git a/rust-toolchain b/rust-toolchain index 7c5b5e97a5c7..293fcbf39928 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-10-21" +channel = "nightly-2023-11-02" components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] diff --git a/src/driver.rs b/src/driver.rs index 11290f88a497..7bb49d08da65 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -126,7 +126,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks { // JUSTIFICATION: necessary in clippy driver to set `mir_opt_level` #[allow(rustc::bad_opt_access)] fn config(&mut self, config: &mut interface::Config) { - let conf_path = clippy_lints::lookup_conf_file(); + let conf_path = clippy_config::lookup_conf_file(); let previous = config.register_lints.take(); let clippy_args_var = self.clippy_args_var.take(); config.parse_sess_created = Some(Box::new(move |parse_sess| { @@ -147,7 +147,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks { (previous)(sess, lint_store); } - let conf = clippy_lints::Conf::read(sess, &conf_path); + let conf = clippy_config::Conf::read(sess, &conf_path); clippy_lints::register_plugins(lint_store, sess, conf); clippy_lints::register_pre_expansion_lints(lint_store, conf); clippy_lints::register_renamed(lint_store); @@ -266,10 +266,12 @@ pub fn main() { if clippy_enabled { args.extend(clippy_args); rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var }) - .set_using_internal_features(using_internal_features).run() + .set_using_internal_features(using_internal_features) + .run() } else { rustc_driver::RunCompiler::new(&args, &mut RustcCallbacks { clippy_args_var }) - .set_using_internal_features(using_internal_features).run() + .set_using_internal_features(using_internal_features) + .run() } })) } diff --git a/tests/compile-test.rs b/tests/compile-test.rs index 1494c7d31796..3b7c974b65be 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -30,6 +30,7 @@ mod test_utils; /// All crates used in UI tests are listed here static TEST_DEPENDENCIES: &[&str] = &[ + "clippy_config", "clippy_lints", "clippy_utils", "futures", diff --git a/tests/dogfood.rs b/tests/dogfood.rs index afde31face11..3f16c180ea78 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -28,6 +28,7 @@ fn dogfood_clippy() { "clippy_dev", "clippy_lints", "clippy_utils", + "clippy_config", "lintcheck", "rustc_tools_util", ] { @@ -56,7 +57,10 @@ fn run_metadata_collection_lint() { // Run collection as is std::env::set_var("ENABLE_METADATA_COLLECTION", "1"); - run_clippy_for_package("clippy_lints", &["-A", "unfulfilled_lint_expectations"]); + assert!(run_clippy_for_package( + "clippy_lints", + &["-A", "unfulfilled_lint_expectations"] + )); // Check if cargo caching got in the way if let Ok(file) = File::open(metadata_output_path) { @@ -79,9 +83,13 @@ fn run_metadata_collection_lint() { .unwrap(); // Running the collection again - run_clippy_for_package("clippy_lints", &["-A", "unfulfilled_lint_expectations"]); + assert!(run_clippy_for_package( + "clippy_lints", + &["-A", "unfulfilled_lint_expectations"] + )); } +#[must_use] fn run_clippy_for_package(project: &str, args: &[&str]) -> bool { let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); diff --git a/tests/ui-internal/invalid_msrv_attr_impl.fixed b/tests/ui-internal/invalid_msrv_attr_impl.fixed index 928596d08091..9b5bf736f137 100644 --- a/tests/ui-internal/invalid_msrv_attr_impl.fixed +++ b/tests/ui-internal/invalid_msrv_attr_impl.fixed @@ -8,8 +8,8 @@ extern crate rustc_lint; extern crate rustc_middle; #[macro_use] extern crate rustc_session; +use clippy_config::msrvs::Msrv; use clippy_utils::extract_msrv_attr; -use clippy_utils::msrvs::Msrv; use rustc_hir::Expr; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; diff --git a/tests/ui-internal/invalid_msrv_attr_impl.rs b/tests/ui-internal/invalid_msrv_attr_impl.rs index 50b28648ccc9..c5bde47e4ce8 100644 --- a/tests/ui-internal/invalid_msrv_attr_impl.rs +++ b/tests/ui-internal/invalid_msrv_attr_impl.rs @@ -8,8 +8,8 @@ extern crate rustc_lint; extern crate rustc_middle; #[macro_use] extern crate rustc_session; +use clippy_config::msrvs::Msrv; use clippy_utils::extract_msrv_attr; -use clippy_utils::msrvs::Msrv; use rustc_hir::Expr; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; diff --git a/tests/ui/auxiliary/proc_macros.rs b/tests/ui/auxiliary/proc_macros.rs index 43df654389b1..3303eb145678 100644 --- a/tests/ui/auxiliary/proc_macros.rs +++ b/tests/ui/auxiliary/proc_macros.rs @@ -379,7 +379,8 @@ impl MacroArm { p.span(), )?; self.add_parenthesized_arg_def(kind, dollar_span, g.span(), out); - self.args.push(TT::Group(group_with_span(Parenthesis, inner.collect(), g.span()))) + self.args + .push(TT::Group(group_with_span(Parenthesis, inner.collect(), g.span()))) } else { self.add_multi_arg_def(dollar_span, g.span(), out); self.args.push(TT::Group(g)); @@ -436,7 +437,12 @@ impl Expander { && p.as_char() == ESCAPE_CHAR && let Some(arm) = self.arm.as_mut() { - arm.add_arg(p.span(), mem::replace(&mut input.tt, tt), &mut input.iter, &mut self.expn)?; + arm.add_arg( + p.span(), + mem::replace(&mut input.tt, tt), + &mut input.iter, + &mut self.expn, + )?; if input.next().is_none() { return Ok(()); } diff --git a/tests/ui/bool_to_int_with_if.fixed b/tests/ui/bool_to_int_with_if.fixed index 44d7f6e6d796..167263d31df8 100644 --- a/tests/ui/bool_to_int_with_if.fixed +++ b/tests/ui/bool_to_int_with_if.fixed @@ -80,9 +80,7 @@ fn main() { // https://github.com/rust-lang/rust-clippy/issues/10452 let should_not_lint = [(); if true { 1 } else { 0 }]; - let should_not_lint = const { - if true { 1 } else { 0 } - }; + let should_not_lint = const { if true { 1 } else { 0 } }; some_fn(a); } @@ -110,7 +108,9 @@ fn if_let(a: Enum, b: Enum) { 0 }; - if let Enum::A = a && let Enum::B = b { + if let Enum::A = a + && let Enum::B = b + { 1 } else { 0 diff --git a/tests/ui/bool_to_int_with_if.rs b/tests/ui/bool_to_int_with_if.rs index 7d989ae4bb31..f3f055eb7f06 100644 --- a/tests/ui/bool_to_int_with_if.rs +++ b/tests/ui/bool_to_int_with_if.rs @@ -112,9 +112,7 @@ fn main() { // https://github.com/rust-lang/rust-clippy/issues/10452 let should_not_lint = [(); if true { 1 } else { 0 }]; - let should_not_lint = const { - if true { 1 } else { 0 } - }; + let should_not_lint = const { if true { 1 } else { 0 } }; some_fn(a); } @@ -142,7 +140,9 @@ fn if_let(a: Enum, b: Enum) { 0 }; - if let Enum::A = a && let Enum::B = b { + if let Enum::A = a + && let Enum::B = b + { 1 } else { 0 diff --git a/tests/ui/bool_to_int_with_if.stderr b/tests/ui/bool_to_int_with_if.stderr index 837ed05d3a65..714da8a41695 100644 --- a/tests/ui/bool_to_int_with_if.stderr +++ b/tests/ui/bool_to_int_with_if.stderr @@ -99,7 +99,7 @@ LL | | }; = note: `!b as i32` or `(!b).into()` can also be valid options error: boolean to int conversion using if - --> $DIR/bool_to_int_with_if.rs:124:5 + --> $DIR/bool_to_int_with_if.rs:122:5 | LL | if a { 1 } else { 0 } | ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)` diff --git a/tests/ui/comparison_to_empty.fixed b/tests/ui/comparison_to_empty.fixed index 90eb50715a27..e102b13a7618 100644 --- a/tests/ui/comparison_to_empty.fixed +++ b/tests/ui/comparison_to_empty.fixed @@ -15,7 +15,9 @@ fn main() { let s = [0].as_slice(); if s.is_empty() {} if s.is_empty() {} - if s.is_empty() && s.is_empty() {} + if s.is_empty() + && s.is_empty() + {} // Allow comparisons to non-empty let s = String::new(); @@ -28,5 +30,7 @@ fn main() { if let [0] = &*v {} let s = [0].as_slice(); if let [0] = s {} - if let [0] = &*s && s == [0] {} + if let [0] = &*s + && s == [0] + {} } diff --git a/tests/ui/comparison_to_empty.rs b/tests/ui/comparison_to_empty.rs index 0964c4a20a9a..69a6c967d382 100644 --- a/tests/ui/comparison_to_empty.rs +++ b/tests/ui/comparison_to_empty.rs @@ -15,7 +15,9 @@ fn main() { let s = [0].as_slice(); if let [] = s {} if let [] = &*s {} - if let [] = &*s && s == [] {} + if let [] = &*s + && s == [] + {} // Allow comparisons to non-empty let s = String::new(); @@ -28,5 +30,7 @@ fn main() { if let [0] = &*v {} let s = [0].as_slice(); if let [0] = s {} - if let [0] = &*s && s == [0] {} + if let [0] = &*s + && s == [0] + {} } diff --git a/tests/ui/comparison_to_empty.stderr b/tests/ui/comparison_to_empty.stderr index b97ab4c3c937..83d431fd52b4 100644 --- a/tests/ui/comparison_to_empty.stderr +++ b/tests/ui/comparison_to_empty.stderr @@ -46,14 +46,14 @@ LL | if let [] = &*s {} error: comparison to empty slice using `if let` --> $DIR/comparison_to_empty.rs:18:8 | -LL | if let [] = &*s && s == [] {} +LL | if let [] = &*s | ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()` error: comparison to empty slice - --> $DIR/comparison_to_empty.rs:18:24 + --> $DIR/comparison_to_empty.rs:19:12 | -LL | if let [] = &*s && s == [] {} - | ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()` +LL | && s == [] + | ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()` error: aborting due to 9 previous errors diff --git a/tests/ui/doc/doc-fixable.fixed b/tests/ui/doc/doc-fixable.fixed index 47b56960a00f..aee89719728f 100644 --- a/tests/ui/doc/doc-fixable.fixed +++ b/tests/ui/doc/doc-fixable.fixed @@ -224,3 +224,6 @@ where [(); N.checked_next_power_of_two().unwrap()]: { } } } + +/// this checks if the lowerCamelCase issue is fixed +fn issue_11568() {} diff --git a/tests/ui/doc/doc-fixable.rs b/tests/ui/doc/doc-fixable.rs index 4d9a4eafa5fc..b6346b881ad3 100644 --- a/tests/ui/doc/doc-fixable.rs +++ b/tests/ui/doc/doc-fixable.rs @@ -224,3 +224,6 @@ where [(); N.checked_next_power_of_two().unwrap()]: { } } } + +/// this checks if the lowerCamelCase issue is fixed +fn issue_11568() {} diff --git a/tests/ui/enum_variants.rs b/tests/ui/enum_variants.rs index 85df852f7296..ddf2dfdaea9b 100644 --- a/tests/ui/enum_variants.rs +++ b/tests/ui/enum_variants.rs @@ -204,4 +204,21 @@ mod allow_attributes_on_variants { } } +mod issue11494 { + // variant order should not affect lint + enum Data { + Valid, + Invalid, + DataDependent, + //~^ ERROR: variant name starts with the enum's name + } + + enum Datas { + DatasDependent, + //~^ ERROR: variant name starts with the enum's name + Valid, + Invalid, + } +} + fn main() {} diff --git a/tests/ui/enum_variants.stderr b/tests/ui/enum_variants.stderr index 9ea80b635f46..b1e88de0fcf1 100644 --- a/tests/ui/enum_variants.stderr +++ b/tests/ui/enum_variants.stderr @@ -158,5 +158,17 @@ LL | | } | = help: remove the postfixes and use full paths to the variants instead of glob imports -error: aborting due to 14 previous errors +error: variant name starts with the enum's name + --> $DIR/enum_variants.rs:212:9 + | +LL | DataDependent, + | ^^^^^^^^^^^^^ + +error: variant name starts with the enum's name + --> $DIR/enum_variants.rs:217:9 + | +LL | DatasDependent, + | ^^^^^^^^^^^^^^ + +error: aborting due to 16 previous errors diff --git a/tests/ui/floating_point_mul_add.fixed b/tests/ui/floating_point_mul_add.fixed index c23f4d7c4d3a..a4d6d49e57c9 100644 --- a/tests/ui/floating_point_mul_add.fixed +++ b/tests/ui/floating_point_mul_add.fixed @@ -33,6 +33,9 @@ fn main() { let _ = a.mul_add(a, b).sqrt(); + let u = 1usize; + let _ = b.mul_add(-(u as f64), a); + // Cases where the lint shouldn't be applied let _ = (a * a + b * b).sqrt(); } diff --git a/tests/ui/floating_point_mul_add.rs b/tests/ui/floating_point_mul_add.rs index 431badc8db44..262a20f0f557 100644 --- a/tests/ui/floating_point_mul_add.rs +++ b/tests/ui/floating_point_mul_add.rs @@ -33,6 +33,9 @@ fn main() { let _ = (a * a + b).sqrt(); + let u = 1usize; + let _ = a - (b * u as f64); + // Cases where the lint shouldn't be applied let _ = (a * a + b * b).sqrt(); } diff --git a/tests/ui/floating_point_mul_add.stderr b/tests/ui/floating_point_mul_add.stderr index 81b7126db54d..38dbefbe14c6 100644 --- a/tests/ui/floating_point_mul_add.stderr +++ b/tests/ui/floating_point_mul_add.stderr @@ -73,5 +73,11 @@ error: multiply and add expressions can be calculated more efficiently and accur LL | let _ = (a * a + b).sqrt(); | ^^^^^^^^^^^ help: consider using: `a.mul_add(a, b)` -error: aborting due to 12 previous errors +error: multiply and add expressions can be calculated more efficiently and accurately + --> $DIR/floating_point_mul_add.rs:37:13 + | +LL | let _ = a - (b * u as f64); + | ^^^^^^^^^^^^^^^^^^ help: consider using: `b.mul_add(-(u as f64), a)` + +error: aborting due to 13 previous errors diff --git a/tests/ui/get_first.fixed b/tests/ui/get_first.fixed index a7cdd2a93bac..710ebab1ef2d 100644 --- a/tests/ui/get_first.fixed +++ b/tests/ui/get_first.fixed @@ -32,9 +32,12 @@ fn main() { let _ = z[0]; let vecdeque: VecDeque<_> = x.iter().cloned().collect(); + let _ = vecdeque.front(); + //~^ ERROR: accessing first element with `vecdeque.get(0)` + let _ = vecdeque.get(1); + let hashmap: HashMap = HashMap::from_iter(vec![(0, 'a'), (1, 'b')]); let btreemap: BTreeMap = BTreeMap::from_iter(vec![(0, 'a'), (1, 'b')]); - let _ = vecdeque.get(0); // Do not lint, because VecDeque is not slice. let _ = hashmap.get(&0); // Do not lint, because HashMap is not slice. let _ = btreemap.get(&0); // Do not lint, because BTreeMap is not slice. diff --git a/tests/ui/get_first.rs b/tests/ui/get_first.rs index cca743c4bf5e..ad2ba6ce2c3b 100644 --- a/tests/ui/get_first.rs +++ b/tests/ui/get_first.rs @@ -32,9 +32,12 @@ fn main() { let _ = z[0]; let vecdeque: VecDeque<_> = x.iter().cloned().collect(); + let _ = vecdeque.get(0); + //~^ ERROR: accessing first element with `vecdeque.get(0)` + let _ = vecdeque.get(1); + let hashmap: HashMap = HashMap::from_iter(vec![(0, 'a'), (1, 'b')]); let btreemap: BTreeMap = BTreeMap::from_iter(vec![(0, 'a'), (1, 'b')]); - let _ = vecdeque.get(0); // Do not lint, because VecDeque is not slice. let _ = hashmap.get(&0); // Do not lint, because HashMap is not slice. let _ = btreemap.get(&0); // Do not lint, because BTreeMap is not slice. diff --git a/tests/ui/get_first.stderr b/tests/ui/get_first.stderr index 8ee66e33cc81..7474a2ada669 100644 --- a/tests/ui/get_first.stderr +++ b/tests/ui/get_first.stderr @@ -19,11 +19,17 @@ error: accessing first element with `z.get(0)` LL | let _ = z.get(0); | ^^^^^^^^ help: try: `z.first()` +error: accessing first element with `vecdeque.get(0)` + --> $DIR/get_first.rs:35:13 + | +LL | let _ = vecdeque.get(0); + | ^^^^^^^^^^^^^^^ help: try: `vecdeque.front()` + error: accessing first element with `non_primitives.get(0)` - --> $DIR/get_first.rs:45:13 + --> $DIR/get_first.rs:48:13 | LL | let _ = non_primitives.get(0); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `non_primitives.first()` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors diff --git a/tests/ui/if_not_else_bittest.rs b/tests/ui/if_not_else_bittest.rs new file mode 100644 index 000000000000..586ce6ce1bcc --- /dev/null +++ b/tests/ui/if_not_else_bittest.rs @@ -0,0 +1,11 @@ +#![deny(clippy::if_not_else)] + +fn show_permissions(flags: u32) { + if flags & 0x0F00 != 0 { + println!("Has the 0x0F00 permission."); + } else { + println!("The 0x0F00 permission is missing."); + } +} + +fn main() {} diff --git a/tests/ui/ignored_unit_patterns.fixed b/tests/ui/ignored_unit_patterns.fixed index 15eaf1f659ab..707a0e76e4eb 100644 --- a/tests/ui/ignored_unit_patterns.fixed +++ b/tests/ui/ignored_unit_patterns.fixed @@ -38,3 +38,19 @@ pub fn moo(_: ()) { let _: () = foo().unwrap(); let _: () = (); } + +fn test_unit_ref_1() { + let x: (usize, &&&&&()) = (1, &&&&&&()); + match x { + (1, ()) => unimplemented!(), + //~^ ERROR: matching over `()` is more explicit + _ => unimplemented!(), + }; +} + +fn test_unit_ref_2(v: &[(usize, ())]) { + for (x, ()) in v { + //~^ ERROR: matching over `()` is more explicit + let _ = x; + } +} diff --git a/tests/ui/ignored_unit_patterns.rs b/tests/ui/ignored_unit_patterns.rs index 9cac3a440aba..544f2b8f6929 100644 --- a/tests/ui/ignored_unit_patterns.rs +++ b/tests/ui/ignored_unit_patterns.rs @@ -38,3 +38,19 @@ pub fn moo(_: ()) { let _: () = foo().unwrap(); let _: () = (); } + +fn test_unit_ref_1() { + let x: (usize, &&&&&()) = (1, &&&&&&()); + match x { + (1, _) => unimplemented!(), + //~^ ERROR: matching over `()` is more explicit + _ => unimplemented!(), + }; +} + +fn test_unit_ref_2(v: &[(usize, ())]) { + for (x, _) in v { + //~^ ERROR: matching over `()` is more explicit + let _ = x; + } +} diff --git a/tests/ui/ignored_unit_patterns.stderr b/tests/ui/ignored_unit_patterns.stderr index cac01a87dba0..05c8f281e554 100644 --- a/tests/ui/ignored_unit_patterns.stderr +++ b/tests/ui/ignored_unit_patterns.stderr @@ -43,5 +43,17 @@ error: matching over `()` is more explicit LL | let _ = foo().unwrap(); | ^ help: use `()` instead of `_`: `()` -error: aborting due to 7 previous errors +error: matching over `()` is more explicit + --> $DIR/ignored_unit_patterns.rs:45:13 + | +LL | (1, _) => unimplemented!(), + | ^ help: use `()` instead of `_`: `()` + +error: matching over `()` is more explicit + --> $DIR/ignored_unit_patterns.rs:52:13 + | +LL | for (x, _) in v { + | ^ help: use `()` instead of `_`: `()` + +error: aborting due to 9 previous errors diff --git a/tests/ui/into_iter_without_iter.rs b/tests/ui/into_iter_without_iter.rs index e6ff821a8ad0..448d0114dff8 100644 --- a/tests/ui/into_iter_without_iter.rs +++ b/tests/ui/into_iter_without_iter.rs @@ -3,127 +3,117 @@ use std::iter::IntoIterator; -fn main() { - { - struct S; - - impl<'a> IntoIterator for &'a S { - //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method - type IntoIter = std::slice::Iter<'a, u8>; - type Item = &'a u8; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } - impl<'a> IntoIterator for &'a mut S { - //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method - type IntoIter = std::slice::IterMut<'a, u8>; - type Item = &'a mut u8; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } +pub struct S1; +impl<'a> IntoIterator for &'a S1 { + //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method + type IntoIter = std::slice::Iter<'a, u8>; + type Item = &'a u8; + fn into_iter(self) -> Self::IntoIter { + todo!() } - { - struct S(T); - impl<'a, T> IntoIterator for &'a S { - //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method - type IntoIter = std::slice::Iter<'a, T>; - type Item = &'a T; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } - impl<'a, T> IntoIterator for &'a mut S { - //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method - type IntoIter = std::slice::IterMut<'a, T>; - type Item = &'a mut T; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } +} +impl<'a> IntoIterator for &'a mut S1 { + //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method + type IntoIter = std::slice::IterMut<'a, u8>; + type Item = &'a mut u8; + fn into_iter(self) -> Self::IntoIter { + todo!() } - { - // Both iter and iter_mut methods exist, don't lint - struct S<'a, T>(&'a T); - - impl<'a, T> S<'a, T> { - fn iter(&self) -> std::slice::Iter<'a, T> { - todo!() - } - fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> { - todo!() - } - } +} - impl<'a, T> IntoIterator for &S<'a, T> { - type IntoIter = std::slice::Iter<'a, T>; - type Item = &'a T; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } +pub struct S2(T); +impl<'a, T> IntoIterator for &'a S2 { + //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method + type IntoIter = std::slice::Iter<'a, T>; + type Item = &'a T; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} +impl<'a, T> IntoIterator for &'a mut S2 { + //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method + type IntoIter = std::slice::IterMut<'a, T>; + type Item = &'a mut T; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} - impl<'a, T> IntoIterator for &mut S<'a, T> { - type IntoIter = std::slice::IterMut<'a, T>; - type Item = &'a mut T; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } +// Both iter and iter_mut methods exist, don't lint +pub struct S3<'a, T>(&'a T); +impl<'a, T> S3<'a, T> { + fn iter(&self) -> std::slice::Iter<'a, T> { + todo!() + } + fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> { + todo!() + } +} +impl<'a, T> IntoIterator for &S3<'a, T> { + type IntoIter = std::slice::Iter<'a, T>; + type Item = &'a T; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} +impl<'a, T> IntoIterator for &mut S3<'a, T> { + type IntoIter = std::slice::IterMut<'a, T>; + type Item = &'a mut T; + fn into_iter(self) -> Self::IntoIter { + todo!() } - { - // Only `iter` exists, no `iter_mut` - struct S<'a, T>(&'a T); +} - impl<'a, T> S<'a, T> { - fn iter(&self) -> std::slice::Iter<'a, T> { - todo!() - } - } +// Only `iter` exists, no `iter_mut` +pub struct S4<'a, T>(&'a T); - impl<'a, T> IntoIterator for &S<'a, T> { - type IntoIter = std::slice::Iter<'a, T>; - type Item = &'a T; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } +impl<'a, T> S4<'a, T> { + fn iter(&self) -> std::slice::Iter<'a, T> { + todo!() + } +} - impl<'a, T> IntoIterator for &mut S<'a, T> { - //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method - type IntoIter = std::slice::IterMut<'a, T>; - type Item = &'a mut T; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } +impl<'a, T> IntoIterator for &S4<'a, T> { + type IntoIter = std::slice::Iter<'a, T>; + type Item = &'a T; + fn into_iter(self) -> Self::IntoIter { + todo!() } - { - // `iter` exists, but `IntoIterator` is implemented for an alias. inherent_impls doesn't "normalize" - // aliases so that `inherent_impls(Alias)` where `type Alias = S` returns nothing, so this can lead - // to fun FPs. Make sure it doesn't happen here (we're using type_of, which should skip the alias). - struct S; +} - impl S { - fn iter(&self) -> std::slice::Iter<'static, u8> { - todo!() - } - } +impl<'a, T> IntoIterator for &mut S4<'a, T> { + //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method + type IntoIter = std::slice::IterMut<'a, T>; + type Item = &'a mut T; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} - type Alias = S; +// `iter` exists, but `IntoIterator` is implemented for an alias. inherent_impls doesn't "normalize" +// aliases so that `inherent_impls(Alias)` where `type Alias = S` returns nothing, so this can lead +// to fun FPs. Make sure it doesn't happen here (we're using type_of, which should skip the alias). +pub struct S5; - impl IntoIterator for &Alias { - type IntoIter = std::slice::Iter<'static, u8>; - type Item = &'static u8; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } +impl S5 { + fn iter(&self) -> std::slice::Iter<'static, u8> { + todo!() + } +} + +pub type Alias = S5; + +impl IntoIterator for &Alias { + type IntoIter = std::slice::Iter<'static, u8>; + type Item = &'static u8; + fn into_iter(self) -> Self::IntoIter { + todo!() } } -fn issue11635() { +fn main() {} + +pub mod issue11635 { // A little more involved than the original repro in the issue, but this tests that it correctly // works for more than one deref step diff --git a/tests/ui/into_iter_without_iter.stderr b/tests/ui/into_iter_without_iter.stderr index f543d1d8e86c..70f3f82a936c 100644 --- a/tests/ui/into_iter_without_iter.stderr +++ b/tests/ui/into_iter_without_iter.stderr @@ -1,21 +1,21 @@ error: `IntoIterator` implemented for a reference type without an `iter` method - --> $DIR/into_iter_without_iter.rs:10:9 + --> $DIR/into_iter_without_iter.rs:7:1 | -LL | / impl<'a> IntoIterator for &'a S { +LL | / impl<'a> IntoIterator for &'a S1 { LL | | -LL | | type IntoIter = std::slice::Iter<'a, u8>; -LL | | type Item = &'a u8; +LL | | type IntoIter = std::slice::Iter<'a, u8>; +LL | | type Item = &'a u8; ... | -LL | | } -LL | | } - | |_________^ +LL | | } +LL | | } + | |_^ | = note: `-D clippy::into-iter-without-iter` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::into_iter_without_iter)]` help: consider implementing `iter` | -LL ~ -LL + impl S { +LL + +LL + impl S1 { LL + fn iter(&self) -> std::slice::Iter<'a, u8> { LL + <&Self as IntoIterator>::into_iter(self) LL + } @@ -23,21 +23,21 @@ LL + } | error: `IntoIterator` implemented for a reference type without an `iter_mut` method - --> $DIR/into_iter_without_iter.rs:18:9 + --> $DIR/into_iter_without_iter.rs:15:1 | -LL | / impl<'a> IntoIterator for &'a mut S { +LL | / impl<'a> IntoIterator for &'a mut S1 { LL | | -LL | | type IntoIter = std::slice::IterMut<'a, u8>; -LL | | type Item = &'a mut u8; +LL | | type IntoIter = std::slice::IterMut<'a, u8>; +LL | | type Item = &'a mut u8; ... | -LL | | } -LL | | } - | |_________^ +LL | | } +LL | | } + | |_^ | help: consider implementing `iter_mut` | -LL ~ -LL + impl S { +LL + +LL + impl S1 { LL + fn iter_mut(&mut self) -> std::slice::IterMut<'a, u8> { LL + <&mut Self as IntoIterator>::into_iter(self) LL + } @@ -45,21 +45,21 @@ LL + } | error: `IntoIterator` implemented for a reference type without an `iter` method - --> $DIR/into_iter_without_iter.rs:29:9 + --> $DIR/into_iter_without_iter.rs:25:1 | -LL | / impl<'a, T> IntoIterator for &'a S { +LL | / impl<'a, T> IntoIterator for &'a S2 { LL | | -LL | | type IntoIter = std::slice::Iter<'a, T>; -LL | | type Item = &'a T; +LL | | type IntoIter = std::slice::Iter<'a, T>; +LL | | type Item = &'a T; ... | -LL | | } -LL | | } - | |_________^ +LL | | } +LL | | } + | |_^ | help: consider implementing `iter` | -LL ~ -LL + impl S { +LL + +LL + impl S2 { LL + fn iter(&self) -> std::slice::Iter<'a, T> { LL + <&Self as IntoIterator>::into_iter(self) LL + } @@ -67,21 +67,21 @@ LL + } | error: `IntoIterator` implemented for a reference type without an `iter_mut` method - --> $DIR/into_iter_without_iter.rs:37:9 + --> $DIR/into_iter_without_iter.rs:33:1 | -LL | / impl<'a, T> IntoIterator for &'a mut S { +LL | / impl<'a, T> IntoIterator for &'a mut S2 { LL | | -LL | | type IntoIter = std::slice::IterMut<'a, T>; -LL | | type Item = &'a mut T; +LL | | type IntoIter = std::slice::IterMut<'a, T>; +LL | | type Item = &'a mut T; ... | -LL | | } -LL | | } - | |_________^ +LL | | } +LL | | } + | |_^ | help: consider implementing `iter_mut` | -LL ~ -LL + impl S { +LL + +LL + impl S2 { LL + fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> { LL + <&mut Self as IntoIterator>::into_iter(self) LL + } @@ -89,21 +89,21 @@ LL + } | error: `IntoIterator` implemented for a reference type without an `iter_mut` method - --> $DIR/into_iter_without_iter.rs:93:9 + --> $DIR/into_iter_without_iter.rs:84:1 | -LL | / impl<'a, T> IntoIterator for &mut S<'a, T> { +LL | / impl<'a, T> IntoIterator for &mut S4<'a, T> { LL | | -LL | | type IntoIter = std::slice::IterMut<'a, T>; -LL | | type Item = &'a mut T; +LL | | type IntoIter = std::slice::IterMut<'a, T>; +LL | | type Item = &'a mut T; ... | -LL | | } -LL | | } - | |_________^ +LL | | } +LL | | } + | |_^ | help: consider implementing `iter_mut` | -LL ~ -LL + impl S<'a, T> { +LL + +LL + impl S4<'a, T> { LL + fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> { LL + <&mut Self as IntoIterator>::into_iter(self) LL + } diff --git a/tests/ui/iter_without_into_iter.rs b/tests/ui/iter_without_into_iter.rs index cedb756c79de..29f526b455cb 100644 --- a/tests/ui/iter_without_into_iter.rs +++ b/tests/ui/iter_without_into_iter.rs @@ -1,120 +1,124 @@ //@no-rustfix #![warn(clippy::iter_without_into_iter)] -fn main() { - { - struct S; - impl S { - pub fn iter(&self) -> std::slice::Iter<'_, u8> { - //~^ ERROR: `iter` method without an `IntoIterator` impl - [].iter() - } - pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { - //~^ ERROR: `iter_mut` method without an `IntoIterator` impl - [].iter_mut() - } - } - } - { - struct S; - impl S { - pub fn iter(&self) -> impl Iterator { - // RPITIT is not stable, so we can't generally suggest it here yet - [].iter() - } - } - } - { - struct S<'a>(&'a mut [u8]); - impl<'a> S<'a> { - pub fn iter(&self) -> std::slice::Iter<'_, u8> { - //~^ ERROR: `iter` method without an `IntoIterator` impl - self.0.iter() - } - pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { - //~^ ERROR: `iter_mut` method without an `IntoIterator` impl - self.0.iter_mut() - } - } - } - { - // Incompatible signatures - struct S; - impl S { - pub fn iter(self) -> std::slice::Iter<'static, u8> { - todo!() - } - } - struct S2; - impl S2 { - pub async fn iter(&self) -> std::slice::Iter<'static, u8> { - todo!() - } - } - struct S3; - impl S3 { - pub fn iter(&self, _additional_param: ()) -> std::slice::Iter<'static, u8> { - todo!() - } - } - struct S4(T); - impl S4 { - pub fn iter(&self) -> std::slice::Iter<'static, (T, U)> { - todo!() - } - } - struct S5(T); - impl S5 { - pub fn iter(&self) -> std::slice::Iter<'static, T> { - todo!() - } - } - } - { - struct S(T); - impl S { - pub fn iter(&self) -> std::slice::Iter<'_, T> { - //~^ ERROR: `iter` method without an `IntoIterator` impl - todo!() - } - pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { - //~^ ERROR: `iter_mut` method without an `IntoIterator` impl - todo!() - } - } - } - { - struct S(T); - impl S { - pub fn iter(&self) -> std::slice::Iter<'_, T> { - // Don't lint, there's an existing (wrong) IntoIterator impl - todo!() - } - } +pub struct S1; +impl S1 { + pub fn iter(&self) -> std::slice::Iter<'_, u8> { + //~^ ERROR: `iter` method without an `IntoIterator` impl + [].iter() + } + pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { + //~^ ERROR: `iter_mut` method without an `IntoIterator` impl + [].iter_mut() + } +} + +pub struct S2; +impl S2 { + pub fn iter(&self) -> impl Iterator { + // RPITIT is not stable, so we can't generally suggest it here yet + [].iter() + } +} + +pub struct S3<'a>(&'a mut [u8]); +impl<'a> S3<'a> { + pub fn iter(&self) -> std::slice::Iter<'_, u8> { + //~^ ERROR: `iter` method without an `IntoIterator` impl + self.0.iter() + } + pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { + //~^ ERROR: `iter_mut` method without an `IntoIterator` impl + self.0.iter_mut() + } +} + +// Incompatible signatures +pub struct S4; +impl S4 { + pub fn iter(self) -> std::slice::Iter<'static, u8> { + todo!() + } +} + +pub struct S5; +impl S5 { + pub async fn iter(&self) -> std::slice::Iter<'static, u8> { + todo!() + } +} + +pub struct S6; +impl S6 { + pub fn iter(&self, _additional_param: ()) -> std::slice::Iter<'static, u8> { + todo!() + } +} + +pub struct S7(T); +impl S7 { + pub fn iter(&self) -> std::slice::Iter<'static, (T, U)> { + todo!() + } +} + +pub struct S8(T); +impl S8 { + pub fn iter(&self) -> std::slice::Iter<'static, T> { + todo!() + } +} + +// =========================== +pub struct S9(T); +impl S9 { + pub fn iter(&self) -> std::slice::Iter<'_, T> { + //~^ ERROR: `iter` method without an `IntoIterator` impl + todo!() + } + pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { + //~^ ERROR: `iter_mut` method without an `IntoIterator` impl + todo!() + } +} + +pub struct S10(T); +impl S10 { + pub fn iter(&self) -> std::slice::Iter<'_, T> { + // Don't lint, there's an existing (wrong) IntoIterator impl + todo!() + } +} + +impl<'a, T> IntoIterator for &'a S10 { + type Item = &'a String; + type IntoIter = std::slice::Iter<'a, String>; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} - impl<'a, T> IntoIterator for &'a S { - type Item = &'a String; - type IntoIter = std::slice::Iter<'a, String>; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } - } - { - struct S(T); - impl S { - pub fn iter_mut(&self) -> std::slice::IterMut<'_, T> { - // Don't lint, there's an existing (wrong) IntoIterator impl - todo!() - } - } +pub struct S11(T); +impl S11 { + pub fn iter_mut(&self) -> std::slice::IterMut<'_, T> { + // Don't lint, there's an existing (wrong) IntoIterator impl + todo!() + } +} +impl<'a, T> IntoIterator for &'a mut S11 { + type Item = &'a mut String; + type IntoIter = std::slice::IterMut<'a, String>; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} - impl<'a, T> IntoIterator for &'a mut S { - type Item = &'a mut String; - type IntoIter = std::slice::IterMut<'a, String>; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } +// Private type not exported: don't lint +struct S12; +impl S12 { + fn iter(&self) -> std::slice::Iter<'_, u8> { + todo!() } } + +fn main() {} diff --git a/tests/ui/iter_without_into_iter.stderr b/tests/ui/iter_without_into_iter.stderr index 9d0b99415a50..af5afd47bfc4 100644 --- a/tests/ui/iter_without_into_iter.stderr +++ b/tests/ui/iter_without_into_iter.stderr @@ -1,146 +1,146 @@ -error: `iter` method without an `IntoIterator` impl for `&S` - --> $DIR/iter_without_into_iter.rs:8:13 +error: `iter` method without an `IntoIterator` impl for `&S1` + --> $DIR/iter_without_into_iter.rs:6:5 | -LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> { +LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> { LL | | -LL | | [].iter() -LL | | } - | |_____________^ +LL | | [].iter() +LL | | } + | |_____^ | = note: `-D clippy::iter-without-into-iter` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::iter_without_into_iter)]` -help: consider implementing `IntoIterator` for `&S` +help: consider implementing `IntoIterator` for `&S1` | -LL ~ -LL + impl IntoIterator for &S { +LL + +LL + impl IntoIterator for &S1 { LL + type IntoIter = std::slice::Iter<'_, u8>; -LL + type Iter = &u8; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &u8; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } | -error: `iter_mut` method without an `IntoIterator` impl for `&mut S` - --> $DIR/iter_without_into_iter.rs:12:13 +error: `iter_mut` method without an `IntoIterator` impl for `&mut S1` + --> $DIR/iter_without_into_iter.rs:10:5 | -LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { +LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { LL | | -LL | | [].iter_mut() -LL | | } - | |_____________^ +LL | | [].iter_mut() +LL | | } + | |_____^ | -help: consider implementing `IntoIterator` for `&mut S` +help: consider implementing `IntoIterator` for `&mut S1` | -LL ~ -LL + impl IntoIterator for &mut S { +LL + +LL + impl IntoIterator for &mut S1 { LL + type IntoIter = std::slice::IterMut<'_, u8>; -LL + type Iter = &mut u8; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &mut u8; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } | -error: `iter` method without an `IntoIterator` impl for `&S<'a>` - --> $DIR/iter_without_into_iter.rs:30:13 +error: `iter` method without an `IntoIterator` impl for `&S3<'a>` + --> $DIR/iter_without_into_iter.rs:26:5 | -LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> { +LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> { LL | | -LL | | self.0.iter() -LL | | } - | |_____________^ +LL | | self.0.iter() +LL | | } + | |_____^ | -help: consider implementing `IntoIterator` for `&S<'a>` +help: consider implementing `IntoIterator` for `&S3<'a>` | -LL ~ -LL + impl IntoIterator for &S<'a> { +LL + +LL + impl IntoIterator for &S3<'a> { LL + type IntoIter = std::slice::Iter<'_, u8>; -LL + type Iter = &u8; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &u8; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } | -error: `iter_mut` method without an `IntoIterator` impl for `&mut S<'a>` - --> $DIR/iter_without_into_iter.rs:34:13 +error: `iter_mut` method without an `IntoIterator` impl for `&mut S3<'a>` + --> $DIR/iter_without_into_iter.rs:30:5 | -LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { +LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { LL | | -LL | | self.0.iter_mut() -LL | | } - | |_____________^ +LL | | self.0.iter_mut() +LL | | } + | |_____^ | -help: consider implementing `IntoIterator` for `&mut S<'a>` +help: consider implementing `IntoIterator` for `&mut S3<'a>` | -LL ~ -LL + impl IntoIterator for &mut S<'a> { +LL + +LL + impl IntoIterator for &mut S3<'a> { LL + type IntoIter = std::slice::IterMut<'_, u8>; -LL + type Iter = &mut u8; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &mut u8; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } | -error: `iter` method without an `IntoIterator` impl for `&S5` - --> $DIR/iter_without_into_iter.rs:68:13 +error: `iter` method without an `IntoIterator` impl for `&S8` + --> $DIR/iter_without_into_iter.rs:67:5 | -LL | / pub fn iter(&self) -> std::slice::Iter<'static, T> { -LL | | todo!() -LL | | } - | |_____________^ +LL | / pub fn iter(&self) -> std::slice::Iter<'static, T> { +LL | | todo!() +LL | | } + | |_____^ | -help: consider implementing `IntoIterator` for `&S5` +help: consider implementing `IntoIterator` for `&S8` | -LL ~ -LL + impl IntoIterator for &S5 { +LL + +LL + impl IntoIterator for &S8 { LL + type IntoIter = std::slice::Iter<'static, T>; -LL + type Iter = &T; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &T; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } | -error: `iter` method without an `IntoIterator` impl for `&S` - --> $DIR/iter_without_into_iter.rs:76:13 +error: `iter` method without an `IntoIterator` impl for `&S9` + --> $DIR/iter_without_into_iter.rs:75:5 | -LL | / pub fn iter(&self) -> std::slice::Iter<'_, T> { +LL | / pub fn iter(&self) -> std::slice::Iter<'_, T> { LL | | -LL | | todo!() -LL | | } - | |_____________^ +LL | | todo!() +LL | | } + | |_____^ | -help: consider implementing `IntoIterator` for `&S` +help: consider implementing `IntoIterator` for `&S9` | -LL ~ -LL + impl IntoIterator for &S { +LL + +LL + impl IntoIterator for &S9 { LL + type IntoIter = std::slice::Iter<'_, T>; -LL + type Iter = &T; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &T; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } | -error: `iter_mut` method without an `IntoIterator` impl for `&mut S` - --> $DIR/iter_without_into_iter.rs:80:13 +error: `iter_mut` method without an `IntoIterator` impl for `&mut S9` + --> $DIR/iter_without_into_iter.rs:79:5 | -LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { +LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { LL | | -LL | | todo!() -LL | | } - | |_____________^ +LL | | todo!() +LL | | } + | |_____^ | -help: consider implementing `IntoIterator` for `&mut S` +help: consider implementing `IntoIterator` for `&mut S9` | -LL ~ -LL + impl IntoIterator for &mut S { +LL + +LL + impl IntoIterator for &mut S9 { LL + type IntoIter = std::slice::IterMut<'_, T>; -LL + type Iter = &mut T; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &mut T; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } diff --git a/tests/ui/let_and_return.fixed b/tests/ui/let_and_return.fixed index 88b8ae673758..b5584fcde8c9 100644 --- a/tests/ui/let_and_return.fixed +++ b/tests/ui/let_and_return.fixed @@ -168,7 +168,26 @@ mod issue_5729 { impl FooStorage for FooStorageImpl { fn foo_cloned(&self) -> Arc { - Arc::clone(&self.foo) as _ + (Arc::clone(&self.foo)) as _ + //~^ ERROR: returning the result of a `let` binding from a block + } + } +} + +mod issue_11335 { + pub enum E { + A(T), + B(T), + } + + impl E { + pub fn inner(&self) -> &T { + + + (match self { + E::A(x) => x, + E::B(x) => x, + }) as _ //~^ ERROR: returning the result of a `let` binding from a block } } diff --git a/tests/ui/let_and_return.rs b/tests/ui/let_and_return.rs index f366842c5d77..f13c7c4e2034 100644 --- a/tests/ui/let_and_return.rs +++ b/tests/ui/let_and_return.rs @@ -174,6 +174,25 @@ mod issue_5729 { } } +mod issue_11335 { + pub enum E { + A(T), + B(T), + } + + impl E { + pub fn inner(&self) -> &T { + let result = match self { + E::A(x) => x, + E::B(x) => x, + }; + + result + //~^ ERROR: returning the result of a `let` binding from a block + } + } +} + // https://github.com/rust-lang/rust-clippy/issues/11167 macro_rules! fn_in_macro { ($b:block) => { diff --git a/tests/ui/let_and_return.stderr b/tests/ui/let_and_return.stderr index c09c2b32aad0..fe60072d13f8 100644 --- a/tests/ui/let_and_return.stderr +++ b/tests/ui/let_and_return.stderr @@ -53,8 +53,30 @@ LL | clone help: return the expression directly | LL ~ -LL ~ Arc::clone(&self.foo) as _ +LL ~ (Arc::clone(&self.foo)) as _ | -error: aborting due to 4 previous errors +error: returning the result of a `let` binding from a block + --> $DIR/let_and_return.rs:190:13 + | +LL | / let result = match self { +LL | | E::A(x) => x, +LL | | E::B(x) => x, +LL | | }; + | |______________- unnecessary `let` binding +LL | +LL | result + | ^^^^^^ + | +help: return the expression directly + | +LL ~ +LL | +LL ~ (match self { +LL + E::A(x) => x, +LL + E::B(x) => x, +LL + }) as _ + | + +error: aborting due to 5 previous errors diff --git a/tests/ui/manual_filter.rs b/tests/ui/manual_filter.rs index 06968f8bae4a..ee44909f37ed 100644 --- a/tests/ui/manual_filter.rs +++ b/tests/ui/manual_filter.rs @@ -191,9 +191,7 @@ fn main() { None => None, }; let _ = match Some(15) { - Some(x) => unsafe { - if f(x) { Some(x) } else { None } - }, + Some(x) => unsafe { if f(x) { Some(x) } else { None } }, None => None, }; diff --git a/tests/ui/manual_filter.stderr b/tests/ui/manual_filter.stderr index 1490f209735a..b23ad887eb2c 100644 --- a/tests/ui/manual_filter.stderr +++ b/tests/ui/manual_filter.stderr @@ -169,15 +169,13 @@ error: manual implementation of `Option::filter` | LL | let _ = match Some(15) { | _____________^ -LL | | Some(x) => unsafe { -LL | | if f(x) { Some(x) } else { None } -LL | | }, +LL | | Some(x) => unsafe { if f(x) { Some(x) } else { None } }, LL | | None => None, LL | | }; | |_____^ help: try: `Some(15).filter(|&x| unsafe { f(x) })` error: manual implementation of `Option::filter` - --> $DIR/manual_filter.rs:203:12 + --> $DIR/manual_filter.rs:201:12 | LL | } else if let Some(x) = Some(16) { | ____________^ diff --git a/tests/ui/manual_let_else.rs b/tests/ui/manual_let_else.rs index 6775fdc921f9..27717ab3a73a 100644 --- a/tests/ui/manual_let_else.rs +++ b/tests/ui/manual_let_else.rs @@ -35,9 +35,7 @@ fn fire() { let v = if let Some(v) = g() { //~^ ERROR: this could be rewritten as `let...else` // Blocks around the identity should have no impact - { - { v } - } + { { v } } } else { // Some computation should still make it fire g(); diff --git a/tests/ui/manual_let_else.stderr b/tests/ui/manual_let_else.stderr index 49dbd7615e02..2b6504a18278 100644 --- a/tests/ui/manual_let_else.stderr +++ b/tests/ui/manual_let_else.stderr @@ -31,7 +31,7 @@ error: this could be rewritten as `let...else` LL | / let v = if let Some(v) = g() { LL | | LL | | // Blocks around the identity should have no impact -LL | | { +LL | | { { v } } ... | LL | | return; LL | | }; @@ -47,25 +47,25 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:49:9 + --> $DIR/manual_let_else.rs:47:9 | LL | let v = if let Some(v_some) = g() { v_some } else { continue }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { continue };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:51:9 + --> $DIR/manual_let_else.rs:49:9 | LL | let v = if let Some(v_some) = g() { v_some } else { break }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { break };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:56:5 + --> $DIR/manual_let_else.rs:54:5 | LL | let v = if let Some(v_some) = g() { v_some } else { panic!() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { panic!() };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:60:5 + --> $DIR/manual_let_else.rs:58:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -83,7 +83,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:68:5 + --> $DIR/manual_let_else.rs:66:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -101,7 +101,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:76:5 + --> $DIR/manual_let_else.rs:74:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -121,7 +121,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:87:5 + --> $DIR/manual_let_else.rs:85:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -143,13 +143,13 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:98:5 + --> $DIR/manual_let_else.rs:96:5 | LL | let v = if let Some(v_some) = g() { v_some } else { if panic!() {} }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { if panic!() {} };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:102:5 + --> $DIR/manual_let_else.rs:100:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -170,7 +170,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:112:5 + --> $DIR/manual_let_else.rs:110:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -191,7 +191,7 @@ LL + } }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:122:5 + --> $DIR/manual_let_else.rs:120:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -220,7 +220,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:140:5 + --> $DIR/manual_let_else.rs:138:5 | LL | / let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) { LL | | @@ -238,7 +238,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:148:5 + --> $DIR/manual_let_else.rs:146:5 | LL | / let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) { LL | | @@ -256,7 +256,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:158:13 + --> $DIR/manual_let_else.rs:156:13 | LL | let $n = if let Some(v) = $e { v } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some($n) = g() else { return };` @@ -267,19 +267,19 @@ LL | create_binding_if_some!(w, g()); = note: this error originates in the macro `create_binding_if_some` (in Nightly builds, run with -Z macro-backtrace for more info) error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:167:5 + --> $DIR/manual_let_else.rs:165:5 | LL | let v = if let Variant::A(a, 0) = e() { a } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(v, 0) = e() else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:171:5 + --> $DIR/manual_let_else.rs:169:5 | LL | let mut v = if let Variant::B(b) = e() { b } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::B(mut v) = e() else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:176:5 + --> $DIR/manual_let_else.rs:174:5 | LL | / let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested { LL | | @@ -297,19 +297,19 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:183:5 + --> $DIR/manual_let_else.rs:181:5 | LL | let v = if let Variant::A(.., a) = e() { a } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(.., v) = e() else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:187:5 + --> $DIR/manual_let_else.rs:185:5 | LL | let w = if let (Some(v), ()) = (g(), ()) { v } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let (Some(w), ()) = (g(), ()) else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:191:5 + --> $DIR/manual_let_else.rs:189:5 | LL | / let w = if let Some(S { v: x }) = Some(S { v: 0 }) { LL | | @@ -327,7 +327,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:199:5 + --> $DIR/manual_let_else.rs:197:5 | LL | / let v = if let Some(S { v: x }) = Some(S { v: 0 }) { LL | | @@ -345,7 +345,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:207:5 + --> $DIR/manual_let_else.rs:205:5 | LL | / let (x, S { v }, w) = if let Some(U { v, w, x }) = None::>> { LL | | @@ -363,7 +363,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:324:5 + --> $DIR/manual_let_else.rs:322:5 | LL | / let _ = match ff { LL | | diff --git a/tests/ui/manual_map_option_2.fixed b/tests/ui/manual_map_option_2.fixed index 513f6e32340a..f5bb4e0af1ba 100644 --- a/tests/ui/manual_map_option_2.fixed +++ b/tests/ui/manual_map_option_2.fixed @@ -42,9 +42,7 @@ fn main() { // Lint. `s` is captured by reference, so no lifetime issues. let s = Some(String::new()); - let _ = s.as_ref().map(|x| { - if let Some(ref s) = s { (x.clone(), s) } else { panic!() } - }); + let _ = s.as_ref().map(|x| { if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }); // Issue #7820 unsafe fn f(x: u32) -> u32 { diff --git a/tests/ui/manual_map_option_2.rs b/tests/ui/manual_map_option_2.rs index fd186743fe24..cbc2356e0a2d 100644 --- a/tests/ui/manual_map_option_2.rs +++ b/tests/ui/manual_map_option_2.rs @@ -46,9 +46,7 @@ fn main() { // Lint. `s` is captured by reference, so no lifetime issues. let s = Some(String::new()); let _ = match &s { - Some(x) => Some({ - if let Some(ref s) = s { (x.clone(), s) } else { panic!() } - }), + Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), None => None, }; diff --git a/tests/ui/manual_map_option_2.stderr b/tests/ui/manual_map_option_2.stderr index bf242c0416c2..d3754f22d899 100644 --- a/tests/ui/manual_map_option_2.stderr +++ b/tests/ui/manual_map_option_2.stderr @@ -26,22 +26,13 @@ error: manual implementation of `Option::map` | LL | let _ = match &s { | _____________^ -LL | | Some(x) => Some({ -LL | | if let Some(ref s) = s { (x.clone(), s) } else { panic!() } -LL | | }), +LL | | Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), LL | | None => None, LL | | }; - | |_____^ - | -help: try - | -LL ~ let _ = s.as_ref().map(|x| { -LL + if let Some(ref s) = s { (x.clone(), s) } else { panic!() } -LL ~ }); - | + | |_____^ help: try: `s.as_ref().map(|x| { if let Some(ref s) = s { (x.clone(), s) } else { panic!() } })` error: manual implementation of `Option::map` - --> $DIR/manual_map_option_2.rs:60:17 + --> $DIR/manual_map_option_2.rs:58:17 | LL | let _ = match Some(0) { | _________________^ @@ -51,7 +42,7 @@ LL | | }; | |_________^ help: try: `Some(0).map(|x| f(x))` error: manual implementation of `Option::map` - --> $DIR/manual_map_option_2.rs:65:13 + --> $DIR/manual_map_option_2.rs:63:13 | LL | let _ = match Some(0) { | _____________^ @@ -61,7 +52,7 @@ LL | | }; | |_____^ help: try: `Some(0).map(|x| unsafe { f(x) })` error: manual implementation of `Option::map` - --> $DIR/manual_map_option_2.rs:69:13 + --> $DIR/manual_map_option_2.rs:67:13 | LL | let _ = match Some(0) { | _____________^ diff --git a/tests/ui/manual_string_new.fixed b/tests/ui/manual_string_new.fixed index 273be4e0fd2b..2d4c5a029153 100644 --- a/tests/ui/manual_string_new.fixed +++ b/tests/ui/manual_string_new.fixed @@ -1,4 +1,5 @@ #![warn(clippy::manual_string_new)] +#![allow(clippy::unnecessary_fallible_conversions)] macro_rules! create_strings_from_macro { // When inside a macro, nothing should warn to prevent false positives. diff --git a/tests/ui/manual_string_new.rs b/tests/ui/manual_string_new.rs index 0d5514fc893e..20f0be6aaf97 100644 --- a/tests/ui/manual_string_new.rs +++ b/tests/ui/manual_string_new.rs @@ -1,4 +1,5 @@ #![warn(clippy::manual_string_new)] +#![allow(clippy::unnecessary_fallible_conversions)] macro_rules! create_strings_from_macro { // When inside a macro, nothing should warn to prevent false positives. diff --git a/tests/ui/manual_string_new.stderr b/tests/ui/manual_string_new.stderr index 399652d3fecb..cb2d78c39ed1 100644 --- a/tests/ui/manual_string_new.stderr +++ b/tests/ui/manual_string_new.stderr @@ -1,5 +1,5 @@ error: empty String is being created manually - --> $DIR/manual_string_new.rs:13:13 + --> $DIR/manual_string_new.rs:14:13 | LL | let _ = "".to_string(); | ^^^^^^^^^^^^^^ help: consider using: `String::new()` @@ -8,49 +8,49 @@ LL | let _ = "".to_string(); = help: to override `-D warnings` add `#[allow(clippy::manual_string_new)]` error: empty String is being created manually - --> $DIR/manual_string_new.rs:16:13 + --> $DIR/manual_string_new.rs:17:13 | LL | let _ = "".to_owned(); | ^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:19:21 + --> $DIR/manual_string_new.rs:20:21 | LL | let _: String = "".into(); | ^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:26:13 + --> $DIR/manual_string_new.rs:27:13 | LL | let _ = String::from(""); | ^^^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:27:13 + --> $DIR/manual_string_new.rs:28:13 | LL | let _ = ::from(""); | ^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:32:13 + --> $DIR/manual_string_new.rs:33:13 | LL | let _ = String::try_from("").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:38:21 + --> $DIR/manual_string_new.rs:39:21 | LL | let _: String = From::from(""); | ^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:43:21 + --> $DIR/manual_string_new.rs:44:21 | LL | let _: String = TryFrom::try_from("").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:46:21 + --> $DIR/manual_string_new.rs:47:21 | LL | let _: String = TryFrom::try_from("").expect("this should warn"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` diff --git a/tests/ui/map_identity.fixed b/tests/ui/map_identity.fixed index e756d9b59354..62b0ba018600 100644 --- a/tests/ui/map_identity.fixed +++ b/tests/ui/map_identity.fixed @@ -22,6 +22,30 @@ fn main() { let _ = Ok(1).map_err(std::convert::identity::); } +fn issue7189() { + // should lint + let x = [(1, 2), (3, 4)]; + let _ = x.iter(); + let _ = x.iter(); + let _ = x.iter(); + + let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))]; + let _ = y.iter(); + + // should not lint + let _ = x.iter().map(|(x, y)| (x, y, y)); + let _ = x.iter().map(|(x, _y)| (x,)); + let _ = x.iter().map(|(x, _)| (x,)); + let _ = x.iter().map(|(x, ..)| (x,)); + let _ = y.iter().map(|(x, y, (z, _))| (x, y, (z, z))); + let _ = y + .iter() + .map(|(x, y, (z, _)): &(i32, i32, (i32, (i32,)))| (x, y, (z, z))); + let _ = y + .iter() + .map(|(x, y, (z, (w,))): &(i32, i32, (i32, (i32,)))| (x, y, (z, (w,)))); +} + fn not_identity(x: &u16) -> u16 { *x } diff --git a/tests/ui/map_identity.rs b/tests/ui/map_identity.rs index 74cbaade4054..b7f4c99f2730 100644 --- a/tests/ui/map_identity.rs +++ b/tests/ui/map_identity.rs @@ -24,6 +24,32 @@ fn main() { let _ = Ok(1).map_err(std::convert::identity::); } +fn issue7189() { + // should lint + let x = [(1, 2), (3, 4)]; + let _ = x.iter().map(|(x, y)| (x, y)); + let _ = x.iter().map(|(x, y)| { + return (x, y); + }); + let _ = x.iter().map(|(x, y)| return (x, y)); + + let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))]; + let _ = y.iter().map(|(x, y, (z, (w,)))| (x, y, (z, (w,)))); + + // should not lint + let _ = x.iter().map(|(x, y)| (x, y, y)); + let _ = x.iter().map(|(x, _y)| (x,)); + let _ = x.iter().map(|(x, _)| (x,)); + let _ = x.iter().map(|(x, ..)| (x,)); + let _ = y.iter().map(|(x, y, (z, _))| (x, y, (z, z))); + let _ = y + .iter() + .map(|(x, y, (z, _)): &(i32, i32, (i32, (i32,)))| (x, y, (z, z))); + let _ = y + .iter() + .map(|(x, y, (z, (w,))): &(i32, i32, (i32, (i32,)))| (x, y, (z, (w,)))); +} + fn not_identity(x: &u16) -> u16 { *x } diff --git a/tests/ui/map_identity.stderr b/tests/ui/map_identity.stderr index 8942fd7c0d26..4ca24b0b04c4 100644 --- a/tests/ui/map_identity.stderr +++ b/tests/ui/map_identity.stderr @@ -40,5 +40,32 @@ error: unnecessary map of the identity function LL | let _: Result = Ok(1).map_err(|a| a); | ^^^^^^^^^^^^^^^ help: remove the call to `map_err` -error: aborting due to 6 previous errors +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:30:21 + | +LL | let _ = x.iter().map(|(x, y)| (x, y)); + | ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` + +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:31:21 + | +LL | let _ = x.iter().map(|(x, y)| { + | _____________________^ +LL | | return (x, y); +LL | | }); + | |______^ help: remove the call to `map` + +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:34:21 + | +LL | let _ = x.iter().map(|(x, y)| return (x, y)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` + +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:37:21 + | +LL | let _ = y.iter().map(|(x, y, (z, (w,)))| (x, y, (z, (w,)))); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` + +error: aborting due to 10 previous errors diff --git a/tests/ui/min_rust_version_invalid_attr.rs b/tests/ui/min_rust_version_invalid_attr.rs index c8a0d6641675..3917bb9e03de 100644 --- a/tests/ui/min_rust_version_invalid_attr.rs +++ b/tests/ui/min_rust_version_invalid_attr.rs @@ -11,13 +11,12 @@ fn outer_attr() {} mod multiple { #![clippy::msrv = "1.40"] #![clippy::msrv = "=1.35.0"] - //~^ ERROR: `msrv` is defined multiple times #![clippy::msrv = "1.10.1"] - //~^ ERROR: `msrv` is defined multiple times + //~^ ERROR: `clippy::msrv` is defined multiple times mod foo { #![clippy::msrv = "1"] #![clippy::msrv = "1.0.0"] - //~^ ERROR: `msrv` is defined multiple times + //~^ ERROR: `clippy::msrv` is defined multiple times } } diff --git a/tests/ui/min_rust_version_invalid_attr.stderr b/tests/ui/min_rust_version_invalid_attr.stderr index 8d4071e258eb..cf8392f03165 100644 --- a/tests/ui/min_rust_version_invalid_attr.stderr +++ b/tests/ui/min_rust_version_invalid_attr.stderr @@ -10,20 +10,8 @@ error: `invalid.version` is not a valid Rust version LL | #[clippy::msrv = "invalid.version"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `msrv` is defined multiple times - --> $DIR/min_rust_version_invalid_attr.rs:13:5 - | -LL | #![clippy::msrv = "=1.35.0"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: first definition found here - --> $DIR/min_rust_version_invalid_attr.rs:12:5 - | -LL | #![clippy::msrv = "1.40"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: `msrv` is defined multiple times - --> $DIR/min_rust_version_invalid_attr.rs:15:5 +error: `clippy::msrv` is defined multiple times + --> $DIR/min_rust_version_invalid_attr.rs:14:5 | LL | #![clippy::msrv = "1.10.1"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,17 +22,17 @@ note: first definition found here LL | #![clippy::msrv = "1.40"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `msrv` is defined multiple times - --> $DIR/min_rust_version_invalid_attr.rs:20:9 +error: `clippy::msrv` is defined multiple times + --> $DIR/min_rust_version_invalid_attr.rs:19:9 | LL | #![clippy::msrv = "1.0.0"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first definition found here - --> $DIR/min_rust_version_invalid_attr.rs:19:9 + --> $DIR/min_rust_version_invalid_attr.rs:18:9 | LL | #![clippy::msrv = "1"] | ^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/needless_if.fixed b/tests/ui/needless_if.fixed index b84182c5756e..be35dcddbe6b 100644 --- a/tests/ui/needless_if.fixed +++ b/tests/ui/needless_if.fixed @@ -39,11 +39,21 @@ fn main() { } // Do not lint `if let` or let chains if let true = true {} - if let true = true && true {} - if true && let true = true {} + if let true = true + && true + {} + if true + && let true = true + {} // Can lint nested `if let`s ({ - if let true = true && true { true } else { false } + if let true = true + && true + { + true + } else { + false + } } && true); external! { if (true) {} } with_span! { diff --git a/tests/ui/needless_if.rs b/tests/ui/needless_if.rs index 6c6023c72dcf..e2ad17e69a87 100644 --- a/tests/ui/needless_if.rs +++ b/tests/ui/needless_if.rs @@ -39,11 +39,21 @@ fn main() { } // Do not lint `if let` or let chains if let true = true {} - if let true = true && true {} - if true && let true = true {} + if let true = true + && true + {} + if true + && let true = true + {} // Can lint nested `if let`s if { - if let true = true && true { true } else { false } + if let true = true + && true + { + true + } else { + false + } } && true {} external! { if (true) {} } diff --git a/tests/ui/needless_if.stderr b/tests/ui/needless_if.stderr index ed5b9452b86b..c3e83c0f1f59 100644 --- a/tests/ui/needless_if.stderr +++ b/tests/ui/needless_if.stderr @@ -29,10 +29,13 @@ LL + }); | error: this `if` branch is empty - --> $DIR/needless_if.rs:45:5 + --> $DIR/needless_if.rs:49:5 | LL | / if { -LL | | if let true = true && true { true } else { false } +LL | | if let true = true +LL | | && true +LL | | { +... | LL | | } && true LL | | {} | |______^ @@ -40,24 +43,30 @@ LL | | {} help: you can remove it | LL ~ ({ -LL + if let true = true && true { true } else { false } +LL + if let true = true +LL + && true +LL + { +LL + true +LL + } else { +LL + false +LL + } LL + } && true); | error: this `if` branch is empty - --> $DIR/needless_if.rs:83:5 + --> $DIR/needless_if.rs:93:5 | LL | if { maybe_side_effect() } {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() });` error: this `if` branch is empty - --> $DIR/needless_if.rs:85:5 + --> $DIR/needless_if.rs:95:5 | LL | if { maybe_side_effect() } && true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() } && true);` error: this `if` branch is empty - --> $DIR/needless_if.rs:89:5 + --> $DIR/needless_if.rs:99:5 | LL | if true {} | ^^^^^^^^^^ help: you can remove it: `true;` diff --git a/tests/ui/needless_late_init.fixed b/tests/ui/needless_late_init.fixed index 9f45da04862c..891b2b014374 100644 --- a/tests/ui/needless_late_init.fixed +++ b/tests/ui/needless_late_init.fixed @@ -230,7 +230,9 @@ fn does_not_lint() { } let x; - if true && let Some(n) = Some("let chains too") { + if true + && let Some(n) = Some("let chains too") + { x = 1; } else { x = 2; diff --git a/tests/ui/needless_late_init.rs b/tests/ui/needless_late_init.rs index 0dab0faad561..55399511639e 100644 --- a/tests/ui/needless_late_init.rs +++ b/tests/ui/needless_late_init.rs @@ -230,7 +230,9 @@ fn does_not_lint() { } let x; - if true && let Some(n) = Some("let chains too") { + if true + && let Some(n) = Some("let chains too") + { x = 1; } else { x = 2; diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed index c3415a7df9e3..f0113ca696e1 100644 --- a/tests/ui/option_if_let_else.fixed +++ b/tests/ui/option_if_let_else.fixed @@ -1,7 +1,6 @@ #![warn(clippy::option_if_let_else)] #![allow( unused_tuple_struct_fields, - clippy::redundant_closure, clippy::ref_option_ref, clippy::equatable_if_let, clippy::let_unit_value, @@ -52,7 +51,7 @@ fn impure_else(arg: Option) { println!("return 1"); 1 }; - let _ = arg.map_or_else(|| side_effect(), |x| x); + let _ = arg.map_or_else(side_effect, |x| x); } fn test_map_or_else(arg: Option) { @@ -224,3 +223,17 @@ mod issue10729 { fn do_something(_value: &str) {} fn do_something2(_value: &mut str) {} } + +fn issue11429() { + use std::collections::HashMap; + + macro_rules! new_map { + () => {{ HashMap::new() }}; + } + + let opt: Option> = None; + + let mut _hashmap = opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone()); + + let mut _hm = opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone()); +} diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs index 86537f62057b..18b7af443925 100644 --- a/tests/ui/option_if_let_else.rs +++ b/tests/ui/option_if_let_else.rs @@ -1,7 +1,6 @@ #![warn(clippy::option_if_let_else)] #![allow( unused_tuple_struct_fields, - clippy::redundant_closure, clippy::ref_option_ref, clippy::equatable_if_let, clippy::let_unit_value, @@ -271,3 +270,21 @@ mod issue10729 { fn do_something(_value: &str) {} fn do_something2(_value: &mut str) {} } + +fn issue11429() { + use std::collections::HashMap; + + macro_rules! new_map { + () => {{ HashMap::new() }}; + } + + let opt: Option> = None; + + let mut _hashmap = if let Some(hm) = &opt { + hm.clone() + } else { + HashMap::new() + }; + + let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() }; +} diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr index 6d7d02f8c255..e36357bcb385 100644 --- a/tests/ui/option_if_let_else.stderr +++ b/tests/ui/option_if_let_else.stderr @@ -1,5 +1,5 @@ error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:12:5 + --> $DIR/option_if_let_else.rs:11:5 | LL | / if let Some(x) = string { LL | | (true, x) @@ -12,19 +12,19 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::option_if_let_else)]` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:30:13 + --> $DIR/option_if_let_else.rs:29:13 | LL | let _ = if let Some(s) = *string { s.len() } else { 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:31:13 + --> $DIR/option_if_let_else.rs:30:13 | LL | let _ = if let Some(s) = &num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:32:13 + --> $DIR/option_if_let_else.rs:31:13 | LL | let _ = if let Some(s) = &mut num { | _____________^ @@ -44,13 +44,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:38:13 + --> $DIR/option_if_let_else.rs:37:13 | LL | let _ = if let Some(ref s) = num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:39:13 + --> $DIR/option_if_let_else.rs:38:13 | LL | let _ = if let Some(mut s) = num { | _____________^ @@ -70,7 +70,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:45:13 + --> $DIR/option_if_let_else.rs:44:13 | LL | let _ = if let Some(ref mut s) = num { | _____________^ @@ -90,7 +90,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:54:5 + --> $DIR/option_if_let_else.rs:53:5 | LL | / if let Some(x) = arg { LL | | let y = x * x; @@ -109,7 +109,7 @@ LL + }) | error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:67:13 + --> $DIR/option_if_let_else.rs:66:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -118,10 +118,10 @@ LL | | } else { LL | | // map_or_else must be suggested LL | | side_effect() LL | | }; - | |_____^ help: try: `arg.map_or_else(|| side_effect(), |x| x)` + | |_____^ help: try: `arg.map_or_else(side_effect, |x| x)` error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:76:13 + --> $DIR/option_if_let_else.rs:75:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -144,7 +144,7 @@ LL ~ }, |x| x * x * x * x); | error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:109:13 + --> $DIR/option_if_let_else.rs:108:13 | LL | / if let Some(idx) = s.find('.') { LL | | vec![s[..idx].to_string(), s[idx..].to_string()] @@ -154,7 +154,7 @@ LL | | } | |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])` error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:120:5 + --> $DIR/option_if_let_else.rs:119:5 | LL | / if let Ok(binding) = variable { LL | | println!("Ok {binding}"); @@ -173,13 +173,13 @@ LL + }) | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:142:13 + --> $DIR/option_if_let_else.rs:141:13 | LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:152:13 + --> $DIR/option_if_let_else.rs:151:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -201,13 +201,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:180:13 + --> $DIR/option_if_let_else.rs:179:13 | LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:184:13 + --> $DIR/option_if_let_else.rs:183:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -227,7 +227,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:223:13 + --> $DIR/option_if_let_else.rs:222:13 | LL | let _ = match s { | _____________^ @@ -237,7 +237,7 @@ LL | | }; | |_____^ help: try: `s.map_or(1, |string| string.len())` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:227:13 + --> $DIR/option_if_let_else.rs:226:13 | LL | let _ = match Some(10) { | _____________^ @@ -247,7 +247,7 @@ LL | | }; | |_____^ help: try: `Some(10).map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:233:13 + --> $DIR/option_if_let_else.rs:232:13 | LL | let _ = match res { | _____________^ @@ -257,7 +257,7 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:237:13 + --> $DIR/option_if_let_else.rs:236:13 | LL | let _ = match res { | _____________^ @@ -267,13 +267,13 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:241:13 + --> $DIR/option_if_let_else.rs:240:13 | LL | let _ = if let Ok(a) = res { a + 1 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:258:9 + --> $DIR/option_if_let_else.rs:257:9 | LL | / match initial { LL | | Some(value) => do_something(value), @@ -282,7 +282,7 @@ LL | | } | |_________^ help: try: `initial.as_ref().map_or({}, |value| do_something(value))` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:265:9 + --> $DIR/option_if_let_else.rs:264:9 | LL | / match initial { LL | | Some(value) => do_something2(value), @@ -290,5 +290,22 @@ LL | | None => {}, LL | | } | |_________^ help: try: `initial.as_mut().map_or({}, |value| do_something2(value))` -error: aborting due to 23 previous errors +error: use Option::map_or_else instead of an if let/else + --> $DIR/option_if_let_else.rs:283:24 + | +LL | let mut _hashmap = if let Some(hm) = &opt { + | ________________________^ +LL | | hm.clone() +LL | | } else { +LL | | HashMap::new() +LL | | }; + | |_____^ help: try: `opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone())` + +error: use Option::map_or_else instead of an if let/else + --> $DIR/option_if_let_else.rs:289:19 + | +LL | let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone())` + +error: aborting due to 25 previous errors diff --git a/tests/ui/redundant_guards.fixed b/tests/ui/redundant_guards.fixed index f23116a7e1c5..f8af90927252 100644 --- a/tests/ui/redundant_guards.fixed +++ b/tests/ui/redundant_guards.fixed @@ -48,7 +48,7 @@ fn main() { Some(x) if let Some(1) = x => { x; .. - } + }, _ => todo!(), }; let y = 1; diff --git a/tests/ui/redundant_guards.rs b/tests/ui/redundant_guards.rs index c0206b4cec75..b46f8a6207e6 100644 --- a/tests/ui/redundant_guards.rs +++ b/tests/ui/redundant_guards.rs @@ -48,7 +48,7 @@ fn main() { Some(x) if let Some(1) = x => { x; .. - } + }, _ => todo!(), }; let y = 1; diff --git a/tests/ui/redundant_pattern_matching_option.fixed b/tests/ui/redundant_pattern_matching_option.fixed index 60f9fb6d493a..c9b76262d70b 100644 --- a/tests/ui/redundant_pattern_matching_option.fixed +++ b/tests/ui/redundant_pattern_matching_option.fixed @@ -16,10 +16,15 @@ fn issue_11174(boolean: bool, maybe_some: Option) -> bool { fn issue_11174_edge_cases(boolean: bool, boolean2: bool, maybe_some: Option) { let _ = maybe_some.is_none() && (boolean || boolean2); // guard needs parentheses - let _ = match maybe_some { // can't use `matches!` here - // because `expr` metavars in macros don't allow let exprs - None if let Some(x) = Some(0) && x > 5 => true, - _ => false + let _ = match maybe_some { + // can't use `matches!` here + // because `expr` metavars in macros don't allow let exprs + None if let Some(x) = Some(0) + && x > 5 => + { + true + }, + _ => false, }; } diff --git a/tests/ui/redundant_pattern_matching_option.rs b/tests/ui/redundant_pattern_matching_option.rs index 94bbb569c2a8..a5f9caf659c6 100644 --- a/tests/ui/redundant_pattern_matching_option.rs +++ b/tests/ui/redundant_pattern_matching_option.rs @@ -16,10 +16,15 @@ fn issue_11174(boolean: bool, maybe_some: Option) -> bool { fn issue_11174_edge_cases(boolean: bool, boolean2: bool, maybe_some: Option) { let _ = matches!(maybe_some, None if boolean || boolean2); // guard needs parentheses - let _ = match maybe_some { // can't use `matches!` here - // because `expr` metavars in macros don't allow let exprs - None if let Some(x) = Some(0) && x > 5 => true, - _ => false + let _ = match maybe_some { + // can't use `matches!` here + // because `expr` metavars in macros don't allow let exprs + None if let Some(x) = Some(0) + && x > 5 => + { + true + }, + _ => false, }; } diff --git a/tests/ui/redundant_pattern_matching_option.stderr b/tests/ui/redundant_pattern_matching_option.stderr index fdf395d82862..a75551c56f29 100644 --- a/tests/ui/redundant_pattern_matching_option.stderr +++ b/tests/ui/redundant_pattern_matching_option.stderr @@ -14,49 +14,49 @@ LL | let _ = matches!(maybe_some, None if boolean || boolean2); // guard nee | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `maybe_some.is_none() && (boolean || boolean2)` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:27:12 + --> $DIR/redundant_pattern_matching_option.rs:32:12 | LL | if let None = None::<()> {} | -------^^^^------------- help: try: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:29:12 + --> $DIR/redundant_pattern_matching_option.rs:34:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:31:12 + --> $DIR/redundant_pattern_matching_option.rs:36:12 | LL | if let Some(_) = Some(42) { | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:37:15 + --> $DIR/redundant_pattern_matching_option.rs:42:15 | LL | while let Some(_) = Some(42) {} | ----------^^^^^^^----------- help: try: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:39:15 + --> $DIR/redundant_pattern_matching_option.rs:44:15 | LL | while let None = Some(42) {} | ----------^^^^----------- help: try: `while Some(42).is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:41:15 + --> $DIR/redundant_pattern_matching_option.rs:46:15 | LL | while let None = None::<()> {} | ----------^^^^------------- help: try: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:44:15 + --> $DIR/redundant_pattern_matching_option.rs:49:15 | LL | while let Some(_) = v.pop() { | ----------^^^^^^^---------- help: try: `while v.pop().is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:52:5 + --> $DIR/redundant_pattern_matching_option.rs:57:5 | LL | / match Some(42) { LL | | Some(_) => true, @@ -65,7 +65,7 @@ LL | | }; | |_____^ help: try: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:57:5 + --> $DIR/redundant_pattern_matching_option.rs:62:5 | LL | / match None::<()> { LL | | Some(_) => false, @@ -74,7 +74,7 @@ LL | | }; | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:62:13 + --> $DIR/redundant_pattern_matching_option.rs:67:13 | LL | let _ = match None::<()> { | _____________^ @@ -84,55 +84,55 @@ LL | | }; | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:68:20 + --> $DIR/redundant_pattern_matching_option.rs:73:20 | LL | let _ = if let Some(_) = opt { true } else { false }; | -------^^^^^^^------ help: try: `if opt.is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:74:20 + --> $DIR/redundant_pattern_matching_option.rs:79:20 | LL | let _ = if let Some(_) = gen_opt() { | -------^^^^^^^------------ help: try: `if gen_opt().is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:76:19 + --> $DIR/redundant_pattern_matching_option.rs:81:19 | LL | } else if let None = gen_opt() { | -------^^^^------------ help: try: `if gen_opt().is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:82:12 + --> $DIR/redundant_pattern_matching_option.rs:87:12 | LL | if let Some(..) = gen_opt() {} | -------^^^^^^^^------------ help: try: `if gen_opt().is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:97:12 + --> $DIR/redundant_pattern_matching_option.rs:102:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:99:12 + --> $DIR/redundant_pattern_matching_option.rs:104:12 | LL | if let None = None::<()> {} | -------^^^^------------- help: try: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:101:15 + --> $DIR/redundant_pattern_matching_option.rs:106:15 | LL | while let Some(_) = Some(42) {} | ----------^^^^^^^----------- help: try: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:103:15 + --> $DIR/redundant_pattern_matching_option.rs:108:15 | LL | while let None = None::<()> {} | ----------^^^^------------- help: try: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:105:5 + --> $DIR/redundant_pattern_matching_option.rs:110:5 | LL | / match Some(42) { LL | | Some(_) => true, @@ -141,7 +141,7 @@ LL | | }; | |_____^ help: try: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:110:5 + --> $DIR/redundant_pattern_matching_option.rs:115:5 | LL | / match None::<()> { LL | | Some(_) => false, @@ -150,19 +150,19 @@ LL | | }; | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:118:12 + --> $DIR/redundant_pattern_matching_option.rs:123:12 | LL | if let None = *(&None::<()>) {} | -------^^^^----------------- help: try: `if (&None::<()>).is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:119:12 + --> $DIR/redundant_pattern_matching_option.rs:124:12 | LL | if let None = *&None::<()> {} | -------^^^^--------------- help: try: `if (&None::<()>).is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:125:5 + --> $DIR/redundant_pattern_matching_option.rs:130:5 | LL | / match x { LL | | Some(_) => true, @@ -171,7 +171,7 @@ LL | | }; | |_____^ help: try: `x.is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:130:5 + --> $DIR/redundant_pattern_matching_option.rs:135:5 | LL | / match x { LL | | None => true, @@ -180,7 +180,7 @@ LL | | }; | |_____^ help: try: `x.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:135:5 + --> $DIR/redundant_pattern_matching_option.rs:140:5 | LL | / match x { LL | | Some(_) => false, @@ -189,7 +189,7 @@ LL | | }; | |_____^ help: try: `x.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:140:5 + --> $DIR/redundant_pattern_matching_option.rs:145:5 | LL | / match x { LL | | None => false, @@ -198,13 +198,13 @@ LL | | }; | |_____^ help: try: `x.is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:155:13 + --> $DIR/redundant_pattern_matching_option.rs:160:13 | LL | let _ = matches!(x, Some(_)); | ^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:157:13 + --> $DIR/redundant_pattern_matching_option.rs:162:13 | LL | let _ = matches!(x, None); | ^^^^^^^^^^^^^^^^^ help: try: `x.is_none()` diff --git a/tests/ui/unnecessary_fallible_conversions.fixed b/tests/ui/unnecessary_fallible_conversions.fixed new file mode 100644 index 000000000000..9668a6b99bf0 --- /dev/null +++ b/tests/ui/unnecessary_fallible_conversions.fixed @@ -0,0 +1,6 @@ +#![warn(clippy::unnecessary_fallible_conversions)] + +fn main() { + let _: i64 = 0i32.into(); + let _: i64 = 0i32.into(); +} diff --git a/tests/ui/unnecessary_fallible_conversions.rs b/tests/ui/unnecessary_fallible_conversions.rs new file mode 100644 index 000000000000..9fa6c08b1b07 --- /dev/null +++ b/tests/ui/unnecessary_fallible_conversions.rs @@ -0,0 +1,6 @@ +#![warn(clippy::unnecessary_fallible_conversions)] + +fn main() { + let _: i64 = 0i32.try_into().unwrap(); + let _: i64 = 0i32.try_into().expect("can't happen"); +} diff --git a/tests/ui/unnecessary_fallible_conversions.stderr b/tests/ui/unnecessary_fallible_conversions.stderr new file mode 100644 index 000000000000..b918fdf774b5 --- /dev/null +++ b/tests/ui/unnecessary_fallible_conversions.stderr @@ -0,0 +1,17 @@ +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions.rs:4:23 + | +LL | let _: i64 = 0i32.try_into().unwrap(); + | ^^^^^^^^^^^^^^^^^^^ help: use: `into()` + | + = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]` + +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions.rs:5:23 + | +LL | let _: i64 = 0i32.try_into().expect("can't happen"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `into()` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/unnecessary_fallible_conversions_unfixable.rs b/tests/ui/unnecessary_fallible_conversions_unfixable.rs new file mode 100644 index 000000000000..68e617cc062d --- /dev/null +++ b/tests/ui/unnecessary_fallible_conversions_unfixable.rs @@ -0,0 +1,43 @@ +//@aux-build:proc_macros.rs +//@no-rustfix +#![warn(clippy::unnecessary_fallible_conversions)] + +extern crate proc_macros; + +struct Foo; +impl TryFrom for Foo { + type Error = (); + fn try_from(_: i32) -> Result { + Ok(Foo) + } +} +impl From for Foo { + fn from(_: i64) -> Self { + Foo + } +} + +fn main() { + // `Foo` only implements `TryFrom` and not `From`, so don't lint + let _: Result = 0i32.try_into(); + let _: Result = i32::try_into(0i32); + let _: Result = Foo::try_from(0i32); + + // ... it does impl From however + let _: Result = 0i64.try_into(); + //~^ ERROR: use of a fallible conversion when an infallible one could be used + let _: Result = i64::try_into(0i64); + //~^ ERROR: use of a fallible conversion when an infallible one could be used + let _: Result = Foo::try_from(0i64); + //~^ ERROR: use of a fallible conversion when an infallible one could be used + + let _: Result = 0i32.try_into(); + //~^ ERROR: use of a fallible conversion when an infallible one could be used + let _: Result = i32::try_into(0i32); + //~^ ERROR: use of a fallible conversion when an infallible one could be used + let _: Result = <_>::try_from(0i32); + //~^ ERROR: use of a fallible conversion when an infallible one could be used + + // From a macro + let _: Result = proc_macros::external!(0i32).try_into(); +} diff --git a/tests/ui/unnecessary_fallible_conversions_unfixable.stderr b/tests/ui/unnecessary_fallible_conversions_unfixable.stderr new file mode 100644 index 000000000000..286decf8f358 --- /dev/null +++ b/tests/ui/unnecessary_fallible_conversions_unfixable.stderr @@ -0,0 +1,41 @@ +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions_unfixable.rs:27:34 + | +LL | let _: Result = 0i64.try_into(); + | ^^^^^^^^ help: use: `into` + | + = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]` + +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions_unfixable.rs:29:29 + | +LL | let _: Result = i64::try_into(0i64); + | ^^^^^^^^^^^^^ help: use: `Into::into` + +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions_unfixable.rs:31:29 + | +LL | let _: Result = Foo::try_from(0i64); + | ^^^^^^^^^^^^^ help: use: `From::from` + +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions_unfixable.rs:34:34 + | +LL | let _: Result = 0i32.try_into(); + | ^^^^^^^^ help: use: `into` + +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions_unfixable.rs:36:29 + | +LL | let _: Result = i32::try_into(0i32); + | ^^^^^^^^^^^^^ help: use: `Into::into` + +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions_unfixable.rs:38:29 + | +LL | let _: Result = <_>::try_from(0i32); + | ^^^^^^^^^^^^^ help: use: `From::from` + +error: aborting due to 6 previous errors + diff --git a/tests/ui/unused_enumerate_index.fixed b/tests/ui/unused_enumerate_index.fixed new file mode 100644 index 000000000000..d079807ab587 --- /dev/null +++ b/tests/ui/unused_enumerate_index.fixed @@ -0,0 +1,58 @@ +#![allow(unused)] +#![warn(clippy::unused_enumerate_index)] + +use std::iter::Enumerate; + +fn main() { + let v = [1, 2, 3]; + for x in v.iter() { + println!("{x}"); + } + + struct Dummy1; + impl Dummy1 { + fn enumerate(self) -> Vec { + vec![] + } + } + let dummy = Dummy1; + for x in dummy.enumerate() { + println!("{x}"); + } + + struct Dummy2; + impl Dummy2 { + fn enumerate(self) -> Enumerate> { + vec![1, 2].into_iter().enumerate() + } + } + let dummy = Dummy2; + for (_, x) in dummy.enumerate() { + println!("{x}"); + } + + let mut with_used_iterator = [1, 2, 3].into_iter().enumerate(); + with_used_iterator.next(); + for (_, x) in with_used_iterator { + println!("{x}"); + } + + struct Dummy3(std::vec::IntoIter); + + impl Iterator for Dummy3 { + type Item = usize; + + fn next(&mut self) -> Option { + self.0.next() + } + + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } + } + + let dummy = Dummy3(vec![1, 2, 3].into_iter()); + for x in dummy { + println!("{x}"); + } +} diff --git a/tests/ui/unused_enumerate_index.rs b/tests/ui/unused_enumerate_index.rs new file mode 100644 index 000000000000..2d524da76327 --- /dev/null +++ b/tests/ui/unused_enumerate_index.rs @@ -0,0 +1,58 @@ +#![allow(unused)] +#![warn(clippy::unused_enumerate_index)] + +use std::iter::Enumerate; + +fn main() { + let v = [1, 2, 3]; + for (_, x) in v.iter().enumerate() { + println!("{x}"); + } + + struct Dummy1; + impl Dummy1 { + fn enumerate(self) -> Vec { + vec![] + } + } + let dummy = Dummy1; + for x in dummy.enumerate() { + println!("{x}"); + } + + struct Dummy2; + impl Dummy2 { + fn enumerate(self) -> Enumerate> { + vec![1, 2].into_iter().enumerate() + } + } + let dummy = Dummy2; + for (_, x) in dummy.enumerate() { + println!("{x}"); + } + + let mut with_used_iterator = [1, 2, 3].into_iter().enumerate(); + with_used_iterator.next(); + for (_, x) in with_used_iterator { + println!("{x}"); + } + + struct Dummy3(std::vec::IntoIter); + + impl Iterator for Dummy3 { + type Item = usize; + + fn next(&mut self) -> Option { + self.0.next() + } + + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } + } + + let dummy = Dummy3(vec![1, 2, 3].into_iter()); + for (_, x) in dummy.enumerate() { + println!("{x}"); + } +} diff --git a/tests/ui/unused_enumerate_index.stderr b/tests/ui/unused_enumerate_index.stderr new file mode 100644 index 000000000000..b575fbbc4e61 --- /dev/null +++ b/tests/ui/unused_enumerate_index.stderr @@ -0,0 +1,26 @@ +error: you seem to use `.enumerate()` and immediately discard the index + --> $DIR/unused_enumerate_index.rs:8:19 + | +LL | for (_, x) in v.iter().enumerate() { + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::unused-enumerate-index` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unused_enumerate_index)]` +help: remove the `.enumerate()` call + | +LL | for x in v.iter() { + | ~ ~~~~~~~~ + +error: you seem to use `.enumerate()` and immediately discard the index + --> $DIR/unused_enumerate_index.rs:55:19 + | +LL | for (_, x) in dummy.enumerate() { + | ^^^^^^^^^^^^^^^^^ + | +help: remove the `.enumerate()` call + | +LL | for x in dummy { + | ~ ~~~~~ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/useless_conversion_try.rs b/tests/ui/useless_conversion_try.rs index a5feefbe0f09..803d3b39f375 100644 --- a/tests/ui/useless_conversion_try.rs +++ b/tests/ui/useless_conversion_try.rs @@ -1,5 +1,5 @@ #![deny(clippy::useless_conversion)] -#![allow(clippy::needless_if)] +#![allow(clippy::needless_if, clippy::unnecessary_fallible_conversions)] fn test_generic(val: T) -> T { let _ = T::try_from(val).unwrap(); diff --git a/tests/ui/waker_clone_wake.fixed b/tests/ui/waker_clone_wake.fixed new file mode 100644 index 000000000000..9c02b9a90fdd --- /dev/null +++ b/tests/ui/waker_clone_wake.fixed @@ -0,0 +1,29 @@ +#[derive(Clone)] +pub struct Custom; + +impl Custom { + pub fn wake(self) {} +} + +macro_rules! mac { + ($cx:ident) => { + $cx.waker() + }; +} + +pub fn wake(cx: &mut std::task::Context) { + cx.waker().wake_by_ref(); + + mac!(cx).wake_by_ref(); +} + +pub fn no_lint(cx: &mut std::task::Context, c: &Custom) { + c.clone().wake(); + + let w = cx.waker().clone(); + w.wake(); + + cx.waker().clone().wake_by_ref(); +} + +fn main() {} diff --git a/tests/ui/waker_clone_wake.rs b/tests/ui/waker_clone_wake.rs new file mode 100644 index 000000000000..edc3bbd8fc08 --- /dev/null +++ b/tests/ui/waker_clone_wake.rs @@ -0,0 +1,29 @@ +#[derive(Clone)] +pub struct Custom; + +impl Custom { + pub fn wake(self) {} +} + +macro_rules! mac { + ($cx:ident) => { + $cx.waker() + }; +} + +pub fn wake(cx: &mut std::task::Context) { + cx.waker().clone().wake(); + + mac!(cx).clone().wake(); +} + +pub fn no_lint(cx: &mut std::task::Context, c: &Custom) { + c.clone().wake(); + + let w = cx.waker().clone(); + w.wake(); + + cx.waker().clone().wake_by_ref(); +} + +fn main() {} diff --git a/tests/ui/waker_clone_wake.stderr b/tests/ui/waker_clone_wake.stderr new file mode 100644 index 000000000000..f1abf4d9cb05 --- /dev/null +++ b/tests/ui/waker_clone_wake.stderr @@ -0,0 +1,17 @@ +error: cloning a `Waker` only to wake it + --> $DIR/waker_clone_wake.rs:15:5 + | +LL | cx.waker().clone().wake(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `cx.waker().wake_by_ref()` + | + = note: `-D clippy::waker-clone-wake` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::waker_clone_wake)]` + +error: cloning a `Waker` only to wake it + --> $DIR/waker_clone_wake.rs:17:5 + | +LL | mac!(cx).clone().wake(); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `mac!(cx).wake_by_ref()` + +error: aborting due to 2 previous errors + diff --git a/tests/versioncheck.rs b/tests/versioncheck.rs index c721e9969c9a..eba5405e67ed 100644 --- a/tests/versioncheck.rs +++ b/tests/versioncheck.rs @@ -26,6 +26,7 @@ fn consistent_clippy_crate_versions() { let paths = [ "declare_clippy_lint/Cargo.toml", + "clippy_config/Cargo.toml", "clippy_lints/Cargo.toml", "clippy_utils/Cargo.toml", ]; From 17c7d21650124f8c9ce8f2c0db9aa581ac20d09f Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 23 Oct 2023 18:55:04 +0200 Subject: [PATCH 04/10] Warn when lint level is set on a match arm --- tests/ui/match_same_arms_non_exhaustive.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/match_same_arms_non_exhaustive.rs b/tests/ui/match_same_arms_non_exhaustive.rs index e1b95aa57760..5c277f925a8f 100644 --- a/tests/ui/match_same_arms_non_exhaustive.rs +++ b/tests/ui/match_same_arms_non_exhaustive.rs @@ -9,12 +9,12 @@ fn repeat() -> ! { } pub fn f(x: Ordering) { + #[deny(non_exhaustive_omitted_patterns)] match x { Ordering::Relaxed => println!("relaxed"), Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), Ordering::AcqRel | Ordering::SeqCst => repeat(), - #[deny(non_exhaustive_omitted_patterns)] _ => repeat(), } } From 67cc4b0cadf1882fe174254c1dd7bfaba91c12a5 Mon Sep 17 00:00:00 2001 From: Dinu Blanovschi Date: Sat, 4 Nov 2023 21:43:18 +0100 Subject: [PATCH 05/10] fix clippy author and failing test --- clippy_lints/src/utils/author.rs | 9 +++++++-- tests/ui/author/blocks.stdout | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index ce93aea21360..152248afc903 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -7,7 +7,7 @@ use rustc_ast::LitIntType; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::{ - ArrayLen, BindingAnnotation, Closure, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind, + ArrayLen, BindingAnnotation, Closure, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind, CaptureBy }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::declare_lint_pass; @@ -479,6 +479,11 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { movability, .. }) => { + let capture_clause = match capture_clause { + CaptureBy::Value { .. } => "Value { .. }", + CaptureBy::Ref => "Ref", + }; + let movability = OptionPat::new(movability.map(|m| format!("Movability::{m:?}"))); let ret_ty = match fn_decl.output { @@ -487,7 +492,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }; bind!(self, fn_decl, body_id); - kind!("Closure(CaptureBy::{capture_clause:?}, {fn_decl}, {body_id}, _, {movability})"); + kind!("Closure(CaptureBy::{capture_clause}, {fn_decl}, {body_id}, _, {movability})"); chain!(self, "let {ret_ty} = {fn_decl}.output"); self.body(body_id); }, diff --git a/tests/ui/author/blocks.stdout b/tests/ui/author/blocks.stdout index eb3e5189c823..140300a16730 100644 --- a/tests/ui/author/blocks.stdout +++ b/tests/ui/author/blocks.stdout @@ -40,10 +40,10 @@ if let ExprKind::Block(block, None) = expr.kind { // report your lint here } -if let ExprKind::Closure(CaptureBy::Value, fn_decl, body_id, _, None) = expr.kind +if let ExprKind::Closure(CaptureBy::Value { .. }, fn_decl, body_id, _, None) = expr.kind && let FnRetTy::DefaultReturn(_) = fn_decl.output && expr1 = &cx.tcx.hir().body(body_id).value - && let ExprKind::Closure(CaptureBy::Value, fn_decl1, body_id1, _, Some(Movability::Static)) = expr1.kind + && let ExprKind::Closure(CaptureBy::Value { .. }, fn_decl1, body_id1, _, Some(Movability::Static)) = expr1.kind && let FnRetTy::DefaultReturn(_) = fn_decl1.output && expr2 = &cx.tcx.hir().body(body_id1).value && let ExprKind::Block(block, None) = expr2.kind From c4971f9f65b81bb61ab2d3a7ae89ecbc90b596de Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 13 Nov 2023 14:00:05 +0000 Subject: [PATCH 06/10] rename `ReLateBound` to `ReBound` other changes: - `Region::new_late_bound` -> `Region::new_bound` - `Region::is_late_bound` -> `Region::is_bound` --- clippy_lints/src/eta_reduction.rs | 4 ++-- clippy_lints/src/pass_by_ref_or_value.rs | 2 +- clippy_lints/src/ptr.rs | 2 +- clippy_utils/src/ty.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index fad8fbf04497..150b1c777db1 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -247,8 +247,8 @@ fn check_sig<'tcx>(cx: &LateContext<'tcx>, closure: ClosureArgs<'tcx>, call_sig: /// This is needed because rustc is unable to late bind early-bound regions in a function signature. fn has_late_bound_to_non_late_bound_regions(from_sig: FnSig<'_>, to_sig: FnSig<'_>) -> bool { fn check_region(from_region: Region<'_>, to_region: Region<'_>) -> bool { - matches!(from_region.kind(), RegionKind::ReLateBound(..)) - && !matches!(to_region.kind(), RegionKind::ReLateBound(..)) + matches!(from_region.kind(), RegionKind::ReBound(..)) + && !matches!(to_region.kind(), RegionKind::ReBound(..)) } fn check_subs(from_subs: &[GenericArg<'_>], to_subs: &[GenericArg<'_>]) -> bool { diff --git a/clippy_lints/src/pass_by_ref_or_value.rs b/clippy_lints/src/pass_by_ref_or_value.rs index 4d7a055dae17..d6fa742b7968 100644 --- a/clippy_lints/src/pass_by_ref_or_value.rs +++ b/clippy_lints/src/pass_by_ref_or_value.rs @@ -168,7 +168,7 @@ impl<'tcx> PassByRefOrValue { match *ty.skip_binder().kind() { ty::Ref(lt, ty, Mutability::Not) => { match lt.kind() { - RegionKind::ReLateBound(index, region) + RegionKind::ReBound(index, region) if index.as_u32() == 0 && output_regions.contains(®ion) => { continue; diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 83863b92caff..c6ac96a4539c 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -466,7 +466,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>( .filter_map(|arg| { arg.as_region().and_then(|lifetime| match lifetime.kind() { ty::ReEarlyBound(r) => Some(r.def_id), - ty::ReLateBound(_, r) => r.kind.get_id(), + ty::ReBound(_, r) => r.kind.get_id(), ty::ReFree(r) => r.bound_region.get_id(), ty::ReStatic | ty::ReVar(_) diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 7eff93881b26..758aa40a2dd1 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -890,7 +890,7 @@ pub fn for_each_top_level_late_bound_region( impl<'tcx, B, F: FnMut(BoundRegion) -> ControlFlow> TypeVisitor> for V { type BreakTy = B; fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow { - if let RegionKind::ReLateBound(idx, bound) = r.kind() + if let RegionKind::ReBound(idx, bound) = r.kind() && idx.as_u32() == self.index { (self.f)(bound) From 9ab054d71499dc20ca25718c452d1814e4b7cd56 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 13 Nov 2023 14:12:56 +0000 Subject: [PATCH 07/10] update type flags - `HAS_RE_LATE_BOUND` -> `HAS_RE_BOUND` - `HAS_TY_LATE_BOUND` -> `HAS_TY_BOUND` - `HAS_CT_LATE_BOUND` -> `HAS_CT_BOUND` - `HAS_LATE_BOUND` -> `HAS_BOUND_VARS` - `fn has_late_bound_regions` -> `fn has_bound_regions` - `fnhas_non_region_late_bound` -> `fn has_non_region_bound_vars` - `fn has_late_bound_vars` -> `fn has_bound_vars` --- clippy_lints/src/eta_reduction.rs | 2 +- clippy_utils/src/ty.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 150b1c777db1..02c53fafd696 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -290,7 +290,7 @@ fn has_late_bound_to_non_late_bound_regions(from_sig: FnSig<'_>, to_sig: FnSig<' .zip(to_tys) .any(|(from_ty, to_ty)| check_ty(from_ty, to_ty)) }, - _ => from_ty.has_late_bound_regions(), + _ => from_ty.has_bound_regions(), } } diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 758aa40a2dd1..2ff979f2dcb3 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -1160,7 +1160,7 @@ pub fn make_normalized_projection<'tcx>( ) -> Option> { fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option> { #[cfg(debug_assertions)] - if let Some((i, arg)) = ty.args.iter().enumerate().find(|(_, arg)| arg.has_late_bound_regions()) { + if let Some((i, arg)) = ty.args.iter().enumerate().find(|(_, arg)| arg.has_bound_regions()) { debug_assert!( false, "args contain late-bound region at index `{i}` which can't be normalized.\n\ @@ -1233,7 +1233,7 @@ pub fn make_normalized_projection_with_regions<'tcx>( ) -> Option> { fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option> { #[cfg(debug_assertions)] - if let Some((i, arg)) = ty.args.iter().enumerate().find(|(_, arg)| arg.has_late_bound_regions()) { + if let Some((i, arg)) = ty.args.iter().enumerate().find(|(_, arg)| arg.has_bound_regions()) { debug_assert!( false, "args contain late-bound region at index `{i}` which can't be normalized.\n\ From 9aa2330e41b9d6e25fb357b54f5ae98448543752 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 14 Nov 2023 13:13:27 +0000 Subject: [PATCH 08/10] finish `RegionKind` rename - `ReFree` -> `ReLateParam` - `ReEarlyBound` -> `ReEarlyParam` --- clippy_lints/src/pass_by_ref_or_value.rs | 2 +- clippy_lints/src/ptr.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/pass_by_ref_or_value.rs b/clippy_lints/src/pass_by_ref_or_value.rs index d6fa742b7968..4db65b0d04fe 100644 --- a/clippy_lints/src/pass_by_ref_or_value.rs +++ b/clippy_lints/src/pass_by_ref_or_value.rs @@ -175,7 +175,7 @@ impl<'tcx> PassByRefOrValue { }, // Early bound regions on functions are either from the containing item, are bounded by another // lifetime, or are used as a bound for a type or lifetime. - RegionKind::ReEarlyBound(..) => continue, + RegionKind::ReEarlyParam(..) => continue, _ => (), } diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index c6ac96a4539c..1d4b4d10d501 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -465,9 +465,9 @@ fn check_fn_args<'cx, 'tcx: 'cx>( .walk() .filter_map(|arg| { arg.as_region().and_then(|lifetime| match lifetime.kind() { - ty::ReEarlyBound(r) => Some(r.def_id), + ty::ReEarlyParam(r) => Some(r.def_id), ty::ReBound(_, r) => r.kind.get_id(), - ty::ReFree(r) => r.bound_region.get_id(), + ty::ReLateParam(r) => r.bound_region.get_id(), ty::ReStatic | ty::ReVar(_) | ty::RePlaceholder(_) From 887f5a5bb469033b925de7732f43587a2b4051de Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 16 Nov 2023 19:02:15 +0100 Subject: [PATCH 09/10] Bump nightly version -> 2023-11-16 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 293fcbf39928..d40e176b4b0a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-11-02" +channel = "nightly-2023-11-16" components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] From 6f952fbe5384d31734eb1f8219aa531a3e0d2ebd Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 16 Nov 2023 19:02:33 +0100 Subject: [PATCH 10/10] Bump Clippy version -> 0.1.76 --- Cargo.toml | 2 +- clippy_config/Cargo.toml | 2 +- clippy_lints/Cargo.toml | 2 +- clippy_utils/Cargo.toml | 2 +- declare_clippy_lint/Cargo.toml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4b6688a76b46..3b138b480b6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.75" +version = "0.1.76" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml index 2d41087b51d1..20f313201276 100644 --- a/clippy_config/Cargo.toml +++ b/clippy_config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_config" -version = "0.1.75" +version = "0.1.76" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index a41166036884..84246d285c09 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_lints" -version = "0.1.75" +version = "0.1.76" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index 1f9802dc5eec..d7053d3ff848 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_utils" -version = "0.1.75" +version = "0.1.76" edition = "2021" publish = false diff --git a/declare_clippy_lint/Cargo.toml b/declare_clippy_lint/Cargo.toml index beea9fd00e7a..8c1150ed0104 100644 --- a/declare_clippy_lint/Cargo.toml +++ b/declare_clippy_lint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "declare_clippy_lint" -version = "0.1.75" +version = "0.1.76" edition = "2021" publish = false