- Use `int` instead of `unsigned int` to represent # of non-defaultable bindings.
Because the formula is `-(Total - Defaultable)` which could only be `0` or negative.
- Increase number of defaultable bindings iff the binding is accepted.
* Gardening for `@dynamicMemberLookup`.
- Unify code style of `@dynamicMemberLookup` and `@dynamicCallable` implementations.
- Use consistent variable names, diagnostic messages, doc comments, etc.
- Move `@dynamicMemberLookup` test to `test/attr` directory.
When `bind param` constraint is associated with a given
type variable a set of bindings collected for it is
potentially incomplete, because binding gathering doesn't
look through related type variables. Which means that
such type variable has to be de-prioritized until
`bind param` constraint is resolved or there is just
nothing else to try, otherwise there is a risk that
solver would skip some of the valid solutions.
This only affects type variable that appears one the
right-hand side of the `bind param` constraint and
represents result type of the closure body, because
left-hand side gets types from overload choices.
Resolves: rdar://problem/45659733
* Implement dynamically callable types (`@dynamicCallable`).
- Implement dynamically callable types as proposed in SE-0216.
- Dynamic calls are resolved based on call-site syntax.
- Use the `withArguments:` method if it's defined and there are no
keyword arguments.
- Otherwise, use the `withKeywordArguments:` method.
- Support multiple `dynamicallyCall` methods.
- This enables two scenarios:
- Overloaded `dynamicallyCall` methods on a single
`@dynamicCallable` type.
- Multiple `dynamicallyCall` methods from a `@dynamicCallable`
superclass or from `@dynamicCallable` protocols.
- Add `DynamicCallableApplicableFunction` constraint. This, used with
an overload set, is necessary to support multiple `dynamicallyCall`
methods.
When `bind param` constraint is associated with a given type
variable a set of bindings collected for it is potentially
incomplete, because binding gathering doesn't look through related
type variables. Which means that such type variable has to be
de-prioritized until `bind param` constraint is resolved
or there is just nothing else to try, otherwise there is a
risk that solver would skip some of the valid solutions.
Resolves: rdar://problem/45659733
In cases where we have multiple designated types, sort the types that
were designated for this operator based on any information we can
gather about actual argument types at usage sites.
We can consider extending this further in a future commit to ignore
designated types when we have concrete type information that we are
confident of.
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.