Extend effects checking to ensure that each reference to a variable
bound by an 'async let' is covered by an "await" expression and occurs
in a suitable context.
The substituted type of the member reference is an OpaqueTypeArchetypeType
whose substitution map sends Self to the opened existential type for the
base value. Sema erases opened existential types to their upper bound, but
this is not a valid transformation in this case, because the 'Self' type
reference is invariant. Calling this member on two different existential
values would produce the same erased type, but this is wrong, because
it actually depends on the concrete type stored in the existential.
Fixes <https://bugs.swift.org/browse/SR-13419>, <rdar://problem/67451810>.
In @frozen structs, stored properties and property wrappers must
have inlinable initial value expressions, since they are re-emitted
into designated initializer bodies, which themselves might be
@inlinable.
However, 'lazy' properties don't follow this pattern; the
initial value expression is emitted inside the getter, which
is never @inlinable.
getFragileFunctionKind() would report that all initializers in
non-resilient public types were inlinable, including static
properties.
This was later patched by VarDecl::isInitExposedToClients(),
which was checked in diagnoseInlinableDeclRefAccess().
However, the latter function only looked at the innermost
DeclContexts, not all parent contexts, so it would incorrectly
diagnose code with a nested DeclContext inside of a static
property initializer.
Fix this by changing getFragileFunctionKind() to call
isInitExposedToClients() and simplifying
diagnoseInlinableDeclRefAccess().
This commit also introduces a new isLayoutExposedToClients()
method, which is similar to isInitExposedToClients(), except
it also returns 'true' if the property does not have an
initializer (and in fact the latter is implemented in terms
of the former).
This attribute allows to define a pre-specialized entry point of a
generic function in a library.
The following definition provides a pre-specialized entry point for
`genericFunc(_:)` for the parameter type `Int` that clients of the
library can call.
```
@_specialize(exported: true, where T == Int)
public func genericFunc<T>(_ t: T) { ... }
```
Pre-specializations of internal `@inlinable` functions are allowed.
```
@usableFromInline
internal struct GenericThing<T> {
@_specialize(exported: true, where T == Int)
@inlinable
internal func genericMethod(_ t: T) {
}
}
```
There is syntax to pre-specialize a method from a different module.
```
import ModuleDefiningGenericFunc
@_specialize(exported: true, target: genericFunc(_:), where T == Double)
func prespecialize_genericFunc(_ t: T) { fatalError("dont call") }
```
Specially marked extensions allow for pre-specialization of internal
methods accross module boundries (respecting `@inlinable` and
`@usableFromInline`).
```
import ModuleDefiningGenericThing
public struct Something {}
@_specializeExtension
extension GenericThing {
@_specialize(exported: true, target: genericMethod(_:), where T == Something)
func prespecialize_genericMethod(_ t: T) { fatalError("dont call") }
}
```
rdar://64993425
Extend the actor isolation checking rules to account for global
actors. For example, a function annotated with a given global actor
can invoke synchronous methods from the same global actor, but not
from a different global actor or a particular actor instance.
Similarly, a method of an (instance) actor that is annotated with a
global actor attribute is not part of the (instance) actor and,
therefore, cannot operate on its actor-isolated state.
Global actor types can be used as attributes on various kinds of
declarations to indicate that those declarations are part of the
isolated state of that global actor. Allow such annotation and perform
basic correctness checks.
The globalActor attribute indicates that a particular type describes a
global actor. Global actors allow the notion of actor state isolation
to be spread across various declarations throughout a program, rather
than being centered around a single actor class. There are useful
primarily for existing notions such as "main thread" or subsystems
accessed through global/singleton state.