1
1
use rustc:: lint:: * ;
2
2
use rustc_front:: hir:: * ;
3
3
use utils:: span_lint;
4
- use rustc:: middle:: ty:: { TypeAndMut , TypeVariants , MethodCall } ;
4
+ use rustc:: middle:: ty:: { TypeAndMut , TypeVariants , MethodCall , TyS } ;
5
+ use syntax:: ptr:: P ;
5
6
6
7
declare_lint ! {
7
8
pub UNNECESSARY_MUT_PASSED ,
@@ -22,62 +23,52 @@ impl LintPass for UnnecessaryMutPassed {
22
23
23
24
impl LateLintPass for UnnecessaryMutPassed {
24
25
fn check_expr ( & mut self , cx : & LateContext , e : & Expr ) {
26
+ let borrowed_table = cx. tcx . tables . borrow ( ) ;
25
27
match e. node {
26
28
ExprCall ( ref fn_expr, ref arguments) => {
27
- let borrowed_table = cx. tcx . tables . borrow ( ) ;
28
- let funtion_type = match borrowed_table. node_types . get ( & fn_expr. id ) {
29
- Some ( funtion_type) => funtion_type,
29
+ match borrowed_table. node_types . get ( & fn_expr. id ) {
30
+ Some ( function_type) => {
31
+ if let ExprPath ( _, ref path) = fn_expr. node {
32
+ check_arguments ( cx, & arguments, function_type,
33
+ & format ! ( "{}" , path) ) ;
34
+ }
35
+ } ,
30
36
None => unreachable ! ( ) , // A function with unknown type is called.
31
37
// If this happened the compiler would have aborted the
32
38
// compilation long ago.
33
39
} ;
34
- if let TypeVariants :: TyBareFn ( _, ref b) = funtion_type. sty {
35
- let parameters = b. sig . skip_binder ( ) . inputs . clone ( ) ;
36
- for ( argument, parameter) in arguments. iter ( ) . zip ( parameters. iter ( ) ) {
37
- match parameter. sty {
38
- TypeVariants :: TyRef ( _, TypeAndMut { ty : _, mutbl : MutImmutable } ) |
39
- TypeVariants :: TyRawPtr ( TypeAndMut { ty : _, mutbl : MutImmutable } ) => {
40
- if let Expr_ :: ExprAddrOf ( MutMutable , _) = argument. node {
41
- if let ExprPath ( _, path) = fn_expr. node . clone ( ) {
42
- span_lint ( cx, UNNECESSARY_MUT_PASSED ,
43
- argument. span , & format ! ( "This argument of the \
44
- function \" {}\" doesn't need to be mutable", path) ) ;
45
- }
46
- }
47
- } ,
48
- _ => { }
49
- }
50
- }
51
- }
40
+
41
+
52
42
} ,
53
43
ExprMethodCall ( ref name, _, ref arguments) => {
54
44
let method_call = MethodCall :: expr ( e. id ) ;
55
- let borrowed_table = cx . tcx . tables . borrow ( ) ;
56
- let method_type = match borrowed_table . method_map . get ( & method_call ) {
57
- Some ( method_type ) => method_type ,
45
+ match borrowed_table. method_map . get ( & method_call ) {
46
+ Some ( method_type) => check_arguments ( cx , & arguments , method_type . ty ,
47
+ & format ! ( "{}" , name . node . as_str ( ) ) ) ,
58
48
None => unreachable ! ( ) , // Just like above, this should never happen.
59
49
} ;
60
- if let TypeVariants :: TyBareFn ( _, ref b) = method_type. ty . sty {
61
- let parameters = b. sig . skip_binder ( ) . inputs . iter ( ) . clone ( ) ;
62
- for ( argument, parameter) in arguments. iter ( ) . zip ( parameters) . skip ( 1 ) {
63
- // Skip the first argument and the first parameter because it is the
64
- // struct the function is called on.
65
- match parameter. sty {
66
- TypeVariants :: TyRef ( _, TypeAndMut { ty : _, mutbl : MutImmutable } ) |
67
- TypeVariants :: TyRawPtr ( TypeAndMut { ty : _, mutbl : MutImmutable } ) => {
68
- if let Expr_ :: ExprAddrOf ( MutMutable , _) = argument. node {
69
- span_lint ( cx, UNNECESSARY_MUT_PASSED ,
70
- argument. span , & format ! ( "This argument of the \
71
- method \" {}\" doesn't need to be mutable",
72
- name. node. as_str( ) ) ) ;
73
- }
74
- } ,
75
- _ => { }
76
- }
77
- }
78
- }
79
50
} ,
80
51
_ => { }
81
52
}
82
53
}
83
54
}
55
+
56
+ fn check_arguments ( cx : & LateContext , arguments : & [ P < Expr > ] , type_definition : & TyS , name : & str ) {
57
+ if let TypeVariants :: TyBareFn ( _, ref fn_type) = type_definition. sty {
58
+ let parameters = & fn_type. sig . skip_binder ( ) . inputs ;
59
+ for ( argument, parameter) in arguments. iter ( ) . zip ( parameters. iter ( ) ) {
60
+ match parameter. sty {
61
+ TypeVariants :: TyRef ( _, TypeAndMut { ty : _, mutbl : MutImmutable } ) |
62
+ TypeVariants :: TyRawPtr ( TypeAndMut { ty : _, mutbl : MutImmutable } ) => {
63
+ if let Expr_ :: ExprAddrOf ( MutMutable , _) = argument. node {
64
+ span_lint ( cx, UNNECESSARY_MUT_PASSED ,
65
+ argument. span , & format ! ( "The function/method \" {}\" \
66
+ doesn't need a mutable reference",
67
+ name) ) ;
68
+ }
69
+ } ,
70
+ _ => { }
71
+ }
72
+ }
73
+ }
74
+ }
0 commit comments