The walker in SILGenLazyConformance.cpp should be sufficient to catch
any conformances needed at runtime, and after all the recent changes
SILGen is now able to trigger lazy conformance checking and synthesis
of fully-checked function bodies for accessors, which is enough to
remove the explicit conformance checks from Sema in this case.
When applying a solution to a nil literal of Optional type, we would
build a direct reference to Optional<T>.none instead of leaving the
NilLiteralExpr in place, because this would generate more efficient
SIL that avoided the call to the Optional(nilLiteral: ()) witness.
However, a few places in the type checker build type-checked AST, and
they build NilLiteralExpr directly. Moving the peephole to SILGen's
lowering of NilLiteralExpr allows us to simplify generated SIL even
further by eliding an unnecessary metatype value. Furthermore, it
allows SILGen to accept NilLiteralExprs that do not have a
ConcreteDeclRef set, which makes type-checked AST easier to build.
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) }
```
THere is no longer any reason to complete ClangImporter-synthesized _ObjectiveCBridgeable
conformances in Sema. SILGen will determine the ones that it needs and will trigger
conformance checking as needed automatically.
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.
The initialization of an instance property that has an attached
property delegate involves the initial value written on the property
declaration, the implicit memberwise initializer, and the default
arguments to the implicit memberwise initializer. Implement SILGen
support for each of these cases.
There is a small semantic change to the creation of the implicit
memberwise initializer due to SE-0242 (default arguments for the
memberwise initializer). Specifically, the memberwise initializer will
use the original property type for the parameter to memberwise
initializer when either of the following is true:
- The corresponding property has an initial value specified with the
`=` syntax, e.g., `@Lazy var i = 17`, or
- The corresponding property has no initial value, but the property
delegate type has an `init(initialValue:)`.
The specific case that changed is when a property has an initial value
specified as a direct initialization of the delegate *and* the
property delegate type has an `init(initialValue:)`, e.g.,
```swift
struct X {
@Lazy(closure: { ... })
var i: Int
}
```
Previously, this would have synthesized an initializer:
```swift
init(i: Int = ???) { ... }
```
However, there is no way for the initialization specified within the
declaration of i to be expressed via the default argument. Now, it
synthesizes an initializer:
```swift
init(i: Lazy<Int> = Lazy(closure: { ... }))
```
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
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
```
In a few corner cases we built DeclRefExpr and MemberRefExpr
for references to types. These should just be TypeExpr so that
SILGen doesn't have to deal with it.
This also fixes a bug where a protocol typealias with an
unbound generic type could not be accessed properly from
expression context, but that is just so incredibly obscure.
Move checking for index Hashable conformance from CSApply (post-factum)
to the solver and use recorded conformance records complete subscript
components.
For example if there a structure which requires multiple implicit
dynamic member calls to get the members:
```swift
struct Point { var x, y: Int }
@dynamicMemberLookup
struct Lens<T> {
var obj: T
subscript<U>(dynamicMember member: KeyPath<T, U>) -> U {
get { return obj[keyPath: member] }
}
}
func foo(_ lens: Lens<Lens<Point>>) {
_ = lens.x
_ = lens.obj.x
_ = lens.obj.obj.x
}
_ = \Lens<Lens<Point>>.x
```