Skip to content

[stdlib] Update Codable.swift (NFC) #63184

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

Merged
merged 4 commits into from
Feb 27, 2023
Merged

Conversation

benrimmington
Copy link
Contributor

@benrimmington benrimmington commented Jan 24, 2023

  • Use any keyword.
  • Use primary associated types.

@benrimmington
Copy link
Contributor Author

benrimmington commented Jan 24, 2023

https://ci.swift.org/job/swift-PR-macos-smoke-test/5161/

dyld: Symbol not found:

_$ss24UnkeyedEncodingContainerP6encode10contentsOfyqd___tKSTRd__SE7ElementRpd__lFTq

swift demangle:

Swift.UnkeyedEncodingContainer.encode<A where A1: Swift.Sequence, A1.Element: Swift.Encodable>(
  contentsOf: A1
) throws -> ()

UPDATE: The "dyld: Symbol not found" error was because:

mutating func encode(
  contentsOf sequence: some Sequence<some Encodable>
) throws

uses two generic parameters:

mutating func encode<T, U>(
  contentsOf sequence: T
) throws where T: Sequence, U: Encodable, T.Element == U

@benrimmington
Copy link
Contributor Author

benrimmington commented Jan 24, 2023

https://ci.swift.org/job/swift-PR-macos-smoke-test/5166/

Failed Tests (1):
  Swift(macosx-x86_64) :: api-digester/stability-stdlib-source.swift
