Here is a function I ended up writing in my code (or almost this function, I changed the domain of application to not add cognitive complexity, I guess everyone knows about species and animals).
fn species(
&self,
) -> <<Self::SubFamilyType as SubFamilyTrait>::FamilyType as FamilyTrait>::SpeciesType {
self.sub_family().family().species()
}
So, of course, this function is not alone, it is part of a collection of traits and you're missing the context here. Take a look at this playground for more details.
So here is my question: Is there a way to write this return type in sections/intermediate types, in order to make it more readable?
Actually, in my real code, the chain of associated types was so long that I even made Clippy complained with type_complexity. And Clippy gives a possible solution: define types.
But in this case, I don't really see how I can define a type
:
- since I depend on
Self
I cannot make a simpletype IntermediateType1 = ...
outside of the trait - and inside the trait, this would be another associated trait which raises 2 problems:
- it would show in the documentation (but this is basically noise since it's already defined somewhere else)
- I would need to define it as, in
Animal
for example:type FamilyType = <Self::SubFamilyType as SubFamily>::FamilyType;
, but this gives me the following error
error[E0658]: associated type defaults are unstable
--> src/lib.rs:22:5
|
22 | type FamilyType = <Self::SubFamilyType as SubFamily>::FamilyType;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #29661 <https://github.com/rust-lang/rust/issues/29661> for more information
error: aborting due to previous error
And I don't really see if and how I could leverage generics to name the intermediate types...
Any ideas?