-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
What it does
I'm not a weathered crustacean, but I got bitten the other day because I mistakenly created the same impl block twice in the same file but with different functions, and I didn't realise it for ages but kept on getting strange inconsistencies because of it.
So my file looked something like
struct Foo<'a> {
i: &'a mut i32,
}
// lots of code here
impl Foo<'_> {
fn bar(&mut self) {
*self.i += 1;
}
}
// lots of code here
impl Foo<'_> {
fn baz(&mut self) {
*self.i += 2;
}
}
// lots of code here
fn main() {
println!("Hello world");
// And more code here
}I'm not sure if this is worth linting for to warn the user that this probably isn't a thing they intended? It's probably more common in larger projects with new people joining and not knowing if something's been impl-ed yet.
If someone more knowledgeable knows of a situation in which you would use two impl blocks with identical headers, I'd be interested to hear it as well.
Lint Name
duplicate-impl-headers
Category
suspicious, style, complexity
Advantage
- Remove confusion introduced in bigger projects
- Guide the user away from creating an
implblock for every single function they want for their struct - Make it clear that different
implblocks are actually different in what they allow or what they can contain
Drawbacks
- Maybe a bit picky
- I don't think it would crop up very often
- There might be a legitimate use case for multiple
impls - I'm not sure if
impls which are duplicated but in different files should be flagged or not
Example
From the description:
struct Foo<'a> {
i: &'a mut i32,
// j: &'b mut i32,
}
// lots of code here
impl Foo<'_> {
// --------- note bar in this impl ---------
fn bar(&mut self) {
*self.i += 1;
}
}
// lots of code here
impl Foo<'_> {
// --------- note baz in this impl ---------
fn baz(&mut self) {
*self.i += 2;
}
}
// lots of code here
fn main() {
println!("Hello world");
// And more code here
}Could be written as:
struct Foo<'a> {
i: &'a mut i32,
}
// lots of code here
// --------- note bar and baz now in one impl ---------
impl Foo<'_> {
fn bar(&mut self) {
*self.i += 1;
}
fn baz(&mut self) {
*self.i += 2;
}
}
// lots of code here
fn main() {
println!("Hello world");
// And more code here
}