Initializer expressions are always type checked against a pattern, so also
include the pattern in the solution application target and use that to
compute the contextual type from the pattern type.
Rework most of typeCheckExpression() to use SolutionApplicationTarget,
folding more information into that data structure and sinking more
expression-checking behavior down into the more general solver and
solution-application code.
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.
The right solution is to extend the notion of the "anchor" of a locator
to also cover statements (and TypeReprs, and Patterns, and more), so
this is a stop-gap.
Fix `getArgumentExpr` to not assume that constraint system
always asks for index that exists in an argument tuple,
because sometimes arguments could be synthesized (such
arguments do not have corresponding expression).
Resolves: rdar://problem/56221372
`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`.
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.
Introduce a `ImplicitCallAsFunction` locator path
element to represent an implicit member reference
to `callAsFunction`. Then adjust CSApply a little
to check whether it's finishing an apply for a
callable type, and if so build the implicit member
access.
Change the locator for the applicable fn
constraint for the inner subscript reference in an
implicit `outer[dynamicMember: \Inner.[0]]` expr
such that it uses the member locator with a
KeyPathDynamicMember element.
Then add a case to `getCalleeLocator` to handle
these locators. We also need to handle this
specially in `getArgumentInfoLocator` due to the
fact that the argument labels for the inner
subscript reference correspond to those written
by the user for the outer subscript reference.
Resolves SR-11933.
Resolves rdar://problem/57824025.
Now that overload binding for dynamic member
lookup occurs after having recorded the
`subscript(dynamicMember:)` overload, we can
attempt simplification of this constraint right
away.
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`.
Apply the same checks as ApplyExprs to
UnresolvedMemberExprs in getCalleeLocator to
resolve callees in cases where they're used with
`callAsFunction` in addition to a weird edge case
where we currently allow them with constructor
calls, e.g:
```
struct S {
static let s = S.self
}
let x: S = .s()
```
Arguably we should be representing ".member()"
expressions with an UnresolvedMemberExpr + CallExpr,
which would avoid the need to apply these special
cases, and reject the above syntax for not using
an explicit ".init". Doing so will likely require
a bit of hacking in CSGen though.
Resolves SR-11909.
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.
It's possible to construct subscript member responsible for key path
dynamic member lookup in a way which is going to be self-recursive
and an attempt to lookup any non-existent member is going to trigger
infine recursion.
Let's guard against that by making sure that the base type of the
member lookup is different from root type of the key path.
Resolves: rdar://problem/50420029
Resolves: rdar://problem/57410798
Solutions passed to `diagnoseAmbiguityWithFixes` aren't filtered
so we need to remove all of the solutions with the score worse
than overall "best". Also logic has to account for some fixes being
"warnings".
If none of the candidates produce expected contextual type, record
all of the posibilities to produce a note per and diagnose this as
contextual type mismatch instead of a reference ambiguity.
Add a case to getCalleeLocator to return the
appropriate locator for a call to an implicit
callAsFunction member reference.
Resolves SR-11386 & SR-11778.
Locator builders keep a pointer to their underlying
locator, so it's not generally sound to extend an
rvalue locator builder.
This commit enforces that withPathElement is called
on an lvalue, and adds a couple more overloads of
getConstraintLocator to make it more convenient to
extend locators with multiple elements.
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