Skip to content
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

[SE-0283] Implement Equatable, Comparable, and Hashable conformance for Tuples #28833

Merged
merged 15 commits into from
Oct 26, 2020

Conversation

Azoy
Copy link
Contributor

@Azoy Azoy commented Dec 17, 2019

From: https://forums.swift.org/t/hacking-equatable-conformance-on-void/25975

The tests right now are kind of lackluster, what else can I be testing with this? What else can be improved upon in this implementation? Is there an edge case that I hadn't thought about?

cc: @jckarter @rjmccall

@Azoy
Copy link
Contributor Author

Azoy commented Dec 19, 2019

@rjmccall I've updated the implementation to have IRGen emit conformance descriptors for the stdlib. Let me know if this is what you had in mind.

@Azoy Azoy force-pushed the void-is-equatable branch from d507263 to fc5facc Compare December 19, 2019 15:16
Copy link
Contributor

@rjmccall rjmccall left a comment

Choose a reason for hiding this comment

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

Yes, this is basically what I was asking for, thank you.

As a general matter, I wonder if it wouldn't be better to just go a step further and make this a conditional conformance for all tuple types. That would be a big request except that you've obviously already figured out how to do some quite sophisticated stuff.

include/swift/AST/ProtocolConformance.h Outdated Show resolved Hide resolved
lib/IRGen/GenDecl.cpp Outdated Show resolved Hide resolved
lib/SIL/TypeLowering.cpp Outdated Show resolved Hide resolved
@Azoy
Copy link
Contributor Author

Azoy commented Dec 20, 2019

I'll look into doing this conditionally for all tuples to see what work is needed.

@Azoy Azoy force-pushed the void-is-equatable branch from 0ec88a1 to ed9783e Compare December 21, 2019 15:55
@Azoy Azoy force-pushed the void-is-equatable branch from 598d795 to a6b47dd Compare January 4, 2020 18:56
@Azoy
Copy link
Contributor Author

Azoy commented Jan 4, 2020

@rjmccall @jckarter I've gone ahead and implemented Equatable conformance for all tuples. Let me know what other tests you would like and any improvements I can make to the implementation. This is pretty exciting!

@Azoy Azoy changed the title Implement Equatable conformance for Void Implement Equatable conformance for Tuples Jan 4, 2020
@Azoy Azoy force-pushed the void-is-equatable branch from f192891 to a2519b5 Compare January 7, 2020 00:39
@Azoy
Copy link
Contributor Author

Azoy commented Jan 9, 2020

Currently this initializes a new witness table everytime we need one, but it should be possible to have a single witness table in the runtime. Hmm...
Edit: Although maybe not because a conformance descriptor's witness table pattern is relative direct, and the address of the witness table I'm getting from the conformance at runtime does not match up to the address of the witness table in the runtime...

@jckarter
Copy link
Contributor

jckarter commented Jan 9, 2020

The conformance descriptor format isn't absolutely important. Fundamentally, we just need something the witness table can point to that uniquely identifies the conformance. It seems to me like we should be able to have one descriptor and one witness table that works for all tuples.

@Azoy Azoy force-pushed the void-is-equatable branch from a2519b5 to b5ff0fd Compare January 9, 2020 19:30
@Azoy
Copy link
Contributor Author

Azoy commented Jan 9, 2020

@jckarter Sorry I was being dumb, does this look ok? Single descriptor and witness table now!

@Azoy Azoy force-pushed the void-is-equatable branch from b5ff0fd to c1de7fd Compare January 9, 2020 19:35
@jckarter
Copy link
Contributor

jckarter commented Jan 9, 2020

I haven't had time yet to look at this PR in depth, but I hope to soon. Sorry!

@Azoy Azoy force-pushed the void-is-equatable branch from c1de7fd to 5313bb4 Compare January 9, 2020 20:10
@Azoy Azoy force-pushed the void-is-equatable branch from 5313bb4 to 6d29ce7 Compare January 18, 2020 21:19
@Azoy
Copy link
Contributor Author

