@@ -20,7 +20,7 @@ use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
20
20
use rustc_middle:: hir:: map:: Map ;
21
21
use rustc_middle:: lint:: in_external_macro;
22
22
use rustc_middle:: ty:: { self , TraitRef , Ty , TyS } ;
23
- use rustc_session:: { declare_lint_pass , declare_tool_lint } ;
23
+ use rustc_session:: { declare_tool_lint , impl_lint_pass } ;
24
24
use rustc_span:: source_map:: Span ;
25
25
use rustc_span:: symbol:: { sym, SymbolStr } ;
26
26
@@ -30,10 +30,11 @@ use crate::utils::usage::mutated_variables;
30
30
use crate :: utils:: {
31
31
contains_ty, get_arg_name, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait, in_macro,
32
32
is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath,
33
- match_trait_method, match_type, match_var, method_calls, method_chain_args, paths, remove_blocks, return_ty ,
34
- single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint,
33
+ match_trait_method, match_type, match_var, meets_msrv , method_calls, method_chain_args, paths, remove_blocks,
34
+ return_ty , single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint,
35
35
span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg, walk_ptrs_ty_depth, SpanlessEq ,
36
36
} ;
37
+ use semver:: { Version , VersionReq } ;
37
38
38
39
declare_clippy_lint ! {
39
40
/// **What it does:** Checks for `.unwrap()` calls on `Option`s and on `Result`s.
@@ -1404,7 +1405,18 @@ declare_clippy_lint! {
1404
1405
"use `.collect()` instead of `::from_iter()`"
1405
1406
}
1406
1407
1407
- declare_lint_pass ! ( Methods => [
1408
+ pub struct Methods {
1409
+ msrv : Option < VersionReq > ,
1410
+ }
1411
+
1412
+ impl Methods {
1413
+ #[ must_use]
1414
+ pub fn new ( msrv : Option < VersionReq > ) -> Self {
1415
+ Self { msrv }
1416
+ }
1417
+ }
1418
+
1419
+ impl_lint_pass ! ( Methods => [
1408
1420
UNWRAP_USED ,
1409
1421
EXPECT_USED ,
1410
1422
SHOULD_IMPLEMENT_TRAIT ,
@@ -1531,8 +1543,12 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
1531
1543
check_pointer_offset ( cx, expr, arg_lists[ 0 ] )
1532
1544
} ,
1533
1545
[ "is_file" , ..] => lint_filetype_is_file ( cx, expr, arg_lists[ 0 ] ) ,
1534
- [ "map" , "as_ref" ] => lint_option_as_ref_deref ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , false ) ,
1535
- [ "map" , "as_mut" ] => lint_option_as_ref_deref ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , true ) ,
1546
+ [ "map" , "as_ref" ] => {
1547
+ lint_option_as_ref_deref ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , false , self . msrv . as_ref ( ) )
1548
+ } ,
1549
+ [ "map" , "as_mut" ] => {
1550
+ lint_option_as_ref_deref ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , true , self . msrv . as_ref ( ) )
1551
+ } ,
1536
1552
[ "unwrap_or_else" , ..] => unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , "unwrap_or" ) ,
1537
1553
[ "get_or_insert_with" , ..] => unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , "get_or_insert" ) ,
1538
1554
[ "ok_or_else" , ..] => unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , "ok_or" ) ,
@@ -1738,6 +1754,8 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
1738
1754
}
1739
1755
}
1740
1756
}
1757
+
1758
+ extract_msrv_attr ! ( LateContext ) ;
1741
1759
}
1742
1760
1743
1761
/// Checks for the `OR_FUN_CALL` lint.
@@ -3453,14 +3471,27 @@ fn lint_suspicious_map(cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
3453
3471
) ;
3454
3472
}
3455
3473
3474
+ const OPTION_AS_REF_DEREF_MSRV : Version = Version {
3475
+ major : 1 ,
3476
+ minor : 40 ,
3477
+ patch : 0 ,
3478
+ pre : Vec :: new ( ) ,
3479
+ build : Vec :: new ( ) ,
3480
+ } ;
3481
+
3456
3482
/// lint use of `_.as_ref().map(Deref::deref)` for `Option`s
3457
3483
fn lint_option_as_ref_deref < ' tcx > (
3458
3484
cx : & LateContext < ' tcx > ,
3459
3485
expr : & hir:: Expr < ' _ > ,
3460
3486
as_ref_args : & [ hir:: Expr < ' _ > ] ,
3461
3487
map_args : & [ hir:: Expr < ' _ > ] ,
3462
3488
is_mut : bool ,
3489
+ msrv : Option < & VersionReq > ,
3463
3490
) {
3491
+ if !meets_msrv ( msrv, & OPTION_AS_REF_DEREF_MSRV ) {
3492
+ return ;
3493
+ }
3494
+
3464
3495
let same_mutability = |m| ( is_mut && m == & hir:: Mutability :: Mut ) || ( !is_mut && m == & hir:: Mutability :: Not ) ;
3465
3496
3466
3497
let option_ty = cx. typeck_results ( ) . expr_ty ( & as_ref_args[ 0 ] ) ;
0 commit comments