func foo(a: Int, b: Int) {}
func foo(a: String) {}
// Int and String should both be valid, despite the missing argument for the
// first overload since the second arg may just have not been written yet.
foo(a: <complete here>
func bar(a: (Int) -> ()) {}
func bar(a: (String, Int) -> ()) {}
// $0 being of type String should be valid, rather than just Int, since $1 may
// just have not been written yet.
bar { $0.<complete here> }
This is necessary in order to have access to private members of
a `ConstraintSystem` for testing purposes, such as logic related
to potential binding computation.
Implements iterative protocol requirement inference through
subtype, conversion and equivalence relationships.
This algorithm doesn't depend on a type variable finalization
order (which is currently the order of type variable introduction).
If a given type variable doesn't yet have its transitive protocol
requirements inferred, algorithm would use iterative depth-first
walk through its supertypes and equivalences and incrementally
infer transitive protocols for each type variable involved,
transferring new information down the chain e.g.
T1 T3
\ /
T4 T5
\ /
T2
Here `T1`, `T3` are supertypes of `T4`, `T4` and `T5`
are supertypes of `T2`.
Let's assume that algorithm starts at `T2` and none of the involved
type variables have their protocol requirements inferred yet.
First, it would consider supertypes of `T2` which are `T4` and `T5`,
since `T5` is the last in the chain algorithm would transfer its
direct protocol requirements to `T2`. `T4` has supertypes `T1` and
`T3` - they transfer their direct protocol requirements to `T4`
and `T4` transfers its direct and transitive (from `T1` and `T3`)
protocol requirements to `T2`. At this point all the type variables
in subtype chain have their transitive protocol requirements resolved
and cached so they don't have to be re-inferred later.
Instead of recording all of the binding "sources" let's only record
subtype, supertype and equivalence relationships which didn't materialize
as bindings (because other side is a type variable).
This is the only information necessary to infer transitive bindings
and protocol requirements.
While inferring bindings, let's record not only the fact that current
type variable is a subtype of some other type variable but track
constraint which establishes this relationship.