Azoy commented Jan 18, 2020

@jckarter I've hopefully added backward compatibility for these conformances for both 5.0 and 5.1 runtimes. I'm not too versed with how the compatibility library works, but let me know if I made a mistake or something of the like. The test for compatibility should be exercised through the interpreter test I added in earlier commits, correct? I remember reading something from here: #25030 (comment)

@Azoy Azoy force-pushed the void-is-equatable branch from 6d29ce7 to 04d9fb3 Compare January 23, 2020 02:00
lib/IRGen/GenProto.cpp Outdated Show resolved Hide resolved
lib/IRGen/GenProto.cpp Outdated Show resolved Hide resolved
@Azoy Azoy force-pushed the void-is-equatable branch from 04d9fb3 to 4406a47 Compare February 22, 2020 20:37
@Azoy
Copy link
Contributor Author

Azoy commented Feb 22, 2020

Does it make sense to also implement comparable and hashable in this pr, or should those be in separate prs?

@jckarter
Copy link
Contributor

@Azoy It might be easier to review to break them out into their own PRs. Thanks!

@benrimmington
Copy link
Contributor

@swift-ci Please test Windows platform

@jckarter
Copy link
Contributor

@Azoy Have you asked for commit access yet? If you have commit access then you ought to be able to trigger CI by yourself.

@benrimmington
Copy link
Contributor

All checks have passed. Should we test source compatibility again?

@Azoy
Copy link
Contributor Author

Azoy commented Oct 23, 2020

I would say yes because they failed last time due to the macOS failure.

@benrimmington
Copy link
Contributor

@swift-ci Please test source compatibility

@xwu
Copy link
Collaborator

xwu commented Oct 25, 2020

@Azoy, this is fantastic. I guess it's ready to go?

@Azoy
Copy link
Contributor Author

Azoy commented Oct 26, 2020

@xwu I believe so! @jckarter are we clear for takeoff?

@jckarter
Copy link
Contributor

Should be good to go. Thanks @Azoy !

@Azoy Azoy merged commit 84e5fd2 into swiftlang:main Oct 26, 2020
@Azoy Azoy deleted the void-is-equatable branch October 26, 2020 18:02
@drodriguez
Copy link
Contributor

Has an internal crash in clang appeared during development?

It seems to have started around the introduction of these changes. The full logs can be seen in https://ci-external.swift.org/job/oss-swift-RA-linux-ubuntu-16.04-android-arm64/6614/console.

The failed assertion seems to be

