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

Support synthesis of protocol conformances (including conditional ones) in extensions #16376

Merged
merged 7 commits into from May 7, 2018

Conversation

huonw
Copy link
Contributor

@huonw huonw commented May 4, 2018

This works for Equatable, Hashable, Encodable, Decodable (and thus Codable), and CaseIterable. For instance,

struct Foo<T> {
    var x: T 
}
extension Foo: Equatable where T: Equatable {}

Fixes rdar://problem/39199726 and https://bugs.swift.org/browse/SR-6803

@huonw
Copy link
Contributor Author

huonw commented May 4, 2018

@swift-ci please test

@huonw
Copy link
Contributor Author

huonw commented May 4, 2018

@swift-ci please test source compatibility

@swift-ci
Copy link
Collaborator

swift-ci commented May 4, 2018

Build failed
Swift Test Linux Platform
Git Sha - 4ec037f64aa47fb142c84bfd18be2523eee9fd71

@huonw
Copy link
Contributor Author

huonw commented May 4, 2018

For future reference/if the builds disappear before I get back to this:

Swift(linux-x86_64).stdlib.KeyPath.swift
Script:
--
rm -rf "/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/test-linux-x86_64/stdlib/Output/KeyPath.swift.tmp" && mkdir -p "/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/test-linux-x86_64/stdlib/Output/KeyPath.swift.tmp"
/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swiftc -target x86_64-unknown-linux-gnu  -module-cache-path '/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/swift-test-results/x86_64-unknown-linux-gnu/clang-module-cache' -swift-version 3  -O /home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/swift/test/stdlib/KeyPath.swift -Xfrontend -enable-sil-ownership -Xfrontend -g -o /home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/test-linux-x86_64/stdlib/Output/KeyPath.swift.tmp/a.out
/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/test-linux-x86_64/stdlib/Output/KeyPath.swift.tmp/a.out
--
swift: /home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/swift/lib/AST/Type.cpp:2680: swift::AssociatedTypeDecl *swift::ArchetypeType::getAssocType() const: Assertion `!getOpenedExistentialType()' failed.
#0 0x00000000040dbb34 PrintStackTraceSignalHandler(void*) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x40dbb34)
#1 0x00000000040dbe76 SignalHandler(int) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x40dbe76)
#2 0x00007fb369cb0390 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x11390)
#3 0x00007fb3683ef428 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x35428)
#4 0x00007fb3683f102a abort (/lib/x86_64-linux-gnu/libc.so.6+0x3702a)
#5 0x00007fb3683e7bd7 (/lib/x86_64-linux-gnu/libc.so.6+0x2dbd7)
#6 0x00007fb3683e7c82 (/lib/x86_64-linux-gnu/libc.so.6+0x2dc82)
#7 0x00000000017d6fc8 (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x17d6fc8)
#8 0x0000000000641914 swift::irgen::emitArchetypeTypeMetadataRef(swift::irgen::IRGenFunction&, swift::CanTypeWrapper<swift::ArchetypeType>, swift::irgen::DynamicMetadataRequest) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x641914)
#9 0x000000000062b8da swift::CanTypeVisitor<(anonymous namespace)::EmitTypeMetadataRef, swift::irgen::MetadataResponse, swift::irgen::DynamicMetadataRequest>::visit(swift::CanType, swift::irgen::DynamicMetadataRequest) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x62b8da)
#10 0x0000000000629ffa swift::irgen::IRGenFunction::emitTypeMetadataRef(swift::CanType, swift::irgen::DynamicMetadataRequest) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x629ffa)
#11 0x000000000062a532 swift::CanTypeVisitor<(anonymous namespace)::EmitTypeMetadataRefForLayout, llvm::Value*, swift::irgen::DynamicMetadataRequest>::visit(swift::CanType, swift::irgen::DynamicMetadataRequest) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x62a532)
#12 0x000000000062a467 swift::irgen::IRGenFunction::emitTypeMetadataRefForLayout(swift::SILType, swift::irgen::DynamicMetadataRequest) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x62a467)
#13 0x00000000005647b4 swift::irgen::IRGenFunction::emitValueWitnessTableRef(swift::SILType, swift::irgen::DynamicMetadataRequest, llvm::Value**) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5647b4)
#14 0x00000000005646ed swift::irgen::IRGenFunction::emitValueWitnessTableRef(swift::SILType, llvm::Value**) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5646ed)
#15 0x000000000057767a swift::irgen::emitLoadOfSize(swift::irgen::IRGenFunction&, swift::SILType) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x57767a)
#16 0x0000000000644dd4 swift::irgen::emitBuiltinCall(swift::irgen::IRGenFunction&, swift::BuiltinInfo const&, swift::Identifier, swift::SILType, swift::irgen::Explosion&, swift::irgen::Explosion&, swift::SubstitutionMap) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x644dd4)
#17 0x00000000005e779a swift::SILInstructionVisitor<(anonymous namespace)::IRGenSILFunction, void>::visit(swift::SILInstruction*) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5e779a)
#18 0x00000000005e1990 (anonymous namespace)::IRGenSILFunction::emitSILFunction() (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5e1990)
#19 0x00000000005df8c4 swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5df8c4)
#20 0x0000000000504c0b swift::irgen::IRGenerator::emitLazyDefinitions() (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x504c0b)
#21 0x00000000005b9e17 performIRGeneration(swift::IRGenOptions&, swift::ModuleDecl*, std::unique_ptr<swift::SILModule, std::default_delete<swift::SILModule> >, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::LLVMContext&, swift::SourceFile*, llvm::GlobalVariable**, unsigned int) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5b9e17)
#22 0x00000000005ba491 swift::performIRGeneration(swift::IRGenOptions&, swift::SourceFile&, std::unique_ptr<swift::SILModule, std::default_delete<swift::SILModule> >, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::LLVMContext&, unsigned int, llvm::GlobalVariable**) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5ba491)
#23 0x00000000004dd01d performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x4dd01d)
#24 0x00000000004d8320 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x4d8320)
#25 0x000000000048b362 main (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x48b362)
#26 0x00007fb3683da830 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20830)
#27 0x0000000000488239 _start (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x488239)
Stack dump:
0.	Program arguments: /home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift -frontend -c -primary-file /home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/swift/test/stdlib/KeyPath.swift -target x86_64-unknown-linux-gnu -disable-objc-interop -module-cache-path /home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/swift-test-results/x86_64-unknown-linux-gnu/clang-module-cache -swift-version 3 -O -enable-sil-ownership -g -module-name a -o /tmp/lit_tmp_QJzx7_/KeyPath-b610f2.o 
1.	While emitting IR SIL function "@$Ss7KeyPathC15projectReadOnly4fromq_x_tFq_s0aB6BufferVXEfU_1a10SubscriptsVyAG0A1AVG_AG15SubscriptResultVyAkG0A1BVGTg5Tf4xn_n".
Swift(linux-x86_64).stdlib.KeyPathImplementation.swift
Script:
--
rm -rf "/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/test-linux-x86_64/stdlib/Output/KeyPathImplementation.swift.tmp" && mkdir -p "/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/test-linux-x86_64/stdlib/Output/KeyPathImplementation.swift.tmp"
/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swiftc -target x86_64-unknown-linux-gnu  -module-cache-path '/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/swift-test-results/x86_64-unknown-linux-gnu/clang-module-cache' -swift-version 3  -O /home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/swift/test/stdlib/KeyPathImplementation.swift -g -o /home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/test-linux-x86_64/stdlib/Output/KeyPathImplementation.swift.tmp/a.out
/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/test-linux-x86_64/stdlib/Output/KeyPathImplementation.swift.tmp/a.out
--
Exit Code: 254
swift: /home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/swift/lib/AST/Type.cpp:2680: swift::AssociatedTypeDecl *swift::ArchetypeType::getAssocType() const: Assertion `!getOpenedExistentialType()' failed.
#0 0x00000000040dbb34 PrintStackTraceSignalHandler(void*) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x40dbb34)
#1 0x00000000040dbe76 SignalHandler(int) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x40dbe76)
#2 0x00007f33c4dbf390 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x11390)
#3 0x00007f33c34fe428 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x35428)
#4 0x00007f33c350002a abort (/lib/x86_64-linux-gnu/libc.so.6+0x3702a)
#5 0x00007f33c34f6bd7 (/lib/x86_64-linux-gnu/libc.so.6+0x2dbd7)
#6 0x00007f33c34f6c82 (/lib/x86_64-linux-gnu/libc.so.6+0x2dc82)
#7 0x00000000017d6fc8 (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x17d6fc8)
#8 0x0000000000641914 swift::irgen::emitArchetypeTypeMetadataRef(swift::irgen::IRGenFunction&, swift::CanTypeWrapper<swift::ArchetypeType>, swift::irgen::DynamicMetadataRequest) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x641914)
#9 0x000000000062b8da swift::CanTypeVisitor<(anonymous namespace)::EmitTypeMetadataRef, swift::irgen::MetadataResponse, swift::irgen::DynamicMetadataRequest>::visit(swift::CanType, swift::irgen::DynamicMetadataRequest) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x62b8da)
#10 0x0000000000629ffa swift::irgen::IRGenFunction::emitTypeMetadataRef(swift::CanType, swift::irgen::DynamicMetadataRequest) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x629ffa)
#11 0x000000000062a532 swift::CanTypeVisitor<(anonymous namespace)::EmitTypeMetadataRefForLayout, llvm::Value*, swift::irgen::DynamicMetadataRequest>::visit(swift::CanType, swift::irgen::DynamicMetadataRequest) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x62a532)
#12 0x000000000062a467 swift::irgen::IRGenFunction::emitTypeMetadataRefForLayout(swift::SILType, swift::irgen::DynamicMetadataRequest) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x62a467)
#13 0x00000000005647b4 swift::irgen::IRGenFunction::emitValueWitnessTableRef(swift::SILType, swift::irgen::DynamicMetadataRequest, llvm::Value**) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5647b4)
#14 0x00000000005646ed swift::irgen::IRGenFunction::emitValueWitnessTableRef(swift::SILType, llvm::Value**) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5646ed)
#15 0x000000000057767a swift::irgen::emitLoadOfSize(swift::irgen::IRGenFunction&, swift::SILType) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x57767a)
#16 0x0000000000644dd4 swift::irgen::emitBuiltinCall(swift::irgen::IRGenFunction&, swift::BuiltinInfo const&, swift::Identifier, swift::SILType, swift::irgen::Explosion&, swift::irgen::Explosion&, swift::SubstitutionMap) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x644dd4)
#17 0x00000000005e779a swift::SILInstructionVisitor<(anonymous namespace)::IRGenSILFunction, void>::visit(swift::SILInstruction*) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5e779a)
#18 0x00000000005e1990 (anonymous namespace)::IRGenSILFunction::emitSILFunction() (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5e1990)
#19 0x00000000005df8c4 swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5df8c4)
#20 0x0000000000504c0b swift::irgen::IRGenerator::emitLazyDefinitions() (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x504c0b)
#21 0x00000000005b9e17 performIRGeneration(swift::IRGenOptions&, swift::ModuleDecl*, std::unique_ptr<swift::SILModule, std::default_delete<swift::SILModule> >, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::LLVMContext&, swift::SourceFile*, llvm::GlobalVariable**, unsigned int) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5b9e17)
#22 0x00000000005ba491 swift::performIRGeneration(swift::IRGenOptions&, swift::SourceFile&, std::unique_ptr<swift::SILModule, std::default_delete<swift::SILModule> >, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::LLVMContext&, unsigned int, llvm::GlobalVariable**) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x5ba491)
#23 0x00000000004dd01d performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x4dd01d)
#24 0x00000000004d8320 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x4d8320)
#25 0x000000000048b362 main (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x48b362)
#26 0x00007f33c34e9830 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20830)
#27 0x0000000000488239 _start (/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift+0x488239)
Stack dump:
0.	Program arguments: /home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/bin/swift -frontend -c -primary-file /home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/swift/test/stdlib/KeyPathImplementation.swift -emit-module-path /tmp/lit_tmp_QJzx7_/KeyPathImplementation-ebf81d.swiftmodule -emit-module-doc-path /tmp/lit_tmp_QJzx7_/KeyPathImplementation-ebf81d.swiftdoc -target x86_64-unknown-linux-gnu -disable-objc-interop -g -module-cache-path /home/buildnode/jenkins/workspace/swift-PR-Linux/branch-master/buildbot_linux/swift-linux-x86_64/swift-test-results/x86_64-unknown-linux-gnu/clang-module-cache -swift-version 3 -O -module-name a -o /tmp/lit_tmp_QJzx7_/KeyPathImplementation-ebf81d.o 
1.	While emitting IR SIL function "@$Ss7KeyPathC15projectReadOnly4fromq_x_tFq_s0aB6BufferVXEfU_1a10TestGetterV_AITg5".
 for <<debugloc at "<compiler-generated>":0:0>><unknown>:0: error: unable to execute command: Aborted

