This patch replaces the @hasAsyncAlternative attribute with
@completionHandlerAsync. The @completionHandlerAsync attribute takes the
function decl name of the async function and optionally the index of the
completion hander parameter in the function that it's attached to.
If the completion handler index is not provided, it's assumed to be the
last parameter in the parameter list.
We resolve the async function while typechecking the attribute. Before
resolving, we verify that the function the attribute is attached to
isn't async, that it has enough parameters to at least have the
indicated completion handler referenced by the index, that the
completion handler is an escaping non-auto-closure function that returns
Void.
The async function declaration resolution isn't perfect yet, but I want
to get this patch up and we can refine it later. It pulls all of the
delcs with the specified declname in the same context as the
function that the attribute is attached to. Going through that list, it
keeps any that are async functions. If there are none, we emit an error
saying that there are no viable functions, if there are multiple we emit
an error saying that the decl name is ambiguous, and if there is one
function, we keep that as the resolve async function declaration.
This does not take into account the data types of the completion handler
or the async function. There are some complexities to making this
mapping. Here are the pieces:
- If the completion handler takes a single data type, the async
function should return that type. (easy case)
- If the completion handler takes a `Result<T, Error>`, the async
function is a throwing function that returns a T. (Medium difficulty)
- If the completion handler looks like `(T?, Error?) -> Void`, we have
an ambiguous situation between the following async functions:
- func foo() async throws -> T
- func foo() async throws -> T?
That is, we cannot tell whether the `T?` in the completion handler is
optional because it will be nil on an error, or if it is intended to
be optional.
This can be done later if it becomes a problem.
Allow us to tag declarations that are meant to be in a global actor, but
for which we don't yet want to enforce everything. This will be used for
better staging-in of global actor annotations, but for now it's a fancy
way to document @actorIndependent(unsafe).
Stages in the syntax for rdar://74241687 without really implementing it.
property wrapper custom attribute to get the backing wrapper type
in CSApply.
This is necessary because implicit custom attributes do not have
TypeReprs, but they always have TypeExprs.
This attribute marks a function has having an async alternative,
optionally providing the name of that function as a string. Intended to
be used to allow warnings when using a function with an async
alternative in an asynchronous context, to make the async refactorings
more accurate, and for documentation.
Compiler:
- Add `Forward` and `Reverse` to `DifferentiabilityKind`.
- Expand `DifferentiabilityMask` in `ExtInfo` to 3 bits so that it now holds all 4 cases of `DifferentiabilityKind`.
- Parse `@differentiable(reverse)` and `@differentiable(_forward)` declaration attributes and type attributes.
- Emit a warning for `@differentiable` without `reverse`.
- Emit an error for `@differentiable(_forward)`.
- Rename `@differentiable(linear)` to `@differentiable(_linear)`.
- Make `@differentiable(reverse)` type lowering go through today's `@differentiable` code path. We will specialize it to reverse-mode in a follow-up patch.
ABI:
- Add `Forward` and `Reverse` to `FunctionMetadataDifferentiabilityKind`.
- Extend `TargetFunctionTypeFlags` by 1 bit to store the highest bit of differentiability kind (linear). Note that there is a 2-bit gap in `DifferentiabilityMask` which is reserved for `AsyncMask` and `ConcurrentMask`; `AsyncMask` is ABI-stable so we cannot change that.
_Differentiation module:
- Replace all occurrences of `@differentiable` with `@differentiable(reverse)`.
- Delete `_transpose(of:)`.
Resolves rdar://69980056.
[broken] first impl of @actorIndependent in the type checker.
[broken] fixed mistake in my parsing code wrt invalid source range
[broken] found another spot where ActorIndependent needs custom handling
[broken] incomplete set of @actorIndependent(unsafe) tests
updates to ActorIndependentUnsafe
[fixed] add FIXME plus simple handling of IndependentUnsafe context
finished @actorIndependent(unsafe) regression tests
added wip serialization / deserialization test
focus test to just one actor class
round-trip serialize/deserialize test for @actorIndependent
serialize -> deserialize -> serialize -> compare to original
most of doug's comments
addressed robert's comments
fix printing bug; add module printing to regression test
[nfc] update comment for ActorIsolation::IndependentUnsafe
```
@_specialize(exported: true, spi: SPIGroupName, where T == Int)
public func myFunc() { }
```
The specialized entry point is only visible for modules that import
using `_spi(SPIGroupName) import ModuleDefiningMyFunc `.
rdar://64993425
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
* initial changes
* Add tests, undo unnecessary changes.
* Fixing up computed properties accessors and adding tests for getters.
* Adding nested type testcase
* Fixing error message for when accessor is referenced but not acutally found.
* Cleanup.
- Improve diagnostic message.
- Clean up code and tests.
- Delete unrelated nested type `@derivative` attribute tests.
* Temporarily disable class subscript setter derivative registration test.
Blocked by SR-13096.
* Adding libsyntax integration and fixing up an error message.
* Added a helper function for checking if the next token is an accessor label.
* Update utils/gyb_syntax_support/AttributeNodes.py
Co-authored-by: Dan Zheng <danielzheng@google.com>
* Update lib/Parse/ParseDecl.cpp
Co-authored-by: Dan Zheng <danielzheng@google.com>
* Add end-to-end derivative registration tests.
* NFC: run `git clang-format`.
* NFC: clean up formatting.
Re-apply `git clang-format`.
* Clarify parsing ambiguity FIXME comments.
* Adding couple of more testcases and fixing up error message for when accessor is not found on functions resolved.
* Update lib/Sema/TypeCheckAttr.cpp
Co-authored-by: Dan Zheng <danielzheng@google.com>
Co-authored-by: Dan Zheng <danielzheng@google.com>
Start fixing SR-12526: `@derivative` attribute cross-module deserialization
crash. Remove original `AbstractFunctionDecl *` from `DerivativeAttr` and store
`DeclID` instead, mimicking `DynamicReplacementAttr`.
Type erasure requires a circular construction by its very nature:
@_typeEraser(AnyProto)
protocol Proto { /**/ }
public struct AnyProto : Proto {}
If we eagerly resolve AnyProto, the chain of resolution steps that
deserialization must make goes a little something like this:
Lookup(Proto)
-> Deserialize(@_typeEraser(AnyProto))
-> Lookup(AnyProto)
-> DeserializeInheritedStuff(AnyProto)
-> Lookup(Proto)
This cycle could be broken if the order of incremental inputs was
such that we had already cached the lookup of Proto.
Resolve this cycle in any case by suspending the deserialization of the
type eraser until the point it's demanded by adding
ResolveTypeEraserTypeRequest.
rdar://61270195
Previously, all witnesses of a `@differentiable` protocol requirement were
required to have the same attribute (or one with superset parameter indices).
However, this leads to many annotations on witnesses and is not ideal for
usability. `@differentiable` attributes are really only significant on
public witnesses, so that they are clearly `@differentiable` at a glance (in
source code, interface files, and API documentation), without looking through
protocol conformance hierarchies.
Now, only *public* witnesses of `@differentiable` protocol requirements are
required to have the same attribute (or one with superset parameter indices).
For less-visible witnesses, an implicit `@differentiable` attribute is created
with the same configuration as the requirement's.
Resolves TF-1117.
Upstreams #29771 from tensorflow branch.
Delete `@differentiable` attribute `jvp:` and `vjp:` arguments for derivative
registration. `@derivative` attribute is now the canonical way to register
derivatives.
Resolves TF-1001.
This commit refactors NameBinding.cpp virtually to the point of a rewrite. The goal is to make the import handling code process a struct containing information extracted from an ImportDecl, rather than the ImportDecl itself, so that a future commit can perform the same processing on imports that are not directly represented by an ImportDecl. The result takes more code, but it disentangles a knot of complicated logic into separate threads.
One semi-functional change is that validation of scoped imports (i.e. checking that the declaration actually exists) is now deferred until all of the file’s imports have been processed. Once cross-imports are supported, this will be necessary because scoped imports can select declarations from cross-import overlays, and the full set of cross-import overlays can’t be known until all imports have been seen.
Some comments refer to things that won’t exist until the next commit, like the visibleModules property. I’ll let you in on a litlte secret: I didn’t really do this all in one go.
This will be used for compiler-driven type erasure for dynamic
replacement of functions with an opaque return type. For now, just
parse the attribute and ignore it.
Add a platform kind and availability attributes for macCatalyst. macCatalyst
uses iOS version numbers and inherits availability from iOS attributes unless
a macCatalyst attribute is explicitly provided.
The `@differentiable` attribute marks a function as differentiable.
Example:
```
@differentiable(wrt: x, jvp: derivativeFoo where T: Differentiable)
func id<T>(_ x: T) -> T { x }
```
The `@differentiable` attribute has an optional `wrt:` clause specifying the
parameters that are differentiated "with respect to", i.e. the differentiability
parameters. The differentiability parameters must conform to the
`Differentiable` protocol.
If the `wrt:` clause is unspecified, the differentiability parameters are
currently inferred to be all parameters that conform to `Differentiable`.
The `@differentiable` attribute also has optional `jvp:` and `vjp:` labels
for registering derivative functions. These labels are deprecated in favor of
the `@derivative` attribute and will be removed soon.
The `@differentiable` attribute also has an optional `where` clause, specifying
extra differentiability requirements for generic functions.
The `@differentiable` attribute is gated by the
`-enable-experimental-differentiable-programming` flag.
Code changes:
- Add `DifferentiableAttributeTypeCheckRequest`.
- Currently, the request returns differentiability parameter indices, while
also resolving `JVPFunction`, `VJPFunction`, and
`DerivativeGenericSignature` and mutating them in-place in
`DifferentiableAttr`. This was the simplest approach that worked without
introducing request cycles.
- Add "is type-checked" bit to `DifferentiableAttr`.
- Alternatively, I tried changing `DifferentiableAttributeTypeCheckRequest` to
use `CacheKind::Cache` instead of `CacheKind::SeparatelyCached`, but it did
not seem to work: `@differentiable` attributes in non-primary-files were
left unchecked.
Type-checking rules (summary):
- `@differentiable` attribute must be declared on a function-like "original"
declaration: `func`, `init`, `subscript`, `var` (computed properties only).
- Parsed differentiability parameters must be valid (if they exist).
- Parsed `where` clause must be valid (if it exists).
- Differentiability parameters must all conform to `Differentiable`.
- Original result must all conform to `Differentiable`.
- If JVP/VJP functions are specified, they must match the expected type.
- `@differentiable(jvp:vjp:)` for derivative registration is deprecated in
favor of `@derivative` attribute, and will be removed soon.
- Duplicate `@differentiable` attributes with the same differentiability
parameters are invalid.
- For protocol requirements and class members with `@differentiable` attribute,
conforming types and subclasses must have the same `@differentiable` attribute
(or one with a superset of differentiability parameter indices) on
implementing/overriding declarations.
Store in `DifferentiableAttr` the original declaration on which the attribute
is declared.
The original declaration is resolved during parsing and deserialization
(not yet upstreamed).
Progress towards TF-828: upstream `@differentiable` attribute type-checking.
Enable qualified declaration names in `@derivative` attribute, just like
`@transpose` attribute.
`DerivativeAttr` now stores a base type `TypeRepr *`, which is non-null for
parsed attributes that reference a qualified original declaration.
Add `TypeResolutionFlags::AllowModule` flag to enable module lookup via
`TypeChecker::lookupMember` given a `ModuleType`.
Add tests for type-qualified and module-qualified declaration names.
Resolves TF-1058.
The `@transpose(of:)` attribute registers a function as a transpose of another
function. This patch adds the `@transpose(of:)` attribute definition, syntax,
parsing, and printing.
Resolves TF-827.
Todos:
- Type-checking (TF-830, TF-1060).
- Enable serialization (TF-838).
- Use module-qualified names instead of custom qualified name syntax/parsing
(TF-1066).
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.
Replaces `ComponentIdentTypeRepr::getIdentifier()` and `getIdLoc()` with `getNameRef()` and `getNameLoc()`, which use `DeclName` and `DeclNameRef` respectively.