This is likely out of scope for this RFC, but I wanted to bring it up as a fairly egregious example of how bad this can look. There's some context for this in my stackoverflow question here.
The error message in this case is:
error[E0599]: no method named `into_actor` found for type `Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>>` in the current scope
--> src/app_socket.rs:194:26
|
194 | .into_actor(&self)
| ^^^^^^^^^^ method not found in `Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>>`
|
= note: the method `into_actor` exists but the following trait bounds were not satisfied:
`&dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send : WrapFuture<_>`
`&dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send : WrapStream<_>`
`&mut dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send : WrapFuture<_>`
`&mut dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send : WrapStream<_>`
`&mut Pin<std::boxed::Box<dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send>> : WrapFuture<_>`
`&mut Pin<std::boxed::Box<dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send>> : WrapStream<_>`
`&Pin<std::boxed::Box<dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send>> : WrapFuture<_>`
`&Pin<std::boxed::Box<dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send>> : WrapStream<_>`
`dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send : WrapFuture<_>`
`dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send : WrapStream<_>`
`Pin<std::boxed::Box<dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send>> : WrapFuture<_>`
`Pin<std::boxed::Box<dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send>> : WrapStream<_>`
I believe I already removed some of the paths here. Your proposal would help a lot, reducing it to something like:
error[E0599]: no method named `into_actor` found for type `Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>>` in the current scope
--> src/app_socket.rs:194:26
|
194 | .into_actor(&self)
| ^^^^^^^^^^ method not found in `Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>>`
|
= note: the method `into_actor` exists but the following trait bounds were not satisfied:
`&dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send : WrapFuture<_>`
`&dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send : WrapStream<_>`
`&mut dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send : WrapFuture<_>`
`&mut dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send : WrapStream<_>`
`&mut Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>> : WrapFuture<_>`
`&mut Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>> : WrapStream<_>`
`&Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>> : WrapFuture<_>`
`&Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>> : WrapStream<_>`
`dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send : WrapFuture<_>`
`dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send : WrapStream<_>`
`Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>> : WrapFuture<_>`
`Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>> : WrapStream<_>`
But I think this could be even better. There is a large type:
Future<Output = Result<Vec<ResultType>, Box<dyn Error>>>
Which is repeated on every line of the implementation list. If this could be transformed into a named type it could be written something like:
error[E0599]: no method named `into_actor` found for type `Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>>` in the current scope
--> src/app_socket.rs:194:26
|
194 | .into_actor(&self)
| ^^^^^^^^^^ method not found in `Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>>`
|
= note: the method `into_actor` exists but the following trait bounds were not satisfied:
`&dyn F + Send : WrapFuture<_>`
`&dyn F + Send : WrapStream<_>`
`&mut dyn F + Send : WrapFuture<_>`
`&mut dyn F + Send : WrapStream<_>`
`&mut Pin<Box<dyn F + Send>> : WrapFuture<_>`
`&mut Pin<Box<dyn F + Send>> : WrapStream<_>`
`&Pin<Box<dyn F + Send>> : WrapFuture<_>`
`&Pin<Box<dyn F + Send>> : WrapStream<_>`
`dyn F + Send : WrapFuture<_>`
`dyn F + Send : WrapStream<_>`
`Pin<Box<dyn F + Send>> : WrapFuture<_>`
`Pin<Box<dyn F + Send>> : WrapStream<_>`
where F is the type:
`Future<Output = Result<Vec<ResultType>, Box<dyn Error>>>`
Then you end up with, again, a significantly more readable error.
I imagine this could be implemented based on a cost function. When the size of some subtype in the error expressions is greater than some weight introduce a named type, starting with the same letter if possible, and rewrite the error expressions using it. I must admit I'm not that confident this would be feasible however.