bestViableResolution
This functions gives the language a chance to refine the results of a SymbolResolver.resolveWithArguments by choosing the best viable function(s) out of the set of viable functions. It can also influence the CallResolutionResult.SuccessKind of the resolution, e.g., if the result is ambiguous.
The default implementation will follow the following heuristic:
If the list of CallResolutionResult.viableFunctions is empty, we can directly return.
If we have only one item in CallResolutionResult.viableFunctions, we can take it.
Next, we can check for direct matches, meaning that they have a SignatureResult that only has DirectMatch casts.
Lastly, if we have no direct matches, we need to sort the viable functions using a simple ranking. The function(s) will the best (lowest) SignatureResult.ranking will be chosen as the best. The ranking is determined by the CastResult.depthDistance of all cast results in the signature results.