1
1
use rustc:: lint:: * ;
2
2
use syntax:: ast:: * ;
3
- use syntax :: print :: pprust :: expr_to_string ;
3
+ use rustc :: middle :: ty ;
4
4
5
- use utils:: span_lint;
5
+ use utils:: { snippet , span_lint} ;
6
6
7
7
8
8
#[ allow( missing_copy_implementations) ]
@@ -47,7 +47,17 @@ fn check_closure(cx: &Context, expr: &Expr) {
47
47
// is no way the closure is the same as the function
48
48
return ;
49
49
}
50
- if args. iter ( ) . any ( |arg| is_adjusted ( cx, arg) ) { return ; }
50
+ if args. iter ( ) . any ( |arg| is_adjusted ( cx, arg) ) {
51
+ // Are the arguments type-adjusted? Then we need the closure
52
+ return ;
53
+ }
54
+ let fn_ty = cx. tcx . expr_ty ( caller) ;
55
+ if let ty:: TyBareFn ( _, fn_ty) = fn_ty. sty {
56
+ // Is it an unsafe function? They don't implement the closure traits
57
+ if fn_ty. unsafety == Unsafety :: Unsafe {
58
+ return ;
59
+ }
60
+ }
51
61
for ( ref a1, ref a2) in decl. inputs . iter ( ) . zip ( args) {
52
62
if let PatIdent ( _, ident, _) = a1. pat . node {
53
63
// XXXManishearth Should I be checking the binding mode here?
@@ -67,9 +77,9 @@ fn check_closure(cx: &Context, expr: &Expr) {
67
77
return
68
78
}
69
79
}
70
- span_lint ( cx, REDUNDANT_CLOSURE , expr. span ,
71
- & format ! ( "redundant closure found. Consider using `{}` in its place" ,
72
- expr_to_string ( caller) ) [ .. ] )
80
+ span_lint ( cx, REDUNDANT_CLOSURE , expr. span , & format ! (
81
+ "redundant closure found. Consider using `{}` in its place" ,
82
+ snippet ( cx , caller. span , ".." ) ) ) ;
73
83
}
74
84
}
75
85
}
0 commit comments