Skip to content

Commit 8c3915e

Browse files
perf: optimize msrv calls (again)
1 parent df49197 commit 8c3915e

10 files changed

Lines changed: 18 additions & 15 deletions

File tree

book/src/development/adding_lints.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,10 @@ if !self.msrv.meets(cx, msrvs::STR_STRIP_PREFIX) {
485485
}
486486
```
487487

488+
An important consideration is that `Msrv::meets` is relatively expensive to
489+
call, so you should typically match the MSRV at the end of an if let chain,
490+
after other short-circuiting checks.
491+
488492
Early lint passes should instead use `MsrvStack` coupled with
489493
`extract_msrv_attr!()`
490494

clippy_lints/src/attrs/deprecated_cfg_attr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {
1515
{
1616
// check for `rustfmt`
1717
if feature_item.has_name(sym::rustfmt)
18-
&& msrv.meets(msrvs::TOOL_ATTRIBUTES)
1918
// check for `rustfmt_skip` and `rustfmt::skip`
2019
&& let Some(skip_item) = &items[1].meta_item()
2120
&& (skip_item.has_name(sym::rustfmt_skip)
@@ -30,6 +29,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {
3029
// Only lint outer attributes, because custom inner attributes are unstable
3130
// Tracking issue: https://github.com/rust-lang/rust/issues/54726
3231
&& attr.style == AttrStyle::Outer
32+
&& msrv.meets(msrvs::TOOL_ATTRIBUTES)
3333
{
3434
span_lint_and_sugg(
3535
cx,

clippy_lints/src/casts/ptr_as_ptr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ pub(super) fn check<'tcx>(
4141
// The `U` in `pointer::cast` have to be `Sized`
4242
// as explained here: https://github.com/rust-lang/rust/issues/60602.
4343
&& to_pointee_ty.is_sized(cx.tcx, cx.typing_env())
44-
&& !is_from_proc_macro(cx, expr)
4544
&& msrv.meets(cx, msrvs::POINTER_CAST)
45+
&& !is_from_proc_macro(cx, expr)
4646
{
4747
let mut app = Applicability::MachineApplicable;
4848
let turbofish = match &cast_to_hir.kind {

clippy_lints/src/methods/inefficient_to_string.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_
1919
&& let self_ty = args.type_at(0)
2020
&& let (deref_self_ty, deref_count, _) = peel_and_count_ty_refs(self_ty)
2121
&& deref_count >= 1
22+
&& specializes_tostring(cx, deref_self_ty)
2223
// Since Rust 1.82, the specialized `ToString` is properly called
2324
&& !msrv.meets(cx, msrvs::SPECIALIZED_TO_STRING_FOR_REFS)
24-
&& specializes_tostring(cx, deref_self_ty)
2525
{
2626
span_lint_and_then(
2727
cx,

clippy_lints/src/methods/manual_is_variant_and.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,8 @@ pub(super) fn check_is_some_is_none<'tcx>(
314314
.expr_ty_adjusted(recv)
315315
.peel_refs()
316316
.is_diag_item(cx, sym::Option)
317-
&& (is_some || msrv.meets(cx, msrvs::IS_NONE_OR))
318317
&& let Ok(map_func) = MapFunc::try_from(arg)
318+
&& (is_some || msrv.meets(cx, msrvs::IS_NONE_OR))
319319
{
320320
let method = if is_some { "is_some_and" } else { "is_none_or" };
321321
let lint_span = recv.span.to(call_span);

clippy_lints/src/methods/manual_try_fold.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ pub(super) fn check<'tcx>(
2929
&& let ExprKind::Path(qpath) = path.kind
3030
&& let Res::Def(DefKind::Ctor(_, _), _) = cx.qpath_res(&qpath, path.hir_id)
3131
&& let ExprKind::Closure(closure) = acc.kind
32+
&& let Some(args_snip) = closure.fn_arg_span.and_then(|fn_arg_span| fn_arg_span.get_text(cx))
3233
&& msrv.meets(cx, msrvs::ITERATOR_TRY_FOLD)
3334
&& !is_from_proc_macro(cx, expr)
34-
&& let Some(args_snip) = closure.fn_arg_span.and_then(|fn_arg_span| fn_arg_span.get_text(cx))
3535
{
3636
let init_snip = rest
3737
.is_empty()

clippy_lints/src/methods/mod.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5728,9 +5728,9 @@ impl Methods {
57285728
no_effect_replace::check(cx, expr, arg1, arg2);
57295729

57305730
// Check for repeated `str::replace` calls to perform `collapsible_str_replace` lint
5731-
if self.msrv.meets(cx, msrvs::PATTERN_TRAIT_CHAR_ARRAY)
5732-
&& name == sym::replace
5731+
if name == sym::replace
57335732
&& let Some((sym::replace, ..)) = method_call(recv)
5733+
&& self.msrv.meets(cx, msrvs::PATTERN_TRAIT_CHAR_ARRAY)
57345734
{
57355735
collapsible_str_replace::check(cx, expr, arg1, arg2);
57365736
}
@@ -5801,10 +5801,9 @@ impl Methods {
58015801
},
58025802
(sym::take, []) => needless_option_take::check(cx, expr, recv),
58035803
(sym::then, [arg]) => {
5804-
if !self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) {
5805-
return;
5804+
if self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) {
5805+
unnecessary_lazy_eval::check(cx, expr, recv, arg, "then_some", true);
58065806
}
5807-
unnecessary_lazy_eval::check(cx, expr, recv, arg, "then_some", true);
58085807
},
58095808
(sym::try_into, []) if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::TryInto) => {
58105809
unnecessary_fallible_conversions::check_method(cx, expr);

clippy_lints/src/methods/string_lit_chars_any.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ pub(super) fn check<'tcx>(
3333
(false, true) => lhs,
3434
_ => return,
3535
}
36+
&& let Some(scrutinee_snip) = scrutinee.span.get_text(cx)
3637
&& msrv.meets(cx, msrvs::MATCHES_MACRO)
3738
&& !is_from_proc_macro(cx, expr)
38-
&& let Some(scrutinee_snip) = scrutinee.span.get_text(cx)
3939
{
4040
// Normalize the char using `map` so `join` doesn't use `Display`, if we don't then
4141
// something like `r"\"` will become `'\'`, which is of course invalid

