Different behaviors of an entity nested in a function scope vs. outside of the scope

Hi,

It might be something very simple that I'm missing here, but trying to get my heads around the different behavior that I'm seeing in the following code samples:

// Example 1
func foo() {
    struct Foo: Equatable, Hashable, CustomStringConvertible {
        var a: Int
        var b: Int = 0

        static func ==(lhs: Foo, rhs: Foo) -> Bool {
            lhs.a == rhs.a
        }

        func hash(into hasher: inout Hasher) {
            hasher.combine(a)
        }

        var description: String {
            "a: \(a), b: \(b)"
        }
    }

    var foos: Set<Foo> = [
        Foo(a: 1, b: 1),
        Foo(a: 2, b: 1),
        Foo(a: 3),
    ]

    var insertedVal = foos.insert(Foo(a: 1)).memberAfterInsert
    insertedVal.b += 1
    foos.update(with: insertedVal)
    foos // {{a 1, b 1}, {a 2, b 1}, {a 1, b 0}, {a 3, b 0}}
}

foo()


// Example 2
struct Foo: Equatable, Hashable, CustomStringConvertible {
    var a: Int
    var b: Int = 0

    static func ==(lhs: Foo, rhs: Foo) -> Bool {
        lhs.a == rhs.a
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(a)
    }

    var description: String {
        "a: \(a), b: \(b)"
    }
}

func foo2() {

    var foos: Set<Foo> = [
        Foo(a: 1, b: 1),
        Foo(a: 2, b: 1),
        Foo(a: 3),
    ]

    var insertedVal = foos.insert(Foo(a: 1)).memberAfterInsert
    insertedVal.b += 1
    foos.update(with: insertedVal)
    foos // {{a 3, b 0}, {a 1, b 2}, {a 2, b 1}}
}

foo2()

In the former, the compiler is using the synthesized equatable implementation and never calls the implementation defined in the nested Foo. However, in the latter, it's using the given implementation.

I'm trying to see if it's a compiler bug or something that I'm missing here.

Appreciate your help.

It's a compiler bug:
https://bugs.swift.org/browse/SR-3092

1 Like

Thanks for the confirmation. Appreciate it !

Terms of Service

Privacy Policy

Cookie Policy