Instead of always requiring a call to be made to pass argument
to `@autoclosure` parameter, it should be allowed to pass argument
by value to `@autoclosure` parameter which can return a function
type.
```swift
func foo<T>(_ fn: @autoclosure () -> T) {}
func bar(_ fn: @autoclosure @escaping () -> Int) { foo(fn) }
```
We don't require or allow '&' for the mutable parameters in
operator calls, since we want to write 'x += 10' and not
'&x += 10'.
The constraint sovler accepted '&x += 10' though, and we had
a separate pass in MiscDiagnostics for rejecting it.
Instead, let's just reject this in the solver.
The main difficulty is that we must now be prepared to fail
certain OperatorArgumentConversion and ApplicableFunction
constraints even when both the LHS and RHS types are equal.
Now covers following new areas (alongside simple assignments):
- Contextual type coercions:
- In assignment e.g. `let _: X = foo`
- In return type positions e.g. `func foo() -> A { return bar }`
- Argument-to-parameter applications (including @autoclosure)
Diagnose extraneous use of address of (`&`) which could only be
associated with arguments to `inout` parameters e.g.
```swift
struct S {}
var a: S = ...
var b: S = ...
a = &b
```
If "convertTo" type is an optional let's look through it to see
whether it contains another function type which, if so, would
rule out possibility of missing explicit call.
Resolves: rdar://problem/50438071
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.