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-12441] Compilation errors involving the usage of struct property wrappers declared in constrained extensions on generic types #54880

Closed
jeremyabannister opened this issue Mar 28, 2020 · 2 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself performance property wrappers Feature: property wrappers type checker Area → compiler: Semantic analysis

Comments

@jeremyabannister
Copy link

Previous ID SR-12441
Radar rdar://problem/62201049
Original Reporter @jeremyabannister
Type Bug
Status Resolved
Resolution Done
Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug, CompileTime, PropertyWrappers, TypeChecker
Assignee @jeremyabannister
Priority Medium

md5: ec32305d51f3ca4dcb6da07d073fcf9f

Issue Description:

I've found an apparent compiler bug introduced in Swift 5.2, and I've whittled the code which reproduces it down as far as it will go. I have explored many small variations of this code, the conclusions of which I'll detail here.


Here's the first player in this mess:

extension Array where Element == Bool {
    @propertyWrapper
    struct A <T> {
        var wrappedValue: T
    }
}

By itself, this code compiles successfully.


The issue is when trying to use this new property wrapper:

struct B <U> {
    @Array.A
    var foo: U
}

With Swift 5.2 we get this error: `Illegal instruction: 4`.


Variations and Consequences


Firstly, if we change B from a struct to a class (and add the necessary initializer which was being synthesized when it was a struct) then the error switches to `Segmentation fault: 11`.

class B <U> {
    @Array.A
    var foo: U
    
    init (foo: U) {
        self._foo = .init(wrappedValue: foo)
    }
}

If we change the type of foo from B's generic parameter U to anything else, the code builds successfully:

struct B <U> {
    @Array.A
    var foo: Int
}

This is also true if B is a class.


If B is a class and we make foo private (or fileprivate) then we get a successful build:

class B <U> {
    @Array.A
    private var foo: U
    
    init (foo: U) {
        self._foo = .init(wrappedValue: foo)
    }
}

If B is a struct, however, then foo being private only fixes the `Illegal instruction: 4` error if we leave the initializer implicit. By contrast, if we use the explicit initializer that we just wrote so that B could be a class, but now we switch it back to a struct (with foo still being private) then we get `Illegal instruction: 4`. Unsurprisingly, if foo is public then we get errors for both the class and the struct.


If the property wrapper, Array.A, is a class then everything compiles successfully no matter what:

extension Array where Element == Bool {
    @propertyWrapper
    class A <T> {
        var wrappedValue: T
        init (wrappedValue: T) {
            self.wrappedValue = wrappedValue
        }
    }
}

If the property wrapper is declared at the top level instead of inside the extension then the code builds successfully:

@propertyWrapper
struct A <T> {
    var wrappedValue: T
}

struct B <U> {
    @A
    var foo: U
}

If the property wrapper is declared inside an extension of a non-generic type then the code builds successfully:

extension Bool {
    @propertyWrapper
    struct A <T> {
        var wrappedValue: T
    }
}

struct B <U> {
    @Bool.A
    var foo: U
}

If the property wrapper is declared inside of an unconstrained extension on a generic type with the generic parameter being specified at the call site then the code builds successfully:

extension Array {
    @propertyWrapper
    struct A <T> {
        var wrappedValue: T
    }
}

struct B <U> {
    @Array<Bool>.A
    var foo: U
}

That's all I know about it. It has caused some code of mine to stop compiling, which I can work around for now, but of course will be appreciative whenever the fix arrives. Thanks for reading!

@beccadax
Copy link
Contributor

@swift-ci create

@hborla
Copy link
Member

hborla commented Jan 14, 2021

This code compiles successfully in Swift 5.4. Could you please verify using a 5.4 development snapshot from https://swift.org/download/#snapshots ? Thank you!

@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
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself performance property wrappers Feature: property wrappers type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

4 participants