Fix a bug with contravariant type inference with non-concrete generic types. This can occur with function expressions that return function types where one of the parameter types might be non-concrete. For example, consider this function:
function collectionToStrings<T|m>(col:T[m], func:Function<{T[1]->String[1]}>[0..1]):String[m]
{
let toStringFunc = if($func->isEmpty(), |{x:T[1] | $x->toString()}, |$func->toOne());
$col->map(x | $toStringFunc->eval($x));
}
The issue would occur in computing the type for the if expression. Before the fix, the type would be computed as Function<Nil[1]->String[1]>, whereas it should be Function<T[1]->String[1]>.
This also improves how generic types are hashed when finding the best common generic type. The previous hashing strategy was not fully correct for the case where the raw type was a function type. That is, it might return different hash codes for function types that were equal. The historical reason for this was that the cost of figuring out whether something was a function type outweighed the benefits of having a fully correct hashing strategy. However, now the cost of figuring out whether something is a function type is significantly less, so the benefits now outweigh the costs. The hashing strategy is now fully correct.
In passing, do some clean ups, bug fixes, and other improvements that came up while investigating the issue in question.
Fix a bug with contravariant type inference with non-concrete generic types. This can occur with function expressions that return function types where one of the parameter types might be non-concrete. For example, consider this function:
The issue would occur in computing the type for the if expression. Before the fix, the type would be computed as
Function<Nil[1]->String[1]>
, whereas it should beFunction<T[1]->String[1]>
.This also improves how generic types are hashed when finding the best common generic type. The previous hashing strategy was not fully correct for the case where the raw type was a function type. That is, it might return different hash codes for function types that were equal. The historical reason for this was that the cost of figuring out whether something was a function type outweighed the benefits of having a fully correct hashing strategy. However, now the cost of figuring out whether something is a function type is significantly less, so the benefits now outweigh the costs. The hashing strategy is now fully correct.
In passing, do some clean ups, bug fixes, and other improvements that came up while investigating the issue in question.