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-3092] Function-level nested types cannot conform to Equatable #45682

Closed
swift-ci opened this issue Oct 31, 2016 · 7 comments · Fixed by #59246
Closed

[SR-3092] Function-level nested types cannot conform to Equatable #45682

swift-ci opened this issue Oct 31, 2016 · 7 comments · Fixed by #59246
Assignees

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Oct 31, 2016

Previous ID SR-3092
Radar rdar://problem/44479781
Original Reporter ellneal (JIRA User)
Type Bug
Status Reopened
Resolution
Environment

Swift build number: Xcode 8.1 (8B62) embedded version
Target OS: iOS
Build OS: macOS Sierra 16A323
Build Tool: Xcode Version 8.1 (8B62)

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

md5: f04b40d7c56cb16b9b79a99c8f79b080

is duplicated by:

  • SR-3875 Can't conform to Equatable when type is inside a function
  • SR-5939 Type nested in function cannot satisfy operator protocol requirement
  • SR-6526 Can't conform a type declared inside a function to Equatable
  • SR-8696 Types nested in functions and their operator functions.
  • SR-9956 classes defined inside functions can't be made to conform to Equatable?
  • SR-11482 Some protocols cannot be conformed by code-block-local types
  • SR-13398 Nested Equatable synthesis cannot be overidden.

relates to:

  • SR-14795 Unable to conform to Comparable protocol when nested
  • SR-8696 Types nested in functions and their operator functions.

Issue Description:

The compiler fails to compile a struct that conforms to `Equatable` inside a function.

struct RootLevelStruct: Equatable { // compiles fine
    static func ==(lhs: RootLevelStruct, rhs: RootLevelStruct) -> Bool {
        return false
    }
}

class MyClass {
    struct ClassLevelStruct: Equatable { // compiles fine
        static func ==(lhs: ClassLevelStruct, rhs: ClassLevelStruct) -> Bool {
            return false
        }
    }
    
    func someFunction() {
        struct FunctionLevelStruct: Equatable { // Error: Protocol 'Equatable' can only be used a generic constraint because it has Self or associated type requirements
            static func ==(lhs: FunctionLevelStruct, rhs: FunctionLevelStruct) -> Bool {
                return false
            }
        }
    }
}
@belkadan
Copy link
Contributor

belkadan commented Oct 31, 2016

Even after this is fixed I'm not sure the compiler would find the == definition correctly, so there may be two issues here.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 31, 2016

Comment by Ell Neal (JIRA)

I didn't mention it in the issue but the compiler is also giving a "Type 'FunctionLevelStruct' does not conform to protocol 'Equatable'", so I think you're right.

@lilyball
Copy link
Mannequin

lilyball mannequin commented Feb 24, 2018

This issue is very annoying when writing tests for Decoder-related functionality, because I can't use custom types in each function (because I need equality in order to use XCTAssertEqual).

@swift-ci
Copy link
Collaborator Author

swift-ci commented Jun 27, 2018

Comment by Tim (JIRA)

This seems to be resolved on the Swift 4.2 toolchain.

@lilyball
Copy link
Mannequin

lilyball mannequin commented Jun 27, 2018

After testing, it seems this was fixed in Swift 4.1.

@lilyball
Copy link
Mannequin

lilyball mannequin commented Jan 3, 2019

This isn't fixed. It appeared to go away with Swift 4.1 because of compiler-synthesized Equatable conformance. It appears the synthesized conformance works, but manual conformance doesn't. Tweaking the struct to not be compatible with synthesized conformance demonstrates that it's still broken in Swift 4.2.

func foo() {
    struct Bar: Equatable {
        let x: ()
        static func ==(lhs: Bar, rhs: Bar) -> Bool {
            return true
        }
    }
}

@belkadan
Copy link
Contributor

belkadan commented Jan 7, 2019

>< I feel silly that none of us caught that. Thanks, Lily. Opened a new Radar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants