of adding a property.
This better matches what the actual implementation expects,
and it avoids some possibilities of weird mismatches. However,
it also requires special-case initialization, destruction, and
dynamic-layout support, none of which I've added yet.
In order to get NSObject default actor subclasses to use Swift
refcounting (and thus avoid the need for the default actor runtime
to generally use ObjC refcounting), I've had to introduce a
SwiftNativeNSObject which we substitute as the superclass when
inheriting directly from NSObject. This is something we could
do in all NSObject subclasses; for now, I'm just doing it in
actors, although it's all actors and not just default actors.
We are not yet taking advantage of our special knowledge of this
class anywhere except the reference-counting code.
I went around in circles exploring a number of alternatives for
doing this; at one point I basically had a completely parallel
"ForImplementation" superclass query. That proved to be a lot
of added complexity and created more problems than it solved.
We also don't *really* get any benefit from this subclassing
because there still wouldn't be a consistent superclass for all
actors. So instead it's very ad-hoc.
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.
When an actor class has its `enqueue(partialTask:)` implicitly
synthesized, also synthesize a stored property for the actor's queue.
The type of the property is defined by the _Concurrency library
(`_DefaultActorQueue`), and it will be initialized with a call to
`_defaultActorQueueCreate` (also provided by the _Concurrency
library).
Also synthesize the body of the implicitly-generated
`enqueue(partialTask:)`, which will be a call to
`_defaultActorQueueEnqueuePartialTask(actor:queue:partialTask:)`.
Together, all of these allow us to experiment with the form of the
queue and the queue operation without affecting the type checker.
When `enqueue(partialTask:)` is not implicitly synthesized, the queue
storage is not synthesized either. In such cases, the user has taken
over the execution of tasks for the actor, rather than using the
default implementation.
Introduce a new Actor protocol, which is a class-bound protocol with only
one requirement:
func enqueue(partialTask: PartialAsyncTask)
All actor classes implicitly conform to this protocol, and will synthesize
a (currently empty) definition of `enqueue(partialTask:)` unless a suitable
one is provided explicitly.
The use of "if #available" in function builders can subvert availability
checking if the function builder carries all type information for the
values within the "then" block outside of the "else" block. Tighten up
the model in two ways:
* Check whether the type coming out of an "if #available" references
any declarations that are not available in the outer context, to close
up the model.
* If the function builder provides a buildLimitedAvailability(_:)
operation, call that on the result of the "then" block in an "if
that it cannot leak out of the "if #available"; if it doesn't, the
check above will still fire.
Stage this in with a warning so function builders out there in the wild
can adapt. We'll upgrade the warning to an error later.
Fixes rdar://problem/65021017.
`Differentiable` conformance derivation now supports
`Differentiable.zeroTangentVectorInitializer`.
There are two potential cases:
1. Memberwise derivation: done when `TangentVector` can be initialized memberwise.
2. `{ TangentVector.zero }` derivation: done as a fallback.
`zeroTangentVectorInitializer` is a closure that produces a zero tangent vector,
capturing minimal necessary information from `self`.
It is an instance property, unlike the static property `AdditiveArithmetic.zero`,
and should be used by the differentiation transform for correctness.
Remove `Differentiable.zeroTangentVectorInitializer` dummy default implementation.
Update stdlib `Differentiable` conformances and tests.
Clean up DerivedConformanceDifferentiable.cpp cruft.
Resolves TF-1007.
Progress towards TF-1008: differentiation correctness for projection operations.
Extend function builders with support for for..in loops, such as
for person in contacts {
"Hello \(person.name)"
}
The loop will be (eagerly) executed and all results will be collected
into an array. That array will be passed to a function `buildArray` to
produce the result from the loop. Specifically, the above will be
translated to the following when used with a function builder type
named `FunctionBuilder`,, where all $ names are introduced by the
compiler and are not user-visible:
let $a1: $T1
var $a2: [$T2] = []
for person in contacts {
let $a3: $T3
let $a4 = FunctionBuilder.buildExpression("Hello \(person.name)")
$a3 = FunctionBuilder.buildBlock($a4)
$a2.append($3)
}
$a1 = FunctionBuilder.buildArray($a2)
where `$a1` is the result of the for-each loop.
When a type (class, enum, or struct) is annotated @main, it is required
to provide a function with the following signature:
static func main() -> ()
That function will be called when the executable the type is defined
within is launched.
Add `AdditiveArithmetic` derived conformances for structs and classes, gated by
the `-enable-experimental-differentiable-programming` flag.
Structs and classes whose stored properties all conform to `Differentiable` can
derive `Differentiable`:
- `associatedtype TangentVector: Differentiable & AdditiveArithmetic`
- Member `TangentVector` structs are synthesized whose stored properties are
all `var` stored properties that conform to `Differentiable` and that are
not `@noDerivative`.
- `mutating func move(along: TangentVector)`
The `@noDerivative` attribute may be declared on stored properties to opt out of
inclusion in synthesized `TangentVector` structs.
Some stored properties cannot be used in `TangentVector` struct synthesis and
are implicitly marked as `@noDerivative`, with a warning:
- `let` stored properties.
- These cannot be updated by `mutating func move(along: TangentVector)`.
- Non-`Differentiable`-conforming stored properties.
`@noDerivative` also implies `@_semantics("autodiff.nonvarying")`, which is
relevant for differentiable activity analysis.
Add type-checking and SILGen tests.
Resolves TF-845.
Add `AdditiveArithmetic` derived conformances for structs, gated by the
`-enable-experimential-additive-arithmetic-derivation` flag.
Structs whose stored properties all conform to `AdditiveArithmetic` can derive
`AdditiveArithmetic`:
- `static var zero: Self`
- `static func +(lhs: Self, rhs: Self) -> Self`
- `static func -(lhs: Self, rhs: Self) -> Self`
- An "effective memberwise initializer":
- Either a synthesized memberwise initializer or a user-defined initializer
with the same type.
Effective memberwise initializers are used only by derived conformances for
`Self`-returning protocol requirements like `AdditiveArithmetic.+`, which
require memberwise initialization.
Resolves TF-844.
Unblocks TF-845: upstream `Differentiable` derived conformances.
Define type signatures and SILGen for the following builtins:
```
/// Applies the {jvp|vjp} of `f` to `arg1`, ..., `argN`.
func applyDerivative_arityN_{jvp|vjp}(f, arg1, ..., argN) -> jvp/vjp return type
/// Applies the transpose of `f` to `arg`.
func applyTranspose_arityN(f, arg) -> transpose return type
/// Makes a differentiable function from the given `original`, `jvp`, and
/// `vjp` functions.
func differentiableFunction_arityN(original, jvp, vjp)
/// Makes a linear function from the given `original` and `transpose` functions.
func linearFunction_arityN(original, transpose)
```
Add SILGen FileCheck tests for all builtins.
When present in a function builder, buildFinalResult() will be called on
the value of the outermost block to form the final result of the closure.
This allows one to collapse the full function builder computation into
a single result without having to do it in each buildBlock() call.
The `@derivative` attribute registers a function as a derivative of another
function-like declaration: a `func`, `init`, `subscript`, or `var` computed
property declaration.
The `@derivative` attribute also has an optional `wrt:` clause specifying the
parameters that are differentiated "with respect to", i.e. the differentiation
parameters. The differentiation parameters must conform to the `Differentiable`
protocol.
If the `wrt:` clause is unspecified, the differentiation parameters are inferred
to be all parameters that conform to `Differentiable`.
`@derivative` attribute type-checking verifies that the type of the derivative
function declaration is consistent with the type of the referenced original
declaration and the differentiation parameters.
The `@derivative` attribute is gated by the
`-enable-experimental-differentiable-programming` flag.
Resolves TF-829.
The `_Differentiation` module is the experimental support library for
differentiable programming. It is built when the build-script flag
`--enable-experimental-differentiable-programming` is enabled.
The `Differentiable` protocol generalizes all types that work with
differentiation. It is a core piece of the differentiable programming
project. Other parts depending on the `Differentiable` protocol will
be upstreamed piece by piece.
The `Differentiable` protocol is compiler-known and will be used during
type-checking, SILGen, and the SIL differentiation transform.
If a function builder type has a static method buildExpression(), use
it to pass through each expression whose value will become part of the
final result. This is part of the function builders pitch that had not
yet been implemented.
Introduce callables: values of types that declare `func callAsFunction`
methods can be called like functions. The call syntax is shorthand for
applying `func callAsFunction` methods.
```swift
struct Adder {
var base: Int
func callAsFunction(_ x: Int) -> Int {
return x + base
}
}
var adder = Adder(base: 3)
adder(10) // desugars to `adder.callAsFunction(10)`
```
`func callAsFunction` argument labels are required at call sites.
Multiple `func callAsFunction` methods on a single type are supported.
`mutating func callAsFunction` is supported.
SR-11378 tracks improving `callAsFunction` diagnostics.
Extend handling of enclosing-self subscripts by differentiating
between the original wrapped property (which now goes through
`subscript(_enclosingInstance:wrapped:storage:)`) and the projected
property (which goes through
`subscript(_enclosingInstance:projected:storage:)`). The new middle
argument provides a key path to the property that was accessed,
allowing one to distinguish the property being updated.
A substantial amount of this patch goes towards trying to get at least
minimal diagnostics working, since of course I messed up the rule a few
times when implementing this.
rdar://50149837
If a function builder contains a buildIf function, then "if" statements
will be supported by passing an optional of the "then" branch.
"if" statements with an "else" statement are unsupported at present.
When calling a function whose parameter specifies a function builder
with a multi-statement closure argument, transform the closure into
a single expression via the function builder. Should the result
type checker, replace the closure body with the single expression.
This allows the conversion of the Windows `BOOL` type to be converted to
`Bool` implicitly. The implicit bridging allows for a more ergonomic
use of the native Windows APIs in Swift.
Due to the ambiguity between the Objective C `BOOL` and the Windows
`BOOL`, we must manually map the `BOOL` type to the appropriate type.
This required lifting the mapping entry for `ObjCBool` from the mapped
types XMACRO definition into the inline definition in the importer.
Take the opportunity to simplify the mapping code.
Adjust the standard library usage of the `BOOL` type which is now
eclipsed by the new `WindowsBool` type, preferring to use `Bool`
whenever possible.
Thanks to Jordan Rose for the suggestion to do this and a couple of
hints along the way.
Removes the _getBuiltinLogicValue intrinsic in favor of an open-coded
struct_extract in SIL. This removes Sema's last non-literal use of builtin
integer types and unblocks a bunch of cleanup.
This patch would be NFC, but it improves line information for conditional expression codegen.
* Implement dynamically callable types (`@dynamicCallable`).
- Implement dynamically callable types as proposed in SE-0216.
- Dynamic calls are resolved based on call-site syntax.
- Use the `withArguments:` method if it's defined and there are no
keyword arguments.
- Otherwise, use the `withKeywordArguments:` method.
- Support multiple `dynamicallyCall` methods.
- This enables two scenarios:
- Overloaded `dynamicallyCall` methods on a single
`@dynamicCallable` type.
- Multiple `dynamicallyCall` methods from a `@dynamicCallable`
superclass or from `@dynamicCallable` protocols.
- Add `DynamicCallableApplicableFunction` constraint. This, used with
an overload set, is necessary to support multiple `dynamicallyCall`
methods.