Skip to content

Commit ad4df72

Browse files
authored
Merge pull request #1393 from oli-obk/linkedlists
Don’t warn for types used in trait implementation
2 parents 5060d2f + 00a3bfb commit ad4df72

File tree

2 files changed

+100
-7
lines changed

2 files changed

+100
-7
lines changed

clippy_lints/src/types.rs

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,47 @@ impl LintPass for TypePass {
7070
}
7171

7272
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+
_ => (),
7694
}
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) => {
78114
let def = cx.tcx.tables().qpath_def(qpath, ast_ty.id);
79115
if let Some(def_id) = opt_def_id(def) {
80116
if Some(def_id) == cx.tcx.lang_items.owned_box() {
@@ -92,16 +128,48 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypePass {
92128
ast_ty.span,
93129
"you seem to be trying to use `Box<Vec<T>>`. Consider using just `Vec<T>`",
94130
"`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation.");
131+
return; // don't recurse into the type
95132
}}
96133
} else if match_def_path(cx, def_id, &paths::LINKED_LIST) {
97134
span_help_and_lint(cx,
98135
LINKEDLIST,
99136
ast_ty.span,
100137
"I see you're using a LinkedList! Perhaps you meant some other data structure?",
101138
"a VecDeque might work");
139+
return; // don't recurse into the type
102140
}
103141
}
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+
_ => {},
105173
}
106174
}
107175

tests/compile-fail/dlist.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,39 @@
11
#![feature(plugin, collections)]
2+
#![feature(associated_type_defaults)]
3+
#![feature(associated_consts)]
24

35
#![plugin(clippy)]
46
#![deny(clippy)]
7+
#![allow(dead_code)]
58

69
extern crate collections;
710
use collections::linked_list::LinkedList;
811

9-
pub fn test(_: LinkedList<u8>) { //~ ERROR I see you're using a LinkedList!
12+
trait Foo {
13+
type Baz = LinkedList<u8>; //~ ERROR I see you're using a LinkedList!
14+
fn foo(LinkedList<u8>); //~ ERROR I see you're using a LinkedList!
15+
const BAR : Option<LinkedList<u8>>; //~ ERROR I see you're using a LinkedList!
16+
}
17+
18+
// ok, we don’t want to warn for implementations, see #605
19+
impl Foo for LinkedList<u8> {
20+
fn foo(_: LinkedList<u8>) {}
21+
const BAR : Option<LinkedList<u8>> = None;
22+
}
23+
24+
struct Bar;
25+
impl Bar {
26+
fn foo(_: LinkedList<u8>) {} //~ ERROR I see you're using a LinkedList!
27+
}
28+
29+
pub fn test(my_favourite_linked_list: LinkedList<u8>) { //~ ERROR I see you're using a LinkedList!
30+
println!("{:?}", my_favourite_linked_list)
31+
}
32+
33+
pub fn test_ret() -> Option<LinkedList<u8>> { //~ ERROR I see you're using a LinkedList!
34+
unimplemented!();
1035
}
1136

1237
fn main(){
13-
test(LinkedList::new()); //~ ERROR I see you're using a LinkedList!
38+
test(LinkedList::new());
1439
}

0 commit comments

Comments
 (0)