clang++: /home/ubuntu/jenkins/workspace/oss-swift-RA-linux-ubuntu-16.04-android-arm64/llvm-project/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp:120: virtual unsigned int (anonymous namespace)::AArch64ELFObjectWriter::getRelocType(llvm::MCContext &, const llvm::MCValue &, const llvm::MCFixup &, bool) const: Assertion `(!Target.getSymA() || Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None || Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT) && "Should only be expression-level modifiers here"' failed.

In the case of the Android ARM32, the error is slightly different and might give someone a clue:

<inline asm>:1:41: error: expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '%<type>' or "<type>"
  .type __swift_tupleEquatable_private, @object
                                        ^
<inline asm>:5:37: error: expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '%<type>' or "<type>"
  .type _swift_tupleEquatable_conf, @object
                                    ^
<inline asm>:23:58: error: expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '%<type>' or "<type>"
  .type "associated conformance _swift_tupleComparable", @object
                                                         ^
<inline asm>:33:42: error: expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '%<type>' or "<type>"
  .type __swift_tupleComparable_private, @object
                                         ^
<inline asm>:37:38: error: expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '%<type>' or "<type>"
  .type _swift_tupleComparable_conf, @object
                                     ^
<inline asm>:62:40: error: expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '%<type>' or "<type>"
  .type __swift_tupleHashable_private, @object
                                       ^
<inline asm>:66:36: error: expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '%<type>' or "<type>"
  .type _swift_tupleHashable_conf, @object

There's some __asm pieces in the code, but I cannot match the reported errors to any of them.

Does someone has any idea what might be going on?

@drodriguez
Copy link
Contributor

I found the problematic assembly. It was collapsed by GitHub.

Seems that @ is a comment symbol in AArch32 according to https://reviews.llvm.org/D10651. __ELF__ is probably exercised only in Linux, and not in ARM. ARM has probably checked in __MACH__, but not others.

Does anybody know which symbol can be used in front of object so it works both in every ELF platform (or at least in x86 and ARM)?

@Azoy
Copy link
Contributor Author

Azoy commented Oct 27, 2020

@drodriguez for ARM32 on Android, it looks like it wants %object which should be a quick fix, but the ARM64 android looks like it doesn't support @GOTPCREL relocation from the error you gave (either nothing or @PLT which is different iirc) which I'm assuming will be an issue with ARM32. @jckarter I think a lot of these issues could be avoided if we manually created got equivalent structures for linux platforms, but that'll increase the amount of assembly for this dramatically. Maybe we can move this to an .S?

@drodriguez
Copy link
Contributor

Thanks for the answer. I found that the Linux AArch64 testing seems to also had failed with a similar error: https://ci-external.swift.org/job/oss-swift-RA-linux-ubuntu-18.04-aarch64/2177/console. I will try to double check tonight about using the percent sign instead of the at-symbol.

@jckarter
Copy link
Contributor

@Azoy The ELF syntax is @GOT instead of @GOTPCREL, IIRC.

@aschwaighofer
Copy link
Contributor

@aschwaighofer
Copy link
Contributor

Temporary disabled the test here: #34480

@aschwaighofer
Copy link
Contributor

@Azoy Can you take a look, I expect that the test just needs updating.

@tbkka
Copy link
Contributor

tbkka commented Oct 29, 2020

We're also seeing some tests fail with errors about invalid relative offsets in a conformance. I don't know for sure that it was this PR, but the timing is suspicious. I'm trying to get more details.

@tbkka
Copy link
Contributor

tbkka commented Oct 29, 2020

@rjmccall @jckarter -- Do you see a way that @Azoy could declare these conformances without resorting to assembly?

@Azoy
Copy link
Contributor Author

Azoy commented Oct 29, 2020

@tbkka we're discussing writing them in LLVM IR instead over here: #34457

@jckarter
Copy link
Contributor

@Azoy would it be OK if you reverted this? Another issue we're seeing is that it appears that executables and dylibs that link the compatibility versions of the tuple conformance implementation end up reexporting the __swift_tuple* symbols. The compatibility implementation ought to be private to the binary it gets linked in, so we'll want to make sure they have hidden visibility in the compatibility .a files (and it'd probably be good to give them different symbol names like __swift50_tuple* so they don't collide with the real runtime implementations in newer OSes).

I wonder if the issues @tbkka alluded to about invalid conformance addresses might be related to the compatibility libraries as well—if we link the compatibility libraries into a binary, but run with a new runtime that contains the real implementation of tuple conformance, that real implementation needs to take precedence, and the compatibility implementation would be invalid from the host runtime's perspective. Binaries that relies on the compatibility library for backward deployment might need to use a stub function that picks either the compatibility or host runtime version of the symbols to resolve the address of these symbols, instead of referencing the symbols directly.

@airspeedswift
Copy link
Member

Reverted in #34492

@AnthonyLatsis AnthonyLatsis added swift evolution implemented Flag → feature: A feature that was approved through the Swift evolution process and implemented and removed swift evolution approved Flag → feature: A feature that was approved through the Swift evolution process labels Mar 11, 2024
@AnthonyLatsis AnthonyLatsis added swift evolution approved Flag → feature: A feature that was approved through the Swift evolution process and removed swift evolution implemented Flag → feature: A feature that was approved through the Swift evolution process and implemented labels Jan 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
swift evolution approved Flag → feature: A feature that was approved through the Swift evolution process
Projects
None yet
Development

Successfully merging this pull request may close these issues.