-
Notifications
You must be signed in to change notification settings - Fork 10.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Try to derive a type witness in a known conformance before attempting associated type inference #32578
Try to derive a type witness in a known conformance before attempting associated type inference #32578
Conversation
@swift-ci Please test |
@swift-ci Please test source compatibility |
Build failed |
…which was always true
Sema can infer type witnesses for a small set of known conformances, to RawRepresentable, CaseIterable, and Differentiable. Previously, we would try to compute the type witness in this order: 1) First, via name lookup, to find an explicit nested type with the same name as an associated type. 2) Second, we would attempt inference. 3) Third, we would attempt derivation. Instead, let's do 3) before 2). This avoids circularity errors in situations where the witness can be derived, but inference fails. This breaks source compatibility with enum declarations where the raw type in the inheritance clause is a lie, and the user defines their own witnesses with mismatched types. However, I suspect this does not come up in practice, because if you don't synthesize witnesses, there is no way to access the actual raw literal values of the enum cases.
bf43ee1
to
dfbb958
Compare
@swift-ci Please test |
@swift-ci Please test source compatibility |
@swift-ci Please test |
@swift-ci Please test source compatibility |
@dan-zheng @rxwei Please take a look at the AutoDiff change I had to make here to get the test suite to pass. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
The source compat failures are caused by a swiftpm issue and they're failing on the main branch as well. |
Associated type inference behavior was changed in swiftlang/swift#32578: derived conformances are now attempted before associated type inference. This broke `ParameterlessLayer`, which relied on a `TangentVector == EmptyTangentVector` same-type constraint to set a default `TangentVector` type witness for conforming types. Add explicit `TangentVector` type witnesses to `ParameterlessLayer`-conforming types to fix this regression.
Associated type inference behavior was changed in swiftlang/swift#32578: derived conformances are now attempted before associated type inference. This broke `ParameterlessLayer`, which relied on a `TangentVector == EmptyTangentVector` same-type constraint to set a default `TangentVector` type witness for conforming types. Add explicit `TangentVector` type witnesses to `ParameterlessLayer`-conforming types to fix this regression. This workaround is forward- and backward-compatible, but makes code more verbose.
Associated type inference behavior was changed in swiftlang/swift#32578: derived conformances are now attempted before associated type inference. This broke `ParameterlessLayer`, which relied on a `TangentVector == EmptyTangentVector` same-type constraint to set a default `TangentVector` type witness for conforming types. Add explicit `TangentVector` type witnesses to `ParameterlessLayer`-conforming types to fix this regression. This workaround is forward- and backward-compatible, but makes code more verbose.
Associated type inference behavior was changed in swiftlang/swift#32578: derived conformances are now attempted before associated type inference. This broke `ParameterlessLayer`, which relied on a `TangentVector == EmptyTangentVector` same-type constraint to set a default `TangentVector` type witness for conforming types. Add explicit `TangentVector` type witnesses to `ParameterlessLayer`-conforming types to fix this regression. This workaround is forward- and backward-compatible, but makes code more verbose.
This week, the S4TF team encountered several failures building toolchains: 1. Outdated Package.resolved in [swift/FastaiNotebook_11_imagenette](https://github.com/fastai/fastai_dev/blob/master/swift/FastaiNotebook_11_imagenette/Package.resolved). 2. A regression in `ParameterlessLayer` caused by a change in type inference behavior in [swiftlang/swift#32578](swiftlang/swift#32578). This PR includes two workarounds that unblock toolchain builds: 1. Remove Package.resolved ([swift-apis/1036](tensorflow/swift-apis#1036)). Since this file is regenerated on build, it's often not necessary to include in source control. 2. Add a typealias to instances conforming to `ParameterlessLayer`, which was effective in swift-apis and swift-models (see [tensorflow/swift-apis#1037](tensorflow/swift-apis#1037)). I'm happy to create an additional PR to remove the other Package.resolved files in this repo and add to .gitignore, if desired.
A recent change to witness matching in swiftlang#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
Sema can infer type witnesses for a small set of known conformances, to RawRepresentable, CaseIterable, and Differentiable.
Previously, we would try to compute the type witness in this order:
First, via name lookup, to find an explicit nested type with the same name as an associated type.
Second, we would attempt inference.
Third, we would attempt derivation.
Instead, let's do 3) before 2). This avoids circularity errors in situations where the witness can be derived, but inference fails.
This breaks source compatibility with enum declarations where the raw type in the inheritance clause is a lie, and the user defines their own witnesses with mismatched types. However, I suspect this does not come up in practice, because if you don't synthesize witnesses, there is no way to access the actual raw literal values of the enum cases.