We should be able to attach fixes to overload choices that don't
refer to declarations e.g. keypath applications which refer to
`AnyObject` is a base type.
VarargExpansionExpr shows up in call argument lists in synthesized
initializers and modify accessors when we need to forward arguments
to a call taking varargs.
Previously we would say that the type of VarargExpansionExpr is
$T when its subexpression type is [$T]. matchCallArguments() would
then 'collect' the single VarargExpansionExpr into a variadic
argument list with a single element, and build an ArgumentShuffleExpr
for the argument list.
In turn, SILGen would peephole vararg emission of a variadic
argument list with a single entry that happens to be a
VarargExpansionExpr, by returning the subexpression's value,
which happened to be an array of the right element type,
instead of building a new array containing the elements of the
variadic argument list.
This was all too complicated. Instead, let's say that the type of
a VarargExpansionExpr is [$T], except that when it appears in a
TupleExpr, the variadic bit of the corresponding element is set.
Then, matchCallArguments() needs to support a case where both
the parameter and argument list have a matching vararg element.
In this case, instead of collecting multiple arguments into a
single variadic argument list, we treat the variadic argument like
an ordinary parameter, bypassing construction of the
ArgumentShuffleExpr altogether.
Finally, SILGen now needs to be able to emit a VarargExpansionExpr
in ordinary rvalue position, since it now appears as a child of a
TupleExpr; it can do this by simply emitting the sub-expression
to produce an array value.
Cases with arguments form `(Self.Type) -> (Arg...) -> Self`
function types, so `areConservativelyCompatibleArgumentLabels`
should remove curried self before trying to match argument/parameter
labels.
Resolves: rdar://problem/49159472
Try to form a "complete" set of overload choices based on lookup
results, which means include both viable and unviable-but-fixed
candidates for solver to attempt. Latter are going to be skipped
until "salvage" mode so there should be no overhead for the solver
in "performance first" mode.
Instead of waiting until the overload is attempted, let's figure out
if there is anything wrong with it beforehand and attach a fix to the
"bind overload" constraint representing it.
Further simplify `addOverloadSet` and move "outer" candidate handling
to the only place where it comes up - `simplifyMemberConstraint`.
Also move constraint generation for choices into a separate method.
This is a stepping stone on the path to enable attaching fixes to
the overload choices.
When we’re trying to find the overload set corresponding to a particular
type variable, look through “optional object of” constraints that represent
the use of ? binding or ! forcing. This allows us to find overload sets
when referring to, e.g., @objc optional protocol requirements.
This narrow favoring rule makes more sense as part of disjunction
partitioning, because it is not dependent on the use site at all and
should only kick in when other options fail.
Detect and fix closure parameter destructuring where
it's not currently allowed e.g. free standing closures
with contextual type `let _: ((Int, Int)) -> Void = { $0 + $1 }`
The walker that was setting argument labels was looking through ! and ?
postfix expressions, but the lookup code itself was not, leading to missed
opportunities for filtering based on argument labels. Generalize the
transformation that maps from the function expression down to the locator
for which we will retrieve argument labels.
Extend argument label matching to handle key path application choices,
which are accessed via subscript syntax with the argument labels “keyPath:”.
This gets us to the point where it’s possible to filter down to a single
subscript if there is no type-based overloading going on.
Record the argument labels provided to a subscript in the solver, and
use that to filter out subscript declarations with non-matching
argument labels during function application. This reduces the number of
overloaded subscript declarations that will be considered in later
steps in the solver, reducing the solution space.
*Disable* this optimization in the normal member-lookup path, which is
intended to go away in the near future. This limits the scope of the
change somewhat, so we can separately tackle the diagnostics issue.
The one diagnostics change here is probably an improvement, because
the user explicitly stated the argument labels, and is more likely
missing a conversion on the argument than having typed the wrong
label.
When simplifying a function application constraint, check the argument
labels for that application against the disjunction containing the overload
set, disabling any overloads with mis-matching labels. This is staging for
several different directions:
* Eliminating the argument label matching from performMemberLookup, where it
does not belong
* More aggressively filtering the overload set when we have some concrete
information about argument types
* Identifying favored constraints when we have some concrete information
about argument types
At present, the only easily-visible effect of this change is that
we now properly handle argument label matching for non-member functions.
There are cases where SE-0110 allows tuple splatting behavior,
so to aid diagnostics let's use a new type variable to represent
a tuple type formed from existing arguments instead of imploding
them directly.
Constraint generation for function application expressions contains a simple
hack to try to find the common result type for an overload set containing
callable things. Instead, perform this “common result type” computation
when simplifying an applicable function constraint, so it is more
widely applicable.