@@ -70,11 +70,47 @@ impl LintPass for TypePass {
70
70
}
71
71
72
72
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for TypePass {
73
- fn check_ty ( & mut self , cx : & LateContext < ' a , ' tcx > , ast_ty : & ' tcx Ty ) {
74
- if in_macro ( cx, ast_ty. span ) {
75
- return ;
73
+ fn check_fn ( & mut self , cx : & LateContext , _: FnKind , decl : & FnDecl , _: & Expr , _: Span , id : NodeId ) {
74
+ // skip trait implementations, see #605
75
+ if let Some ( map:: NodeItem ( item) ) = cx. tcx . map . find ( cx. tcx . map . get_parent ( id) ) {
76
+ if let ItemImpl ( _, _, _, Some ( ..) , _, _) = item. node {
77
+ return ;
78
+ }
79
+ }
80
+
81
+ check_fn_decl ( cx, decl) ;
82
+ }
83
+
84
+ fn check_struct_field ( & mut self , cx : & LateContext , field : & StructField ) {
85
+ check_ty ( cx, & field. ty ) ;
86
+ }
87
+
88
+ fn check_trait_item ( & mut self , cx : & LateContext , item : & TraitItem ) {
89
+ match item. node {
90
+ ConstTraitItem ( ref ty, _) |
91
+ TypeTraitItem ( _, Some ( ref ty) ) => check_ty ( cx, ty) ,
92
+ MethodTraitItem ( ref sig, _) => check_fn_decl ( cx, & sig. decl ) ,
93
+ _ => ( ) ,
76
94
}
77
- if let TyPath ( ref qpath) = ast_ty. node {
95
+ }
96
+ }
97
+
98
+ fn check_fn_decl ( cx : & LateContext , decl : & FnDecl ) {
99
+ for input in & decl. inputs {
100
+ check_ty ( cx, & input. ty ) ;
101
+ }
102
+
103
+ if let FunctionRetTy :: Return ( ref ty) = decl. output {
104
+ check_ty ( cx, ty) ;
105
+ }
106
+ }
107
+
108
+ fn check_ty ( cx : & LateContext , ast_ty : & Ty ) {
109
+ if in_macro ( cx, ast_ty. span ) {
110
+ return ;
111
+ }
112
+ match ast_ty. node {
113
+ TyPath ( ref qpath) => {
78
114
let def = cx. tcx . tables ( ) . qpath_def ( qpath, ast_ty. id ) ;
79
115
if let Some ( def_id) = opt_def_id ( def) {
80
116
if Some ( def_id) == cx. tcx . lang_items . owned_box ( ) {
@@ -92,16 +128,48 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypePass {
92
128
ast_ty. span,
93
129
"you seem to be trying to use `Box<Vec<T>>`. Consider using just `Vec<T>`" ,
94
130
"`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation." ) ;
131
+ return ; // don't recurse into the type
95
132
} }
96
133
} else if match_def_path ( cx, def_id, & paths:: LINKED_LIST ) {
97
134
span_help_and_lint ( cx,
98
135
LINKEDLIST ,
99
136
ast_ty. span ,
100
137
"I see you're using a LinkedList! Perhaps you meant some other data structure?" ,
101
138
"a VecDeque might work" ) ;
139
+ return ; // don't recurse into the type
102
140
}
103
141
}
104
- }
142
+ match * qpath {
143
+ QPath :: Resolved ( Some ( ref ty) , ref p) => {
144
+ check_ty ( cx, ty) ;
145
+ for ty in p. segments . iter ( ) . flat_map ( |seg| seg. parameters . types ( ) ) {
146
+ check_ty ( cx, ty) ;
147
+ }
148
+ } ,
149
+ QPath :: Resolved ( None , ref p) => {
150
+ for ty in p. segments . iter ( ) . flat_map ( |seg| seg. parameters . types ( ) ) {
151
+ check_ty ( cx, ty) ;
152
+ }
153
+ } ,
154
+ QPath :: TypeRelative ( ref ty, ref seg) => {
155
+ check_ty ( cx, ty) ;
156
+ for ty in seg. parameters . types ( ) {
157
+ check_ty ( cx, ty) ;
158
+ }
159
+ } ,
160
+ }
161
+ } ,
162
+ // recurse
163
+ TySlice ( ref ty) |
164
+ TyArray ( ref ty, _) |
165
+ TyPtr ( MutTy { ref ty, .. } ) |
166
+ TyRptr ( _, MutTy { ref ty, .. } ) => check_ty ( cx, ty) ,
167
+ TyTup ( ref tys) => {
168
+ for ty in tys {
169
+ check_ty ( cx, ty) ;
170
+ }
171
+ } ,
172
+ _ => { } ,
105
173
}
106
174
}
107
175
0 commit comments