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-1779] Generic Objective-C classes cannot conform to protocols with associated types #44388

Open
swift-ci opened this issue Jun 15, 2016 · 17 comments

Comments

@swift-ci
Copy link
Collaborator

@swift-ci swift-ci commented Jun 15, 2016

Previous ID SR-1779
Radar rdar://problem/27652431
Original Reporter austin (JIRA User)
Type Bug

Attachment: Download

Environment

OS X 10.11.5, Xcode 8S128d

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, 3.0Regression, CompilerCrash
Assignee @jckarter
Priority Medium

md5: e97d74f501ffd9cfb45f8b3fe956579f

Issue Description:

I've attached an Xcode 8b1 project that contains a reproduction case. You can trigger the compiler segfault by attempting to run the unit tests (building the framework target alone isn't sufficient).

This bug is a little complicated. Here is the setup:

1. We have a framework target written in Objective-C. We've defined a generic Objective-C class `C` that conforms to an Objective-C protocol `P`.

2. To make things easier for our users, we provide a separate Swift file that is intended to provide additional functionality by making `C` conform to Swift's `Sequence` protocol.

2b. That file is not part of the framework target. In order to stand in for our users' applications, the file belongs to the unit test target, which acts like an application. The unit test target has a bridging header that pulls in our framework's Objective-C sources, and it also builds the aforementioned Swift file to provide the enhanced functionality.

3. That Swift file contains two things: a non-generic Swift class `Z` that is supposed to act as the iterator, and an extension to `C` to conform it to `Sequence` (by using `Z` as its iterator).

4. `Z` initializer takes in an argument of type `P`. The extension on `C` attempts to construct a `Z` iterator by passing in `self` to the initializer (since `C : P`, this should work).

5. Instead, the compiler crashes. I've attached the output as well in the text file.

@belkadan
Copy link
Contributor

@belkadan belkadan commented Jun 20, 2016

@slavapestov, look familiar?

@slavapestov
Copy link
Member

@slavapestov slavapestov commented Jun 21, 2016

Yeah, I think this is the issue where allocating constructors cannot be called from an extension of an Obj-C generic class.

@swift-ci
Copy link
Collaborator Author

@swift-ci swift-ci commented Jun 21, 2016

Comment by Austin Zheng (JIRA)

I think so too; the following is enough to trigger the same issue:

final class TestClass {
    var a : Int = 0
}

extension SomeObjCGenericClass {
    func doSomething() {
        let _ = TestClass()
    }
}

@swift-ci
Copy link
Collaborator Author

@swift-ci swift-ci commented Jun 21, 2016

Comment by Austin Zheng (JIRA)

If there's another Jira ticket tracking the issue, I'm happy to close this one as a duplicate; otherwise I can rename it to be more correct.

@bdash
Copy link
Contributor

@bdash bdash commented Jul 26, 2016

This is still an issue with Swift 3 in Xcode 8 beta 3.

@bdash
Copy link
Contributor

@bdash bdash commented Aug 2, 2016

And with Xcode 8 beta 4, too.

@slavapestov
Copy link
Member

@slavapestov slavapestov commented Aug 3, 2016

No longer crashes on master.

@slavapestov
Copy link
Member

@slavapestov slavapestov commented Aug 8, 2016

Just verifying this again. With beta 4, I get this error:

LLVM ERROR: unsupported relocation with subtraction expression, symbol '__TMnCSo24RLMZeroElementCollection' can not be undefined in a subtraction expression
2016-08-08 12:01:15.916 xcodebuild[37128:7937400]  DVTAssertions: Warning in /Library/Caches/com.apple.xbs/Sources/IDEFrameworks/IDEFrameworks-11222.4/IDEFoundation/Playgrounds/IDEPlaygroundAuxiliarySourceCompilerOperation.m:383
Details:  Unable to read diagnostics from file "/Users/slava/Downloads/CrashReproCase/build/CrashReproCase.build/Release/CrashReproCaseTests.build/Objects-normal/x86_64/Extensions.dia" (Invalid File): Invalid diagnostics signature
Function: void XCGenerateDiagnosticsFromFile(NSString *__strong, NSString *__strong, NSDictionary *__strong, NSDictionary *__strong, IDEActivityLogSectionRecorder *__strong, BOOL (^__strong)(IDEActivityLogMessage *__strong))
Thread:   <NSThread: 0x7fdf4d3913b0>{number = 6, name = (null)}

On master, I get this:

/Users/slava/Downloads/CrashReproCase/CrashReproCase/Extensions.swift:27:15: error: extension of a generic Objective-C class cannot access the class's generic parameters at runtime
  public func makeIterator() -> RLMUniversalIterator {
              ^
/Users/slava/Downloads/CrashReproCase/CrashReproCase/Extensions.swift:29:33: note: generic parameter used here
    return RLMUniversalIterator(self)
                                ^

I'm assuming this is an unsupported case where the associated type depends on Objective-C generic parameters, which is something we'd like to allow eventually, but not yet.

@bdash
Copy link
Contributor

@bdash bdash commented Aug 9, 2016

Xcode 8b5 still crashes as well.

Slava, is there a workaround for the unsupported case you describe? I'm not clear how else we can make an Objective-C collection that uses Objective-C generics for its element type conform to Swift's Sequence protocol.

@jckarter
Copy link
Member

@jckarter jckarter commented Aug 9, 2016

8b5 is the same compiler as 8b4. You'd need to verify using a snapshot for now.

@slavapestov
Copy link
Member

@slavapestov slavapestov commented Aug 9, 2016

@jckarter any ideas re: workaround?

@jckarter
Copy link
Member

@jckarter jckarter commented Aug 9, 2016

It looks like we're overly aggressive with that error now. I noticed the same while investigating another crasher. Does it help if you cast self as! ClassName<AnyObject> first thing?

@bdash
Copy link
Contributor

@bdash bdash commented Aug 9, 2016

It does not appear to make any difference:

CrashReproCase/Extensions.swift:27:15: error: extension of a generic Objective-C class cannot access the class's generic parameters at runtime
  public func makeIterator() -> RLMUniversalIterator {
              ^
CrashReproCase/Extensions.swift:29:21: note: generic parameter used here
    let typedSelf = self as! RLMZeroElementCollection<NSObject>
                    ^

I used NSObject as that's necessary to satisfy the generic constraint of the Objective-C class. Removing the constraint and using AnyObject in the cast also fails in the same way.

@bdash
Copy link
Contributor

@bdash bdash commented Aug 9, 2016

I should note that I was testing that change with swift-DEVELOPMENT-SNAPSHOT-2016-08-07-a-osx.pkg.

@swift-ci
Copy link
Collaborator Author

@swift-ci swift-ci commented Aug 30, 2016

Comment by Xuan (JIRA)

may I ask the progress? As Apple is holding the event on Sep 7th, iOS 10 / swift 3.0 should come in Sep or early Oct, however this bug is still open, and seems not getting much attention.

@jckarter
Copy link
Member

@jckarter jckarter commented Aug 30, 2016

We don't have time to fully implement this before 3.0. However, the workarounds, such as using AnyObject as your associated type and introducing as! casts to change the generic parameters, should be functioning in the latest toolchains.

@jadengeller
Copy link
Mannequin

@jadengeller jadengeller mannequin commented Sep 6, 2016

I ran into this same issue conforming a generic Objective-C type to a Swift protocol with no associated types (and no requirements either). Adding an `@objc` annotation to the protocol fixed it, but it seems that the problem is broader than what is mentioned here.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
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

5 participants