Overload resolution strategy
daniel.smith at oracle.com
Tue Jan 15 12:07:27 PST 2013
I had an off-list question about our motivation for "provisionally applicable" methods -- why not just do all the inference first and then do overload resolution? Here was my reply.
The problem is that we're committed to keeping overload resolution context-independent. The invocation's target type must not be considered before choosing the method resolution. Example:
String m(Object arg);
Object m(String arg);
String s = m("hi"); // resolves to m(String); the assignment has a type error
Context independence for overload resolution is an important property, because it simplifies the story that users need to grasp, and it helps to manage theoretical problems that arise from nesting.
The way this interacts with type inference is in two phases (the JLS and javac have been fuzzy on this):
1) a method is applicable if it is possible to infer valid type arguments based just on the invocation arguments
2) the actual type arguments for a method are inferred from the invocation arguments _and_ invocation target type
So inference happens twice; (1) may get a different answer than (2), and that's okay, because (1) is just a boolean "there exists a solution" test, while (2) produces the "real" answer.
Adding lambdas to the mix, there are cases in which a lambda cannot be typed until after we look at the invocation target. So we're left with dependencies that look like:
lambda argument type <- checking invocation target
checking invocation target <- overload resolution
overload resolution <- argument types
In order to break this circle, we remove the lambda from the set of arguments that need to be typed, and call the method provisionally applicable.
More information about the lambda-spec-experts