Description
What it does
This would be a pair of lints, likely under the restriction
lints group (and thus allowed by default). The idea would be to check for whether non-generic associated types are inlined into definitions or not.
For example, this is the "inlined" style:
impl Iterator for MyType {
type Item = u32;
// note: u32 instead of Self::Item here
fn next(&mut self) -> Option<u32> { /* ... */ }
}
And this is the "non-inlined" style:
impl Iterator for MyType {
type Item = u32;
// note: Self::Item instead of u32 here
fn next(&mut self) -> Option<Self::Item> { /* ... */ }
}
Note that the scope for this would be very limited, only checking for trait methods. Otherwise, it's ambiguous what to do in cases like:
impl MyType {
fn peek(&self) -> Option<<MyType as Iterator>::Item> { /* ... */ }
}
Here, since this is an inherent method, it's unclear whether this type should be inlined or not (replaced with u32
), and the decision is left to the author.
Advantage
Advantages to the inline style:
- The syntax can get very messy after nesting (e.g.
<<MyType as MyTrait>::AssociatedType as OtherTrait>::Item
) - It's immediately clear what the actual type is for all signatures
Advantages to the non-inline style:
- They always match the trait definition, so, you know why a particular type is being used
- The inlined type is not always shorter (especially if the type in the struct definition itself is from a trait's associated type)
Advantages to both styles:
- The result becomes what's shown in rustdoc, so, the benefits of the style gets propagated to the documentation
Drawbacks
- This lint could definitely be annoying if it doesn't have an auto-fixable version, since it can affect a very large portion of the code.
rust-analyzer
tends to prefer the inline style when autocompleting, so, that would likely have to be modified to respect the lint.
Example
I am not bound by your issue template, and I already included an example. I'm not repeating myself.