swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.57k stars 10.36k forks source link

[SR-7595] Compiler crash in protocol with recursive and associated type #50137

Open sharplet opened 6 years ago

sharplet commented 6 years ago
Previous ID SR-7595
Radar rdar://problem/39980909
Original Reporter @sharplet
Type Bug
Environment Xcode Version 9.3 (9E145)
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug | |Assignee | @slavapestov | |Priority | Medium | md5: b21b2f90ca9aded2ee68689963dc3e23

Issue Description:

Using pointfreeco/swift-tagged, I have this protocol in my project:

protocol Entity {
    var id: ID { get }
}

extension Entity {
    typealias ID = Tagged<Self, Int>
}

An example of how it's used:

struct Foo: Entity, Codable, Equatable {
  let id: ID
  let foo: String
  let barID: Bar.ID
}

When I change the protocol to abstract out the raw identifier type, I start getting compiler crashes in other files, and the automatically derived Codable conformance stops working.

protocol Entity {
  associatedtype RawID = Int
  var id: ID { get }
}

extension Entity {
  typealias ID = Tagged<Self, RawID>
}

Error with Codable conformance:

Models/User.swift:1:8: error: type 'User' does not conform to protocol 'Decodable'
struct User: Entity, Codable, Equatable, DefaultsBacked, SessionStorable {
       ^
Swift.Decodable:2:12: note: protocol requires initializer 'init(from:)' with type 'Decodable'
    public init(from decoder: Decoder) throws
           ^
Models/User.swift:14:9: note: cannot automatically synthesize 'Decodable' because '<<error type>>' does not conform to 'Decodable'
    let id: ID
        ^
Models/User.swift:1:8: error: type 'User' does not conform to protocol 'Decodable'
struct User: Entity, Codable, Equatable, DefaultsBacked, SessionStorable {
       ^
Swift.Decodable:2:12: note: protocol requires initializer 'init(from:)' with type 'Decodable'
    public init(from decoder: Decoder) throws
           ^
Models/User.swift:14:9: note: cannot automatically synthesize 'Decodable' because '<<error type>>' does not conform to 'Decodable'
    let id: ID
        ^

Here's a sample crash log:

0  swift                    0x000000010cb37ffa PrintStackTraceSignalHandler(void*) + 42
1  swift                    0x000000010cb373b6 SignalHandler(int) + 966
2  libsystem_platform.dylib 0x00007fff7813cf5a _sigtramp + 26
3  libsystem_platform.dylib 0x00007ffee6ae2ee0 _sigtramp + 1855610784
4  swift                    0x000000010a50eaaf swift::NominalTypeDecl::hasFixedLayout(swift::ModuleDecl*, swift::ResilienceExpansion) const + 31
5  swift                    0x000000010a0383e1 (anonymous namespace)::LowerType::visitAnyStructType(swift::CanType, swift::StructDecl*) + 49
6  swift                    0x000000010a036c2f swift::Lowering::TypeConverter::getTypeLowering(swift::Lowering::AbstractionPattern, swift::Type) + 3743
7  swift                    0x000000010a00921a swift::SILType::getFieldType(swift::VarDecl*, swift::SILModule&) const + 138
8  swift                    0x000000010930dff0 swift::irgen::TypeConverter::convertStructType(swift::TypeBase*, swift::CanType, swift::StructDecl*) + 3616
9  swift                    0x000000010932ad71 swift::irgen::TypeConverter::convertAnyNominalType(swift::CanType, swift::NominalTypeDecl*) + 465
10 swift                    0x000000010932a164 swift::irgen::TypeConverter::getTypeEntry(swift::CanType) + 1060
11 swift                    0x0000000109285a08 swift::irgen::TypeConverter::convertEnumType(swift::TypeBase*, swift::CanType, swift::EnumDecl*) + 2104
12 swift                    0x000000010932ad61 swift::irgen::TypeConverter::convertAnyNominalType(swift::CanType, swift::NominalTypeDecl*) + 449
13 swift                    0x000000010932a164 swift::irgen::TypeConverter::getTypeEntry(swift::CanType) + 1060
14 swift                    0x00000001091e0aab (anonymous namespace)::AllocStackHoisting::run() + 587
15 swift                    0x0000000109c93007 swift::SILPassManager::runOneIteration() + 6711
16 swift                    0x000000010933b90b runIRGenPreparePasses(swift::SILModule&, swift::irgen::IRGenModule&) + 1659
17 swift                    0x000000010933c4b4 performIRGeneration(swift::IRGenOptions&, swift::ModuleDecl*, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, llvm::StringRef, llvm::LLVMContext&, swift::SourceFile*, llvm::GlobalVariable**, unsigned int) + 1284
18 swift                    0x0000000109197dce performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 38110
19 swift                    0x000000010918ce64 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 7908
20 swift                    0x00000001091418b5 main + 18917
21 libdyld.dylib            0x00007fff77e2e015 start + 1
22 libdyld.dylib            0x000000000000004a start + 2283610166
Stack dump:
0.  Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -filelist /var/folders/nl/09nb5jwj5934y_z1cl7wbxg00000gn/T/sources-a6aab3 -primary-file /Users/adsharp/src/peerfit/pf-ios/Peerfit/ViewControllers/StudioConfirmReservationController.swift -target x86_64-apple-ios11.2 -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.3.sdk -I /Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Products/Debug-iphonesimulator -F /Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Products/Debug-iphonesimulator -F /Users/adsharp/src/peerfit/pf-ios/Carthage/Build/iOS -F /Users/adsharp/src/peerfit/pf-ios/Frameworks -enable-testing -g -module-cache-path /Users/adsharp/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -swift-version 4 -enforce-exclusivity=checked -Onone -D PEERFIT_ENVIRONMENT_STAGING -D DEBUG -serialize-debugging-options -Xcc -I/Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/swift-overrides.hmap -Xcc -iquote -Xcc /Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/Peerfit-generated-files.hmap -Xcc -I/Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/Peerfit-own-target-headers.hmap -Xcc -I/Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/Peerfit-all-target-headers.hmap -Xcc -iquote -Xcc /Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/Peerfit-project-headers.hmap -Xcc -I/Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/DerivedSources/x86_64 -Xcc -I/Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/DerivedSources -Xcc -DDEBUG=1 -Xcc -working-directory/Users/adsharp/src/peerfit/pf-ios -emit-module-doc-path /Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/Objects-normal/x86_64/StudioConfirmReservationController~partial.swiftdoc -serialize-diagnostics-path /Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/Objects-normal/x86_64/StudioConfirmReservationController.dia -module-name Peerfit -emit-module-path /Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/Objects-normal/x86_64/StudioConfirmReservationController~partial.swiftmodule -emit-dependencies-path /Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/Objects-normal/x86_64/StudioConfirmReservationController.d -emit-reference-dependencies-path /Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/Objects-normal/x86_64/StudioConfirmReservationController.swiftdeps -o /Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Build/Intermediates.noindex/Peerfit.build/Debug-iphonesimulator/Peerfit.build/Objects-normal/x86_64/StudioConfirmReservationController.o -index-store-path /Users/adsharp/Library/Developer/Xcode/DerivedData/Peerfit-bwnblzujwglcswayzqwnvyzrvwfs/Index/DataStore -index-system-modules 
1.  While running pass #&#8203;84 SILFunctionTransform "SIL alloc_stack Hoisting" on SILFunction "@_T07Peerfit34StudioConfirmReservationControllerC09completedD0AA0D0VSgvpfi".
 for expression at [<invalid loc> - <invalid loc>]
2.  While converting type 'Optional<Reservation>'
3.  While converting type 'Reservation' (declared at [/Users/adsharp/src/peerfit/pf-ios/Peerfit/Models/Reservation.swift:5:1 - line:9:1] RangeText="struct Reservation: Entity, Codable {
    let id: ID
    let session: StudioSession
    let studio: Studio
}")
error: Segmentation fault: 11
sharplet commented 6 years ago

I haven't yet been able to reproduce this in a smaller project, unfortunately.

belkadan commented 6 years ago

@huonw, sound familiar? Or are we going to need a project?

(One that depends on pointfreeco/swift-tagged is fine, as is attaching your real project to a Radar if you're not comfortable putting it here, Adam.)

sharplet commented 6 years ago

Just opened Radar 39980909 with an attached project for you to reproduce. The Xcode workspace in there should be self-contained and build without installing any external dependencies.

sharplet commented 6 years ago

I discovered a workaround, which is to extract the type alias into a base protocol:

protocol _EntityBase {
    associatedtype RawID = Int
}

extension _EntityBase {
    typealias ID = Tagged<Self, RawID>
}

protocol Entity: _EntityBase {
    var id: ID { get }
}