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().
ProtocolConformanceRef already has an invalid state. Drop all of the
uses of Optional<ProtocolConformanceRef> and just use
ProtocolConformanceRef::forInvalid() to represent it. Mechanically
translate all of the callers and callsites to use this new
representation.
A "hole" is a type variable which type couldn't be determined
due to an inference failure e.g. missing member, ambiguous generic
parameter which hasn't been explicitly specified.
It is used to propagate information about failures and avoid
recording fixes which are a consequence of earlier failures e.g.
```swift
func foo<T: BinaryInteger>(_: T) {}
struct S {}
foo(S.bar) // Actual failure here is that `S` doesn't have a member
// `bar` but a consequence of that failure is that generic
// parameter `T` doesn't conform to `BinaryInteger`.
```
Such tracking makes it easier to ignore already "fixed" requirements
which have been recorded in the constraint system multiple times e.g.
a call to initializer would open both base type and initializer
method which have shared (if not the same) requirements.
One-way constraint expressions, which are the only things that
introduce one-way constraints at this point, want to look through
lvalue types to produce values. Rename OneWayBind to OneWayEqual, map
it down to an Equal constraint when it is simplified (to drop
lvalue-ness), and apply that coercion during constraint application.
Part of rdar://problem/50150793.
There were a few places where we wanted fast testing to see whether a
particular type variable is currently of interest. Instead of building
local hash tables in those places, keep type variables in a SetVector
for efficient testing.
Now that we've moved to C++14, we no longer need the llvm::make_unique
implementation from STLExtras.h. This patch is a mechanical replacement
of (hopefully) all the llvm::make_unique instances in the swift repo.
When we transform each expression or statement in a function builder,
introduce a one-way constraint so that type information does not flow
backwards from the context into that statement or expression. This
more closely mimics the behavior of normal code, where type inference
is per-statement, flowing from top to bottom.
This also allows us to isolate different expressions and statements
within a closure that's passed into a function builder parameter,
reducing the search space and (hopefully) improving compile times for
large function builder closures.
For now, put this functionality behind the compiler flag
`-enable-function-builder-one-way-constraints` for testing purposes;
we still have both optimization and correctness work to do to turn
this on by default.