Add the final conversion type and the flag indicating whether a given
expression is discarded to SolutionApplicationTarget, rather than
separating the arguments to the solver implementation.
If a type variable representing "function type" is a hole
or it could be bound to some concrete type with a help of
a fix, let's propagate holes to the "input" type. Doing so
provides more information to upcoming argument and result matching.
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.
Move constraint generation for statement conditions onto the
constraint system; it doesn't really have any reason to be located
within the function builder transform.
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.
* If there is a disjunction associated with closure type e.g.
coercion to some other type `_ = { $0 } as (Int32) -> Void`
* If there is a disjunction associated with a collection which
could provide more context to the constraint solver.
If there is `subtype` relationship between two type variables
binding inference algorithm attempts to infer supertype bindings
transitively, but it doesn't check whether some of the new types
are already included in the set, which leads to duplicate solutions.
If there is a subtype relationship between N types we have to make
sure that type chain is attempted in reverse order because we can't
infer bindings transitively through type variables and attempting
it in any other way would miss potential bindings across the chain.
Instead of trying to hold a "global" set of type variable differences
let's use pair-wise comparison instead because in presence of generic
overloads such would be more precise.
If there are N solutions for a single generic overload we currently
relied on "local" comparison to detect the difference, but it's not
always possible to split the system to do one. Which means higher
level comparisons have to account for "local" (per overload choice)
differences as well otherwise ranking would loose precision.
`getCalleeLocator` has to be able to:
- Retrieve type for given expression via `getType`;
- Simplify given type via `simplifyType`; and
- Retrieve a selected overload choice for a given locator via `getOverloadFor`.
Even if contextual closure type has type variables inside
prefer it over disjunction because it provides a lot of
contextual information early which helps to solve the system
faster.
While resolving closure use contextual locator information to
determine whether given contextual type comes from a "function builder"
parameter and if so, use special `applyFunctionBuilder` to open
closure body instead of regular constraint generation.
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 the way closures are handled in constraint system
let's introduce a special method which is responsible for generation of
constraints for closure body and connecting it to the rest of the
constraint system when contextual type becomes 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).
Separate closure from top-level constraint generation because
its body shouldn't be considered when it comes to parent/weight
computation, otherwise top expression in body is going to get
disconnected from the closure.
This is necessary for ambiguity diagnostics because none of the
solutions are applied back to the constraint system which means
that `getCalleeLocator` needs an ability to query information
from different sources e.g. constraint system and/or solution.
When type checking the body of a function declaration that has a function
builder on it (e.g., `@ViewBuilder var body: some View { ... }`), create a
constraint system that is responsible for constraint generation and
application, sending function declarations through the same code paths
used by closures.
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.
Previously we had a request for this in
IDETypeChecking, but this wasn't used for queries
made from Sema. Move the request into Sema, and
move `hasDynamicMemberLookupAttribute` onto
TypeBase.
There was a single place where it was used to determine whether
a binding comes from an argument conversion constraint. Since
constraint locator is part of the binding now it's possible to
use it instead and remove unused accessor.
Unify all of the fields of `PotentialBinding` which have to do with
location information into a single field with is either a constraint
(for regular bindings) or constraint locator (for "holes").
This helps to reduce the amount of space used by `PotentialBinding`
as well as propagate more contextual information when binding gets
attempted.
Rather than adjusting the opened types for choices
referring to `subscript(dynamicMember:)` down to
the result type, only use the result type to
bind the overload type variable. This avoids the
need for a couple of special cases in CSApply.
To facilitate this change, add
`ConstraintSystem::bindOverload`, which deals with
adding the necessary constraints to bind the
overload's type variable. The eventual goal here
is to remove `adjustTypeOfOverloadReference`, with
adjustments to the opened type being moved to
`getTypeOfMemberReference`, and the adding of
constraints being moved to `bindOverloadType`.