(They could be constantly failing, from a quick glance at the other builds.)

@swift-ci
Copy link
Collaborator

swift-ci commented May 4, 2018

Build failed
Swift Test OS X Platform
Git Sha - 4ec037f64aa47fb142c84bfd18be2523eee9fd71

Copy link
Contributor

@itaiferber itaiferber left a comment

Choose a reason for hiding this comment

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

Wow, thanks for taking this on! The changes here LGTM! 🎉

"implementation of %0 cannot be automatically synthesized in an extension", (Type))
ERROR(cannot_synthesize_init_in_extension_of_nonfinal,none,
"implementation of %0 for non-final class cannot be automatically "
"synthesized in an extension due to 'init' requirement",
Copy link
Contributor

Choose a reason for hiding this comment

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

One question here — excuse my mental lapse, but what is preventing us from synthesizing these? (I suspect that folks are going to hit this and be confused; we might want to be a bit more specific)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In non-final classes, the inits satisfying protocol requirements must be required and those can't occur in extensions. I phrase the message this way because I couldn't get something more explanatory to be shorter, and it was pointed out to me that error messages aren't the place to teach the language. I'd love some alternative phrasings though, do you have any ideas?

Copy link
Contributor

@itaiferber itaiferber May 4, 2018

Choose a reason for hiding this comment

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

Ah, duh 🤦‍♂️ I haven't thought about it much, but I think cribbing some of the messaging we already have (e.g. the existing "error: initializer requirement 'init(foo:)' can only be satisfied by a required initializer in the definition of non-final class 'Foo'") can help.

For instance, "implementation of %0 for non-final class '%1' cannot be synthesized because initializer requirement 'required %2' cannot be implemented in an extension" gets the user a little bit closer to understanding why this can't be done. Of course, the next question people have is "why does Swift treat a same-file extension any differently than writing things in the original declaration", but that's something for another day. 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, that's a great idea! I've gone with:

implementation of 'Decodable' for non-final class cannot be automatically synthesized in extension because initializer requirement 'init(from:)' can only be be satisfied by a 'required' initializer in the class definition

@NachoSoto
Copy link
Contributor

🎉 this is huge

@huonw
Copy link
Contributor Author

huonw commented May 4, 2018

@swift-ci please test OSX platform

@huonw
Copy link
Contributor Author

huonw commented May 4, 2018

@swift-ci please test OS X platform

1 similar comment
@huonw
Copy link
Contributor Author

huonw commented May 4, 2018

@swift-ci please test OS X platform

huonw added 7 commits May 7, 2018 09:10
Instead of passing around a TypeChecker and three Decls (the nominal type, the
protocol, and the decl declaring the conformance) everywhere, we can just pass
one object.

This should be [NFC].
This works for all protocols except for Decodable on non-final classes, because
the init requirement has to be 'required' and thus in the type's declaration.

Fixes most of https://bugs.swift.org/browse/SR-6803.
@huonw huonw force-pushed the same-file-extension-restructure branch from 4ec037f to 27d8f17 Compare May 6, 2018 23:46
@huonw
Copy link
Contributor Author

huonw commented May 6, 2018

@swift-ci please test

@swift-ci
Copy link
Collaborator

swift-ci commented May 6, 2018

Build failed
Swift Test Linux Platform
Git Sha - 4ec037f64aa47fb142c84bfd18be2523eee9fd71

@swift-ci
Copy link
Collaborator

swift-ci commented May 6, 2018

Build failed
Swift Test OS X Platform
Git Sha - 4ec037f64aa47fb142c84bfd18be2523eee9fd71

@huonw
Copy link
Contributor Author

huonw commented May 6, 2018

@swift-ci please test

@huonw huonw merged commit 90ba980 into apple:master May 7, 2018
@huonw huonw deleted the same-file-extension-restructure branch May 7, 2018 05:03
Copy link
Member

@DougGregor DougGregor left a comment

Choose a reason for hiding this comment

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

This looks great. Some minor comments throughout, and one overall request: could you add some tests that go all the way to IRGen, to make sure the type checker is producing valid conformances (particularly for the conditional case) throughout?

@@ -1193,9 +1172,9 @@ static bool canSynthesize(TypeChecker &tc, NominalTypeDecl *target,
diag::decodable_super_init_not_designated_here,
requirement->getFullName(), memberName);
return false;
} else if (!initializer->isAccessibleFrom(target)) {
} else if (!initializer->isAccessibleFrom(classDecl)) {
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be initializer->isAccessibleFrom(conformanceDC), although I'm not convinced that it will ever matter.

// Cannot call an inaccessible method.
auto accessScope = initializer->getFormalAccessScope(target);
auto accessScope = initializer->getFormalAccessScope(classDecl);
Copy link
Member

Choose a reason for hiding this comment

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

Same comment.

tc.diagnose(requirement, diag::no_witnesses, diag::RequirementKind::Func,
requirement->getFullName(), encodableType, /*AddFixIt=*/false);
auto diagnosticTransaction = DiagnosticTransaction(TC.Context.Diags);
TC.diagnose(Nominal, diag::type_does_not_conform, Nominal->getDeclaredType(),
Copy link
Member

Choose a reason for hiding this comment

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

Don't we want this diagnostic to point at the place where the conformance was declared, rather than always pointing at the nominal type declaration?

decodableType);
tc.diagnose(requirement, diag::no_witnesses,
auto diagnosticTransaction = DiagnosticTransaction(TC.Context.Diags);
TC.diagnose(Nominal, diag::type_does_not_conform, Nominal->getDeclaredType(),
Copy link
Member

Choose a reason for hiding this comment

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

Same comment regarding the location of the diagnostic.

@@ -635,14 +635,15 @@ deriveEquatable_eq(TypeChecker &tc, Decl *parentDecl, NominalTypeDecl *typeDecl,
DeclNameLoc()));

if (!C.getEqualIntDecl()) {
tc.diagnose(parentDecl->getLoc(), diag::no_equal_overload_for_int);
derived.TC.diagnose(derived.ConformanceDecl->getLoc(),
Copy link
Member

Choose a reason for hiding this comment

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

Ah, this is the location I was expecting for the other diagnostics above.

if (!tc.conformsToProtocol(intType, intLiteralProto, typeDecl, None)) {
tc.diagnose(typeDecl->getLoc(),
if (!tc.conformsToProtocol(intType, intLiteralProto, derived.Nominal, None)) {
tc.diagnose(derived.Nominal->getLoc(),
Copy link
Member

Choose a reason for hiding this comment

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

This diagnostic probably never fires, but derived.ConformanceDecl would be more appropriate for these two uses.

@@ -1110,15 +1095,17 @@ deriveHashable_hashValue(TypeChecker &tc, Decl *parentDecl,

getterDecl->setInterfaceType(interfaceType);
getterDecl->setValidationStarted();
getterDecl->copyFormalAccessFrom(typeDecl, /*sourceIsParentContext*/true);
getterDecl->copyFormalAccessFrom(derived.Nominal,
Copy link
Member

Choose a reason for hiding this comment

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

Same comment about using derived.ConformanceDecl.


// Finish creating the property.
hashValueDecl->setImplicit();
hashValueDecl->setInterfaceType(intType);
hashValueDecl->setValidationStarted();
hashValueDecl->makeComputed(SourceLoc(), getterDecl,
nullptr, nullptr, SourceLoc());
hashValueDecl->copyFormalAccessFrom(typeDecl, /*sourceIsParentContext*/true);
hashValueDecl->copyFormalAccessFrom(derived.Nominal,
Copy link
Member

Choose a reason for hiding this comment

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

Same :)


VarDecl *propDecl = new (C) VarDecl(/*IsStatic*/isStatic, VarDecl::Specifier::Var,
/*IsCaptureList*/false, SourceLoc(), name,
propertyContextType, parentDC);
propDecl->setImplicit();
propDecl->copyFormalAccessFrom(typeDecl, /*sourceIsParentContext*/true);
propDecl->copyFormalAccessFrom(Nominal, /*sourceIsParentContext*/ true);
Copy link
Member

Choose a reason for hiding this comment

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

ConformanceDecl?

}
}

return false;
Copy link
Member

Choose a reason for hiding this comment

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

In Swift 3 mode, we should disallow synthesis of conformances declared on extensions, because the Swift 3 meaning of private doesn't jive well with synthesis, e.g.,

struct X {
  private var foo: Int
}

extension X: Equatable { /* cannot access foo in Swift 3! */ }

Developers can migrate to Swift 4.x to get this feature.

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.

None yet

5 participants