KeyPath dynamic member lookup is limited to what key path itself
could do, so let's detect and diagnose invalid references just
like we do for regular key path expressions.
Resolves: rdar://problem/50376224
Detect difference in escapiness while matching function types
in the solver and record a fix that suggests to add @escaping
attribute where appropriate.
Also emit a tailored diagnostic when non-escaping parameter
type is used as a type of a generic parameter.
If the source of the assignment is a function type which has
a result that could be converted to expected destination type,
let's diagnose that as missing call if such function doesn't
have any parameters.
Enhance call-argument matching to reject trailing closures that match up
with parameters that cannot accept closures at all.
Fixes rdar://problem/50362170.
Detect situations where key path doesn't have capability required
by the context e.g. read-only vs. writable, or either root or value
types are incorrect e.g.
```swift
struct S { let foo: Int }
let _: WritableKeyPath<S, Int> = \.foo
```
Here context requires a writable key path but `foo` property is
read-only.
When type-checking a return statement's result, pass a new
ContextualTypePurpose when that return statement appears in a function
with a single expression. When solving the corresponding constraint
system, the conversion constraint will have a new ConstraintKind. When
matching types, check whether the constraint kind is this new kind,
meaning that the constraint is between a function's single expression
and the function's result. If it is, allow a conversion from
an uninhabited type (the expression's type) to anything (the function's
result type) by adding an uninhabited upcast restriction to the vector
of conversions. Finally, at coercion time, upon encountering this
restriction, call coerceUninhabited, replacing the original expression
with an UninhabitedUpcastExpr. Finally, at SILGen time, treat this
UninhabitedUpcastExpr as a ForcedCheckedCastExpr.
Eliminates the bare ConstraintSystem usage from
typeCheckFunctionBodyUntil, ensuring that the same code path is followed
for all function bodies.
Referencing (instance or static) methods in the key path is not
currently allowed, solver should be responsible for early detection
and diagnosis of both standalone e.g. `\.foo` and chained
e.g. `\.foo.bar` (where foo is a method) references in key path
components.
```swift
struct S {
func foo() -> Int { return 42 }
}
let _: KeyPath<S, Int> = \.foo
```
Resolves: rdar://problem/49413561
When printing a swiftinterface, represent opaque result types using an attribute that refers to
the mangled name of the defining decl for the opaque type. To turn this back into a reference
to the right decl's implicit OpaqueTypeDecl, use type reconstruction. Since type reconstruction
doesn't normally concern itself with non-type decls, set up a lookup table in SourceFiles and
ModuleFiles to let us handle the mapping from mangled name to opaque type decl in type
reconstruction.
(Since we're invoking type reconstruction during type checking, when the module hasn't yet been
fully validated, we need to plumb a LazyResolver into the ASTBuilder in an unsightly way. Maybe
there's a better way to do this... Longer term, at least, this surface design gives space for
doing things more the right way--a more request-ified decl validator ought to be able to naturally
lazily service this request without the LazyResolver reference, and if type reconstruction in
the future learns how to reconstruct non-type decls, then the lookup tables can go away.)
We have a systemic class of issues where noescape types end up bound to
type variables in places that should not. The existing diagnostic for
this is ad-hoc and duplicated in several places but it doesn't actually
address the root cause of the problem.
For now, I've changed all call sites of createTypeVariable() to set the
new flag. I plan on removing enough occurrences of the flag to replicate
the old diagnostics. Then we can continue to refine this over time.
Looks into the root type of the keypath to find additional members. This
does not currently map the type of the completion to the subscript's
return type.
rdar://49029126
Previously it was possible to create an invalid solution where
static members would be referenced in a key path, which is not
currently supported and would only be diagnosed while applying
such solution to AST e.g.
```swift
struct S {
static var foo: Int = 42
}
_ = \S.Type.foo
```
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.