+Accessor DecodingError.Context.underlyingError.Get() has return type change from Swift.Error? to (Swift.Error)?
+Accessor EncodingError.Context.underlyingError.Get() has return type change from Swift.Error? to (Swift.Error)?
+Constructor DecodingError.Context.init(codingPath:debugDescription:underlyingError:) has parameter 2 type change from Swift.Error? to (Swift.Error)?
+Constructor EncodingError.Context.init(codingPath:debugDescription:underlyingError:) has parameter 2 type change from Swift.Error? to (Swift.Error)?
+Func KeyedEncodingContainer.encode(_:forKey:) has generic signature change from <K, T where K : Swift.CodingKey, T : Swift.Encodable> to <K where K : Swift.CodingKey>
+Func KeyedEncodingContainer.encodeConditional(_:forKey:) has generic signature change from <K, T where K : Swift.CodingKey, T : AnyObject, T : Swift.Encodable> to <K where K : Swift.CodingKey>
+Func KeyedEncodingContainer.encodeIfPresent(_:forKey:) has generic signature change from <K, T where K : Swift.CodingKey, T : Swift.Encodable> to <K where K : Swift.CodingKey>
+Func KeyedEncodingContainer.encodeIfPresent(_:forKey:) has parameter 0 type change from T? to (some Swift.Encodable)?
+Func KeyedEncodingContainerProtocol.encode(_:forKey:) has generic signature change from <Self, T where Self : Swift.KeyedEncodingContainerProtocol, T : Swift.Encodable> to <Self where Self : Swift.KeyedEncodingContainerProtocol>
+Func KeyedEncodingContainerProtocol.encodeConditional(_:forKey:) has generic signature change from <Self, T where Self : Swift.KeyedEncodingContainerProtocol, T : AnyObject, T : Swift.Encodable> to <Self where Self : Swift.KeyedEncodingContainerProtocol>
+Func KeyedEncodingContainerProtocol.encodeIfPresent(_:forKey:) has generic signature change from <Self, T where Self : Swift.KeyedEncodingContainerProtocol, T : Swift.Encodable> to <Self where Self : Swift.KeyedEncodingContainerProtocol>
+Func KeyedEncodingContainerProtocol.encodeIfPresent(_:forKey:) has parameter 0 type change from T? to (some Swift.Encodable)?
+Func SingleValueEncodingContainer.encode(_:) has generic signature change from <Self, T where Self : Swift.SingleValueEncodingContainer, T : Swift.Encodable> to <Self where Self : Swift.SingleValueEncodingContainer>
+Func UnkeyedEncodingContainer.encode(_:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Encodable> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.Bool> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.Double> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.Float> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.Int16> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.Int32> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.Int64> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.Int8> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.Int> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.String> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.UInt16> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.UInt32> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.UInt64> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.UInt8> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element == Swift.UInt> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Func UnkeyedEncodingContainer.encodeConditional(_:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : AnyObject, T : Swift.Encodable> to <Self where Self : Swift.UnkeyedEncodingContainer>
+Var DecodingError.Context.underlyingError has declared type change from Swift.Error? to (Swift.Error)?
+Var EncodingError.Context.underlyingError has declared type change from Swift.Error? to (Swift.Error)?

UPDATE: rdar://99932758 (via #61088).

@benrimmington benrimmington marked this pull request as draft January 24, 2023 17:24
@Azoy
Copy link
Contributor

Azoy commented Jan 24, 2023

cc: @natecook1000

@benrimmington
Copy link
Contributor Author

benrimmington commented Jan 25, 2023

https://ci.swift.org/job/swift-PR-macos-smoke-test/5170/

PASS: Swift(macosx-x86_64) :: api-digester/stability-stdlib-source.swift (7415 of 15820)
PASS: Swift(macosx-x86_64) :: api-digester/stability-stdlib-abi-with-asserts.test (7429 of 15820)
PASS: Swift(macosx-x86_64) :: stdlib/CodableTests.swift (8269 of 15820)

Using some CodingKey in CodingKeyRepresentable has passed.

Opaque parameters in other APIs were removed (in fixup! commits) because of dyld or test failures.

@benrimmington benrimmington marked this pull request as ready for review January 25, 2023 14:40
@natecook1000
Copy link
Member

Some of these are kind of surprising (but my trust in the API digester is... not high)

+Func KeyedEncodingContainerProtocol.encode(_:forKey:) has generic signature change from <Self, T where Self : Swift.KeyedEncodingContainerProtocol, T : Swift.Encodable> to <Self where Self : Swift.KeyedEncodingContainerProtocol>

This seems like it should be a totally standard change to be able to make safely — is it because encode(_:forKey:) is mutating that it drops T from the generic signature? How does it still work without that generic parameter? cc @hborla

return type change from Swift.Error? to (Swift.Error)?

🧐

The changes that succeeded look good to me! 👍🏻

@benrimmington
Copy link
Contributor Author

@natecook1000 Thanks for taking a look. My assumption is that the opaque parameters were valid, but API Digester doesn't understand them yet. (rdar://99932758 might have more details?)

@glessard
Copy link
Contributor

It does look like rdar://99932758, which is blocking #61088. There has been no additional information since #61088.

These changes are clearly source-compatible. The strange behaviour of the API digester suggests not trusting it, and manually checking the generated library before and after this for changes in the list of mangled symbols.

@benrimmington
Copy link
Contributor Author

@glessard Thanks. Do you think this pull request can be merged? I can move the rejected changes to a draft PR.

@glessard
Copy link
Contributor

glessard commented Feb 16, 2023

If we're sure it doesn't change the symbol list, then I would approve -- I haven't checked, and I would like to know whether anyone has. (I don't yet trust the automated tests surrounding these changes.) Moving the rejected changes to another PR would be a good thing.

@glessard
Copy link
Contributor

@benrimmington I've "manually" checked the list of symbols, and I'm happy with what I see (i.e. the list does not change before and after this change.) Given that, I'd be happy to merge.

Copy link
Contributor

@glessard glessard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting in the effort to convert this to the newer syntax!

@benrimmington
Copy link
Contributor Author

@glessard Thanks for checking the symbols.

I re-examined the build log of the first attempt, which included some Sequence<some Encodable>. There were 887 failed tests (mostly "dyld: Symbol not found") so I didn't notice at the time, but ABI stability failed with 3 changes:

+Func UnkeyedEncodingContainer.encode(contentsOf:) has generic signature change from <Self, T where Self : Swift.UnkeyedEncodingContainer, T : Swift.Sequence, T.Element : Swift.Encodable> to <Self where Self : Swift.UnkeyedEncodingContainer>

+Func UnkeyedEncodingContainer.encode(contentsOf:) has mangled name changing from '(extension in Swift):Swift.UnkeyedEncodingContainer.encode<A where A1: Swift.Sequence, A1.Element: Swift.Encodable>(contentsOf: A1) throws -> ()' to '(extension in Swift):Swift.UnkeyedEncodingContainer.encode<A, B where A1: Swift.Sequence, B1: Swift.Encodable, B1 == A1.Element>(contentsOf: A1) throws -> ()'

+Func UnkeyedEncodingContainer.encode(contentsOf:) has mangled name changing from 'Swift.UnkeyedEncodingContainer.encode<A where A1: Swift.Sequence, A1.Element: Swift.Encodable>(contentsOf: A1) throws -> ()' to 'Swift.UnkeyedEncodingContainer.encode<A, B where A1: Swift.Sequence, B1: Swift.Encodable, B1 == A1.Element>(contentsOf: A1) throws -> ()'

I'm inclined to believe that api-digester has checked the mangled names. However, the macos.json baselines haven't been updated for 3 years, so they won't include the CodingKeyRepresentable protocol.

Copy link
Member

@lorentey lorentey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely work! The danger of subtle ABI breaks is a bit higher than usual here, but if the exported symbol names match before/after this change, then we're probably fine.

(False positives in the ABI checker need to be reported to source analysis team, and added to the no-asserts allow list.)

@available(SwiftStdlib 5.6, *)
public init?<T: CodingKey>(codingKey: T) {
public init?(codingKey: some CodingKey) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be careful with this one (and the two others of the same sort below) -- the constraints are weirdly split across the extension and the member, and rewriting them could easily end up causing a subtle ABI issue. This is exploring new language territory, and the ABI checker is unlikely to be of any help (other than flagging this as a potential break), but if the exported symbols match before/after this change, then we may be okay.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm inclined to believe that api-digester has checked the mangled names.

I'm not inclined to believe that. I don't think I've seen a list of symbols that libswiftCore is expected to export anywhere in this repository.

However, the macos.json baselines haven't been updated for 3 years, so they won't include the CodingKeyRepresentable protocol.

D'oh. OK, so the ABI checker results are irrelevant, and we need to do manual checks.

Cc @nkcsgexi

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've deferred the false positives and CodingKeyRepresentable changes to another pull request.

@benrimmington
Copy link
Contributor Author

@swift-ci Please smoke test

@glessard glessard merged commit c94210c into swiftlang:main Feb 27, 2023
@benrimmington benrimmington deleted the codable-nfc branch February 28, 2023 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants