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

Synthesize Equatable/Hashable for complex enums, structs #9619

Merged
merged 27 commits into from Oct 11, 2017

Conversation

@allevato
Contributor

allevato commented May 15, 2017

This is the implementation of the yet-to-be-merged/reviewed evolution proposal to synthesize Equatable/Hashable for enums with payloads and for structs (apple/swift-evolution#706). I'm offering this in the hopes that we can get the proposal reviewed, any updates if needed can be made to the implementation, and it can make it into Swift 4.

This is my first foray into a big change to the compiler itself, so I'm sure there are a number of subtleties about building these ASTs that may have gone over my head. I'm very open to any feedback anyone has on these changes!

@CodaFi

This comment has been minimized.

Show comment
Hide comment
@CodaFi

CodaFi May 15, 2017

Collaborator

Overall it looks pretty good. I'll have more in-depth comments later.

Collaborator

CodaFi commented May 15, 2017

Overall it looks pretty good. I'll have more in-depth comments later.

Show outdated Hide outdated lib/AST/Decl.cpp
@allevato

This comment has been minimized.

Show comment
Hide comment
@allevato

allevato May 16, 2017

Contributor

Thanks for the feedback! I've pushed the low-hanging formatting clean-up and am working on the more involved items.

Contributor

allevato commented May 16, 2017

Thanks for the feedback! I've pushed the low-hanging formatting clean-up and am working on the more involved items.

@allevato

This comment has been minimized.

Show comment
Hide comment
@allevato

allevato May 20, 2017

Contributor

I've updated this PR (and the proposal) to forbid synthesis in extensions, to stay in sync with the recently merged Codable change (#9758).

Contributor

allevato commented May 20, 2017

I've updated this PR (and the proposal) to forbid synthesis in extensions, to stay in sync with the recently merged Codable change (#9758).

@CodaFi

This comment has been minimized.

Show comment
Hide comment
@CodaFi

CodaFi May 21, 2017

Collaborator

@swift-ci please smoke test

Collaborator

CodaFi commented May 21, 2017

@swift-ci please smoke test

@allevato

This comment has been minimized.

Show comment
Hide comment
@allevato

allevato May 22, 2017

Contributor

I'm a bit puzzled at why the swiftpm build is crashing on Linux but not on macOS in that smoke test (especially without a stack trace to look at).

I'll try to get a development environment set up on a Linux instance but it'll take a little while to carve out that time.

Contributor

allevato commented May 22, 2017

I'm a bit puzzled at why the swiftpm build is crashing on Linux but not on macOS in that smoke test (especially without a stack trace to look at).

I'll try to get a development environment set up on a Linux instance but it'll take a little while to carve out that time.

@CodaFi

This comment has been minimized.

Show comment
Hide comment
@CodaFi

CodaFi May 30, 2017

Collaborator

@allevato Could you rebase? I'll try to run this on a Linux box for you.

Collaborator

CodaFi commented May 30, 2017

@allevato Could you rebase? I'll try to run this on a Linux box for you.

@allevato

This comment has been minimized.

Show comment
Hide comment
@allevato

allevato May 30, 2017

Contributor

@CodaFi I've rebased and pushed. Thanks for taking a look at this!

Contributor

allevato commented May 30, 2017

@CodaFi I've rebased and pushed. Thanks for taking a look at this!

@allevato

This comment has been minimized.

Show comment
Hide comment
@allevato

allevato May 31, 2017

Contributor

I did a little more digging and found that the smoke tests on macOS don't build Swift Package Manager, which explains why the problem didn't manifest there. I built it explicitly on my Mac and got the same crash that was in the CI logs, so now I have something to debug with.

Contributor

allevato commented May 31, 2017

I did a little more digging and found that the smoke tests on macOS don't build Swift Package Manager, which explains why the problem didn't manifest there. I built it explicitly on my Mac and got the same crash that was in the CI logs, so now I have something to debug with.

@allevato

This comment has been minimized.

Show comment
Hide comment
@allevato

allevato Jun 2, 2017

Contributor

I've pushed a new commit that fixes the type checker issue, added unit tests to verify the fix, and also verified that Swift Package Manager builds with this change.

Can you please kick off another smoke test?

Contributor

allevato commented Jun 2, 2017

I've pushed a new commit that fixes the type checker issue, added unit tests to verify the fix, and also verified that Swift Package Manager builds with this change.

Can you please kick off another smoke test?

@CodaFi

This comment has been minimized.

Show comment
Hide comment
@CodaFi

CodaFi Jun 2, 2017

Collaborator

@swift-ci please smoke test

Collaborator

CodaFi commented Jun 2, 2017

@swift-ci please smoke test

@CodaFi

This comment has been minimized.

Show comment
Hide comment
@CodaFi

CodaFi Aug 9, 2017

Collaborator

@swift-ci please smoke test

Collaborator

CodaFi commented Aug 9, 2017

@swift-ci please smoke test

@lattner

This comment has been minimized.

Show comment
Hide comment
@lattner

lattner Aug 9, 2017

Collaborator

Please add a test case for indirect enums. Thanks!

Collaborator

lattner commented Aug 9, 2017

Please add a test case for indirect enums. Thanks!

@allevato

This comment has been minimized.

Show comment
Hide comment
@allevato

allevato Aug 9, 2017

Contributor

Please add a test case for indirect enums. Thanks!

Done.

Contributor

allevato commented Aug 9, 2017

Please add a test case for indirect enums. Thanks!

Done.

@DougGregor

This comment has been minimized.

Show comment
Hide comment
@DougGregor

DougGregor Aug 16, 2017

Member

@swift-ci please smoke test

Member

DougGregor commented Aug 16, 2017

@swift-ci please smoke test

@allevato

This comment has been minimized.

Show comment
Hide comment
@allevato

allevato Oct 9, 2017

Contributor

@slavapestov I've merged master in, just because this PR was done over such a long course of time that a true rebase would require a lot of manual conflict fixups across the commit history. Let me know if that's ok, if I should squash my local state and rebase that on top of master, or if I should do those fixups.

Contributor

allevato commented Oct 9, 2017

@slavapestov I've merged master in, just because this PR was done over such a long course of time that a true rebase would require a lot of manual conflict fixups across the commit history. Let me know if that's ok, if I should squash my local state and rebase that on top of master, or if I should do those fixups.

@slavapestov

This comment has been minimized.

Show comment
Hide comment
@slavapestov

slavapestov Oct 10, 2017

Member

@allevato That's fine then, let's leave the history as-is. Looks like there's one more merge conflict (sorry), once you fix that I'll merge this PR. Thanks!

Member

slavapestov commented Oct 10, 2017

@allevato That's fine then, let's leave the history as-is. Looks like there's one more merge conflict (sorry), once you fix that I'll merge this PR. Thanks!

@allevato

This comment has been minimized.

Show comment
Hide comment
@allevato

allevato Oct 10, 2017

Contributor

@slavapestov Done—this should be ready to merge now. Thanks! 😄

Contributor

allevato commented Oct 10, 2017

@slavapestov Done—this should be ready to merge now. Thanks! 😄

@slavapestov

This comment has been minimized.

Show comment
Hide comment
@slavapestov

slavapestov Oct 10, 2017

Member

Alright, thank you!

Member

slavapestov commented Oct 10, 2017

Alright, thank you!

@slavapestov

This comment has been minimized.

Show comment
Hide comment
@slavapestov

slavapestov Oct 10, 2017

Member

@swift-ci Please test

Member

slavapestov commented Oct 10, 2017

@swift-ci Please test

@slavapestov

This comment has been minimized.

Show comment
Hide comment
@slavapestov

slavapestov Oct 10, 2017

Member

@swift-ci Please test source compatibility

Member

slavapestov commented Oct 10, 2017

@swift-ci Please test source compatibility

@slavapestov

This comment has been minimized.

Show comment
Hide comment
@slavapestov

slavapestov Oct 10, 2017

Member

@swift-ci Please test

Member

slavapestov commented Oct 10, 2017

@swift-ci Please test

@slavapestov

This comment has been minimized.

Show comment
Hide comment
@slavapestov

slavapestov Oct 10, 2017

Member

@swift-ci Please test

Member

slavapestov commented Oct 10, 2017

@swift-ci Please test

@slavapestov

This comment has been minimized.

Show comment
Hide comment
@slavapestov

slavapestov Oct 10, 2017

Member

@swift-ci Please test source compatibility

Member

slavapestov commented Oct 10, 2017

@swift-ci Please test source compatibility

@slavapestov

This comment has been minimized.

Show comment
Hide comment
@slavapestov

slavapestov Oct 10, 2017

Member

@swift-ci Please test macOS

Member

slavapestov commented Oct 10, 2017

@swift-ci Please test macOS

@slavapestov

This comment has been minimized.

Show comment
Hide comment
@slavapestov

slavapestov Oct 10, 2017

Member

Looks like CI is down for maintenance. Should be back soon

Member

slavapestov commented Oct 10, 2017

Looks like CI is down for maintenance. Should be back soon

@swift-ci

This comment has been minimized.

Show comment
Hide comment
@swift-ci

swift-ci Oct 10, 2017

Contributor

Build failed
Swift Test Linux Platform
Git Sha - ddaa390

Contributor

swift-ci commented Oct 10, 2017

Build failed
Swift Test Linux Platform
Git Sha - ddaa390

@allevato

This comment has been minimized.

Show comment
Hide comment
@allevato

allevato Oct 10, 2017

Contributor

It looks like that failure might be unrelated, but can someone else verify?

<unknown>:0: error: module map file '/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/swift-corelibs-libdispatch/dispatch/module.modulemap' not found
<unknown>:0: error: missing required module 'SwiftShims'
ninja: build stopped: subcommand failed.
Contributor

allevato commented Oct 10, 2017

It looks like that failure might be unrelated, but can someone else verify?

<unknown>:0: error: module map file '/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/swift-corelibs-libdispatch/dispatch/module.modulemap' not found
<unknown>:0: error: missing required module 'SwiftShims'
ninja: build stopped: subcommand failed.
@DougGregor

This comment has been minimized.

Show comment
Hide comment
@DougGregor

DougGregor Oct 10, 2017

Member

@swift-ci please clean smoke test Linux

Member

DougGregor commented Oct 10, 2017

@swift-ci please clean smoke test Linux

@DougGregor

This comment has been minimized.

Show comment
Hide comment
@DougGregor

DougGregor Oct 10, 2017

Member

@swift-ci please clean smoke test Linux

Member

DougGregor commented Oct 10, 2017

@swift-ci please clean smoke test Linux

@DougGregor

This comment has been minimized.

Show comment
Hide comment
@DougGregor

DougGregor Oct 10, 2017

Member

Yeah, it's unrelated. Would like to get actual Linux testing though

Member

DougGregor commented Oct 10, 2017

Yeah, it's unrelated. Would like to get actual Linux testing though

@DougGregor

This comment has been minimized.

Show comment
Hide comment
@DougGregor

DougGregor Oct 10, 2017

Member

@swift-ci please clean smoke test Linux

Member

DougGregor commented Oct 10, 2017

@swift-ci please clean smoke test Linux

@DougGregor

This comment has been minimized.

Show comment
Hide comment
@DougGregor

DougGregor Oct 10, 2017

Member

@swift-ci please clean test Linux

Member

DougGregor commented Oct 10, 2017

@swift-ci please clean test Linux

@slavapestov slavapestov merged commit 124251c into apple:master Oct 11, 2017

5 checks passed

Swift Source Compatibility Suite on macOS Platform Build finished.
Details
Swift Test Linux Platform 10481 tests run, 0 skipped, 0 failed.
Details
Swift Test Linux Platform (smoke test)
Details
Swift Test OS X Platform 52530 tests run, 0 skipped, 0 failed.
Details
Swift Test OS X Platform (smoke test)
Details
@therealbnut

This comment has been minimized.

Show comment
Hide comment
@therealbnut

therealbnut Oct 11, 2017

Contributor

🎉 congratulations @allevato et al. I look forward to seeing this in an upcoming Swift release! (hopefully not too far away 😉)

Contributor

therealbnut commented Oct 11, 2017

🎉 congratulations @allevato et al. I look forward to seeing this in an upcoming Swift release! (hopefully not too far away 😉)

@allevato allevato deleted the allevato:synthesize-equatable-hashable branch Oct 11, 2017

@lattner

This comment has been minimized.

Show comment
Hide comment
@lattner

lattner Oct 11, 2017

Collaborator

Great work @allevato !

Collaborator

lattner commented Oct 11, 2017

Great work @allevato !

@solidcell

This comment has been minimized.

Show comment
Hide comment
@solidcell

solidcell Oct 14, 2017

Thanks so much @allevato! This was one of my top most wanted features in Swift.

Is this likely to make it into a specific upcoming version? I'm not sure how release coordination works for Swift.

solidcell commented Oct 14, 2017

Thanks so much @allevato! This was one of my top most wanted features in Swift.

Is this likely to make it into a specific upcoming version? I'm not sure how release coordination works for Swift.

@lattner

This comment has been minimized.

Show comment
Hide comment
@lattner

lattner Oct 15, 2017

Collaborator

This is most likely to go out in "swift 4.1" in spring 2018

Collaborator

lattner commented Oct 15, 2017

This is most likely to go out in "swift 4.1" in spring 2018

@bielikb

This comment has been minimized.

Show comment
Hide comment
@bielikb

bielikb Dec 13, 2017

Hi guys, today I've tried snapshot of Swift 4.1. (4.1-DEVELOPMENT-SNAPSHOT-2017-12-12-a) I've tried to define enum with associated values in which the value also conforms to Equatable.

enum EnumWithAssociatedValues : Equatable {
    case first(String)
    case second(String)
}

However the conformance was not added and compiler threw couple of errors. Is it possible I misread the proposal and enums/value types with associated values are not yet supported/not part of this proposal? Thanks for your answer in advance.

bielikb commented Dec 13, 2017

Hi guys, today I've tried snapshot of Swift 4.1. (4.1-DEVELOPMENT-SNAPSHOT-2017-12-12-a) I've tried to define enum with associated values in which the value also conforms to Equatable.

enum EnumWithAssociatedValues : Equatable {
    case first(String)
    case second(String)
}

However the conformance was not added and compiler threw couple of errors. Is it possible I misread the proposal and enums/value types with associated values are not yet supported/not part of this proposal? Thanks for your answer in advance.

@xwu

This comment has been minimized.

Show comment
Hide comment
@xwu

xwu Dec 13, 2017

Collaborator

@bielikb Your example works without any errors for me. Are you set up to use the toolchain you downloaded? (Xcode Playgrounds, for example, do not.)

Collaborator

xwu commented Dec 13, 2017

@bielikb Your example works without any errors for me. Are you set up to use the toolchain you downloaded? (Xcode Playgrounds, for example, do not.)

@bielikb

This comment has been minimized.

Show comment
Hide comment
@bielikb

bielikb Dec 13, 2017

Ive tried to use both - terminal (set local version using swiftenv) & xcode playgrounds (set toolchain). Ill check it tomorrow. Equatable/Hashable conformance worked for enums/structs with no associated types without any problem.

bielikb commented Dec 13, 2017

Ive tried to use both - terminal (set local version using swiftenv) & xcode playgrounds (set toolchain). Ill check it tomorrow. Equatable/Hashable conformance worked for enums/structs with no associated types without any problem.

@ematejska

This comment has been minimized.

Show comment
Hide comment
@ematejska

ematejska Dec 14, 2017

@bielikb If you want to easily try it and make sure that you're using the correct toolchain do the following:

  1. Launch Xcode and select Xcode->Toolchains->your_downloaded_toolchain
  2. Create a new command line project for MacOS (File->New->macOs->Command Line Tool)
  3. Go to your project and select the main.swift file and paste your code you want to test.

The problem you have is that Playgrounds will not respect the toolchain setting so using those will not work for testing.

ematejska commented Dec 14, 2017

@bielikb If you want to easily try it and make sure that you're using the correct toolchain do the following:

  1. Launch Xcode and select Xcode->Toolchains->your_downloaded_toolchain
  2. Create a new command line project for MacOS (File->New->macOs->Command Line Tool)
  3. Go to your project and select the main.swift file and paste your code you want to test.

The problem you have is that Playgrounds will not respect the toolchain setting so using those will not work for testing.

@bielikb

This comment has been minimized.

Show comment
Hide comment
@bielikb

bielikb Dec 15, 2017

@ematejska Thanks for hints, that's something I already know.
Im getting errors also for swift script file.

Could you try to build the Swift script that I attached to this comment, if it works for you? Maybe then it's env related problem, rather then implementation itself. When I run Enums.swift with associated values, I got couple of compiler errors. If I remove associated values from declaration, it builds just fine.
Please note that the attached zip contains also .swift-version file that specifies 4.1 snapshot I'm using.

Feel free to correct me, if I'm doing something wrong.

enum_associated_values.zip

bielikb commented Dec 15, 2017

@ematejska Thanks for hints, that's something I already know.
Im getting errors also for swift script file.

Could you try to build the Swift script that I attached to this comment, if it works for you? Maybe then it's env related problem, rather then implementation itself. When I run Enums.swift with associated values, I got couple of compiler errors. If I remove associated values from declaration, it builds just fine.
Please note that the attached zip contains also .swift-version file that specifies 4.1 snapshot I'm using.

Feel free to correct me, if I'm doing something wrong.

enum_associated_values.zip

@ematejska

This comment has been minimized.

Show comment
Hide comment
@ematejska

ematejska Dec 15, 2017

@bielikb I already had the 4.1-Snapshot-2017-12-13(a) toolchain installed so I tried it with that and Xcode 9. Seems to work for me. I saw errors with the default toolchain that was shipped with Xcode 9 or the form "error: type 'EnumWithAssociatedValues' does not conform to protocol 'Equatable'" and then when I switched to the 4.1-Snapshot, I was able to build successfully.

Just to be clear, I didn't run this as a script but pasted your code into my command line project as described in the previous comment.

ematejska commented Dec 15, 2017

@bielikb I already had the 4.1-Snapshot-2017-12-13(a) toolchain installed so I tried it with that and Xcode 9. Seems to work for me. I saw errors with the default toolchain that was shipped with Xcode 9 or the form "error: type 'EnumWithAssociatedValues' does not conform to protocol 'Equatable'" and then when I switched to the 4.1-Snapshot, I was able to build successfully.

Just to be clear, I didn't run this as a script but pasted your code into my command line project as described in the previous comment.

@bielikb

This comment has been minimized.

Show comment
Hide comment
@bielikb

bielikb Dec 15, 2017

@ematejska I've tried to run it in XCode 9.1 in sample project and it worked! As you mentioned. I however still get problems to build it as a script - but that might be problem of choosing the correct Swift toolchain - e.g. although I specified 4.1 snapshot as local swift version through swiftenv for dir with my Enums.swift, it's probably picking 4.0.2 toolchain. Thanks for help & getting me out of the "fog". I cannot wait until 4.1 will hit the world, good night boiler plate.

bielikb commented Dec 15, 2017

@ematejska I've tried to run it in XCode 9.1 in sample project and it worked! As you mentioned. I however still get problems to build it as a script - but that might be problem of choosing the correct Swift toolchain - e.g. although I specified 4.1 snapshot as local swift version through swiftenv for dir with my Enums.swift, it's probably picking 4.0.2 toolchain. Thanks for help & getting me out of the "fog". I cannot wait until 4.1 will hit the world, good night boiler plate.

@benrimmington

This comment has been minimized.

Show comment
Hide comment
@benrimmington

benrimmington Dec 16, 2017

Contributor

@bielikb Try including the xctoolchain alias/identifier in your script:

#!/usr/bin/xcrun --toolchain 'swift' swift

or

#!/usr/bin/xcrun --toolchain 'org.swift.4120171212a' swift
Contributor

benrimmington commented Dec 16, 2017

@bielikb Try including the xctoolchain alias/identifier in your script:

#!/usr/bin/xcrun --toolchain 'swift' swift

or

#!/usr/bin/xcrun --toolchain 'org.swift.4120171212a' swift
@bielikb

This comment has been minimized.

Show comment
Hide comment
@bielikb

bielikb Dec 16, 2017

@benrimmington I've tried the former definition and it worked! Thanks a lot guys ;)

bielikb commented Dec 16, 2017

@benrimmington I've tried the former definition and it worked! Thanks a lot guys ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment