The idea so to split solving into non-recursive steps,
represented by `SolverStep`, each of the steps is resposible
for a unit of work e.g. attempting type variable or
disjunction bindings/choices.
Each step could produce more work via "follow-up" steps,
complete "partial" solution when it's done, or error which
terminates solver loop.
* Extract logic for attempting individual choices into `solveForDisjunctionChoice`
* Remove all of the unnecessary information from `DisjunctionChoice`
* Convert auxiliary logic to operate on `TypeBinding` instead of `DisjunctionChoice`
Introduce `TypeBinding` interface with a single `attempt` method
which is useful to encapsulate specific binding logic used for
attempting disjunction choices and type variable bindings under
a single interface. This makes it easier to unify top-level logic
responsible for binding enumeration.
It should also make it possible to introduce unified binding producer
interface in the future.
Currently `allowFreeTypeVariableBindings` flag has to be passed all
the way down from top-level `solve` call to `finalize` that forms
(partial and complete) solutions. Instead of doing that, let's just
make it a part of the solver state, which is already present
throughout whole solver run.
Encapsulate most of the logic related to new binding generation
and iteration into `TypeVarBindingGenerator`. `tryTypeVariableBindings`
is only responsible for attempting bindings and recording results.
One more step towards iterative solver.
* Move logic to ensure that r-value type var would get r-value type to `PotentialBindings`;
* Strip uncessary parens directly when creating `PotentialBinding`;
* Check if the binding is viable before inclusion in the set, instead of filtering it later;
* Assert that bindings don't have types with errors included in the set.
Instead of passing a set of choices, locator and other flags to
`solveForDisjunctionChoices` directly, let's wrap all that information
into "disjunction" iterator which returns `DisjunctionChoice`s
directly.
Since this logic is tightly coupled to constraint, it makes sense
to move just there, also it's easier to re-use it elsewhere since
it doesn't have to be `private` anymore.
Now that function types cannot have a naked type variable as
their input type it's no longer possible to have an unsolved
ArgumentTupleConversion constraint, so we can bypass most of
the logic in matchTypes() and call matchCallArguments() instead.
Now that function types cannot have a naked type variable as
their input type we should never end up down this code path
with an associated declaration and argument labels, so it's
OK to just call matchTypes() on the input types instead.
These are temporary.
FunctionInput is conditional on fixing some ranking behavior to not
depend on type variables having argument tuples bound to them.
Hopefully we can replace TVO_PreferSubtypeBinding with a better
mechanism that compares overload types instead.
FunctionResult is used in CSDiag's contextual type diagnostics.
This is also on the chopping block.
Merge logic from `diagnoseAssignmentFailure` and `diagnoseSubElementFailure`
into new `AssignmentFailure`, together with their support functions, which
decouples `CSDiagnostics` from `CSDiag` and scrubs latter from some functionality.
If all of the solutions in the set have a single fix, which points
to the common anchor, attempt to diagnose the failure as an
ambiguity with a list of candidates and their related problems as notes.
Having richer message like that helps to understand why something is
ambiguous e.g. if there are two overloads, one requires conformance
to some protocol and another has a same-type requirement on some type,
but neither matched exactly, having both candidates in the diagnostic
message with associated errors, instead of simplify pointing to related
declarations, helps tremendously.
Pass constraint system down into offering force unwrap fixits so that we can identify the type of the last member chosen for an optional chain. If there's a chain and the last member's return type isn't optional, then it's cleaner to offer to change that last '?' into a '!' to perform the force, rather than parenthesize the whole expression and force the result.
using it.
It was added to use for selecting the order we visit disjunctions, but
this order turned out to not be great (and I don't think there are
simple variations on the creation order, like reverse order), that
will work well either.
Instead of having to obtain type-checker instance through
constraint system, let's have `emitDiagnostic` do that and
forward all of the argument for easy access.
Aim of this new diagnostic abstraction is to encapsulate each
individual failure into its own class with some shared base.
Good example of this - diagnostics related to generic requirement
failures, where each kind (conformance, same-type etc.) has
some specific logic e.g. diagnostic message but the all share
the same traits like affected declaration/requirement.
Since information comes from `Solution` anyway, it's good to have
that logic localized, but it's also useful for diagnostics based on
fixes attached to solutions.
Any solution which doesn't require source changes should be considered
better than any other solution which does.
Otherwise solutions with fixes are always considered better than
solutions with unavailable overloads, which isn't correct especially
considering that different types of errors are now diagnosed via
forming solutions with fixes.
If fixes are allowed let solver record missing protocol conformance
requirements and assume that `conformsTo` constraint is successfully
solved, this helps to diagnose such errors without involving
heavy-weight expression based diagnostics.
Resolves: rdar://problem/40537858