This commit changes fixit messages from a question/suggestion to an
imperative message for protocol conformances and switch-case. Addresses
https://github.com/apple/swift/issues/67510.
Introduce the notion of "semantic result parameter". Handle differentiation of inouts via semantic result parameter abstraction. Do not consider non-wrt semantic result parameters as semantic results
Fixes#67174
The above referenced issue was causing a compiler crash when writing
differentiable protocols and corresponding implementers, without importing
the `_Differentiation` module.
Changes in this CR fix the issue by marking any `@differentiable`
attributes as invalid, if the `_Differentiation` module has not been
imported. This ignores the `@differentiable` attributes when the
protocol witnesses are being verified. Witness verification was previously
leading to an error (due to missing `@differentiable` attribute on the protocol
requirement implementer), and the corresponding diagnostic emission code was
then leading to a crash, because it was expecting the `_Differentiation`
module to be present.
Code like that is usually indicative of programmer error, and does not
round-trip through module interface files since there is no source
syntax to refer to an outer generic parameter.
For source compatibility this is a warning, but becomes an error with
-swift-version 6.
Fixes rdar://problem/108385980 and https://github.com/apple/swift/issues/62767.
Calling computeExtendedNominal() won't catch the case where the
extended type did not exist at extension binding time but then
appeared later, like an inferred associated type witness for
example.
* Lookup for custom derivatives in non-primary source files after typecheck is finished for the primary source.
This registers all custom derivatives before autodiff transformations and makes them available to them.
Fully resolves#55170
Add new `-print-ast-decl` frontend option for only printing declarations,
to match existing behavior.
Some tests want to print the AST, but don't care about expressions.
The existing `-print-ast` option now prints function bodies and expressions.
Not all expressions are printed yet, but most common ones are.
When checking the viability of an original function candidate as specified in a `@derivative` attribute, a candidate's signautre can have more generic requirements than the required signature. Such cases need to be checked and diagnosed.
Resolves SR-15530 / rdar://85845512.
Improved diagnostic for when the registered derivative function and
the function it derivates (the original) differ in terms of
`static` declaration modifier usage. Suggesting as well a fix-it,
to either remove or add the `static` keyword.
The registered derivative needs to be marked as `static` in two cases:
1. When the original function is a constructor.
2. When the original function is static as well.
When the original function is an instance method, the registered derivative must be as well.
Resolves [SR-13152](https://bugs.swift.org/browse/SR-13152).
Do not mark synthesized `TangentVector` members as synthesized so that the type checker won't sort them. We would like tangent vector members to have the same order as the properties in the parent declaration.
Also add `typealias TangentVector = Self` to the synthesized `TangentVector` so that it will not need its own `Differentiable` conformance derivation.
Resolves SR-14241 / rdar://74659803.
Rename `move(along:)` to `move(by:)` based on the proposal feedback. The main argument for the change is that tangent vectors specify both a direction and a magnitude, whereas `along:` does not indicate that `self` is being moved by the specified magnitude.
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.
Enable `@differentiable` attribute on setters of properties and
subscripts in `Differentiable`-conforming types.
Add automatically-differentiated `@differentiable` setter test.
Resolves TF-1166.
A `@differentiable` function type require at least 1 differentiability parameter. This PR adds a diagnostic that rejects cases where all parameters are marked with `@noDerivative`. This fixes a compiler crasher.
```swift
test2.swift:3:24: error: '@differentiable' function type requires at least one differentiability parameter, i.e. a non-'@noDerivative' parameter whose type conforms to 'Differentiable'
let _: @differentiable (@noDerivative Float) -> Float = { _ in 0 }
^~~~~~~~~~~~~~~~~~~~~
test2.swift:4:32: error: '@differentiable' function type requires at least one differentiability parameter, i.e. a non-'@noDerivative' parameter whose type conforms to 'Differentiable' with its 'TangentVector' equal to itself
let _: @differentiable(linear) (@noDerivative Float, @noDerivative Int) -> Float = { _, _ in 0 }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
Use the FullyQualified<Type> abstraction from the prior commit plus DescriptiveDeclKind to give a bit more information when issuing a missing member type diagnostic during type resolution.
When checking protocol conformances with `@differentiable` requirements, the type checker is supposed to accept omissions of `@differentiable` attributes when there exsits an attribute that covers a superset of the differentiation configuration. This was accidentally regressed in apple/swift#33776 which made the following test case fail to compile. This is fixed by adjusting the witness matching conditions.
```swift
// rdar://70348904 reproducer:
public protocol P: Differentiable {
@differentiable(wrt: self)
@differentiable(wrt: (self, x))
func foo(_ x: Float) -> Float
}
public struct S: P {}
extension S {
// This had worked until apple/swift#33776.
@differentiable(wrt: (self, x))
public func foo(_ x: Float) -> Float { x }
}
```
Also fix some suboptimal diagnostics where more information could be shown.
Resolves rdar://70348904.
During protocol witness matching for a protocol requirement with
`@differentiable` attributes, implicit `@differentiable` attributes may be
created for the witness under specific conditions (when the witness has a
`@differentiable` attribute with superset differentiability parameters, or
when the witness has less-than-public visibility).
Do not generate implicit `@differentiable` attributes for protocol witnesses
when the protocol conformance is declared from a separate file or type context
from the witness.
Resolves SR-13455.
When a derivative function is internal and its original function is
public, there should be an error when the derivative is not `@usableFromInline`.
This patch fixes a bug where the error does not appear in SwiftPM debug
build configurations (or any configurations with `-enable-testing`).
`ValueDecl::getEffectiveAccess()` should not be used when we perform
formal access checking for AutoDiff-related declaration attributes because
it will treat all internal declarations as public when `-enable-testing` is
enabled. Instea we should use a combination of `ValueDecl::getFormalAccess()`
and `ValueDecl::isUsableFromInline()`.
Also, add a `RUN` line with `-enable-testing` to all AutoDiff declaration
attribute test files.
Resolves SR-13500 (rdar://68336300).
In `Differentiable` derived conformances, `let` properties are currently treated as if they had `@noDerivative` and excluded from the derived `Differentiable` conformance implementation. This is limiting to properties that have a non-mutating `move(along:)` (e.g. class properties), which can be mathematically treated as differentiable variables.
This patch changes the derived conformances behavior such that `let` properties will be included as differentiable variables if they have a non-mutating `move(along:)`. This unblocks the following code:
```swift
final class Foo: Differentiable {
let x: ClassStuff // Class type with a non-mutating 'move(along:)'
// Synthesized code:
// struct TangentVector {
// var x: ClassStuff.TangentVector
// }
// ...
// func move(along direction: TangentVector) {
// x.move(along: direction.x)
// }
}
```
Resolves SR-13474 (rdar://67982207).
Mention the type, the requirement, and the extension in the error that
follows. In editor mode, try to insert stubs for the missing requirement
as well so the user isn't just left with a pile of unactionable errors.
A recent change to witness matching in #32578 suddenly made the
following construction illegal:
// File1.swift
enum MyEnumInAnotherFile { /**/ }
// File2.swift
extension MyEnumInAnotherFile {
static var allCases: [MyEnumInAnotherFile] { /**/ }
}
Because it was no longer possible to derive the type witness for
`AllCases`. This is because, when inference ran before synthesis, we
would use the value witness to pick out the type witness and thus had no
need for synthesis. Now that we run synthesis first, we ought to just
allow deriving type witnesses across files, but still ban deriving value
witnesses. In general, if you can utter a type in a different file to
extend it, you should be able to see the requirements necessary to
derive a default type witness.
rdar://66279278, rdar://66279375, rdar://66279384, rdar://66279415, rdar://66279503
Improve `@derivative` and `@transpose` type-checking diagnostics for resolving
the referenced original declaration.
Previously, an error was produced on one invalid candidate at the attribute's
location. This did not indicate the invalid candidate's location or the total
number of invalid candidates.
Now:
- Diagnostic notes are produced on all invalid candidates at their location.
Invalid candidates' descriptive declaration kind are shown for clarity.
- Derivative registration for protocol requirements (not yet supported, TF-982)
now has a clear, dedicated diagnostic.
- The "original declaration type mismatch" diagnostic is improved for expected
original function types with generic signatures. The message now accurately
reads "candidate does not have type equal to *or less constrained than* ...",
instead of "candidate does not have expected type ...".
Resolves SR-13150.
Paves the way for future diagnostic improvements: SR-13151, SR-13152.
Reject `@differentiable` and `@derivative` attribute for original
functions with opaque result types.
It is not possible to support derivative registration nor the
differentiation transform for such functions.
Resolves SR-12656.