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

[SR-7412] Swift crashes when a class conforms to a protocol with associated type as AnyObject #49955

Closed
swift-ci opened this issue Apr 11, 2018 · 3 comments

Comments

@swift-ci
Copy link
Collaborator

@swift-ci swift-ci commented Apr 11, 2018

Previous ID SR-7412
Radar None
Original Reporter iulian.corcoja (JIRA User)
Type Bug
Status Resolved
Resolution Duplicate

Attachment: Download

Environment

System Version: macOS 10.13.4 (17E199)

Model Name: MacBook Pro

Model Identifier: MacBookPro11,5

Xcode 9.2:

Version: 9.2

Obtained from: Apple

Xcode:

Version: 9.3

Obtained from: Mac App Store

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: 88a96e0fa13427206c7a2339f609d60d

duplicates:

  • SR-55 non-@objc protocol existentials do not conform to their own protocol type

Issue Description:

Summary

Within Xcode (or Playground), when creating a new class which conforms to a generic protocol with associatedtype with a type constraint, defining the typealias with a protocol composition causes the compiler to crash.

I couldn't reproduce this in REPL (see attached screenshot).

How to reproduce?

Tested with Xcode 9.2, i. e. toolchain for Swift 4.0.3 Release

protocol Observable {
    associatedtype Observer: AnyObject

    func addObserver(_ observer: Observer)
}

// MARK: - Default Implementation

extension Observable {

    func addObserver(_ observer: Observer) {
        print("Observer added!")
    }
}

// MARK: - Some Delegate

protocol SomeDelegate: class {

    func someFunc(_ someClass: SomeClass)
}

// MARK: - Some Class

class SomeClass: NSObject, Observable {

    typealias Observer = SomeDelegate & AnyObject
}

Error

Command failed due to signal: Abort trap: 6

Stack Trace

Assertion failed: (expectedSchema.size() == IGF.IGM.getExplosionSize(applyContextArchetypes(IGF, substTy))), function reemitAsUnsubstituted, file /Users/buildnode/jenkins/workspace/oss-swift-4.0-package-osx/swift/lib/IRGen/GenPoly.cpp, line 66.
0  swift                    0x000000010f527f38 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 40
1  swift                    0x000000010f526e96 llvm::sys::RunSignalHandlers() + 86
2  swift                    0x000000010f5284fe SignalHandler(int) + 366
3  libsystem_platform.dylib 0x00007fff65999f5a _sigtramp + 26
4  libsystem_platform.dylib 000000000000000000 _sigtramp + 2590400704
5  libsystem_c.dylib        0x00007fff657371ae abort + 127
6  libsystem_c.dylib        0x00007fff656ff1ac basename_r + 0
7  swift                    0x000000010c5b7962 swift::irgen::reemitAsUnsubstituted(swift::irgen::IRGenFunction&, swift::SILType, swift::SILType, swift::irgen::Explosion&, swift::irgen::Explosion&) + 658
8  swift                    0x000000010c62ebd6 emitApplyArgument((anonymous namespace)::IRGenSILFunction&, swift::SILValue, swift::SILType, swift::irgen::Explosion&) + 294
9  swift                    0x000000010c62dfa3 (anonymous namespace)::IRGenSILFunction::visitFullApplySite(swift::FullApplySite) + 2035
10 swift                    0x000000010c616e92 (anonymous namespace)::IRGenSILFunction::emitSILFunction() + 7330
11 swift                    0x000000010c614cfe swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 1358
12 swift                    0x000000010c5306bb swift::irgen::IRGenerator::emitLazyDefinitions() + 987
13 swift                    0x000000010c5f25d6 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) + 1350
14 swift                    0x000000010c5f2b46 swift::performIRGeneration(swift::IRGenOptions&, swift::SourceFile&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, llvm::StringRef, llvm::LLVMContext&, unsigned int, llvm::GlobalVariable**) + 86
15 swift                    0x000000010c4b6825 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 12533
16 swift                    0x000000010c4b2845 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3493
17 swift                    0x000000010c474950 main + 3312
18 libdyld.dylib            0x00007fff6568b015 start + 1

1.  While emitting IR SIL function "@_T07TestBug9SomeClassCAA10ObservableA2aDP11addObservery0G0QzFTW".
 for 'addObserver(_:)' at /Users/iuliancorcoja/Desktop/TestBug/TestBug/TestBug/main.swift:19:2

The exact same code though, doesn't cause the compiler to crash in the latest Xcode (Xcode 9.3, Swift 4.1 Release). Instead, I get the following error when compiling:

Error

Type 'SomeClass' does not conform to protocol 'Observable'
Possibly intended match 'SomeClass.Observer' (aka 'SomeDelegate & AnyObject') does not conform to 'AnyObject'

It doesn't really make sense since SomeClass.Observer does conform to AnyObject.


Remark

Changing the parameter in the addObserver(_:) method of the Observable protocol from Observer to anything else, e. g. AnyObject, doesn't throw any errors in Swift 4.0.3, but throws the same error as above in Swift 4.1

Error

Type 'SomeClass' does not conform to protocol 'Observable'
Possibly intended match 'SomeClass.Observer' (aka 'SomeDelegate & AnyObject') does not conform to 'AnyObject'

Code

protocol Observable {
    associatedtype Observer: AnyObject

    func addObserver(_ observer: AnyObject)
}

extension Observable {

    func addObserver(_ observer: AnyObject) {
        print("Observer added!")
    }
}

protocol SomeDelegate: class {

    func someFunc(_ someClass: SomeClass)
}

class SomeClass: NSObject, Observable {

    typealias Observer = SomeDelegate & AnyObject
}
@belkadan
Copy link
Contributor

@belkadan belkadan commented Apr 11, 2018

More discussion on this in SR-6039.

@swift-ci
Copy link
Collaborator Author

@swift-ci swift-ci commented Apr 13, 2018

Comment by Iulian Corcoja (JIRA)

@belkadan, I don't think these issues are related to each other. Even if I remove the "class" from "protocol SomeDelegate: class" the error still persists. Both Xcode and the compiler are clearly confused by the type composition:

Type 'SomeClass' does not conform to protocol 'Observable'
Possibly intended match 'SomeClass.Observer' (aka 'SomeDelegate & AnyObject') does not conform to 'AnyObject'

@belkadan
Copy link
Contributor

@belkadan belkadan commented Apr 13, 2018

@slavapestov had a relevant comment on SR-6039:

A value of protocol type carries a payload together with a witness table. So it can be converted to a reference type via a representation change, but it is not directly usable as one. This is why you cannot bind a protocol type to a generic parameter that is class constrained.

This is more of an implementation restriction than a language design decision, but it is difficult to change now so we are probably stuck with it.

SR-55 probably has a few too many things dup'd to it, but the error is correct in the current Swift, if poorly phrased.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants