TypeResolutionFlags is overly complicated at the moment because the vast
majority of flag combinations are impossible and nonsensical. With this
patch, we create a new TypeResolverContext type that is a classic enum
and far easier to reason about. It also enables "exhaustive enum"
checking, unlike the "flags" based approach.
This is a legacy holdover from when tuple types had default
arguments, and also the constraint solver's matching of function
types pre-SE-0110.
Well, move the last live usage to CSDiag, where it can die a slow
painful death over time. The other usages were not doing anything.
This is helpful in experimenting with constraint solver changes that
might help us remove some of these unsound options. It's not ever mean
to be enabled, but if we're able to remove the things guarded by the
option we can eventually remove the option.
so that they must result in an optional type.
Add constraint locator path for identifying constraints/variables that are part of the convert type passed into the system.
Polling the timers used to measure “expression too complex” is not *that*
cheap. When the constraint solver is doing a lot of work, the overhead can
add up. Reduce the number of places where we poll the timer down to
main decision points (i.e., before exploring a disjunction or binding a
new type variable), taking the timing overhead from ~3.7% —> ~1.7%.
Most of the use-cases of `gatherConstraints` require filtering
at least based on the constraint kind that caller is interested in,
so instead of returning unrelated results and asking caller to
filter separately, let's add that functionality directly to
`gatherConstraints`.
Since it's possible to find the same constraint through two different
but equivalent type variables, let's use a set to store constraints
instead of a vector to avoid processing the same constraint multiple
times.
Rather than avoiding short-circuiting if we've selected any
unavailable overload or applied any fixes as part of the previously
found solution, only avoid short-circuiting if selecting those
overloads or applying those fixes was a direct result of the
disjunction choice we were visiting in the previously found solution.
For now, the accessors have been underscored as `_read` and `_modify`.
I'll prepare an evolution proposal for this feature which should allow
us to remove the underscores or, y'know, rename them to `purple` and
`lettuce`.
`_read` accessors do not make any effort yet to avoid copying the
value being yielded. I'll work on it in follow-up patches.
Opaque accesses to properties and subscripts defined with `_modify`
accessors will use an inefficient `materializeForSet` pattern that
materializes the value to a temporary instead of accessing it in-place.
That will be fixed by migrating to `modify` over `materializeForSet`,
which is next up after the `read` optimizations.
SIL ownership verification doesn't pass yet for the test cases here
because of a general fault in SILGen where borrows can outlive their
borrowed value due to being cleaned up on the general cleanup stack
when the borrowed value is cleaned up on the formal-access stack.
Michael, Andy, and I discussed various ways to fix this, but it seems
clear to me that it's not in any way specific to coroutine accesses.
rdar://35399664
I am reverting the effect of 6fa403dc7d
in 7fd052efd8, and removing this
optimization was dependent on that change in ordering.
This reverts commit c29f660652.
Implementation is as follows: In `preCheckExpression` try to
detect if there is `T(literal)` call in the AST, replace it with
implicit `literal as T`, while trying to form type-checked AST,
after constraint solving, restore source information and drop
unnecessary coercion expression.
Resolves: rdar://problem/17088188
Resolves: rdar://problem/39120081
Resolves: rdar://problem/23672697
Resolves: rdar://problem/40379985
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