mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-23 05:03:21 +00:00
Add clippy_utils::msrv::Msrv
to keep track of the current MSRV
This commit is contained in:
parent
51ec465cc3
commit
637139d2ff
56 changed files with 466 additions and 433 deletions
|
@ -443,22 +443,22 @@ value is passed to the constructor in `clippy_lints/lib.rs`.
|
|||
|
||||
```rust
|
||||
pub struct ManualStrip {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl ManualStrip {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The project's MSRV can then be matched against the feature MSRV in the LintPass
|
||||
using the `meets_msrv` utility function.
|
||||
using the `Msrv::meets` method.
|
||||
|
||||
``` rust
|
||||
if !meets_msrv(self.msrv, msrvs::STR_STRIP_PREFIX) {
|
||||
if !self.msrv.meets(msrvs::STR_STRIP_PREFIX) {
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
|
|
@ -120,7 +120,7 @@ fn add_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {
|
|||
|
||||
let new_lint = if enable_msrv {
|
||||
format!(
|
||||
"store.register_{lint_pass}_pass(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(msrv)));\n ",
|
||||
"store.register_{lint_pass}_pass(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(msrv())));\n ",
|
||||
lint_pass = lint.pass,
|
||||
ctor_arg = if lint.pass == "late" { "_" } else { "" },
|
||||
module_name = lint.name,
|
||||
|
@ -238,10 +238,9 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
|
|||
result.push_str(&if enable_msrv {
|
||||
formatdoc!(
|
||||
r#"
|
||||
use clippy_utils::msrvs;
|
||||
use clippy_utils::msrvs::{{self, Msrv}};
|
||||
{pass_import}
|
||||
use rustc_lint::{{{context_import}, {pass_type}, LintContext}};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{{declare_tool_lint, impl_lint_pass}};
|
||||
|
||||
"#
|
||||
|
@ -263,12 +262,12 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
|
|||
formatdoc!(
|
||||
r#"
|
||||
pub struct {name_camel} {{
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}}
|
||||
|
||||
impl {name_camel} {{
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {{
|
||||
pub fn new(msrv: Msrv) -> Self {{
|
||||
Self {{ msrv }}
|
||||
}}
|
||||
}}
|
||||
|
@ -357,15 +356,14 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R
|
|||
let _ = writedoc!(
|
||||
lint_file_contents,
|
||||
r#"
|
||||
use clippy_utils::{{meets_msrv, msrvs}};
|
||||
use clippy_utils::msrvs::{{self, Msrv}};
|
||||
use rustc_lint::{{{context_import}, LintContext}};
|
||||
use rustc_semver::RustcVersion;
|
||||
|
||||
use super::{name_upper};
|
||||
|
||||
// TODO: Adjust the parameters as necessary
|
||||
pub(super) fn check(cx: &{context_import}, msrv: Option<RustcVersion>) {{
|
||||
if !meets_msrv(msrv, todo!("Add a new entry in `clippy_utils/src/msrvs`")) {{
|
||||
pub(super) fn check(cx: &{context_import}, msrv: &Msrv) {{
|
||||
if !msrv.meets(todo!("Add a new entry in `clippy_utils/src/msrvs`")) {{
|
||||
return;
|
||||
}}
|
||||
todo!();
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
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 clippy_utils::{meets_msrv, msrvs};
|
||||
use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::Span;
|
||||
|
||||
|
@ -33,10 +32,10 @@ declare_clippy_lint! {
|
|||
impl_lint_pass!(AlmostCompleteLetterRange => [ALMOST_COMPLETE_LETTER_RANGE]);
|
||||
|
||||
pub struct AlmostCompleteLetterRange {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
impl AlmostCompleteLetterRange {
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +45,7 @@ impl EarlyLintPass for AlmostCompleteLetterRange {
|
|||
let ctxt = e.span.ctxt();
|
||||
let sugg = if let Some(start) = walk_span_to_context(start.span, ctxt)
|
||||
&& let Some(end) = walk_span_to_context(end.span, ctxt)
|
||||
&& meets_msrv(self.msrv, msrvs::RANGE_INCLUSIVE)
|
||||
&& self.msrv.meets(msrvs::RANGE_INCLUSIVE)
|
||||
{
|
||||
Some((trim_span(cx.sess().source_map(), start.between(end)), "..="))
|
||||
} else {
|
||||
|
@ -60,7 +59,7 @@ impl EarlyLintPass for AlmostCompleteLetterRange {
|
|||
if let PatKind::Range(Some(start), Some(end), kind) = &p.kind
|
||||
&& matches!(kind.node, RangeEnd::Excluded)
|
||||
{
|
||||
let sugg = if meets_msrv(self.msrv, msrvs::RANGE_INCLUSIVE) {
|
||||
let sugg = if self.msrv.meets(msrvs::RANGE_INCLUSIVE) {
|
||||
"..="
|
||||
} else {
|
||||
"..."
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
@ -63,12 +63,12 @@ const KNOWN_CONSTS: [(f64, &str, usize, Option<RustcVersion>); 19] = [
|
|||
];
|
||||
|
||||
pub struct ApproxConstant {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl ApproxConstant {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ impl ApproxConstant {
|
|||
let s = s.as_str();
|
||||
if s.parse::<f64>().is_ok() {
|
||||
for &(constant, name, min_digits, msrv) in &KNOWN_CONSTS {
|
||||
if is_approx_const(constant, s, min_digits) && msrv.map_or(true, |msrv| meets_msrv(self.msrv, msrv)) {
|
||||
if is_approx_const(constant, s, min_digits) && msrv.map_or(true, |msrv| self.msrv.meets(msrv)) {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
APPROX_CONSTANT,
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
|
||||
use clippy_utils::macros::{is_panic, macro_backtrace};
|
||||
use clippy_utils::msrvs;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
|
||||
use clippy_utils::{extract_msrv_attr, meets_msrv};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
|
||||
use rustc_errors::Applicability;
|
||||
|
@ -14,7 +13,6 @@ use rustc_hir::{
|
|||
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::source_map::Span;
|
||||
use rustc_span::symbol::Symbol;
|
||||
|
@ -599,7 +597,7 @@ fn is_word(nmi: &NestedMetaItem, expected: Symbol) -> bool {
|
|||
}
|
||||
|
||||
pub struct EarlyAttributes {
|
||||
pub msrv: Option<RustcVersion>,
|
||||
pub msrv: Msrv,
|
||||
}
|
||||
|
||||
impl_lint_pass!(EarlyAttributes => [
|
||||
|
@ -614,7 +612,7 @@ impl EarlyLintPass for EarlyAttributes {
|
|||
}
|
||||
|
||||
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
|
||||
check_deprecated_cfg_attr(cx, attr, self.msrv);
|
||||
check_deprecated_cfg_attr(cx, attr, &self.msrv);
|
||||
check_mismatched_target_os(cx, attr);
|
||||
}
|
||||
|
||||
|
@ -654,9 +652,9 @@ fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::It
|
|||
}
|
||||
}
|
||||
|
||||
fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute, msrv: Option<RustcVersion>) {
|
||||
fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &Msrv) {
|
||||
if_chain! {
|
||||
if meets_msrv(msrv, msrvs::TOOL_ATTRIBUTES);
|
||||
if msrv.meets(msrvs::TOOL_ATTRIBUTES);
|
||||
// check cfg_attr
|
||||
if attr.has_name(sym::cfg_attr);
|
||||
if let Some(items) = attr.meta_item_list();
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_semver::RustcVersion;
|
||||
|
||||
use super::CAST_ABS_TO_UNSIGNED;
|
||||
|
||||
|
@ -15,9 +14,9 @@ pub(super) fn check(
|
|||
cast_expr: &Expr<'_>,
|
||||
cast_from: Ty<'_>,
|
||||
cast_to: Ty<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) {
|
||||
if meets_msrv(msrv, msrvs::UNSIGNED_ABS)
|
||||
if msrv.meets(msrvs::UNSIGNED_ABS)
|
||||
&& let ty::Int(from) = cast_from.kind()
|
||||
&& let ty::Uint(to) = cast_to.kind()
|
||||
&& let ExprKind::MethodCall(method_path, receiver, ..) = cast_expr.kind
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
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 clippy_utils::{in_constant, meets_msrv, msrvs};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{self, FloatTy, Ty};
|
||||
use rustc_semver::RustcVersion;
|
||||
|
||||
use super::{utils, CAST_LOSSLESS};
|
||||
|
||||
|
@ -16,7 +16,7 @@ pub(super) fn check(
|
|||
cast_op: &Expr<'_>,
|
||||
cast_from: Ty<'_>,
|
||||
cast_to: Ty<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) {
|
||||
if !should_lint(cx, expr, cast_from, cast_to, msrv) {
|
||||
return;
|
||||
|
@ -57,13 +57,7 @@ pub(super) fn check(
|
|||
);
|
||||
}
|
||||
|
||||
fn should_lint(
|
||||
cx: &LateContext<'_>,
|
||||
expr: &Expr<'_>,
|
||||
cast_from: Ty<'_>,
|
||||
cast_to: Ty<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
) -> bool {
|
||||
fn should_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>, msrv: &Msrv) -> bool {
|
||||
// Do not suggest using From in consts/statics until it is valid to do so (see #2267).
|
||||
if in_constant(cx, expr.hir_id) {
|
||||
return false;
|
||||
|
@ -89,7 +83,7 @@ fn should_lint(
|
|||
};
|
||||
!is_isize_or_usize(cast_from) && from_nbits < to_nbits
|
||||
},
|
||||
(false, true) if matches!(cast_from.kind(), ty::Bool) && meets_msrv(msrv, msrvs::FROM_BOOL) => true,
|
||||
(false, true) if matches!(cast_from.kind(), ty::Bool) && msrv.meets(msrvs::FROM_BOOL) => true,
|
||||
(_, _) => {
|
||||
matches!(cast_from.kind(), ty::Float(FloatTy::F32)) && matches!(cast_to.kind(), ty::Float(FloatTy::F64))
|
||||
},
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use clippy_utils::{diagnostics::span_lint_and_then, meets_msrv, msrvs, source};
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::{diagnostics::span_lint_and_then, source};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_hir::{Expr, ExprKind, Node};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{self, layout::LayoutOf, Ty, TypeAndMut};
|
||||
use rustc_semver::RustcVersion;
|
||||
|
||||
use super::CAST_SLICE_DIFFERENT_SIZES;
|
||||
|
||||
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: Option<RustcVersion>) {
|
||||
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv) {
|
||||
// suggestion is invalid if `ptr::slice_from_raw_parts` does not exist
|
||||
if !meets_msrv(msrv, msrvs::PTR_SLICE_RAW_PARTS) {
|
||||
if !msrv.meets(msrvs::PTR_SLICE_RAW_PARTS) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::{match_def_path, meets_msrv, msrvs, paths};
|
||||
use clippy_utils::{match_def_path, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{def_id::DefId, Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_semver::RustcVersion;
|
||||
|
||||
use super::CAST_SLICE_FROM_RAW_PARTS;
|
||||
|
||||
|
@ -25,15 +25,9 @@ fn raw_parts_kind(cx: &LateContext<'_>, did: DefId) -> Option<RawPartsKind> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn check(
|
||||
cx: &LateContext<'_>,
|
||||
expr: &Expr<'_>,
|
||||
cast_expr: &Expr<'_>,
|
||||
cast_to: Ty<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
) {
|
||||
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>, msrv: &Msrv) {
|
||||
if_chain! {
|
||||
if meets_msrv(msrv, msrvs::PTR_SLICE_RAW_PARTS);
|
||||
if msrv.meets(msrvs::PTR_SLICE_RAW_PARTS);
|
||||
if let ty::RawPtr(ptrty) = cast_to.kind();
|
||||
if let ty::Slice(_) = ptrty.ty.kind();
|
||||
if let ExprKind::Call(fun, [ptr_arg, len_arg]) = cast_expr.peel_blocks().kind;
|
||||
|
|
|
@ -21,11 +21,11 @@ mod ptr_as_ptr;
|
|||
mod unnecessary_cast;
|
||||
mod utils;
|
||||
|
||||
use clippy_utils::{is_hir_ty_cfg_dependant, meets_msrv, msrvs};
|
||||
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;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -648,12 +648,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct Casts {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl Casts {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -686,7 +686,7 @@ impl_lint_pass!(Casts => [
|
|||
impl<'tcx> LateLintPass<'tcx> for Casts {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if !in_external_macro(cx.sess(), expr.span) {
|
||||
ptr_as_ptr::check(cx, expr, self.msrv);
|
||||
ptr_as_ptr::check(cx, expr, &self.msrv);
|
||||
}
|
||||
|
||||
if expr.span.from_expansion() {
|
||||
|
@ -705,7 +705,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
|
|||
if unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) {
|
||||
return;
|
||||
}
|
||||
cast_slice_from_raw_parts::check(cx, expr, cast_expr, cast_to, self.msrv);
|
||||
cast_slice_from_raw_parts::check(cx, expr, cast_expr, cast_to, &self.msrv);
|
||||
as_ptr_cast_mut::check(cx, expr, cast_expr, cast_to);
|
||||
fn_to_numeric_cast_any::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||
fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||
|
@ -717,16 +717,16 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
|
|||
cast_possible_wrap::check(cx, expr, cast_from, cast_to);
|
||||
cast_precision_loss::check(cx, expr, cast_from, cast_to);
|
||||
cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||
cast_abs_to_unsigned::check(cx, expr, cast_expr, cast_from, cast_to, self.msrv);
|
||||
cast_abs_to_unsigned::check(cx, expr, cast_expr, cast_from, cast_to, &self.msrv);
|
||||
cast_nan_to_int::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||
}
|
||||
cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to, self.msrv);
|
||||
cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to, &self.msrv);
|
||||
cast_enum_constructor::check(cx, expr, cast_expr, cast_from);
|
||||
}
|
||||
|
||||
as_underscore::check(cx, expr, cast_to_hir);
|
||||
|
||||
if meets_msrv(self.msrv, msrvs::BORROW_AS_PTR) {
|
||||
if self.msrv.meets(msrvs::BORROW_AS_PTR) {
|
||||
borrow_as_ptr::check(cx, expr, cast_expr, cast_to_hir);
|
||||
}
|
||||
}
|
||||
|
@ -734,8 +734,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
|
|||
cast_ref_to_mut::check(cx, expr);
|
||||
cast_ptr_alignment::check(cx, expr);
|
||||
char_lit_as_u8::check(cx, expr);
|
||||
ptr_as_ptr::check(cx, expr, self.msrv);
|
||||
cast_slice_different_sizes::check(cx, expr, self.msrv);
|
||||
ptr_as_ptr::check(cx, expr, &self.msrv);
|
||||
cast_slice_different_sizes::check(cx, expr, &self.msrv);
|
||||
}
|
||||
|
||||
extract_msrv_attr!(LateContext);
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, Mutability, TyKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{self, TypeAndMut};
|
||||
use rustc_semver::RustcVersion;
|
||||
|
||||
use super::PTR_AS_PTR;
|
||||
|
||||
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Option<RustcVersion>) {
|
||||
if !meets_msrv(msrv, msrvs::POINTER_CAST) {
|
||||
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
|
||||
if !msrv.meets(msrvs::POINTER_CAST) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
//! lint on manually implemented checked conversions that could be transformed into `try_from`
|
||||
|
||||
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, meets_msrv, msrvs, SpanlessEq};
|
||||
use clippy_utils::{in_constant, is_integer_literal, SpanlessEq};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind, QPath, TyKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -37,12 +37,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct CheckedConversions {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl CheckedConversions {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ impl_lint_pass!(CheckedConversions => [CHECKED_CONVERSIONS]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for CheckedConversions {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {
|
||||
if !meets_msrv(self.msrv, msrvs::TRY_FROM) {
|
||||
if !self.msrv.meets(msrvs::TRY_FROM) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_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_applicability, snippet_with_context};
|
||||
use clippy_utils::sugg::has_enclosing_paren;
|
||||
use clippy_utils::ty::{expr_sig, is_copy, peel_mid_ty_refs, ty_sig, variant_of_res};
|
||||
use clippy_utils::{
|
||||
fn_def_id, get_parent_expr, get_parent_expr_for_hir, is_lint_allowed, meets_msrv, msrvs, path_to_local,
|
||||
walk_to_expr_usage,
|
||||
fn_def_id, get_parent_expr, get_parent_expr_for_hir, is_lint_allowed, path_to_local, walk_to_expr_usage,
|
||||
};
|
||||
|
||||
use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX};
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::graph::iterate::{CycleDetector, TriColorDepthFirstSearch};
|
||||
|
@ -28,7 +29,6 @@ use rustc_middle::ty::{
|
|||
self, Binder, BoundVariableKind, EarlyBinder, FnSig, GenericArgKind, List, ParamTy, PredicateKind,
|
||||
ProjectionPredicate, Ty, TyCtxt, TypeVisitable, TypeckResults,
|
||||
};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
|
||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||
|
@ -181,12 +181,12 @@ pub struct Dereferencing<'tcx> {
|
|||
possible_borrowers: Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
|
||||
|
||||
// `IntoIterator` for arrays requires Rust 1.53.
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl<'tcx> Dereferencing<'tcx> {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self {
|
||||
msrv,
|
||||
..Dereferencing::default()
|
||||
|
@ -286,7 +286,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
|
|||
match (self.state.take(), kind) {
|
||||
(None, kind) => {
|
||||
let expr_ty = typeck.expr_ty(expr);
|
||||
let (position, adjustments) = walk_parents(cx, &mut self.possible_borrowers, expr, self.msrv);
|
||||
let (position, adjustments) = walk_parents(cx, &mut self.possible_borrowers, expr, &self.msrv);
|
||||
match kind {
|
||||
RefOp::Deref => {
|
||||
if let Position::FieldAccess {
|
||||
|
@ -698,7 +698,7 @@ fn walk_parents<'tcx>(
|
|||
cx: &LateContext<'tcx>,
|
||||
possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
|
||||
e: &'tcx Expr<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) -> (Position, &'tcx [Adjustment<'tcx>]) {
|
||||
let mut adjustments = [].as_slice();
|
||||
let mut precedence = 0i8;
|
||||
|
@ -1082,7 +1082,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
|
|||
param_ty: ParamTy,
|
||||
mut expr: &Expr<'tcx>,
|
||||
precedence: i8,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) -> Position {
|
||||
let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
|
||||
let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
|
||||
|
@ -1182,7 +1182,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
|
|||
&& let ty::Param(param_ty) = trait_predicate.self_ty().kind()
|
||||
&& let GenericArgKind::Type(ty) = substs_with_referent_ty[param_ty.index as usize].unpack()
|
||||
&& ty.is_array()
|
||||
&& !meets_msrv(msrv, msrvs::ARRAY_INTO_ITERATOR)
|
||||
&& !msrv.meets(msrvs::ARRAY_INTO_ITERATOR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
||||
use clippy_utils::is_diag_trait_item;
|
||||
use clippy_utils::macros::FormatParamKind::{Implicit, Named, Numbered, Starred};
|
||||
use clippy_utils::macros::{
|
||||
is_format_macro, is_panic, root_macro_call, Count, FormatArg, FormatArgsExpn, FormatParam, FormatParamUsage,
|
||||
};
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||
use clippy_utils::{is_diag_trait_item, meets_msrv, msrvs};
|
||||
use if_chain::if_chain;
|
||||
use itertools::Itertools;
|
||||
use rustc_errors::Applicability;
|
||||
|
@ -13,7 +14,6 @@ use rustc_hir::{Expr, ExprKind, HirId, QPath};
|
|||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::edition::Edition::Edition2021;
|
||||
|
@ -158,12 +158,12 @@ impl_lint_pass!(FormatArgs => [
|
|||
]);
|
||||
|
||||
pub struct FormatArgs {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl FormatArgs {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
|
|||
check_format_in_format_args(cx, outermost_expn_data.call_site, name, arg.param.value);
|
||||
check_to_string_in_format_args(cx, name, arg.param.value);
|
||||
}
|
||||
if meets_msrv(self.msrv, msrvs::FORMAT_ARGS_CAPTURE) {
|
||||
if self.msrv.meets(msrvs::FORMAT_ARGS_CAPTURE) {
|
||||
check_uninlined_args(cx, &format_args, outermost_expn_data.call_site, macro_def_id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
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 clippy_utils::{meets_msrv, msrvs, path_def_id};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{walk_path, Visitor};
|
||||
use rustc_hir::{
|
||||
|
@ -10,7 +11,6 @@ use rustc_hir::{
|
|||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter::OnlyBodies;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
@ -49,12 +49,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct FromOverInto {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl FromOverInto {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
FromOverInto { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ impl_lint_pass!(FromOverInto => [FROM_OVER_INTO]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for FromOverInto {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
if !meets_msrv(self.msrv, msrvs::RE_REBALANCING_COHERENCE) || !span_is_local(item.span) {
|
||||
if !self.msrv.meets(msrvs::RE_REBALANCING_COHERENCE) || !span_is_local(item.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
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_macro_callsite;
|
||||
use clippy_utils::{
|
||||
contains_return, higher, is_else_clause, is_res_lang_ctor, meets_msrv, msrvs, path_res, peel_blocks,
|
||||
};
|
||||
use clippy_utils::{contains_return, higher, is_else_clause, is_res_lang_ctor, path_res, peel_blocks};
|
||||
use rustc_hir::LangItem::{OptionNone, OptionSome};
|
||||
use rustc_hir::{Expr, ExprKind, Stmt, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -47,12 +45,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct IfThenSomeElseNone {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl IfThenSomeElseNone {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +59,7 @@ impl_lint_pass!(IfThenSomeElseNone => [IF_THEN_SOME_ELSE_NONE]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
if !meets_msrv(self.msrv, msrvs::BOOL_THEN) {
|
||||
if !self.msrv.meets(msrvs::BOOL_THEN) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -94,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
|
|||
} else {
|
||||
format!("{{ /* snippet */ {arg_snip} }}")
|
||||
};
|
||||
let method_name = if switch_to_eager_eval(cx, expr) && meets_msrv(self.msrv, msrvs::BOOL_THEN_SOME) {
|
||||
let method_name = if switch_to_eager_eval(cx, expr) && self.msrv.meets(msrvs::BOOL_THEN_SOME) {
|
||||
"then_some"
|
||||
} else {
|
||||
method_body.insert_str(0, "|| ");
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
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, meets_msrv, msrvs, path_to_local};
|
||||
use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local};
|
||||
use if_chain::if_chain;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
|
||||
use rustc_errors::Applicability;
|
||||
|
@ -11,7 +12,6 @@ use rustc_hir::intravisit::{self, Visitor};
|
|||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{symbol::Ident, Span};
|
||||
|
||||
|
@ -51,14 +51,13 @@ declare_clippy_lint! {
|
|||
"avoid indexing on slices which could be destructed"
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct IndexRefutableSlice {
|
||||
max_suggested_slice: u64,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl IndexRefutableSlice {
|
||||
pub fn new(max_suggested_slice_pattern_length: u64, msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(max_suggested_slice_pattern_length: u64, msrv: Msrv) -> Self {
|
||||
Self {
|
||||
max_suggested_slice: max_suggested_slice_pattern_length,
|
||||
msrv,
|
||||
|
@ -74,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexRefutableSlice {
|
|||
if !expr.span.from_expansion() || is_expn_of(expr.span, "if_chain").is_some();
|
||||
if let Some(IfLet {let_pat, if_then, ..}) = IfLet::hir(cx, expr);
|
||||
if !is_lint_allowed(cx, INDEX_REFUTABLE_SLICE, expr.hir_id);
|
||||
if meets_msrv(self.msrv, msrvs::SLICE_PATTERNS);
|
||||
if self.msrv.meets(msrvs::SLICE_PATTERNS);
|
||||
|
||||
let found_slices = find_slice_values(cx, let_pat);
|
||||
if !found_slices.is_empty();
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
use clippy_utils::{
|
||||
diagnostics::{self, span_lint_and_sugg},
|
||||
meets_msrv, msrvs, source,
|
||||
sugg::Sugg,
|
||||
ty,
|
||||
};
|
||||
use clippy_utils::diagnostics::{self, span_lint_and_sugg};
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::source;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{source_map::Spanned, sym};
|
||||
|
||||
|
@ -68,12 +66,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct InstantSubtraction {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl InstantSubtraction {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +99,7 @@ impl LateLintPass<'_> for InstantSubtraction {
|
|||
} else {
|
||||
if_chain! {
|
||||
if !expr.span.from_expansion();
|
||||
if meets_msrv(self.msrv, msrvs::TRY_FROM);
|
||||
if self.msrv.meets(msrvs::TRY_FROM);
|
||||
|
||||
if is_an_instant(cx, lhs);
|
||||
if is_a_duration(cx, rhs);
|
||||
|
|
|
@ -52,10 +52,9 @@ extern crate declare_clippy_lint;
|
|||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clippy_utils::parse_msrv;
|
||||
use clippy_utils::msrvs::Msrv;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_lint::{Lint, LintId};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::Session;
|
||||
|
||||
#[cfg(feature = "internal")]
|
||||
|
@ -322,48 +321,10 @@ pub use crate::utils::conf::{lookup_conf_file, Conf};
|
|||
/// Used in `./src/driver.rs`.
|
||||
pub fn register_pre_expansion_lints(store: &mut rustc_lint::LintStore, sess: &Session, conf: &Conf) {
|
||||
// NOTE: Do not add any more pre-expansion passes. These should be removed eventually.
|
||||
let msrv = Msrv::read(&conf.msrv, sess);
|
||||
let msrv = move || msrv.clone();
|
||||
|
||||
let msrv = conf.msrv.as_ref().and_then(|s| {
|
||||
parse_msrv(s, None, None).or_else(|| {
|
||||
sess.err(format!(
|
||||
"error reading Clippy's configuration file. `{s}` is not a valid Rust version"
|
||||
));
|
||||
None
|
||||
})
|
||||
});
|
||||
|
||||
store.register_pre_expansion_pass(move || Box::new(attrs::EarlyAttributes { msrv }));
|
||||
}
|
||||
|
||||
fn read_msrv(conf: &Conf, sess: &Session) -> Option<RustcVersion> {
|
||||
let cargo_msrv = std::env::var("CARGO_PKG_RUST_VERSION")
|
||||
.ok()
|
||||
.and_then(|v| parse_msrv(&v, None, None));
|
||||
let clippy_msrv = conf.msrv.as_ref().and_then(|s| {
|
||||
parse_msrv(s, None, None).or_else(|| {
|
||||
sess.err(format!(
|
||||
"error reading Clippy's configuration file. `{s}` is not a valid Rust version"
|
||||
));
|
||||
None
|
||||
})
|
||||
});
|
||||
|
||||
if let Some(cargo_msrv) = cargo_msrv {
|
||||
if let Some(clippy_msrv) = clippy_msrv {
|
||||
// if both files have an msrv, let's compare them and emit a warning if they differ
|
||||
if clippy_msrv != cargo_msrv {
|
||||
sess.warn(format!(
|
||||
"the MSRV in `clippy.toml` and `Cargo.toml` differ; using `{clippy_msrv}` from `clippy.toml`"
|
||||
));
|
||||
}
|
||||
|
||||
Some(clippy_msrv)
|
||||
} else {
|
||||
Some(cargo_msrv)
|
||||
}
|
||||
} else {
|
||||
clippy_msrv
|
||||
}
|
||||
store.register_pre_expansion_pass(move || Box::new(attrs::EarlyAttributes { msrv: msrv() }));
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
@ -595,43 +556,44 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
store.register_late_pass(|_| Box::new(non_octal_unix_permissions::NonOctalUnixPermissions));
|
||||
store.register_early_pass(|| Box::new(unnecessary_self_imports::UnnecessarySelfImports));
|
||||
|
||||
let msrv = read_msrv(conf, sess);
|
||||
let msrv = Msrv::read(&conf.msrv, sess);
|
||||
let msrv = move || msrv.clone();
|
||||
let avoid_breaking_exported_api = conf.avoid_breaking_exported_api;
|
||||
let allow_expect_in_tests = conf.allow_expect_in_tests;
|
||||
let allow_unwrap_in_tests = conf.allow_unwrap_in_tests;
|
||||
store.register_late_pass(move |_| Box::new(approx_const::ApproxConstant::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(approx_const::ApproxConstant::new(msrv())));
|
||||
store.register_late_pass(move |_| {
|
||||
Box::new(methods::Methods::new(
|
||||
avoid_breaking_exported_api,
|
||||
msrv,
|
||||
msrv(),
|
||||
allow_expect_in_tests,
|
||||
allow_unwrap_in_tests,
|
||||
))
|
||||
});
|
||||
store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv())));
|
||||
let matches_for_let_else = conf.matches_for_let_else;
|
||||
store.register_late_pass(move |_| Box::new(manual_let_else::ManualLetElse::new(msrv, matches_for_let_else)));
|
||||
store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(manual_strip::ManualStrip::new(msrv)));
|
||||
store.register_early_pass(move || Box::new(redundant_static_lifetimes::RedundantStaticLifetimes::new(msrv)));
|
||||
store.register_early_pass(move || Box::new(redundant_field_names::RedundantFieldNames::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(checked_conversions::CheckedConversions::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(mem_replace::MemReplace::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(ranges::Ranges::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(from_over_into::FromOverInto::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(use_self::UseSelf::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(missing_const_for_fn::MissingConstForFn::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(manual_let_else::ManualLetElse::new(msrv(), matches_for_let_else)));
|
||||
store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv())));
|
||||
store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv())));
|
||||
store.register_late_pass(move |_| Box::new(manual_strip::ManualStrip::new(msrv())));
|
||||
store.register_early_pass(move || Box::new(redundant_static_lifetimes::RedundantStaticLifetimes::new(msrv())));
|
||||
store.register_early_pass(move || Box::new(redundant_field_names::RedundantFieldNames::new(msrv())));
|
||||
store.register_late_pass(move |_| Box::new(checked_conversions::CheckedConversions::new(msrv())));
|
||||
store.register_late_pass(move |_| Box::new(mem_replace::MemReplace::new(msrv())));
|
||||
store.register_late_pass(move |_| Box::new(ranges::Ranges::new(msrv())));
|
||||
store.register_late_pass(move |_| Box::new(from_over_into::FromOverInto::new(msrv())));
|
||||
store.register_late_pass(move |_| Box::new(use_self::UseSelf::new(msrv())));
|
||||
store.register_late_pass(move |_| Box::new(missing_const_for_fn::MissingConstForFn::new(msrv())));
|
||||
store.register_late_pass(move |_| Box::new(needless_question_mark::NeedlessQuestionMark));
|
||||
store.register_late_pass(move |_| Box::new(casts::Casts::new(msrv)));
|
||||
store.register_early_pass(move || Box::new(unnested_or_patterns::UnnestedOrPatterns::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(casts::Casts::new(msrv())));
|
||||
store.register_early_pass(move || Box::new(unnested_or_patterns::UnnestedOrPatterns::new(msrv())));
|
||||
store.register_late_pass(|_| Box::new(size_of_in_element_count::SizeOfInElementCount));
|
||||
store.register_late_pass(|_| Box::new(same_name_method::SameNameMethod));
|
||||
let max_suggested_slice_pattern_length = conf.max_suggested_slice_pattern_length;
|
||||
store.register_late_pass(move |_| {
|
||||
Box::new(index_refutable_slice::IndexRefutableSlice::new(
|
||||
max_suggested_slice_pattern_length,
|
||||
msrv,
|
||||
msrv(),
|
||||
))
|
||||
});
|
||||
store.register_late_pass(|_| Box::<shadow::Shadow>::default());
|
||||
|
@ -648,7 +610,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
store.register_late_pass(|_| Box::new(borrow_deref_ref::BorrowDerefRef));
|
||||
store.register_late_pass(|_| Box::new(no_effect::NoEffect));
|
||||
store.register_late_pass(|_| Box::new(temporary_assignment::TemporaryAssignment));
|
||||
store.register_late_pass(move |_| Box::new(transmute::Transmute::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(transmute::Transmute::new(msrv())));
|
||||
let cognitive_complexity_threshold = conf.cognitive_complexity_threshold;
|
||||
store.register_late_pass(move |_| {
|
||||
Box::new(cognitive_complexity::CognitiveComplexity::new(
|
||||
|
@ -806,7 +768,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports)));
|
||||
store.register_late_pass(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default());
|
||||
store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress));
|
||||
store.register_late_pass(move |_| Box::new(dereference::Dereferencing::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(dereference::Dereferencing::new(msrv())));
|
||||
store.register_late_pass(|_| Box::new(option_if_let_else::OptionIfLetElse));
|
||||
store.register_late_pass(|_| Box::new(future_not_send::FutureNotSend));
|
||||
store.register_late_pass(|_| Box::new(if_let_mutex::IfLetMutex));
|
||||
|
@ -840,7 +802,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
store.register_late_pass(|_| Box::<vec_init_then_push::VecInitThenPush>::default());
|
||||
store.register_late_pass(|_| Box::new(redundant_slicing::RedundantSlicing));
|
||||
store.register_late_pass(|_| Box::new(from_str_radix_10::FromStrRadix10));
|
||||
store.register_late_pass(move |_| Box::new(if_then_some_else_none::IfThenSomeElseNone::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(if_then_some_else_none::IfThenSomeElseNone::new(msrv())));
|
||||
store.register_late_pass(|_| Box::new(bool_assert_comparison::BoolAssertComparison));
|
||||
store.register_early_pass(move || Box::new(module_style::ModStyle));
|
||||
store.register_late_pass(|_| Box::new(unused_async::UnusedAsync));
|
||||
|
@ -865,14 +827,14 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
))
|
||||
});
|
||||
store.register_late_pass(move |_| Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks));
|
||||
store.register_late_pass(move |_| Box::new(format_args::FormatArgs::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(format_args::FormatArgs::new(msrv())));
|
||||
store.register_late_pass(|_| Box::new(trailing_empty_array::TrailingEmptyArray));
|
||||
store.register_early_pass(|| Box::new(octal_escapes::OctalEscapes));
|
||||
store.register_late_pass(|_| Box::new(needless_late_init::NeedlessLateInit));
|
||||
store.register_late_pass(|_| Box::new(return_self_not_must_use::ReturnSelfNotMustUse));
|
||||
store.register_late_pass(|_| Box::new(init_numbered_fields::NumberedFields));
|
||||
store.register_early_pass(|| Box::new(single_char_lifetime_names::SingleCharLifetimeNames));
|
||||
store.register_late_pass(move |_| Box::new(manual_bits::ManualBits::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(manual_bits::ManualBits::new(msrv())));
|
||||
store.register_late_pass(|_| Box::new(default_union_representation::DefaultUnionRepresentation));
|
||||
store.register_late_pass(|_| Box::<only_used_in_recursion::OnlyUsedInRecursion>::default());
|
||||
let allow_dbg_in_tests = conf.allow_dbg_in_tests;
|
||||
|
@ -896,20 +858,20 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
store.register_late_pass(|_| Box::new(rc_clone_in_vec_init::RcCloneInVecInit));
|
||||
store.register_early_pass(|| Box::<duplicate_mod::DuplicateMod>::default());
|
||||
store.register_early_pass(|| Box::new(unused_rounding::UnusedRounding));
|
||||
store.register_early_pass(move || Box::new(almost_complete_letter_range::AlmostCompleteLetterRange::new(msrv)));
|
||||
store.register_early_pass(move || Box::new(almost_complete_letter_range::AlmostCompleteLetterRange::new(msrv())));
|
||||
store.register_late_pass(|_| Box::new(swap_ptr_to_ref::SwapPtrToRef));
|
||||
store.register_late_pass(|_| Box::new(mismatching_type_param_order::TypeParamMismatch));
|
||||
store.register_late_pass(|_| Box::new(read_zero_byte_vec::ReadZeroByteVec));
|
||||
store.register_late_pass(|_| Box::new(default_instead_of_iter_empty::DefaultIterEmpty));
|
||||
store.register_late_pass(move |_| Box::new(manual_rem_euclid::ManualRemEuclid::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(manual_rem_euclid::ManualRemEuclid::new(msrv())));
|
||||
store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(msrv())));
|
||||
let verbose_bit_mask_threshold = conf.verbose_bit_mask_threshold;
|
||||
store.register_late_pass(move |_| Box::new(operators::Operators::new(verbose_bit_mask_threshold)));
|
||||
store.register_late_pass(|_| Box::new(invalid_utf8_in_unchecked::InvalidUtf8InUnchecked));
|
||||
store.register_late_pass(|_| Box::<std_instead_of_core::StdReexports>::default());
|
||||
store.register_late_pass(move |_| Box::new(instant_subtraction::InstantSubtraction::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(instant_subtraction::InstantSubtraction::new(msrv())));
|
||||
store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone));
|
||||
store.register_late_pass(move |_| Box::new(manual_clamp::ManualClamp::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(manual_clamp::ManualClamp::new(msrv())));
|
||||
store.register_late_pass(|_| Box::new(manual_string_new::ManualStringNew));
|
||||
store.register_late_pass(|_| Box::new(unused_peekable::UnusedPeekable));
|
||||
store.register_early_pass(|| Box::new(multi_assignments::MultiAssignments));
|
||||
|
@ -920,7 +882,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
store.register_late_pass(|_| Box::new(missing_trait_methods::MissingTraitMethods));
|
||||
store.register_late_pass(|_| Box::new(from_raw_with_void_ptr::FromRawWithVoidPtr));
|
||||
store.register_late_pass(|_| Box::new(suspicious_xor_used_as_pow::ConfusingXorAndPow));
|
||||
store.register_late_pass(move |_| Box::new(manual_is_ascii_check::ManualIsAsciiCheck::new(msrv)));
|
||||
store.register_late_pass(move |_| Box::new(manual_is_ascii_check::ManualIsAsciiCheck::new(msrv())));
|
||||
// add lints here, do not remove this comment, it's used in `new_lint`
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
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_applicability;
|
||||
use clippy_utils::{get_parent_expr, meets_msrv, msrvs};
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, GenericArg, QPath};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::sym;
|
||||
|
||||
|
@ -34,12 +34,12 @@ declare_clippy_lint! {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct ManualBits {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl ManualBits {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ impl_lint_pass!(ManualBits => [MANUAL_BITS]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for ManualBits {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if !meets_msrv(self.msrv, msrvs::MANUAL_BITS) {
|
||||
if !self.msrv.meets(msrvs::MANUAL_BITS) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,28 +1,25 @@
|
|||
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;
|
||||
use clippy_utils::MaybePath;
|
||||
use clippy_utils::{
|
||||
eq_expr_value, is_diag_trait_item, is_trait_method, path_res, path_to_local_id, peel_blocks, peel_blocks_with_stmt,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_errors::Diagnostic;
|
||||
use rustc_hir::{
|
||||
def::Res, Arm, BinOpKind, Block, Expr, ExprKind, Guard, HirId, PatKind, PathSegment, PrimTy, QPath, StmtKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{symbol::sym, Span};
|
||||
use std::ops::Deref;
|
||||
|
||||
use clippy_utils::{
|
||||
diagnostics::{span_lint_and_then, span_lint_hir_and_then},
|
||||
eq_expr_value,
|
||||
higher::If,
|
||||
is_diag_trait_item, is_trait_method, meets_msrv, msrvs, path_res, path_to_local_id, peel_blocks,
|
||||
peel_blocks_with_stmt,
|
||||
sugg::Sugg,
|
||||
ty::implements_trait,
|
||||
visitors::is_const_evaluatable,
|
||||
MaybePath,
|
||||
};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Identifies good opportunities for a clamp function from std or core, and suggests using it.
|
||||
|
@ -87,11 +84,11 @@ declare_clippy_lint! {
|
|||
impl_lint_pass!(ManualClamp => [MANUAL_CLAMP]);
|
||||
|
||||
pub struct ManualClamp {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl ManualClamp {
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +111,7 @@ struct InputMinMax<'tcx> {
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for ManualClamp {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
if !meets_msrv(self.msrv, msrvs::CLAMP) {
|
||||
if !self.msrv.meets(msrvs::CLAMP) {
|
||||
return;
|
||||
}
|
||||
if !expr.span.from_expansion() {
|
||||
|
@ -130,7 +127,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualClamp {
|
|||
}
|
||||
|
||||
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
|
||||
if !meets_msrv(self.msrv, msrvs::CLAMP) {
|
||||
if !self.msrv.meets(msrvs::CLAMP) {
|
||||
return;
|
||||
}
|
||||
for suggestion in is_two_if_pattern(cx, block) {
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::{diagnostics::span_lint_and_sugg, in_constant, macros::root_macro_call, source::snippet};
|
||||
use rustc_ast::LitKind::{Byte, Char};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, PatKind, RangeEnd};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{def_id::DefId, sym};
|
||||
|
||||
use clippy_utils::{
|
||||
diagnostics::span_lint_and_sugg, in_constant, macros::root_macro_call, meets_msrv, msrvs, source::snippet,
|
||||
};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Suggests to use dedicated built-in methods,
|
||||
|
@ -45,12 +42,12 @@ declare_clippy_lint! {
|
|||
impl_lint_pass!(ManualIsAsciiCheck => [MANUAL_IS_ASCII_CHECK]);
|
||||
|
||||
pub struct ManualIsAsciiCheck {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl ManualIsAsciiCheck {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -70,11 +67,11 @@ enum CharRange {
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if !meets_msrv(self.msrv, msrvs::IS_ASCII_DIGIT) {
|
||||
if !self.msrv.meets(msrvs::IS_ASCII_DIGIT) {
|
||||
return;
|
||||
}
|
||||
|
||||
if in_constant(cx, expr.hir_id) && !meets_msrv(self.msrv, msrvs::IS_ASCII_DIGIT_CONST) {
|
||||
if in_constant(cx, expr.hir_id) && !self.msrv.meets(msrvs::IS_ASCII_DIGIT_CONST) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::higher::IfLetOrMatch;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::peel_blocks;
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::visitors::{for_each_expr, Descend};
|
||||
use clippy_utils::{meets_msrv, msrvs, peel_blocks};
|
||||
use if_chain::if_chain;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatKind, QPath, Stmt, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
|
@ -50,13 +50,13 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct ManualLetElse {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
matches_behaviour: MatchLintBehaviour,
|
||||
}
|
||||
|
||||
impl ManualLetElse {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>, matches_behaviour: MatchLintBehaviour) -> Self {
|
||||
pub fn new(msrv: Msrv, matches_behaviour: MatchLintBehaviour) -> Self {
|
||||
Self {
|
||||
msrv,
|
||||
matches_behaviour,
|
||||
|
@ -69,7 +69,7 @@ impl_lint_pass!(ManualLetElse => [MANUAL_LET_ELSE]);
|
|||
impl<'tcx> LateLintPass<'tcx> for ManualLetElse {
|
||||
fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) {
|
||||
let if_let_or_match = if_chain! {
|
||||
if meets_msrv(self.msrv, msrvs::LET_ELSE);
|
||||
if self.msrv.meets(msrvs::LET_ELSE);
|
||||
if !in_external_macro(cx.sess(), stmt.span);
|
||||
if let StmtKind::Local(local) = stmt.kind;
|
||||
if let Some(init) = local.init;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
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 clippy_utils::{is_doc_hidden, meets_msrv, msrvs};
|
||||
use rustc_ast::ast::{self, VisibilityKind};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Applicability;
|
||||
|
@ -8,7 +9,6 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
|||
use rustc_hir::{self as hir, Expr, ExprKind, QPath};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::ty::DefIdTree;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::def_id::{DefId, LocalDefId};
|
||||
use rustc_span::{sym, Span};
|
||||
|
@ -63,12 +63,12 @@ declare_clippy_lint! {
|
|||
|
||||
#[expect(clippy::module_name_repetitions)]
|
||||
pub struct ManualNonExhaustiveStruct {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl ManualNonExhaustiveStruct {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -77,14 +77,14 @@ impl_lint_pass!(ManualNonExhaustiveStruct => [MANUAL_NON_EXHAUSTIVE]);
|
|||
|
||||
#[expect(clippy::module_name_repetitions)]
|
||||
pub struct ManualNonExhaustiveEnum {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
constructed_enum_variants: FxHashSet<(DefId, DefId)>,
|
||||
potential_enums: Vec<(LocalDefId, LocalDefId, Span, Span)>,
|
||||
}
|
||||
|
||||
impl ManualNonExhaustiveEnum {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self {
|
||||
msrv,
|
||||
constructed_enum_variants: FxHashSet::default(),
|
||||
|
@ -97,7 +97,7 @@ impl_lint_pass!(ManualNonExhaustiveEnum => [MANUAL_NON_EXHAUSTIVE]);
|
|||
|
||||
impl EarlyLintPass for ManualNonExhaustiveStruct {
|
||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
|
||||
if !meets_msrv(self.msrv, msrvs::NON_EXHAUSTIVE) {
|
||||
if !self.msrv.meets(msrvs::NON_EXHAUSTIVE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ impl EarlyLintPass for ManualNonExhaustiveStruct {
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||
if !meets_msrv(self.msrv, msrvs::NON_EXHAUSTIVE) {
|
||||
if !self.msrv.meets(msrvs::NON_EXHAUSTIVE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
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 clippy_utils::{in_constant, meets_msrv, msrvs, path_to_local};
|
||||
use clippy_utils::{in_constant, path_to_local};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, Node, TyKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -34,12 +34,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct ManualRemEuclid {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl ManualRemEuclid {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -48,11 +48,11 @@ impl_lint_pass!(ManualRemEuclid => [MANUAL_REM_EUCLID]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if !meets_msrv(self.msrv, msrvs::REM_EUCLID) {
|
||||
if !self.msrv.meets(msrvs::REM_EUCLID) {
|
||||
return;
|
||||
}
|
||||
|
||||
if in_constant(cx, expr.hir_id) && !meets_msrv(self.msrv, msrvs::REM_EUCLID_CONST) {
|
||||
if in_constant(cx, expr.hir_id) && !self.msrv.meets(msrvs::REM_EUCLID_CONST) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
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::{get_parent_expr, match_def_path, paths, SpanlessEq};
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
@ -50,12 +50,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct ManualRetain {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl ManualRetain {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -71,9 +71,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualRetain {
|
|||
&& let hir::ExprKind::MethodCall(_, target_expr, [], _) = &collect_expr.kind
|
||||
&& let Some(collect_def_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id)
|
||||
&& match_def_path(cx, collect_def_id, &paths::CORE_ITER_COLLECT) {
|
||||
check_into_iter(cx, parent_expr, left_expr, target_expr, self.msrv);
|
||||
check_iter(cx, parent_expr, left_expr, target_expr, self.msrv);
|
||||
check_to_owned(cx, parent_expr, left_expr, target_expr, self.msrv);
|
||||
check_into_iter(cx, parent_expr, left_expr, target_expr, &self.msrv);
|
||||
check_iter(cx, parent_expr, left_expr, target_expr, &self.msrv);
|
||||
check_to_owned(cx, parent_expr, left_expr, target_expr, &self.msrv);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ fn check_into_iter(
|
|||
parent_expr: &hir::Expr<'_>,
|
||||
left_expr: &hir::Expr<'_>,
|
||||
target_expr: &hir::Expr<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) {
|
||||
if let hir::ExprKind::MethodCall(_, into_iter_expr, [_], _) = &target_expr.kind
|
||||
&& let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
|
||||
|
@ -104,7 +104,7 @@ fn check_iter(
|
|||
parent_expr: &hir::Expr<'_>,
|
||||
left_expr: &hir::Expr<'_>,
|
||||
target_expr: &hir::Expr<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) {
|
||||
if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
|
||||
&& let Some(copied_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
|
||||
|
@ -127,9 +127,9 @@ fn check_to_owned(
|
|||
parent_expr: &hir::Expr<'_>,
|
||||
left_expr: &hir::Expr<'_>,
|
||||
target_expr: &hir::Expr<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) {
|
||||
if meets_msrv(msrv, msrvs::STRING_RETAIN)
|
||||
if msrv.meets(msrvs::STRING_RETAIN)
|
||||
&& let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
|
||||
&& let Some(to_owned_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
|
||||
&& match_def_path(cx, to_owned_def_id, &paths::TO_OWNED_METHOD)
|
||||
|
@ -215,10 +215,10 @@ fn match_acceptable_def_path(cx: &LateContext<'_>, collect_def_id: DefId) -> boo
|
|||
.any(|&method| match_def_path(cx, collect_def_id, method))
|
||||
}
|
||||
|
||||
fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: Option<RustcVersion>) -> bool {
|
||||
fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: &Msrv) -> bool {
|
||||
let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs();
|
||||
ACCEPTABLE_TYPES.iter().any(|(ty, acceptable_msrv)| {
|
||||
is_type_diagnostic_item(cx, expr_ty, *ty)
|
||||
&& acceptable_msrv.map_or(true, |acceptable_msrv| meets_msrv(msrv, acceptable_msrv))
|
||||
&& acceptable_msrv.map_or(true, |acceptable_msrv| msrv.meets(acceptable_msrv))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
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, meets_msrv, msrvs, paths};
|
||||
use clippy_utils::{eq_expr_value, higher, match_def_path, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_hir::def::Res;
|
||||
|
@ -11,7 +12,6 @@ use rustc_hir::BinOpKind;
|
|||
use rustc_hir::{BorrowKind, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::Span;
|
||||
|
@ -48,12 +48,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct ManualStrip {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl ManualStrip {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ enum StripKind {
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for ManualStrip {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if !meets_msrv(self.msrv, msrvs::STR_STRIP_PREFIX) {
|
||||
if !self.msrv.meets(msrvs::STR_STRIP_PREFIX) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,13 +23,13 @@ mod single_match;
|
|||
mod try_err;
|
||||
mod wild_in_or_pats;
|
||||
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::source::{snippet_opt, walk_span_to_context};
|
||||
use clippy_utils::{higher, in_constant, is_span_match, meets_msrv, msrvs};
|
||||
use clippy_utils::{higher, in_constant, is_span_match};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat};
|
||||
use rustc_lexer::{tokenize, TokenKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{Span, SpanData, SyntaxContext};
|
||||
|
||||
|
@ -930,13 +930,13 @@ declare_clippy_lint! {
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct Matches {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
infallible_destructuring_match_linted: bool,
|
||||
}
|
||||
|
||||
impl Matches {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self {
|
||||
msrv,
|
||||
..Matches::default()
|
||||
|
@ -1000,9 +1000,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
|
|||
|
||||
if !from_expansion && !contains_cfg_arm(cx, expr, ex, arms) {
|
||||
if source == MatchSource::Normal {
|
||||
if !(meets_msrv(self.msrv, msrvs::MATCHES_MACRO)
|
||||
&& match_like_matches::check_match(cx, expr, ex, arms))
|
||||
{
|
||||
if !(self.msrv.meets(msrvs::MATCHES_MACRO) && match_like_matches::check_match(cx, expr, ex, arms)) {
|
||||
match_same_arms::check(cx, arms);
|
||||
}
|
||||
|
||||
|
@ -1034,7 +1032,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
|
|||
collapsible_match::check_if_let(cx, if_let.let_pat, if_let.if_then, if_let.if_else);
|
||||
if !from_expansion {
|
||||
if let Some(else_expr) = if_let.if_else {
|
||||
if meets_msrv(self.msrv, msrvs::MATCHES_MACRO) {
|
||||
if self.msrv.meets(msrvs::MATCHES_MACRO) {
|
||||
match_like_matches::check_if_let(
|
||||
cx,
|
||||
expr,
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
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::ty::is_non_aggregate_primitive_type;
|
||||
use clippy_utils::{is_default_equivalent, is_res_lang_ctor, meets_msrv, msrvs, path_res};
|
||||
use clippy_utils::{is_default_equivalent, is_res_lang_ctor, path_res};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::OptionNone;
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, QPath};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::source_map::Span;
|
||||
use rustc_span::symbol::sym;
|
||||
|
@ -227,12 +227,12 @@ fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<
|
|||
}
|
||||
|
||||
pub struct MemReplace {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl MemReplace {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ impl<'tcx> LateLintPass<'tcx> for MemReplace {
|
|||
then {
|
||||
check_replace_option_with_none(cx, src, dest, expr.span);
|
||||
check_replace_with_uninit(cx, src, dest, expr.span);
|
||||
if meets_msrv(self.msrv, msrvs::MEM_TAKE) {
|
||||
if self.msrv.meets(msrvs::MEM_TAKE) {
|
||||
check_replace_with_default(cx, src, dest, expr.span);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
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 clippy_utils::{is_trait_method, meets_msrv, msrvs};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::Expr;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_span::{sym, Span};
|
||||
|
||||
use super::CLONED_INSTEAD_OF_COPIED;
|
||||
|
||||
pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, msrv: Option<RustcVersion>) {
|
||||
pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, msrv: &Msrv) {
|
||||
let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);
|
||||
let inner_ty = match recv_ty.kind() {
|
||||
// `Option<T>` -> `T`
|
||||
ty::Adt(adt, subst)
|
||||
if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && meets_msrv(msrv, msrvs::OPTION_COPIED) =>
|
||||
if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && msrv.meets(msrvs::OPTION_COPIED) =>
|
||||
{
|
||||
subst.type_at(0)
|
||||
},
|
||||
_ if is_trait_method(cx, expr, sym::Iterator) && meets_msrv(msrv, msrvs::ITERATOR_COPIED) => {
|
||||
_ if is_trait_method(cx, expr, sym::Iterator) && msrv.meets(msrvs::ITERATOR_COPIED) => {
|
||||
match get_iterator_item_ty(cx, recv_ty) {
|
||||
// <T as Iterator>::Item
|
||||
Some(ty) => ty,
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
use super::ERR_EXPECT;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::ty::has_debug_impl;
|
||||
use clippy_utils::{meets_msrv, msrvs, ty::is_type_diagnostic_item};
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_span::{sym, Span};
|
||||
|
||||
pub(super) fn check(
|
||||
cx: &LateContext<'_>,
|
||||
_expr: &rustc_hir::Expr<'_>,
|
||||
recv: &rustc_hir::Expr<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
expect_span: Span,
|
||||
err_span: Span,
|
||||
msrv: &Msrv,
|
||||
) {
|
||||
if_chain! {
|
||||
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
|
||||
// Test the version to make sure the lint can be showed (expect_err has been
|
||||
// introduced in rust 1.17.0 : https://github.com/rust-lang/rust/pull/38982)
|
||||
if meets_msrv(msrv, msrvs::EXPECT_ERR);
|
||||
if msrv.meets(msrvs::EXPECT_ERR);
|
||||
|
||||
// Grabs the `Result<T, E>` type
|
||||
let result_type = cx.typeck_results().expr_ty(recv);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
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 clippy_utils::{is_trait_method, meets_msrv, msrvs};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_span::sym;
|
||||
|
||||
use super::FILTER_MAP_NEXT;
|
||||
|
@ -14,10 +14,10 @@ pub(super) fn check<'tcx>(
|
|||
expr: &'tcx hir::Expr<'_>,
|
||||
recv: &'tcx hir::Expr<'_>,
|
||||
arg: &'tcx hir::Expr<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) {
|
||||
if is_trait_method(cx, expr, sym::Iterator) {
|
||||
if !meets_msrv(msrv, msrvs::ITERATOR_FIND_MAP) {
|
||||
if !msrv.meets(msrvs::ITERATOR_FIND_MAP) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
//! Lint for `c.is_digit(10)`
|
||||
|
||||
use super::IS_DIGIT_ASCII_RADIX;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::{
|
||||
consts::constant_full_int, consts::FullInt, diagnostics::span_lint_and_sugg, meets_msrv, msrvs,
|
||||
source::snippet_with_applicability,
|
||||
consts::constant_full_int, consts::FullInt, diagnostics::span_lint_and_sugg, source::snippet_with_applicability,
|
||||
};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::Expr;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_semver::RustcVersion;
|
||||
|
||||
pub(super) fn check<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
expr: &'tcx Expr<'_>,
|
||||
self_arg: &'tcx Expr<'_>,
|
||||
radix: &'tcx Expr<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) {
|
||||
if !meets_msrv(msrv, msrvs::IS_ASCII_DIGIT) {
|
||||
if !msrv.meets(msrvs::IS_ASCII_DIGIT) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
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, meets_msrv, msrvs, peel_blocks};
|
||||
use clippy_utils::{is_diag_trait_item, peel_blocks};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
|
@ -9,19 +10,12 @@ use rustc_lint::LateContext;
|
|||
use rustc_middle::mir::Mutability;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::adjustment::Adjust;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{sym, Span};
|
||||
|
||||
use super::MAP_CLONE;
|
||||
|
||||
pub(super) fn check(
|
||||
cx: &LateContext<'_>,
|
||||
e: &hir::Expr<'_>,
|
||||
recv: &hir::Expr<'_>,
|
||||
arg: &hir::Expr<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
) {
|
||||
pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>, msrv: &Msrv) {
|
||||
if_chain! {
|
||||
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id);
|
||||
if cx.tcx.impl_of_method(method_id)
|
||||
|
@ -97,10 +91,10 @@ fn lint_needless_cloning(cx: &LateContext<'_>, root: Span, receiver: Span) {
|
|||
);
|
||||
}
|
||||
|
||||
fn lint_explicit_closure(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool, msrv: Option<RustcVersion>) {
|
||||
fn lint_explicit_closure(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool, msrv: &Msrv) {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
||||
let (message, sugg_method) = if is_copy && meets_msrv(msrv, msrvs::ITERATOR_COPIED) {
|
||||
let (message, sugg_method) = if is_copy && msrv.meets(msrvs::ITERATOR_COPIED) {
|
||||
("you are using an explicit closure for copying elements", "copied")
|
||||
} else {
|
||||
("you are using an explicit closure for cloning elements", "cloned")
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
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;
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
use super::MAP_UNWRAP_OR;
|
||||
|
@ -19,13 +18,13 @@ pub(super) fn check<'tcx>(
|
|||
recv: &'tcx hir::Expr<'_>,
|
||||
map_arg: &'tcx hir::Expr<'_>,
|
||||
unwrap_arg: &'tcx hir::Expr<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) -> bool {
|
||||
// lint if the caller of `map()` is an `Option`
|
||||
let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Option);
|
||||
let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
|
||||
|
||||
if is_result && !meets_msrv(msrv, msrvs::RESULT_MAP_OR_ELSE) {
|
||||
if is_result && !msrv.meets(msrvs::RESULT_MAP_OR_ELSE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,8 +104,9 @@ mod zst_offset;
|
|||
use bind_instead_of_map::BindInsteadOfMap;
|
||||
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, meets_msrv, msrvs, return_ty};
|
||||
use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, return_ty};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{Expr, ExprKind, TraitItem, TraitItemKind};
|
||||
|
@ -113,7 +114,6 @@ use rustc_hir_analysis::hir_ty_to_ty;
|
|||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::{self, TraitRef, Ty};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{sym, Span};
|
||||
|
||||
|
@ -3163,7 +3163,7 @@ declare_clippy_lint! {
|
|||
|
||||
pub struct Methods {
|
||||
avoid_breaking_exported_api: bool,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
allow_expect_in_tests: bool,
|
||||
allow_unwrap_in_tests: bool,
|
||||
}
|
||||
|
@ -3172,7 +3172,7 @@ impl Methods {
|
|||
#[must_use]
|
||||
pub fn new(
|
||||
avoid_breaking_exported_api: bool,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
allow_expect_in_tests: bool,
|
||||
allow_unwrap_in_tests: bool,
|
||||
) -> Self {
|
||||
|
@ -3325,7 +3325,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
|||
single_char_add_str::check(cx, expr, receiver, args);
|
||||
into_iter_on_ref::check(cx, expr, method_span, method_call.ident.name, receiver);
|
||||
single_char_pattern::check(cx, expr, method_call.ident.name, receiver, args);
|
||||
unnecessary_to_owned::check(cx, expr, method_call.ident.name, receiver, args, self.msrv);
|
||||
unnecessary_to_owned::check(cx, expr, method_call.ident.name, receiver, args, &self.msrv);
|
||||
},
|
||||
hir::ExprKind::Binary(op, lhs, rhs) if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne => {
|
||||
let mut info = BinaryExprInfo {
|
||||
|
@ -3501,7 +3501,7 @@ impl Methods {
|
|||
("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),
|
||||
("cloned", []) => cloned_instead_of_copied::check(cx, expr, recv, span, self.msrv),
|
||||
("cloned", []) => cloned_instead_of_copied::check(cx, expr, recv, span, &self.msrv),
|
||||
("collect", []) if is_trait_method(cx, expr, sym::Iterator) => {
|
||||
needless_collect::check(cx, span, expr, recv, call_span);
|
||||
match method_call(recv) {
|
||||
|
@ -3512,7 +3512,7 @@ impl Methods {
|
|||
map_collect_result_unit::check(cx, expr, m_recv, m_arg);
|
||||
},
|
||||
Some(("take", take_self_arg, [take_arg], _, _)) => {
|
||||
if meets_msrv(self.msrv, msrvs::STR_REPEAT) {
|
||||
if self.msrv.meets(msrvs::STR_REPEAT) {
|
||||
manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg);
|
||||
}
|
||||
},
|
||||
|
@ -3539,7 +3539,7 @@ 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, self.msrv, span, err_span),
|
||||
Some(("err", recv, [], err_span, _)) => err_expect::check(cx, expr, recv, span, err_span, &self.msrv),
|
||||
_ => expect_used::check(cx, expr, recv, false, self.allow_expect_in_tests),
|
||||
},
|
||||
("expect_err", [_]) => expect_used::check(cx, expr, recv, true, self.allow_expect_in_tests),
|
||||
|
@ -3578,7 +3578,7 @@ impl Methods {
|
|||
unit_hash::check(cx, expr, recv, arg);
|
||||
},
|
||||
("is_file", []) => filetype_is_file::check(cx, expr, recv),
|
||||
("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, self.msrv),
|
||||
("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, &self.msrv),
|
||||
("is_none", []) => check_is_some_is_none(cx, expr, recv, false),
|
||||
("is_some", []) => check_is_some_is_none(cx, expr, recv, true),
|
||||
("iter" | "iter_mut" | "into_iter", []) => {
|
||||
|
@ -3601,7 +3601,7 @@ impl Methods {
|
|||
},
|
||||
(name @ ("map" | "map_err"), [m_arg]) => {
|
||||
if name == "map" {
|
||||
map_clone::check(cx, expr, recv, m_arg, self.msrv);
|
||||
map_clone::check(cx, expr, recv, m_arg, &self.msrv);
|
||||
if let Some((map_name @ ("iter" | "into_iter"), recv2, _, _, _)) = method_call(recv) {
|
||||
iter_kv_map::check(cx, map_name, expr, recv2, m_arg);
|
||||
}
|
||||
|
@ -3610,8 +3610,8 @@ impl Methods {
|
|||
}
|
||||
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),
|
||||
("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),
|
||||
("filter", [f_arg]) => {
|
||||
filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, false);
|
||||
},
|
||||
|
@ -3632,7 +3632,7 @@ impl Methods {
|
|||
match (name2, args2) {
|
||||
("cloned", []) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, false),
|
||||
("filter", [arg]) => filter_next::check(cx, expr, recv2, arg),
|
||||
("filter_map", [arg]) => filter_map_next::check(cx, expr, recv2, arg, self.msrv),
|
||||
("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),
|
||||
|
@ -3680,10 +3680,10 @@ impl Methods {
|
|||
vec_resize_to_zero::check(cx, expr, count_arg, default_arg, span);
|
||||
},
|
||||
("seek", [arg]) => {
|
||||
if meets_msrv(self.msrv, msrvs::SEEK_FROM_CURRENT) {
|
||||
if self.msrv.meets(msrvs::SEEK_FROM_CURRENT) {
|
||||
seek_from_current::check(cx, expr, recv, arg);
|
||||
}
|
||||
if meets_msrv(self.msrv, msrvs::SEEK_REWIND) {
|
||||
if self.msrv.meets(msrvs::SEEK_REWIND) {
|
||||
seek_to_start_instead_of_rewind::check(cx, expr, recv, arg, span);
|
||||
}
|
||||
},
|
||||
|
@ -3699,7 +3699,7 @@ impl Methods {
|
|||
("splitn" | "rsplitn", [count_arg, pat_arg]) => {
|
||||
if let Some((Constant::Int(count), _)) = constant(cx, cx.typeck_results(), count_arg) {
|
||||
suspicious_splitn::check(cx, name, expr, recv, count);
|
||||
str_splitn::check(cx, name, expr, recv, pat_arg, count, self.msrv);
|
||||
str_splitn::check(cx, name, expr, recv, pat_arg, count, &self.msrv);
|
||||
}
|
||||
},
|
||||
("splitn_mut" | "rsplitn_mut", [count_arg, _]) => {
|
||||
|
@ -3717,7 +3717,7 @@ impl Methods {
|
|||
},
|
||||
("take", []) => needless_option_take::check(cx, expr, recv),
|
||||
("then", [arg]) => {
|
||||
if !meets_msrv(self.msrv, msrvs::BOOL_THEN_SOME) {
|
||||
if !self.msrv.meets(msrvs::BOOL_THEN_SOME) {
|
||||
return;
|
||||
}
|
||||
unnecessary_lazy_eval::check(cx, expr, recv, arg, "then_some");
|
||||
|
@ -3760,7 +3760,7 @@ impl Methods {
|
|||
},
|
||||
("unwrap_or_else", [u_arg]) => match method_call(recv) {
|
||||
Some(("map", recv, [map_arg], _, _))
|
||||
if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, self.msrv) => {},
|
||||
if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, &self.msrv) => {},
|
||||
_ => {
|
||||
unwrap_or_else_default::check(cx, expr, recv, u_arg);
|
||||
unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or");
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
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, meets_msrv, msrvs, path_to_local_id, paths, peel_blocks};
|
||||
use clippy_utils::{match_def_path, path_to_local_id, paths, peel_blocks};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_span::sym;
|
||||
|
||||
use super::OPTION_AS_REF_DEREF;
|
||||
|
@ -19,9 +19,9 @@ pub(super) fn check(
|
|||
as_ref_recv: &hir::Expr<'_>,
|
||||
map_arg: &hir::Expr<'_>,
|
||||
is_mut: bool,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) {
|
||||
if !meets_msrv(msrv, msrvs::OPTION_AS_DEREF) {
|
||||
if !msrv.meets(msrvs::OPTION_AS_DEREF) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
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};
|
||||
use clippy_utils::{is_diag_item_method, match_def_path, meets_msrv, msrvs, path_to_local_id, paths};
|
||||
use clippy_utils::{is_diag_item_method, match_def_path, path_to_local_id, paths};
|
||||
use core::ops::ControlFlow;
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
|
@ -12,7 +13,6 @@ use rustc_hir::{
|
|||
};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_span::{sym, Span, Symbol, SyntaxContext};
|
||||
|
||||
use super::{MANUAL_SPLIT_ONCE, NEEDLESS_SPLITN};
|
||||
|
@ -24,7 +24,7 @@ pub(super) fn check(
|
|||
self_arg: &Expr<'_>,
|
||||
pat_arg: &Expr<'_>,
|
||||
count: u128,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) {
|
||||
if count < 2 || !cx.typeck_results().expr_ty_adjusted(self_arg).peel_refs().is_str() {
|
||||
return;
|
||||
|
@ -34,7 +34,7 @@ pub(super) fn check(
|
|||
IterUsageKind::Nth(n) => count > n + 1,
|
||||
IterUsageKind::NextTuple => count > 2,
|
||||
};
|
||||
let manual = count == 2 && meets_msrv(msrv, msrvs::STR_SPLIT_ONCE);
|
||||
let manual = count == 2 && msrv.meets(msrvs::STR_SPLIT_ONCE);
|
||||
|
||||
match parse_iter_usage(cx, expr.span.ctxt(), cx.tcx.hir().parent_iter(expr.hir_id)) {
|
||||
Some(usage) if needless(usage.kind) => lint_needless(cx, method_name, expr, self_arg, pat_arg),
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use super::implicit_clone::is_clone_like;
|
||||
use super::unnecessary_iter_cloned::{self, is_into_iter};
|
||||
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_associated_type, get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs};
|
||||
use clippy_utils::visitors::find_all_ret_expressions;
|
||||
use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, return_ty};
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, LangItem, Node};
|
||||
use rustc_hir_analysis::check::{FnCtxt, Inherited};
|
||||
|
@ -16,7 +16,6 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
|
|||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
|
||||
use rustc_middle::ty::EarlyBinder;
|
||||
use rustc_middle::ty::{self, ParamTy, PredicateKind, ProjectionPredicate, TraitPredicate, Ty};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_span::{sym, Symbol};
|
||||
use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
|
||||
use std::cmp::max;
|
||||
|
@ -29,7 +28,7 @@ pub fn check<'tcx>(
|
|||
method_name: Symbol,
|
||||
receiver: &'tcx Expr<'_>,
|
||||
args: &'tcx [Expr<'_>],
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) {
|
||||
if_chain! {
|
||||
if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
|
||||
|
@ -200,7 +199,7 @@ fn check_into_iter_call_arg(
|
|||
expr: &Expr<'_>,
|
||||
method_name: Symbol,
|
||||
receiver: &Expr<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) -> bool {
|
||||
if_chain! {
|
||||
if let Some(parent) = get_parent_expr(cx, expr);
|
||||
|
@ -215,7 +214,7 @@ fn check_into_iter_call_arg(
|
|||
if unnecessary_iter_cloned::check_for_loop_iter(cx, parent, method_name, receiver, true) {
|
||||
return true;
|
||||
}
|
||||
let cloned_or_copied = if is_copy(cx, item_ty) && meets_msrv(msrv, msrvs::ITERATOR_COPIED) {
|
||||
let cloned_or_copied = if is_copy(cx, item_ty) && msrv.meets(msrvs::ITERATOR_COPIED) {
|
||||
"copied"
|
||||
} else {
|
||||
"cloned"
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
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, meets_msrv, msrvs, trait_ref_of_method,
|
||||
};
|
||||
use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, trait_ref_of_method};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::CRATE_DEF_ID;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
|
@ -11,7 +10,6 @@ use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId};
|
|||
use rustc_hir_analysis::hir_ty_to_ty;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::Span;
|
||||
|
||||
|
@ -75,12 +73,12 @@ declare_clippy_lint! {
|
|||
impl_lint_pass!(MissingConstForFn => [MISSING_CONST_FOR_FN]);
|
||||
|
||||
pub struct MissingConstForFn {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl MissingConstForFn {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
|
|||
span: Span,
|
||||
hir_id: HirId,
|
||||
) {
|
||||
if !meets_msrv(self.msrv, msrvs::CONST_IF_MATCH) {
|
||||
if !self.msrv.meets(msrvs::CONST_IF_MATCH) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -152,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
|
|||
|
||||
let mir = cx.tcx.optimized_mir(def_id);
|
||||
|
||||
if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, self.msrv) {
|
||||
if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, &self.msrv) {
|
||||
if cx.tcx.is_const_fn_raw(def_id.to_def_id()) {
|
||||
cx.tcx.sess.span_err(span, err.as_ref());
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use clippy_utils::consts::{constant, Constant};
|
||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
|
||||
use clippy_utils::higher;
|
||||
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, in_constant, is_integer_const, meets_msrv, msrvs, path_to_local};
|
||||
use clippy_utils::{get_parent_expr, in_constant, is_integer_const, path_to_local};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::RangeLimits;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, HirId};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::source_map::{Span, Spanned};
|
||||
use std::cmp::Ordering;
|
||||
|
@ -161,12 +161,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct Ranges {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl Ranges {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ impl_lint_pass!(Ranges => [
|
|||
impl<'tcx> LateLintPass<'tcx> for Ranges {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if let ExprKind::Binary(ref op, l, r) = expr.kind {
|
||||
if meets_msrv(self.msrv, msrvs::RANGE_CONTAINS) {
|
||||
if self.msrv.meets(msrvs::RANGE_CONTAINS) {
|
||||
check_possible_range_contains(cx, op.node, l, r, expr, expr.span);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use rustc_ast::ast::{Expr, ExprKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -37,12 +36,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct RedundantFieldNames {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl RedundantFieldNames {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +50,7 @@ impl_lint_pass!(RedundantFieldNames => [REDUNDANT_FIELD_NAMES]);
|
|||
|
||||
impl EarlyLintPass for RedundantFieldNames {
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
if !meets_msrv(self.msrv, msrvs::FIELD_INIT_SHORTHAND) {
|
||||
if !self.msrv.meets(msrvs::FIELD_INIT_SHORTHAND) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use rustc_ast::ast::{Item, ItemKind, Ty, TyKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -34,12 +33,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct RedundantStaticLifetimes {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl RedundantStaticLifetimes {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +95,7 @@ impl RedundantStaticLifetimes {
|
|||
|
||||
impl EarlyLintPass for RedundantStaticLifetimes {
|
||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
||||
if !meets_msrv(self.msrv, msrvs::STATIC_IN_CONST) {
|
||||
if !self.msrv.meets(msrvs::STATIC_IN_CONST) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,10 +16,10 @@ mod utils;
|
|||
mod wrong_transmute;
|
||||
|
||||
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};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
|
@ -410,7 +410,7 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
pub struct Transmute {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
impl_lint_pass!(Transmute => [
|
||||
CROSSPOINTER_TRANSMUTE,
|
||||
|
@ -431,7 +431,7 @@ impl_lint_pass!(Transmute => [
|
|||
]);
|
||||
impl Transmute {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -461,7 +461,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
|
|||
let linted = wrong_transmute::check(cx, e, from_ty, to_ty)
|
||||
| crosspointer_transmute::check(cx, e, from_ty, to_ty)
|
||||
| transmuting_null::check(cx, e, arg, to_ty)
|
||||
| transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, self.msrv)
|
||||
| transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, &self.msrv)
|
||||
| transmute_int_to_char::check(cx, e, from_ty, to_ty, arg, const_context)
|
||||
| transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
|
||||
| transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use super::TRANSMUTE_PTR_TO_REF;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::{meets_msrv, msrvs, sugg};
|
||||
use clippy_utils::sugg;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{self as hir, Expr, GenericArg, Mutability, Path, TyKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitable};
|
||||
use rustc_semver::RustcVersion;
|
||||
|
||||
/// Checks for `transmute_ptr_to_ref` lint.
|
||||
/// Returns `true` if it's triggered, otherwise returns `false`.
|
||||
|
@ -17,7 +17,7 @@ pub(super) fn check<'tcx>(
|
|||
to_ty: Ty<'tcx>,
|
||||
arg: &'tcx Expr<'_>,
|
||||
path: &'tcx Path<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) -> bool {
|
||||
match (&from_ty.kind(), &to_ty.kind()) {
|
||||
(ty::RawPtr(from_ptr_ty), ty::Ref(_, to_ref_ty, mutbl)) => {
|
||||
|
@ -37,7 +37,7 @@ pub(super) fn check<'tcx>(
|
|||
|
||||
let sugg = if let Some(ty) = get_explicit_type(path) {
|
||||
let ty_snip = snippet_with_applicability(cx, ty.span, "..", &mut app);
|
||||
if meets_msrv(msrv, msrvs::POINTER_CAST) {
|
||||
if msrv.meets(msrvs::POINTER_CAST) {
|
||||
format!("{deref}{}.cast::<{ty_snip}>()", arg.maybe_par())
|
||||
} else if from_ptr_ty.has_erased_regions() {
|
||||
sugg::make_unop(deref, arg.as_ty(format!("{cast} () as {cast} {ty_snip}"))).to_string()
|
||||
|
@ -46,7 +46,7 @@ pub(super) fn check<'tcx>(
|
|||
}
|
||||
} else if from_ptr_ty.ty == *to_ref_ty {
|
||||
if from_ptr_ty.has_erased_regions() {
|
||||
if meets_msrv(msrv, msrvs::POINTER_CAST) {
|
||||
if msrv.meets(msrvs::POINTER_CAST) {
|
||||
format!("{deref}{}.cast::<{to_ref_ty}>()", arg.maybe_par())
|
||||
} else {
|
||||
sugg::make_unop(deref, arg.as_ty(format!("{cast} () as {cast} {to_ref_ty}")))
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
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::{meets_msrv, msrvs, over};
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::over;
|
||||
use rustc_ast::mut_visit::*;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::{self as ast, Mutability, Pat, PatKind, PatKind::*, DUMMY_NODE_ID};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::DUMMY_SP;
|
||||
|
||||
|
@ -45,14 +45,13 @@ declare_clippy_lint! {
|
|||
"unnested or-patterns, e.g., `Foo(Bar) | Foo(Baz) instead of `Foo(Bar | Baz)`"
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct UnnestedOrPatterns {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl UnnestedOrPatterns {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self { msrv }
|
||||
}
|
||||
}
|
||||
|
@ -61,13 +60,13 @@ impl_lint_pass!(UnnestedOrPatterns => [UNNESTED_OR_PATTERNS]);
|
|||
|
||||
impl EarlyLintPass for UnnestedOrPatterns {
|
||||
fn check_arm(&mut self, cx: &EarlyContext<'_>, a: &ast::Arm) {
|
||||
if meets_msrv(self.msrv, msrvs::OR_PATTERNS) {
|
||||
if self.msrv.meets(msrvs::OR_PATTERNS) {
|
||||
lint_unnested_or_patterns(cx, &a.pat);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||
if meets_msrv(self.msrv, msrvs::OR_PATTERNS) {
|
||||
if self.msrv.meets(msrvs::OR_PATTERNS) {
|
||||
if let ast::ExprKind::Let(pat, _, _) = &e.kind {
|
||||
lint_unnested_or_patterns(cx, pat);
|
||||
}
|
||||
|
@ -75,13 +74,13 @@ impl EarlyLintPass for UnnestedOrPatterns {
|
|||
}
|
||||
|
||||
fn check_param(&mut self, cx: &EarlyContext<'_>, p: &ast::Param) {
|
||||
if meets_msrv(self.msrv, msrvs::OR_PATTERNS) {
|
||||
if self.msrv.meets(msrvs::OR_PATTERNS) {
|
||||
lint_unnested_or_patterns(cx, &p.pat);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_local(&mut self, cx: &EarlyContext<'_>, l: &ast::Local) {
|
||||
if meets_msrv(self.msrv, msrvs::OR_PATTERNS) {
|
||||
if self.msrv.meets(msrvs::OR_PATTERNS) {
|
||||
lint_unnested_or_patterns(cx, &l.pat);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
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 clippy_utils::{is_from_proc_macro, meets_msrv, msrvs};
|
||||
use if_chain::if_chain;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Applicability;
|
||||
|
@ -14,7 +15,6 @@ use rustc_hir::{
|
|||
};
|
||||
use rustc_hir_analysis::hir_ty_to_ty;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::Span;
|
||||
|
||||
|
@ -57,13 +57,13 @@ declare_clippy_lint! {
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct UseSelf {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
stack: Vec<StackItem>,
|
||||
}
|
||||
|
||||
impl UseSelf {
|
||||
#[must_use]
|
||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||
pub fn new(msrv: Msrv) -> Self {
|
||||
Self {
|
||||
msrv,
|
||||
..Self::default()
|
||||
|
@ -199,7 +199,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
|
|||
fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) {
|
||||
if_chain! {
|
||||
if !hir_ty.span.from_expansion();
|
||||
if meets_msrv(self.msrv, msrvs::TYPE_ALIAS_ENUM_VARIANTS);
|
||||
if self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS);
|
||||
if let Some(&StackItem::Check {
|
||||
impl_id,
|
||||
in_body,
|
||||
|
@ -228,7 +228,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
|
|||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
if_chain! {
|
||||
if !expr.span.from_expansion();
|
||||
if meets_msrv(self.msrv, msrvs::TYPE_ALIAS_ENUM_VARIANTS);
|
||||
if self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS);
|
||||
if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last();
|
||||
if cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id);
|
||||
then {} else { return; }
|
||||
|
@ -248,7 +248,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
|
|||
fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {
|
||||
if_chain! {
|
||||
if !pat.span.from_expansion();
|
||||
if meets_msrv(self.msrv, msrvs::TYPE_ALIAS_ENUM_VARIANTS);
|
||||
if self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS);
|
||||
if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last();
|
||||
// get the path from the pattern
|
||||
if let PatKind::Path(QPath::Resolved(_, path))
|
||||
|
|
|
@ -41,7 +41,7 @@ impl LateLintPass<'_> for MsrvAttrImpl {
|
|||
.type_of(f.did)
|
||||
.walk()
|
||||
.filter(|t| matches!(t.unpack(), GenericArgKind::Type(_)))
|
||||
.any(|t| match_type(cx, t.expect_ty(), &paths::RUSTC_VERSION))
|
||||
.any(|t| match_type(cx, t.expect_ty(), &paths::MSRV))
|
||||
});
|
||||
if !items.iter().any(|item| item.ident.name == sym!(enter_lint_attrs));
|
||||
then {
|
||||
|
|
|
@ -105,8 +105,6 @@ use rustc_middle::ty::{
|
|||
layout::IntegerExt, BorrowKind, ClosureKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeVisitable, UpvarCapture,
|
||||
};
|
||||
use rustc_middle::ty::{FloatTy, IntTy, UintTy};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::sym;
|
||||
|
@ -118,36 +116,17 @@ use crate::consts::{constant, Constant};
|
|||
use crate::ty::{can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type, ty_is_fn_once_param};
|
||||
use crate::visitors::for_each_expr;
|
||||
|
||||
pub fn parse_msrv(msrv: &str, sess: Option<&Session>, span: Option<Span>) -> Option<RustcVersion> {
|
||||
if let Ok(version) = RustcVersion::parse(msrv) {
|
||||
return Some(version);
|
||||
} else if let Some(sess) = sess {
|
||||
if let Some(span) = span {
|
||||
sess.span_err(span, format!("`{msrv}` is not a valid Rust version"));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn meets_msrv(msrv: Option<RustcVersion>, lint_msrv: RustcVersion) -> bool {
|
||||
msrv.map_or(true, |msrv| msrv.meets(lint_msrv))
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! extract_msrv_attr {
|
||||
($context:ident) => {
|
||||
fn enter_lint_attrs(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
|
||||
let sess = rustc_lint::LintContext::sess(cx);
|
||||
match $crate::get_unique_inner_attr(sess, attrs, "msrv") {
|
||||
Some(msrv_attr) => {
|
||||
if let Some(msrv) = msrv_attr.value_str() {
|
||||
self.msrv = $crate::parse_msrv(&msrv.to_string(), Some(sess), Some(msrv_attr.span));
|
||||
} else {
|
||||
sess.span_err(msrv_attr.span, "bad clippy attribute");
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
self.msrv.enter_lint_attrs(sess, attrs);
|
||||
}
|
||||
|
||||
fn exit_lint_attrs(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
|
||||
let sess = rustc_lint::LintContext::sess(cx);
|
||||
self.msrv.exit_lint_attrs(sess, attrs);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
use std::sync::OnceLock;
|
||||
|
||||
use rustc_ast::Attribute;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::attrs::get_unique_inner_attr;
|
||||
|
||||
macro_rules! msrv_aliases {
|
||||
($($major:literal,$minor:literal,$patch:literal {
|
||||
|
@ -40,3 +47,97 @@ msrv_aliases! {
|
|||
1,16,0 { STR_REPEAT }
|
||||
1,55,0 { SEEK_REWIND }
|
||||
}
|
||||
|
||||
fn parse_msrv(msrv: &str, sess: Option<&Session>, span: Option<Span>) -> Option<RustcVersion> {
|
||||
if let Ok(version) = RustcVersion::parse(msrv) {
|
||||
return Some(version);
|
||||
} else if let Some(sess) = sess {
|
||||
if let Some(span) = span {
|
||||
sess.span_err(span, format!("`{msrv}` is not a valid Rust version"));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Tracks the current MSRV from `clippy.toml`, `Cargo.toml` or set via `#[clippy::msrv]`
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Msrv {
|
||||
stack: Vec<RustcVersion>,
|
||||
}
|
||||
|
||||
impl Msrv {
|
||||
fn new(initial: Option<RustcVersion>) -> Self {
|
||||
Self {
|
||||
stack: Vec::from_iter(initial),
|
||||
}
|
||||
}
|
||||
|
||||
fn read_inner(conf_msrv: &Option<String>, sess: &Session) -> Self {
|
||||
let cargo_msrv = std::env::var("CARGO_PKG_RUST_VERSION")
|
||||
.ok()
|
||||
.and_then(|v| parse_msrv(&v, None, None));
|
||||
let clippy_msrv = conf_msrv.as_ref().and_then(|s| {
|
||||
parse_msrv(s, None, None).or_else(|| {
|
||||
sess.err(format!(
|
||||
"error reading Clippy's configuration file. `{s}` is not a valid Rust version"
|
||||
));
|
||||
None
|
||||
})
|
||||
});
|
||||
|
||||
// if both files have an msrv, let's compare them and emit a warning if they differ
|
||||
if let Some(cargo_msrv) = cargo_msrv
|
||||
&& let Some(clippy_msrv) = clippy_msrv
|
||||
&& clippy_msrv != cargo_msrv
|
||||
{
|
||||
sess.warn(format!(
|
||||
"the MSRV in `clippy.toml` and `Cargo.toml` differ; using `{clippy_msrv}` from `clippy.toml`"
|
||||
));
|
||||
}
|
||||
|
||||
Self::new(clippy_msrv.or(cargo_msrv))
|
||||
}
|
||||
|
||||
/// Set the initial MSRV from the Clippy config file or from Cargo due to the `rust-version`
|
||||
/// field in `Cargo.toml`
|
||||
///
|
||||
/// Returns a `&'static Msrv` as `Copy` types are more easily passed to the
|
||||
/// `register_{late,early}_pass` callbacks
|
||||
pub fn read(conf_msrv: &Option<String>, sess: &Session) -> &'static Self {
|
||||
static PARSED: OnceLock<Msrv> = OnceLock::new();
|
||||
|
||||
PARSED.get_or_init(|| Self::read_inner(conf_msrv, sess))
|
||||
}
|
||||
|
||||
pub fn current(&self) -> Option<RustcVersion> {
|
||||
self.stack.last().copied()
|
||||
}
|
||||
|
||||
pub fn meets(&self, required: RustcVersion) -> bool {
|
||||
self.current().map_or(true, |version| version.meets(required))
|
||||
}
|
||||
|
||||
fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option<RustcVersion> {
|
||||
if let Some(msrv_attr) = get_unique_inner_attr(sess, attrs, "msrv") {
|
||||
if let Some(msrv) = msrv_attr.value_str() {
|
||||
return parse_msrv(&msrv.to_string(), Some(sess), Some(msrv_attr.span));
|
||||
}
|
||||
|
||||
sess.span_err(msrv_attr.span, "bad clippy attribute");
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn enter_lint_attrs(&mut self, sess: &Session, attrs: &[Attribute]) {
|
||||
if let Some(version) = Self::parse_attr(sess, attrs) {
|
||||
self.stack.push(version);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exit_lint_attrs(&mut self, sess: &Session, attrs: &[Attribute]) {
|
||||
if Self::parse_attr(sess, attrs).is_some() {
|
||||
self.stack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,8 @@ pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"];
|
|||
#[cfg(feature = "internal")]
|
||||
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
|
||||
pub const MEM_SWAP: [&str; 3] = ["core", "mem", "swap"];
|
||||
#[cfg(feature = "internal")]
|
||||
pub const MSRV: [&str; 3] = ["clippy_utils", "msrvs", "Msrv"];
|
||||
pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"];
|
||||
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"];
|
||||
|
@ -101,8 +103,6 @@ pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"];
|
|||
pub const REGEX_BYTES_SET_NEW: [&str; 5] = ["regex", "re_set", "bytes", "RegexSet", "new"];
|
||||
pub const REGEX_NEW: [&str; 4] = ["regex", "re_unicode", "Regex", "new"];
|
||||
pub const REGEX_SET_NEW: [&str; 5] = ["regex", "re_set", "unicode", "RegexSet", "new"];
|
||||
#[cfg(feature = "internal")]
|
||||
pub const RUSTC_VERSION: [&str; 2] = ["rustc_semver", "RustcVersion"];
|
||||
pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"];
|
||||
pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"];
|
||||
pub const SLICE_FROM_RAW_PARTS: [&str; 4] = ["core", "slice", "raw", "from_raw_parts"];
|
||||
|
|
|
@ -3,6 +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 rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::mir::{
|
||||
|
@ -18,7 +19,7 @@ use std::borrow::Cow;
|
|||
|
||||
type McfResult = Result<(), (Span, Cow<'static, str>)>;
|
||||
|
||||
pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: Option<RustcVersion>) -> McfResult {
|
||||
pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) -> McfResult {
|
||||
let def_id = body.source.def_id();
|
||||
let mut current = def_id;
|
||||
loop {
|
||||
|
@ -280,7 +281,7 @@ fn check_terminator<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
terminator: &Terminator<'tcx>,
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: &Msrv,
|
||||
) -> McfResult {
|
||||
let span = terminator.source_info.span;
|
||||
match &terminator.kind {
|
||||
|
@ -364,7 +365,7 @@ fn check_terminator<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: Option<RustcVersion>) -> bool {
|
||||
fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
|
||||
tcx.is_const_fn(def_id)
|
||||
&& tcx.lookup_const_stability(def_id).map_or(true, |const_stab| {
|
||||
if let rustc_attr::StabilityLevel::Stable { since, .. } = const_stab.level {
|
||||
|
@ -383,15 +384,12 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: Option<RustcVersion>) -> bo
|
|||
|
||||
let since = rustc_span::Symbol::intern(short_version);
|
||||
|
||||
crate::meets_msrv(
|
||||
msrv,
|
||||
RustcVersion::parse(since.as_str()).unwrap_or_else(|err| {
|
||||
panic!("`rustc_attr::StabilityLevel::Stable::since` is ill-formatted: `{since}`, {err:?}")
|
||||
}),
|
||||
)
|
||||
msrv.meets(RustcVersion::parse(since.as_str()).unwrap_or_else(|err| {
|
||||
panic!("`rustc_attr::StabilityLevel::Stable::since` is ill-formatted: `{since}`, {err:?}")
|
||||
}))
|
||||
} else {
|
||||
// Unstable const fn with the feature enabled.
|
||||
msrv.is_none()
|
||||
msrv.current().is_none()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@ extern crate rustc_middle;
|
|||
#[macro_use]
|
||||
extern crate rustc_session;
|
||||
use clippy_utils::extract_msrv_attr;
|
||||
use clippy_utils::msrvs::Msrv;
|
||||
use rustc_hir::Expr;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
|
||||
use rustc_semver::RustcVersion;
|
||||
|
||||
declare_lint! {
|
||||
pub TEST_LINT,
|
||||
|
@ -22,7 +22,7 @@ declare_lint! {
|
|||
}
|
||||
|
||||
struct Pass {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl_lint_pass!(Pass => [TEST_LINT]);
|
||||
|
|
|
@ -11,9 +11,9 @@ extern crate rustc_middle;
|
|||
#[macro_use]
|
||||
extern crate rustc_session;
|
||||
use clippy_utils::extract_msrv_attr;
|
||||
use clippy_utils::msrvs::Msrv;
|
||||
use rustc_hir::Expr;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
|
||||
use rustc_semver::RustcVersion;
|
||||
|
||||
declare_lint! {
|
||||
pub TEST_LINT,
|
||||
|
@ -22,7 +22,7 @@ declare_lint! {
|
|||
}
|
||||
|
||||
struct Pass {
|
||||
msrv: Option<RustcVersion>,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl_lint_pass!(Pass => [TEST_LINT]);
|
||||
|
|
|
@ -27,3 +27,26 @@ fn no_patch_meets() {
|
|||
#![clippy::msrv = "1.43"]
|
||||
let log2_10 = 3.321928094887362;
|
||||
}
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/6920
|
||||
fn scoping() {
|
||||
mod m {
|
||||
#![clippy::msrv = "1.42.0"]
|
||||
}
|
||||
|
||||
// Should warn
|
||||
let log2_10 = 3.321928094887362;
|
||||
|
||||
mod a {
|
||||
#![clippy::msrv = "1.42.0"]
|
||||
|
||||
fn should_warn() {
|
||||
#![clippy::msrv = "1.43.0"]
|
||||
let log2_10 = 3.321928094887362;
|
||||
}
|
||||
|
||||
fn should_not_warn() {
|
||||
let log2_10 = 3.321928094887362;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,5 +23,21 @@ LL | let log2_10 = 3.321928094887362;
|
|||
|
|
||||
= help: consider using the constant directly
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: approximate value of `f{32, 64}::consts::LOG2_10` found
|
||||
--> $DIR/min_rust_version_attr.rs:38:19
|
||||
|
|
||||
LL | let log2_10 = 3.321928094887362;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider using the constant directly
|
||||
|
||||
error: approximate value of `f{32, 64}::consts::LOG2_10` found
|
||||
--> $DIR/min_rust_version_attr.rs:45:27
|
||||
|
|
||||
LL | let log2_10 = 3.321928094887362;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider using the constant directly
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
Loading…
Reference in a new issue