One more step towards incrementality of binding inference. Instead of
trying to determine literal protocol coverage during finalization
of the bindings, let's do that as soon as new bindings and/or literal
protocol requirements are discovered.
Literal protocol requirements are handled differently from other
protocols, they require additional contextual information (such
as coverage, direct/transitive distinction), and participate in
binding inference (could be turned into default bindings).
The only possible default which could satisfy both protocols is
`Double`, otherwise it has to be some custom type which conforms
to both protocols. Either way it's best to leave `ExpressibleByFloatLiteral`
in place to get to `Double` faster or make sure that custom type
conforms to it even if it would later fail `ExpressibleByIntegerLiteral`
conformance, at least that wouldn't introduce any unviable bindings.
Since `ExpressibleByNilLiteral` doesn't have a default type,
there is no need to track it in the set of protocols that could
produce defaultable bindings if not "covered" by existing bindings.
Let's keep defaults separate from direct and transitive bindings,
that would make it easier to handle them in incremental model.
Instead of generating bindings for defaults and adding to the main
set, let's allow producer to choose what to do with them once type
variable has been picked for attempting.
Look through specifier (inout, l-value) and optional types while
checking for presence of dependent member types to avoid inferring
incorrect bindings (which could lead to infinite recursion in the
solver).
Resolves: SR-13856
Resolves: rdar://problem/71383770
As a step towards making binding inference more incremental, let's
make producer responsible for adding hole type binding instead of
doing so in `finalize`.
Wrapping bindings into optional type based on presence of
an `ExpressibleByNilLiteral` conformance requirement should
be done after type variable has been selected for attempting.
Otherwise such upfront work would be wasteful since it doesn't
affect binding ranking in any way.
Replaces `InvolvesTypeVariables` flag with a set of adjacent type
variables found during binding inference.
This approach is more suitable for incremental binding computation
because it allows to maintain a list of type variables that affect
ranking and check whether something has been resolved without having
to re-evaluate constraints associated with the given type variable.
Use `DelayedBy` in more places:
- If type variable is associated with a disjunction constraint let's
mark it as been delayed by it (until the disjunction is actually
attempted);
- Type variable is "delayed" by presence of member constraint
(of any kind) only if it stands for a member type. Such type
variable would be resolved once the member constraint is
simplified.
If type variable is still connected to `ApplicableFunction` that
means it's either an argument, result or represents a function
(member reference, operator) being applied. Regardless of exact
location such type variable should be delayed until call is
completely resolved to get additional context from parameters,
result type of a function being applied.
- Keep track of all constraints which caused a particular type variable to
be de-prioritized.
- Convert a property to a method which would determine whether
given set of potential bindings is "fully bound" and has to
be delayed until certain constraints are simplified.
Restore recently removed logic to mark type variable representing
closure parameter used in the body of a closure as potentially
incomplete to delay attempting it until `BindParam` is simplified.
Resolves: rdar://problem/71858936
Instead of attempting to join only the last recorded supertype
binding, let's attempt to join any previously recorded supertype
binding with an incoming one to make sure that set contains only
the most viable types.
Following on from updating regular member completion, this hooks up unresolved
member completion (i.e. .<complete here>) to the typeCheckForCodeCompletion API
to generate completions from all solutions the constraint solver produces (even
those requiring fixes), rather than relying on a single solution being applied
to the AST (if any). This lets us produce unresolved member completions even
when the contextual type is ambiguous or involves errors.
Whenever typeCheckExpression is called on an expression containing a code
completion expression and a CompletionCallback has been set, each solution
formed is passed to the callback so the type of the completion expression can
be extracted and used to lookup up the members to return.
Since closure body isn't opened until its contextual type is resolved
there is no need to explicitly delay attempting bindings for closure
parameter used in the body anymore.
Let all of the members of the equivalence class be represented by
the first type variable encountered during the depth-first walk.
This means that supertypes are inferred from the members and all
of the transitive protocol requirements are distributed among the
members upon return back to the "representative".
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.
If the hole is originated from code completion expression
let's not try to add a fix, anything connected to a
code completion is allowed to be a hole because presence
of a code completion token makes constraint system
under-constrained due to e.g. lack of expressions on the
right-hand side of the token, which are required for a
regular type-check.
If type variable is associated with a code completion token
it's possible that it doesn't have enough contextual information
to be resolved to anything, so let's add a hole type which originates
from type variable associated with code completion expression to
make this relationship explicit and avoid "fixing" problems rooted
in fact that type variable is underconstrained due to code completion.
Add a separate method `fixForHole` on `TypeVariableBinding`
responsible for determining whether fix is required and if so,
what kind of fix to apply when a particular type variable is
resolved to a hole.
If subtyping is allowed for a result type of an implicit member chain,
let's delay binding it to an optional until its object type resolved too or
it has been determined that there is no possibility to resolve it.
Otherwise we might end up missing solutions since it's allowed to
implicitly unwrap base type but it can't be done early - type variable
representing chain's result type has a different l-valueness comparing
to generic parameter of an optional.
This used to work before due to a hack in constraint generator where
unresolved member with arguments would return base type (which
doesn't allow l-value) instead of a result type.
Resolves: rdar://problem/68094328