1
- use crate :: utils:: span_lint;
1
+ use crate :: utils:: { fn_def_id , span_lint} ;
2
2
3
3
use rustc_data_structures:: fx:: FxHashSet ;
4
- use rustc_hir:: { Expr , ExprKind } ;
4
+ use rustc_hir:: Expr ;
5
5
use rustc_lint:: { LateContext , LateLintPass } ;
6
6
use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
7
7
use rustc_span:: Symbol ;
8
8
9
9
declare_clippy_lint ! {
10
- /// **What it does:** Lints for specific trait methods defined in clippy.toml
10
+ /// **What it does:** Denies the configured methods and functions in clippy.toml
11
11
///
12
12
/// **Why is this bad?** Some methods are undesirable in certain contexts,
13
- /// and it would be beneficial to lint for them as needed.
13
+ /// and it's beneficial to lint for them as needed.
14
14
///
15
- /// **Known problems:** None.
15
+ /// **Known problems:** Currently, you must write each function as a
16
+ /// fully-qualified path. This lint doesn't support aliases or reexported
17
+ /// names; be aware that many types in `std` are actually reexports.
18
+ ///
19
+ /// For example, if you want to disallow `Duration::as_secs`, your clippy.toml
20
+ /// configuration would look like
21
+ /// `disallowed-methods = ["core::time::Duration::as_secs"]` and not
22
+ /// `disallowed-methods = ["std::time::Duration::as_secs"]` as you might expect.
16
23
///
17
24
/// **Example:**
18
25
///
26
+ /// An example clippy.toml configuration:
27
+ /// ```toml
28
+ /// # clippy.toml
29
+ /// disallowed-methods = ["alloc::vec::Vec::leak", "std::time::Instant::now"]
30
+ /// ```
31
+ ///
19
32
/// ```rust,ignore
20
- /// // example code where clippy issues a warning
21
- /// foo.bad_method(); // Foo::bad_method is disallowed in the configuration
33
+ /// // Example code where clippy issues a warning
34
+ /// let xs = vec![1, 2, 3, 4];
35
+ /// xs.leak(); // Vec::leak is disallowed in the config.
36
+ ///
37
+ /// let _now = Instant::now(); // Instant::now is disallowed in the config.
22
38
/// ```
39
+ ///
23
40
/// Use instead:
24
41
/// ```rust,ignore
25
- /// // example code which does not raise clippy warning
26
- /// goodStruct.bad_method(); // GoodStruct::bad_method is not disallowed
42
+ /// // Example code which does not raise clippy warning
43
+ /// let mut xs = Vec::new(); // Vec::new is _not_ disallowed in the config.
44
+ /// xs.push(123); // Vec::push is _not_ disallowed in the config.
27
45
/// ```
28
46
pub DISALLOWED_METHOD ,
29
47
nursery,
@@ -50,22 +68,20 @@ impl_lint_pass!(DisallowedMethod => [DISALLOWED_METHOD]);
50
68
51
69
impl < ' tcx > LateLintPass < ' tcx > for DisallowedMethod {
52
70
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > ) {
53
- if let ExprKind :: MethodCall ( _path, _, _args, _) = & expr. kind {
54
- let def_id = cx. typeck_results ( ) . type_dependent_def_id ( expr. hir_id ) . unwrap ( ) ;
55
-
56
- let method_call = cx. get_def_path ( def_id) ;
57
- if self . disallowed . contains ( & method_call) {
58
- let method = method_call
59
- . iter ( )
60
- . map ( |s| s. to_ident_string ( ) )
71
+ if let Some ( def_id) = fn_def_id ( cx, expr) {
72
+ let func_path = cx. get_def_path ( def_id) ;
73
+ if self . disallowed . contains ( & func_path) {
74
+ let func_path_string = func_path
75
+ . into_iter ( )
76
+ . map ( Symbol :: to_ident_string)
61
77
. collect :: < Vec < _ > > ( )
62
78
. join ( "::" ) ;
63
79
64
80
span_lint (
65
81
cx,
66
82
DISALLOWED_METHOD ,
67
83
expr. span ,
68
- & format ! ( "use of a disallowed method `{}`" , method ) ,
84
+ & format ! ( "use of a disallowed method `{}`" , func_path_string ) ,
69
85
) ;
70
86
}
71
87
}
0 commit comments