Files
swift-mirror/test/AutoDiff/Sema/ImplicitDifferentiableAttributeCrossFile/main.swift
Richard Wei e29c19cf8b [AutoDiff] [Sema] Fix '@differentiable' witness matching regression. (#34533)
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.
2020-11-01 17:10:03 -08:00

51 lines
2.3 KiB
Swift

// Test missing protocol requirement `@differentiable` attribute errors for
// non-public protocol witnesses, when the protocol conformance is declared in a
// separate file from witnesses.
//
// Implicit `@differentiable` attributes cannot be generated for protocol
// witnesses when the conformance is declared from a separate file from the
// witness. Otherwise, compilation of the file containing the conformance
// creates references to external symbols for implicit `@differentiable`
// attributes, even though no such symbols exist.
//
// Context: https://github.com/apple/swift/pull/29771#issuecomment-585059721
// Note: `swiftc main.swift other_file.swift` runs three commands:
// - `swiftc -frontend -primary-file main.swift other_file.swift -o ...`
// - `swiftc -frontend main.swift -primary-file other_file.swift -o ...`
// - `/usr/bin/ld ...`
//
// `%target-build-swift` performs `swiftc main.swift other_file.swift`, so it is expected to fail (hence `not`).
// `swiftc -frontend -primary-file main.swift other_file.swift` should fail, so `-verify` is needed.
// `swiftc -frontend main.swift -primary-file other_file.swift` should succeed, so no need for `-verify`.
// RUN: %target-swift-frontend -c -verify -primary-file %s %S/Inputs/other_file.swift
// RUN: %target-swift-frontend -c %s -primary-file %S/Inputs/other_file.swift
// RUN: not %target-build-swift %s %S/Inputs/other_file.swift
import _Differentiation
// Error: conformance is in different file than witnesses.
// expected-error @+1 {{type 'ConformingStruct' does not conform to protocol 'Protocol1'}}
extension ConformingStruct: Protocol1 {}
// No error: conformance is in same file as witnesses.
extension ConformingStruct: Protocol2 {
func internalMethod4(_ x: Float) -> Float {
x
}
}
public final class ConformingStructWithSupersetAttr: Protocol2 {}
// rdar://70348904: Witness mismatch failure when a matching witness with a *superset* `@differentiable`
// attribute is specified.
//
// Note that public witnesses are required to explicitly specify `@differentiable` attributes except
// those w.r.t. parameters that have already been covered by an existing `@differentiable` attribute.
extension ConformingStructWithSupersetAttr {
// @differentiable(wrt: self) // Omitting this is okay.
@differentiable
public func internalMethod4(_ x: Float) -> Float { x }
}