seen benefit from.
This was added at one point after the observation that it may in
theory allow us to solve constraint systems more quickly, but there
wasn't really a motivating test case and we do not know of any real
code that it helps with.
We currently have a problem in the solver in that we are both
short-circuiting evaluation of constraints systems, *and* do not have
a stable order that we visit disjunctions. These in combination can
result in inconsistent and unpredictable results, so I am moving to
enforce a stable order for visiting disjunctions, and that requires
this code to be removed.
to be stable.
We currently will stop visiting the elements of a disjunction under
certain circumstances once we have found a solution. The result we get
is inherently dependent on the order in which we determine to visit
the disjunctions themselves (in addition to the elements of the
disjunction).
This change makes the order in which we visit disjunctions
stable. Future commits will create a stable ordering for the elements
of disjunctions. Once we also have that stable ordering in place we
can in theory short circuit more often as part of changing the way in
which we decide what the "best" solution is to a system.
This results in an expression in
validation-test/stdlib/AnyHashable.swift.gyb no longer being able to
typecheck in a reasonable amount of time, so I had to tweak that
expression.
Instead of mixing flags between type-checker and constraint solver, let's
move the ones which are useful in constraint system there. Doing
so allows for `solveForExpression` to be moved from `TypeChecker` to
`ConstraintSystem` which consolidates solver logic.
It also allows to set these flags as part of constraint generation/solving,
which is sometimes important.
We sometimes see expression type checking times increase dramatically
when this is enabled, and having a way to disable will make it
possible to easily do measurements to determine the cost/benefit of
having this enabled.
The call to `solveRec`, below, immediately performs this same check. While that doesn't result in an early return from `solve`, the effect appears to be the same.
When selecting the next disjunction to attempt, try to find one that
is a disjunction of bindings where the type being bound is the
converted-to type in a conversion constraint. Attempting these early
makes it possible to split constraint systems, eliminating exponential
behavior.
Fixes: rdar://problem/40344044
This disappeared in the rework of IUOs but is needed when we have
multiple potential solutions involving different sets of overloads or
type bindings.
Fixes rdar://problem/37475971.
Many (perhaps most?) calls to createTypeVariable explicitly pass 0 for
options. This change just defaults the parameter to 0 and removes all
the explicit 0's in the code.
Don't try to short-circuit disjunctions if one of the choices
produced tuple-to-tuple conversion since that doesn't mean
that there are no other choices out there.
Don't attempt to store literal bindings directly to `PotentialBindings`
since they might get superseded by non-literal bindings deduced from
other constraints, also don't attempt to check literal protocol conformance
on type variables or member types since such types would always end-up
returning trivial conformance which results in removal of viable literal types.
Resolves: rdar://problem/38535743
Such overloads are not going to result in viable solutions anyway,
so it makes sense to attempt them only if solver failed to deduce
proper solution.
Helps to improve type-checking performance of operators which have
multiple unavailable overloads for compatibility reasons.
The current implementation isn't really useful in the face of generic
overloads. It has never been enabled by default, and isn't useful to
keep around if it is disabled. If we ever want to bring it back,
we know where to look!
Improve situation around closure parameter/argument contractions
by allowing such action if it can be proved that none of the bindings
would result in solver attempting to bind parameter to `inout` type.
Resolves: rdar://problem/36838495
If a prior solution required fixes, do not skip generic
overloads. They might result in a fix-free solution.
Suggested by @xedin as an adjunct to a similar change I made for
short-circuiting disjunctions.
There are cases where disjunctions created for IUOs can be solved with
the Optional choice if a fix is applied. We do not want to stop with
this solution as we may be able to solve the constraint system without
a fix by selecting the non-Optional side.
I have opened a JIRA, SR-6626, to investigate one small regression in
diagnostics with this change.
Instead of binding collection types directly let's try to
bind using temporary type variables substituted for element
types, that's going to ensure that subtype relationship is
always preserved.
Resolves: rdar://problem/35541153
There are situations where we know equivalence relationship between
multiple disjunctions, let's prune dependent choice space based on
choice picked for the parent disjunction.
Resolves: rdar://problem/35540159
Consider different overload choices for the same location in evaluation
order, this makes overload resolution more predictable because it's going
to follow expression bottom-up, that prevents situations when some
expressions are considered ambigious because choices taken further up
equate the score, instead each level is given distinct weight
based on evaluation order.
Resolves: rdar://problem/31888810
Currently edge related to the parameter bindings is contracted
without properly checking if newly created equivalence class has
the same inout & l-value requirements. This patch improves the
situation by disallowing contraction of the edges related to parameter
binding constraint where left-hand side has `inout` attribute set.
Such guarantees that parameter can get `inout` type assigned when
argument gets `l-value` type.
Resolves: rdar://problem/33429010
If the best bindings we could get on the current step are bindings
to literal type without any other type variable involved, let's try
to attempt them right away, that should help to prune search space.
When dealing with explicit coercions apply their conversions
early to avoid searching for solutions with incorrect types,
and therefore prune search space.
Move disjunction selection logic one level up from the `solveSimplified`
which allows to simplify its logic and avoid collecting disjunctions
multiple times for each solver step.
Sort constraint components/buckets based on how many disjunctions
they have, that helps to prune some of the branches with incorrect
solutions early which limits overall depth of the search.
Resolves: SR-4714
Limit the scope of the performance hacks which currently exist in the
solver even further by disallowing it to skip generic overlaods or stop
in case when previous solutions involve unavailable overloads, which
otherwise might lead to producing incorrect overall solutions.