Copyed from using Swift: Generic Specicalization Issue in Release Build

Hi, the below code result is different if it runs in Debug build configuration and Release build configuration.

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        Maker<Child>.hello()
    }
}

class GrandFather {

    required init() {
        print("GrandFather init")
    }

    class func instance() -> GrandFather {
        print("should be overridden by subclass")
        return self.init()
    }
}

class Parent: GrandFather {

    required init() {
        super.init()
        print("Parent init")
    }

    override class func instance() -> Parent {
        return self.init()
    }
}

class Child: Parent {

    required init() {
        super.init()
        print("Child init")
    }

}

class Maker<ModelClass: GrandFather> {

    static func hello() {
        print(ModelClass.instance())
    }
}

If I run it under Debug configuration, I get this:

GrandFather init
Parent init
Child init
Demo.Child

But, if Release configuration, the result is:

GrandFather init
Parent init
Demo.Parent

I don't know why Maker.hello() get the different instance types?

My environment:
Xcode 11.2.1
Swift 5 or Swift 4.2
Optimization Level

  • Debug: -Onone
  • Release: -Osize

A behavior change because of optimization level here is a bug. If you haven't yet, would you be able to post this same report to bugs.swift.org ?

Thanks for your reply. [SR-12538] Optimization level bug · Issue #54981 · apple/swift · GitHub is created for this issue.

2 Likes

Thank you!