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-13040] Set collection not working as expected #55486

Closed
swift-ci opened this issue Jun 18, 2020 · 5 comments
Closed

[SR-13040] Set collection not working as expected #55486

swift-ci opened this issue Jun 18, 2020 · 5 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself conformances Feature → protocol: protocol conformances duplicate Resolution: Duplicates another issue nested types Feature: nested types operators Feature: operators swift 5.2 type checker Area → compiler: Semantic analysis unexpected behavior Bug: Unexpected behavior or incorrect output

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Jun 18, 2020

Previous ID SR-13040
Radar rdar://problem/64953125
Original Reporter DeepForest (JIRA User)
Type Bug
Status Resolved
Resolution Duplicate
Environment

Xcode 11.5

Swift version 5.2.4.

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

md5: a50eab392328f1bdf548490201b698a8

relates to:

  • SR-8672 Hashable struct in function

Issue Description:

If I run the following code (contained in testExample) in a Swift playground it works as expected. That is, the "equatable" object is added only once and == operator is called. However, the code in a unit test (or somewhere in app code) adds the object twice.

import XCTest

class settestTests: XCTestCase {

    func testExample() throws {

        struct Object: Equatable, Hashable {
            let name: String
            let completed: Bool  
            static func == (lhs: Object, rhs: Object) -> Bool {
                print("Comparing \(lhs.name) == \(rhs.name)")
                return lhs.name == rhs.name
            }
            public func hash(into hasher: inout Hasher) {
                hasher.combine(name)
            }
        }
        
        let firstObject = Object(name: "apples", completed: false)
        let secondObject = Object(name: "apples", completed: true)
        var set = Set<Object>()
        set.insert(firstObject)
        // set.insert(secondObject) // Adds "duplicate" object
        set.update(with: secondObject) // Also adds "duplicate" object
        print(set) // Why are two "equal" objects added to the set?
    }
}

Playground output:

Comparing apples == apples
[__lldb_expr_5.Object(name: "apples", completed: true)]

Unit test output:

Test Case '-[settestTests.settestTests testExample]' started.
[settestTests.settestTests.(unknown context at $1020e8c18).(unknown context at $1020e8c60).Object(name: "apples", completed: false), settestTests.settestTests.(unknown context at $1020e8c18).(unknown context at $1020e8c60).Object(name: "apples", completed: true)]
Test Case '-[settestTests.settestTests testExample]' passed (0.002 seconds).

If I move the struct Object to class or global scope, as one user on stack overflow suggested, then Set operations work as expected.

https://stackoverflow.com/questions/62438945/why-does-set-operate-differently-in-a-swift-playground

@typesanitizer
Copy link

typesanitizer commented Jun 26, 2020

There is a more fundamental name lookup bug here, where a type defined at function scope does not behave like you'd expect. The following code does not compile:

func f() {
    struct S {
      static func == (lhs: S, rhs: S) -> Bool {
          return true
      }
    }

    let s1 = S()
    let s2 = S()
    print(s1 == s2) // error: binary operator '==' cannot be applied to two 'S' operands
}

If you move the code out of the func f(), it compiles fine.

@swift-ci create

@typesanitizer
Copy link

Also, I see that the set has two elements in an Xcode 12 beta 1 playground. It doesn't solve the problem you're seeing, just pointing out there there has been some change recently, which might hide the difference.

@swift-ci
Copy link
Collaborator Author

Comment by Christopher Combes (JIRA)

Thank you theindigamer (JIRA User). Interesting to see the compile error with '==' 👍

@typesanitizer
Copy link

@swift-ci create

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added duplicate Resolution: Duplicates another issue conformances Feature → protocol: protocol conformances swift 5.2 operators Feature: operators nested types Feature: nested types unexpected behavior Bug: Unexpected behavior or incorrect output labels Feb 22, 2023
@AnthonyLatsis
Copy link
Collaborator

Duplicate of #45682

@AnthonyLatsis AnthonyLatsis marked this as a duplicate of #45682 Feb 22, 2023
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 conformances Feature → protocol: protocol conformances duplicate Resolution: Duplicates another issue nested types Feature: nested types operators Feature: operators swift 5.2 type checker Area → compiler: Semantic analysis unexpected behavior Bug: Unexpected behavior or incorrect output
Projects
None yet
Development

No branches or pull requests

3 participants