clippy_lints/src/operators/manual_is_multiple_of.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ pub(super) fn check<'tcx>(
1919
rhs: &'tcx Expr<'tcx>,
2020
msrv: Msrv,
2121
) {
22-
if msrv.meets(cx, msrvs::UNSIGNED_IS_MULTIPLE_OF)
23-
&& let Some(operand) = uint_compare_to_zero(cx, expr, op, lhs, rhs)
22+
if let Some(operand) = uint_compare_to_zero(cx, expr, op, lhs, rhs)
2423
&& let ExprKind::Binary(operand_op, operand_left, operand_right) = operand.kind
2524
&& operand_op.node == BinOpKind::Rem
2625
&& matches!(
@@ -32,6 +31,7 @@ pub(super) fn check<'tcx>(
3231
ty::Uint(_)
3332
)
3433
&& expr_type_is_certain(cx, operand_left)
34+
&& msrv.meets(cx, msrvs::UNSIGNED_IS_MULTIPLE_OF)
3535
{
3636
let mut app = Applicability::MachineApplicable;
3737
let divisor = deref_sugg(

clippy_lints/src/unnested_or_patterns.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ impl EarlyLintPass for UnnestedOrPatterns {
7070
}
7171

7272
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
73-
if self.msrv.meets(msrvs::OR_PATTERNS)
74-
&& let ast::ExprKind::Let(pat, _, _, _) = &e.kind
73+
if let ast::ExprKind::Let(pat, _, _, _) = &e.kind
74+
&& self.msrv.meets(msrvs::OR_PATTERNS)
7575
{
7676
lint_unnested_or_patterns(cx, pat);
7777
}

0 commit comments

Comments
 (0)