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-2867] With optimization on, type(of:) returns protocol instead of concrete type #45461

Closed
pcantrell opened this issue Oct 5, 2016 · 8 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself optimized only Flag: An issue whose reproduction requires optimized compilation

Comments

@pcantrell
Copy link

Previous ID SR-2867
Radar None
Original Reporter @pcantrell
Type Bug
Status Resolved
Resolution Duplicate
Additional Detail from JIRA
Votes 2
Component/s Compiler
Labels Bug, Miscompile, OptimizedOnly
Assignee @pcantrell
Priority Medium

md5: feb48b9cac66e6d4a7b332444ba939cb

duplicates:

  • SR-3304 type(of:) returning different values when running under Debug and Release configurations

relates to:

  • SR-3304 type(of:) returning different values when running under Debug and Release configurations

Issue Description:

  1. The following code gives different results depending on whether optimization is turned on:
protocol P { }
class C: P { }

struct S<T> {
    init(val: T) {
        print(type(of: val))
        print(type(of: val) is AnyObject.Type)
    }
}

_ = S<P>(val: C())

With an unoptimized build, it prints:

C
true

However, in an optimized build (release configuration in Xcode), it prints:

P
false

The optimization discrepancy is definitely a bug. I think the unoptimized output is the correct one — type(of:​) should always return a concrete type, never a protocol … right?

(Apologies if this is a duplicate. I found it a difficult one to search for.)

@belkadan
Copy link
Contributor

belkadan commented Oct 5, 2016

cc @swiftix

@swiftix
Copy link
Mannequin

swiftix mannequin commented Oct 5, 2016

I discussed it with @jckarter and he explained that the optimized version is correct and the non-optimized version is wrong. This is because "init" gets a C value boxed into an existential of type P. Therefore, the type of this boxed value is P.Protocol and not C. The runtime produces a wrong result in the non-optimized case.

I'll create a radar for it.

@belkadan
Copy link
Contributor

belkadan commented Oct 5, 2016

That would be P.Type, not P.Protocol. But type(of:) doesn't give you a static type; it gives you a dynamic type, always. That's never a protocol type.

@pcantrell
Copy link
Author

Yes, what Jordan wrote was also my understanding:

@swift-ci
Copy link
Collaborator

Comment by 100mango (JIRA)

cc@swiftix
I came to the same situation。But it's not in the init. In my project (https://github.com/100mango/SwiftNotificationCenter)

protocol:

protocol UpdateTitle: class {
    
    func updateWithNewTitle(title: String)
    
}

in view controller

class FirstViewController: UIViewController, UpdateTitle {
    
    override func viewDidLoad() {
        super.viewDidLoad()
         // Crash here
        Broadcaster.register(UpdateTitle.self, observer: self)
    }
}

and with optimization on:

public class Broadcaster {
   
    public static func register<T>(_ protocolType: T.Type, observer: T) {
        let key = "\(protocolType)"
        guard type(of: observer) is AnyClass else {
            //with optimization on.  it will always goes here
            fatalError("expecting reference type but found value type: \(observer)")
            return
        }
        //..........
    }
}

@jckarter
Copy link
Member

The inconsistency was addressed in SR-3304.

@pcantrell
Copy link
Author

I don't think this should be closed…? As of Xcode 9 beta 5, it now always gives “P / false”.

That is the wrong answer, per Jordan above:

But type(of🙂 doesn't give you a static type; it gives you a dynamic type, always. That's never a protocol type.

@jckarter
Copy link
Member

It's correct as the language is defined today, as discussed in detail in SR-3304.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
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 optimized only Flag: An issue whose reproduction requires optimized compilation
Projects
None yet
Development

No branches or pull requests

4 participants