Skip to content

Commit 739ef7b

Browse files
Add unused_trait_names tests
1 parent 05ebce8 commit 739ef7b

File tree

4 files changed

+646
-0
lines changed

4 files changed

+646
-0
lines changed

clippy_lints/src/attrs/useless_attribute.rs

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub(super) fn check(cx: &LateContext<'_>, item: &Item<'_>, attrs: &[Attribute])
5151
| "module_name_repetitions"
5252
| "single_component_path_imports"
5353
| "disallowed_types"
54+
| "unused_trait_names"
5455
)
5556
}) {
5657
return;

tests/ui/unused_trait_names.fixed

+286
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
//@aux-build:proc_macros.rs
2+
3+
#![allow(unused)]
4+
#![warn(clippy::unused_trait_names)]
5+
#![feature(decl_macro)]
6+
7+
extern crate proc_macros;
8+
9+
fn main() {}
10+
11+
fn bad() {
12+
use std::any::Any as _;
13+
14+
println!("{:?}", "foo".type_id());
15+
}
16+
17+
fn good() {
18+
use std::any::Any as _;
19+
20+
println!("{:?}", "foo".type_id());
21+
}
22+
23+
fn used_good() {
24+
use std::any::Any;
25+
26+
println!("{:?}", Any::type_id("foo"));
27+
println!("{:?}", "foo".type_id());
28+
}
29+
30+
fn multi_bad() {
31+
use std::any::{self, Any as _, TypeId};
32+
33+
println!("{:?}", "foo".type_id());
34+
}
35+
36+
fn multi_good() {
37+
use std::any::{self, Any as _, TypeId};
38+
39+
println!("{:?}", "foo".type_id());
40+
}
41+
42+
fn renamed_bad() {
43+
use std::any::Any as _;
44+
45+
println!("{:?}", "foo".type_id());
46+
}
47+
48+
fn multi_renamed_bad() {
49+
use std::any::{Any as _, TypeId as MyTypeId};
50+
51+
println!("{:?}", "foo".type_id());
52+
}
53+
54+
mod pub_good {
55+
pub use std::any::Any;
56+
57+
fn foo() {
58+
println!("{:?}", "foo".type_id());
59+
}
60+
}
61+
62+
mod used_mod_good {
63+
use std::any::Any;
64+
65+
fn foo() {
66+
println!("{:?}", Any::type_id("foo"));
67+
}
68+
}
69+
70+
mod mod_import_bad {
71+
fn mod_import_bad() {
72+
use std::any::Any as _;
73+
74+
println!("{:?}", "foo".type_id());
75+
}
76+
}
77+
78+
mod nested_mod_used_good1 {
79+
use std::any::Any;
80+
81+
mod foo {
82+
fn foo() {
83+
super::Any::type_id("foo");
84+
}
85+
}
86+
}
87+
88+
mod nested_mod_used_good2 {
89+
use std::any::Any;
90+
91+
mod foo {
92+
use super::Any;
93+
94+
fn foo() {
95+
Any::type_id("foo");
96+
}
97+
}
98+
}
99+
100+
mod nested_mod_used_good3 {
101+
use std::any::Any;
102+
103+
mod foo {
104+
use crate::nested_mod_used_good3::Any;
105+
106+
fn foo() {
107+
println!("{:?}", Any::type_id("foo"));
108+
}
109+
}
110+
}
111+
112+
mod nested_mod_used_bad {
113+
use std::any::Any as _;
114+
115+
fn bar() {
116+
println!("{:?}", "foo".type_id());
117+
}
118+
119+
mod foo {
120+
use std::any::Any;
121+
122+
fn foo() {
123+
println!("{:?}", Any::type_id("foo"));
124+
}
125+
}
126+
}
127+
128+
// More complex example where `use std::any::Any;` should be anonymised but `use std::any::Any as
129+
// MyAny;` should not as it is used by a sub module. Even though if you removed `use std::any::Any;`
130+
// the code would still compile.
131+
mod nested_mod_used_bad1 {
132+
use std::any::Any as _;
133+
134+
use std::any::Any as MyAny;
135+
136+
fn baz() {
137+
println!("{:?}", "baz".type_id());
138+
}
139+
140+
mod foo {
141+
use crate::nested_mod_used_bad1::MyAny;
142+
143+
fn foo() {
144+
println!("{:?}", MyAny::type_id("foo"));
145+
}
146+
}
147+
}
148+
149+
// Example of nested import with an unused import to try and trick it
150+
mod nested_mod_used_good5 {
151+
use std::any::Any;
152+
153+
mod foo {
154+
use std::any::Any;
155+
156+
fn baz() {
157+
println!("{:?}", "baz".type_id());
158+
}
159+
160+
mod bar {
161+
use crate::nested_mod_used_good5::foo::Any;
162+
163+
fn foo() {
164+
println!("{:?}", Any::type_id("foo"));
165+
}
166+
}
167+
}
168+
}
169+
170+
mod simple_trait {
171+
pub trait MyTrait {
172+
fn do_things(&self);
173+
}
174+
175+
pub struct MyStruct;
176+
177+
impl MyTrait for MyStruct {
178+
fn do_things(&self) {}
179+
}
180+
}
181+
182+
// Underscore imports were stabilized in 1.33
183+
#[clippy::msrv = "1.32"]
184+
fn msrv_1_32() {
185+
use simple_trait::{MyStruct, MyTrait};
186+
MyStruct.do_things();
187+
}
188+
189+
#[clippy::msrv = "1.33"]
190+
fn msrv_1_33() {
191+
use simple_trait::{MyStruct, MyTrait as _};
192+
MyStruct.do_things();
193+
}
194+
195+
mod lint_inside_macro_expansion_bad {
196+
macro_rules! foo {
197+
() => {
198+
use std::any::Any as _;
199+
fn bar() {
200+
"bar".type_id();
201+
}
202+
};
203+
}
204+
205+
foo!();
206+
}
207+
208+
mod macro_and_trait_same_name {
209+
pub macro Foo() {}
210+
pub trait Foo {
211+
fn bar(&self);
212+
}
213+
impl Foo for () {
214+
fn bar(&self) {}
215+
}
216+
}
217+
218+
fn call_macro_and_trait_good() {
219+
// importing trait and macro but only using macro by path won't allow us to change this to
220+
// `use macro_and_trait_same_name::Foo as _;`
221+
use macro_and_trait_same_name::Foo;
222+
Foo!();
223+
().bar();
224+
}
225+
226+
proc_macros::external!(
227+
fn ignore_inside_external_proc_macro() {
228+
use std::any::Any;
229+
"foo".type_id();
230+
}
231+
);
232+
233+
proc_macros::with_span!(
234+
span
235+
236+
fn ignore_inside_with_span_proc_macro() {
237+
use std::any::Any;
238+
"foo".type_id();
239+
}
240+
);
241+
242+
// This should warn the import is unused but should not trigger unused_trait_names
243+
#[warn(unused)]
244+
mod unused_import {
245+
246+
}
247+
248+
#[allow(clippy::unused_trait_names)]
249+
fn allow_lint_fn() {
250+
use std::any::Any;
251+
252+
"foo".type_id();
253+
}
254+
255+
#[allow(clippy::unused_trait_names)]
256+
mod allow_lint_mod {
257+
use std::any::Any;
258+
259+
fn foo() {
260+
"foo".type_id();
261+
}
262+
}
263+
264+
mod allow_lint_import {
265+
#[allow(clippy::unused_trait_names)]
266+
use std::any::Any;
267+
268+
fn foo() {
269+
"foo".type_id();
270+
}
271+
}
272+
273+
// Limitation: Suggests `use std::any::Any as _::{self};` which looks weird
274+
// fn use_trait_self_good() {
275+
// use std::any::Any::{self};
276+
// "foo".type_id();
277+
// }
278+
279+
// Limitation: Suggests `use std::any::{Any as _, Any as _};`
280+
// mod repeated_renamed {
281+
// use std::any::{Any, Any as MyAny};
282+
283+
// fn foo() {
284+
// "foo".type_id();
285+
// }
286+
// }

0 commit comments

Comments
 (0)