SolutionResult better captures what can happen when solving a constraint
system for the given expression occurs than the ad hoc SolutionKind return
& small vector of Solution results. Also, try to make this logic less
convoluted.
Generalize the representation of contextual types so we can store
contextual types for more than one expression. Allow these to be
added/rolled back in solver scopes. Nothing uses this functionality
yet.
When requesting information about the contextual type of a constraint
system, do so using a given expression rather than treating it like
the global state that it is.
This constraint connects type variable representing a closure
expression to its inferred type and behaves just like regular
`Defaultable` constraint expect for type inference where it's
used only if there are no contextual bindings available.
In preparation to change type-checking behavior of closures
we need to introduce a special mapping from closure expressions
to their inferred types (based on parameters/result and body).
Chip away at the expression-centric nature of the constraint system by
generalizing the "target" of solution application from a single
expression to a a "SolutionApplicationTarget", which can be an
expression or a function body. The latter will be used for applying
function builders to an entire function body.
Introduce a new kind of constraint, the "value witness" constraint,
which captures a reference to a witness for a specific protocol
conformance. It otherwise acts like a more restricted form of a "value
member" constraint, where the specific member is known (as a
ValueDecl*) in advance.
The constraint is effectively dependent on the protocol
conformance itself; if that conformance fails, mark the type variables
in the resolved member type as "holes", so that the conformance
failure does not cascade.
Note that the resolved overload for this constraint always refers to
the requirement, rather than the witness, so we will end up recording
witness-method references in the AST rather than concrete references,
and leave it up to the optimizers to perform devirtualization. This is
demonstrated by the SIL changes needed in tests, and is part of the
wider resilience issue with conformances described by
rdar://problem/22708391.
Rather than maintaining a linked list of overload
choices, which must be linearly searched each time
we need to lookup an overload at a given callee
locator, use a MapVector which can be rolled back
at the end of a scope.
Remove ResolvedOverloadSetListItem in favor of
using SelectedOverload, which avoids the need to
convert between them when moving from
ConstraintSystem to Solution.
Some constraint transformations require knowledge about what state
constraint system is currently in e.g. `constraint generation`,
`solving` or `diagnostics` to make a decision whether simplication
is possible. Notable example is `keypath dynamic member lookup`
which requires a presence of `applicable fn` constraint to retrieve
some contextual information.
Currently presence or absence of solver state is used to determine
whether constraint system is in `constraint generation` or `solving`
phase, but it's incorrect in case of `diagnoseFailureForExpr` which
tries to simplify leftover "active" constraints before it can attempt
type-check based diagnostics.
To make this more robust let's introduce (maybe temporarily until
type-check based diagnostics are completely obsoleted) a proper
notion of "phase" to constraint system so it is always clear what
transitions are allowed and what state constraint system is
currently in.
Resolves: rdar://problem/57201781
Rework the interface to ConstraintSystem::salvage() to (a) not require
an existing set of solutions, which it overwrites anyway, (b) not
depend on having a single expression as input, and (c) be clear with
its client about whether the operation has already emitted a
diagnostic vs. the client being expected to produce a diagnostic.
Rather than setting up the constraint solver with a single expression
(that gets recorded for parents/depths), record each expression that
goes through constraint generation.
solve() is a bit too overloaded, so rename the version that does the
core "evaluate all of the steps to produce a set of solutions"
functionality to solveImpl().