Skip to content

Set<E>.contains(Set<E>) unexpectedly sometimes returns true #804

Closed as not planned
@northnose

Description

@northnose

Description

The documentation of Set.contains(_:) states:

Returns a Boolean value that indicates whether the given element exists in the set.

Given two Sets of String (or other element), then, I would expect that s1.contains(s2) always returns false because s1 contains String elements and does not contain any Set<String> elements. But this is not the case; it actually returns true if the underlying ordering of s2 is found in the identical order in s1.

In the test case code, there are many possible permutations of output, but here are two representative lines of output:

["b", "a", "c"] contains ["b", "a"]: true

Notice in this one above, the elements of the second set ["b", "a"] appears in this exact order in the first one

["a", "c", "b"] contains ["a", "b"]: false

In this second example above, the elements of the second set do not appear in the same order in the first set (there is a "c" in between)

Reproduction

import Foundation

for _ in 0..<1000 {
    let s1 = Set(["a", "b", "c"])
    let s2 = Set(["b", "a"])
    print("\(s1) contains \(s2): \(s1.contains(s2))")
    _ = Set<String>([]) // this seems to increase randomness of the internal ordering
}

Expected behavior

Expected: always returns false because s1 never contains the set s2 as an element
Actual: often returns true

Environment

$ swiftc -version
swift-driver version: 1.115.1 Apple Swift version 6.0.3 (swiftlang-6.0.3.1.10 clang-1600.0.30.1)
Target: arm64-apple-macosx15.0

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions