If the final expression in a function or closure which is missing a
return has the appropriate type, rather than producing the usual
diagnostic about a missing return, produce a diagnostic with a fixit to
insert a return before thatn final expression.
h/t Nate Cook
Taught getSingleExpressionBody to return null and
setSingleExpressionBody to require null in the case that there is a
single stmt of type FailStmt which replaces return nil during sema for
single expression failable initializers (i.e. init?() { nil }).
- preferred dyn_cast to is and get
- restored insertion of () on bare return statements
- used dyn_cast not dyn_cast_or_null when the argument is non-null
- used getSingleExpressionBody accessor during second AST modification
- eliminated erroneous access through null reference
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: { ... }))
```
When a property has an attached property delegate, a backing storage
property of the corresponding delegate type will be
synthesized. Perform this synthesis, and also synthesize the
getter/setter for the original property to reference the backing
storage property.
A property with an attached delegate can be initialized in one of two ways:
* By directly specifying initialization arguments on the attribute,
e.g., "@SomeDelegate(x: 17, y: 42) var a".
* By initializing the original property itself, which goes through the
delegate type's init(initialValue:) initializer, e.g.,
"@Lazy var x = 17".
Implement support for both forms of initialization, including type
inference and checking for inconsistencies (e.g., if the annotation on
the property type doesn't match what the delegate type would
provide).
A custom attribute can be resolved to a property delegate type. Allow
this for property declarations (only), and diagnose the various places
where properties cannot have property delegates.
To represent the abstracted interface of an opaque type, we need a generic signature that refines
the outer context generic signature with an additional generic parameter representing the underlying
type and its exposed constraints. Opaque types also need to be keyed by their originating decl, so
that we can treat values of the same opaque type as the same. When we check a FuncDecl with an
opaque type specified as its return type, create an OpaqueTypeDecl and associate it with the
originating decl. (A representation for *types* derived from the opaque decl will come next.)
Escapingness is a property of the type of a value, not a property of a function
parameter. Having it as a separate parameter flag just meant one more piece of
state that could get out of sync and cause weird problems.
Instead, always look at the noescape bit in a function type as the canonical
source of truth.
This does mean that '@escaping' is now printed in a few diagnostics where it was
not printed before; we can investigate these as separate issues, but it is
correct to print it there because the function types in question are, in fact,
escaping.
Fixes <https://bugs.swift.org/browse/SR-10256>, <rdar://problem/49522774>.
Specifically the bad pattern was:
```
for (auto *vd : *caseStmt->getCaseBodyVariables()) { ... }
```
The problem is that the optional is not lifetime extended over the for loop. To
work around this, I changed the API of CaseStmt's getCaseBodyVariable methods to
never return the inner Optional<MutableArrayRef<T>>. Now we have the following 3
methods (ignoring const differences):
1. CaseStmt::hasCaseBodyVariables().
2. CaseStmt::getCaseBodyVariables(). Asserts if the case body variable array was
never specified.
3. CaseStmt::getCaseBodyVariablesOrEmptyArray(). Returns either the case body
variables array or an empty array if we were never given any case body
variable array.
This should prevent anyone else in the future from hitting this type of bug.
radar://49609717
* Moves the IsStatic flag from VarDecl to AbstractStorageDecl.
* Adds a StaticSubscriptKind to SubscriptDecl.
* Updates serialization for these changes.
* Updates SubscriptDecl constructor call sites for these changes.
While checking for superclasses in isUnitTest, we need to handle
circular inheritance. For good measure, add tests for protocols as well.
The new API is designed to behave the same as walkInheritedProtocols
except that is walks over superclasses.
rdar://49434989
This is a step in the direction of fixing the fallthrough bug. Specifically, in
this commit I give case stmts a set of var decls for the bodies of the case
statement. I have not wired them up to anything except the var decl
list/typechecking.
rdar://47467128
* [typechecker] fix an issue with redeclaration checking
* [typechecker] use mapSignatureFunctionType in getOverloadSignatureType() to compute the type for the enum element decl, etc
* [typechecker] allow matching enums to functions as well, not just functions to enums
* [typechecker] fix the check for two enums
* [typechecker] check for nominal types as well when comparing enum elements
* [test] add more tests
* [typechecker] check for typealias as well