A simpler (from the user’s perspective), but more radical approach could be to change the method call syntax resolution algorithm such that when resolving:
receiver.method(args..)
if every resolution method (inherent impls, trait methods) fails, the compiler will look for a free function in scope:
method(receiver, args...)
This requires zero changes to user code, and it should be backwards compatible since it is used as a fallback.
Another addition, for when the function is not in scope is to allow the caller to write:
receiver.path::to::method(args..)
This also has benefits for traits.
receiver.Itertools::flatten()
The first proposed mechanism has the following benefits:
- It is general
- It requires no changes to user code
It has the following drawbacks:
-
It could lead to questions for an unsuspecting reader:
“where is this method defined? uh… can’t find it; <wait a bit> ooh, it is a free function!”
I believe the main proposal in this thread should also suffer these drawbacks. (?)
A mitigating factor is RLS and IDEs which can make it easier to find the definition of the called function.
Unresolved questions:
- Does this interact in weird ways with Deref-coersion?