-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
05ebce8
commit 739ef7b
Showing
4 changed files
with
646 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,286 @@ | ||
//@aux-build:proc_macros.rs | ||
|
||
#![allow(unused)] | ||
#![warn(clippy::unused_trait_names)] | ||
#![feature(decl_macro)] | ||
|
||
extern crate proc_macros; | ||
|
||
fn main() {} | ||
|
||
fn bad() { | ||
use std::any::Any as _; | ||
|
||
println!("{:?}", "foo".type_id()); | ||
} | ||
|
||
fn good() { | ||
use std::any::Any as _; | ||
|
||
println!("{:?}", "foo".type_id()); | ||
} | ||
|
||
fn used_good() { | ||
use std::any::Any; | ||
|
||
println!("{:?}", Any::type_id("foo")); | ||
println!("{:?}", "foo".type_id()); | ||
} | ||
|
||
fn multi_bad() { | ||
use std::any::{self, Any as _, TypeId}; | ||
|
||
println!("{:?}", "foo".type_id()); | ||
} | ||
|
||
fn multi_good() { | ||
use std::any::{self, Any as _, TypeId}; | ||
|
||
println!("{:?}", "foo".type_id()); | ||
} | ||
|
||
fn renamed_bad() { | ||
use std::any::Any as _; | ||
|
||
println!("{:?}", "foo".type_id()); | ||
} | ||
|
||
fn multi_renamed_bad() { | ||
use std::any::{Any as _, TypeId as MyTypeId}; | ||
|
||
println!("{:?}", "foo".type_id()); | ||
} | ||
|
||
mod pub_good { | ||
pub use std::any::Any; | ||
|
||
fn foo() { | ||
println!("{:?}", "foo".type_id()); | ||
} | ||
} | ||
|
||
mod used_mod_good { | ||
use std::any::Any; | ||
|
||
fn foo() { | ||
println!("{:?}", Any::type_id("foo")); | ||
} | ||
} | ||
|
||
mod mod_import_bad { | ||
fn mod_import_bad() { | ||
use std::any::Any as _; | ||
|
||
println!("{:?}", "foo".type_id()); | ||
} | ||
} | ||
|
||
mod nested_mod_used_good1 { | ||
use std::any::Any; | ||
|
||
mod foo { | ||
fn foo() { | ||
super::Any::type_id("foo"); | ||
} | ||
} | ||
} | ||
|
||
mod nested_mod_used_good2 { | ||
use std::any::Any; | ||
|
||
mod foo { | ||
use super::Any; | ||
|
||
fn foo() { | ||
Any::type_id("foo"); | ||
} | ||
} | ||
} | ||
|
||
mod nested_mod_used_good3 { | ||
use std::any::Any; | ||
|
||
mod foo { | ||
use crate::nested_mod_used_good3::Any; | ||
|
||
fn foo() { | ||
println!("{:?}", Any::type_id("foo")); | ||
} | ||
} | ||
} | ||
|
||
mod nested_mod_used_bad { | ||
use std::any::Any as _; | ||
|
||
fn bar() { | ||
println!("{:?}", "foo".type_id()); | ||
} | ||
|
||
mod foo { | ||
use std::any::Any; | ||
|
||
fn foo() { | ||
println!("{:?}", Any::type_id("foo")); | ||
} | ||
} | ||
} | ||
|
||
// More complex example where `use std::any::Any;` should be anonymised but `use std::any::Any as | ||
// MyAny;` should not as it is used by a sub module. Even though if you removed `use std::any::Any;` | ||
// the code would still compile. | ||
mod nested_mod_used_bad1 { | ||
use std::any::Any as _; | ||
|
||
use std::any::Any as MyAny; | ||
|
||
fn baz() { | ||
println!("{:?}", "baz".type_id()); | ||
} | ||
|
||
mod foo { | ||
use crate::nested_mod_used_bad1::MyAny; | ||
|
||
fn foo() { | ||
println!("{:?}", MyAny::type_id("foo")); | ||
} | ||
} | ||
} | ||
|
||
// Example of nested import with an unused import to try and trick it | ||
mod nested_mod_used_good5 { | ||
use std::any::Any; | ||
|
||
mod foo { | ||
use std::any::Any; | ||
|
||
fn baz() { | ||
println!("{:?}", "baz".type_id()); | ||
} | ||
|
||
mod bar { | ||
use crate::nested_mod_used_good5::foo::Any; | ||
|
||
fn foo() { | ||
println!("{:?}", Any::type_id("foo")); | ||
} | ||
} | ||
} | ||
} | ||
|
||
mod simple_trait { | ||
pub trait MyTrait { | ||
fn do_things(&self); | ||
} | ||
|
||
pub struct MyStruct; | ||
|
||
impl MyTrait for MyStruct { | ||
fn do_things(&self) {} | ||
} | ||
} | ||
|
||
// Underscore imports were stabilized in 1.33 | ||
#[clippy::msrv = "1.32"] | ||
fn msrv_1_32() { | ||
use simple_trait::{MyStruct, MyTrait}; | ||
MyStruct.do_things(); | ||
} | ||
|
||
#[clippy::msrv = "1.33"] | ||
fn msrv_1_33() { | ||
use simple_trait::{MyStruct, MyTrait as _}; | ||
MyStruct.do_things(); | ||
} | ||
|
||
mod lint_inside_macro_expansion_bad { | ||
macro_rules! foo { | ||
() => { | ||
use std::any::Any as _; | ||
fn bar() { | ||
"bar".type_id(); | ||
} | ||
}; | ||
} | ||
|
||
foo!(); | ||
} | ||
|
||
mod macro_and_trait_same_name { | ||
pub macro Foo() {} | ||
pub trait Foo { | ||
fn bar(&self); | ||
} | ||
impl Foo for () { | ||
fn bar(&self) {} | ||
} | ||
} | ||
|
||
fn call_macro_and_trait_good() { | ||
// importing trait and macro but only using macro by path won't allow us to change this to | ||
// `use macro_and_trait_same_name::Foo as _;` | ||
use macro_and_trait_same_name::Foo; | ||
Foo!(); | ||
().bar(); | ||
} | ||
|
||
proc_macros::external!( | ||
fn ignore_inside_external_proc_macro() { | ||
use std::any::Any; | ||
"foo".type_id(); | ||
} | ||
); | ||
|
||
proc_macros::with_span!( | ||
span | ||
|
||
fn ignore_inside_with_span_proc_macro() { | ||
use std::any::Any; | ||
"foo".type_id(); | ||
} | ||
); | ||
|
||
// This should warn the import is unused but should not trigger unused_trait_names | ||
#[warn(unused)] | ||
mod unused_import { | ||
|
||
} | ||
|
||
#[allow(clippy::unused_trait_names)] | ||
fn allow_lint_fn() { | ||
use std::any::Any; | ||
|
||
"foo".type_id(); | ||
} | ||
|
||
#[allow(clippy::unused_trait_names)] | ||
mod allow_lint_mod { | ||
use std::any::Any; | ||
|
||
fn foo() { | ||
"foo".type_id(); | ||
} | ||
} | ||
|
||
mod allow_lint_import { | ||
#[allow(clippy::unused_trait_names)] | ||
use std::any::Any; | ||
|
||
fn foo() { | ||
"foo".type_id(); | ||
} | ||
} | ||
|
||
// Limitation: Suggests `use std::any::Any as _::{self};` which looks weird | ||
// fn use_trait_self_good() { | ||
// use std::any::Any::{self}; | ||
// "foo".type_id(); | ||
// } | ||
|
||
// Limitation: Suggests `use std::any::{Any as _, Any as _};` | ||
// mod repeated_renamed { | ||
// use std::any::{Any, Any as MyAny}; | ||
|
||
// fn foo() { | ||
// "foo".type_id(); | ||
// } | ||
// } |
Oops, something went wrong.