Arbitrary currying is no longer allowed so level could be switched
to a boolean flag for methods like `computeDefaultMap` to identify
if they need to look through curried self type or not.
This counts the number of leaf scopes we reach while solving the
constraint sytem, and is a much better measure of the growth of
unnecessary work than the total number of scopes opened.
There were two tests where I had a difficult time getting scale-test
to fit the curve even after adjusting some of the parameters, so I've
left those to use the old stat for now.
Currently (with or w/o failures) constraint system is not returned
back to its original state after solving, because constraints from
initial "active" list are not returned to the system. To fix that
let's allocate "initial" scope which captures state right before
solving begins, and add "active" list to the solver state to capture
information about "active" constraints at the time of its creation.
This is follow-up to https://github.com/apple/swift/pull/19873
For now this is only used for the same purpose as the previous type
constraint walking utility function.
Eventually we can incorporate this into our selection of overload
choices.
There's no need to instantiate archetypes in the generic environment
of the declaration being opened.
A couple of diagnostics changed. They were already misleading, and the
new diagnostics, while different, are not any more misleading than
before.
It was useful when logic related to `BridgingConstraint` was part of
`Conversion` constraint, which could be generated as a result of implicit
conversion for an operator parameter.
Rename `needsToComputeNext()` to `isEndOfPartition()` and have
`shouldStopAfter()` test `AnySolved() && isEndOfPartition()` to
determine if we can stop iterating over choices for the current step.
Update DisjunctionChoiceProducer so that it creates a sorted ordering
of the choices in the disjunction as well as a partitioning of those
choices.
If we hit the end of a partition and have found a solution, we'll stop
attempting choices from this disjunction.
For now we'll default to keeping the same order that the disjunctions
initially have, and will put them all into the same partition. A
future commit will implement logic to implement more interesting
partitions of the choices.
Attempt to visit disjunctions that are associated with applies where
we have at least some useful information about the types of all of the
arguments before visiting other disjunctions.
Two tests here got faster, and one slightly slower. One of the
faster tests is actually moving from test/ to the slow/ directory in
validation-test because despite going from 16s to less than 1s, it was
still borderline for what we consider the slow threshold, so I made
the test more complex. The one that got a little slower is
rdar22022980, which I also made more complex so that it is clearly
"slow" by the way we are testing it.
slower:
rdar22022980.swift
faster:
rdar33688063.swift
expression_too_complex_4.swift
Instead of printing `trying` for type variable and `assuming`
for disjunction choices, unify it so `BindingStep` logs
`attempting {type variable, disjunction choice}`.
Extract choice attempting logic into `DisjunctionStep::attemptChoice`
and start recording taken choices in constraint system when
requested by disjunction.
`DisjunctionStep` attempts all of the viable choices,
at least one of the choices has to succeed for disjunction
to be considered a success.
`DisjunctionStep` attempts each choice and generates followup
`SplitterStep` to see if applying choice to constraint system
resulted in any simplification.
* `SplitterStep` is responsible for running connected components
algorithm to determine how many independent sub-systems there are.
Once that's done it would create one `ComponentStep` per such
sub-system, and move to try to solve each and then merge partial
solutions produced by components into complete solution(s).
* `ComponentStep` represents a set of type variables and related
constraints which could be solved independently. It's further
simplified into "binding" steps which attempt type variable and
disjunction choices.
* "Binding" steps such as `TypeVariableStep` and `DisjunctionStep`
are responsible for trying type binding choices in attempt to
simplify the system and produce a solution. After attempting each
choice they introduce a new "split" step to compute more work.
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.