The level of optimization affects the comparison of listings

For some reason, for the Fast optimization level, my comparison method returns an additional 3 elements. Is this a problem with my code or a bug in swift 2.0? The problem occurs on Xcode 7.0 and Xcode 7.1 (2 different Macs).

func ==(lhs: ViewController.ItemType, rhs: ViewController.ItemType) -> Bool {
    // For some reasons for different types e.g. .CType and .AType it returns true
    switch(lhs, rhs) {
    case (.AType, .AType):
        return true
    case (let .BType(type1), let .BType(type2)):
        return type1 == type2
    case (.CType,.CType):
        return true
    case (.DType, .DType):
        return true
    case (.EType,.EType):
        return true
    default:
        return false
    }
}

class ViewController: UIViewController {
    enum ItemType {
        case AType
        case BType(Int)
        case CType
        case DType
        case EType
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        let array:[ItemType] = [.AType, .BType(10), .CType, .DType, .EType]
        let array2 = array.filter { (itemType:ItemType) -> Bool in
            return itemType == .CType
        }

        // Prints 1 on [-ONone] optimization and 4 for [-OFast] optimization.
        print("Items \(array2.count):\n\(array2)")
    }
}
+4
source share
1 answer

I played a little with this. Here is a minimal example:

struct Foo {
    enum Enum {
        case A
        case B
        case C(Int)
    }
}

func ==(lhs: Foo.Enum, rhs: Foo.Enum) -> Bool {
    print("comparing \(lhs) == \(rhs) -> ", terminator: "")

    switch(lhs, rhs) {
    case (.A, .A):
        return true
    case (.B,.B):
        return true
    default:
        return false
    }
}

func test() {
    print(  Foo.Enum.A          == .B)
    print([ Foo.Enum.A ][0]     == .B)
    print([ Foo.Enum.A ].first! == .B)
    for itemType in [ Foo.Enum.A ] { print(itemType == .B) }
}

test()

In-Onone builds this print, expected four times true. In optimized lines, it prints ...

comparing A == B -> false
comparing A == B -> false
comparing A == B -> true
comparing A == B -> true

The error disappears when:

  • The test is performed in the external area (not in function)
  • Instead of an operator ==, a normal function is used,
  • Enumeration is not nested in another type
  • case C
  • print switch

Xcode 7.1. ​​ bugreport.apple.com

0

Source: https://habr.com/ru/post/1613853/


All Articles