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-3304] type(of:) returning different values when running under Debug and Release configurations #45892

Closed
swift-ci opened this issue Dec 1, 2016 · 12 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself IRGen LLVM IR generation runtime The Swift Runtime

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Dec 1, 2016

Previous ID SR-3304
Radar rdar://problem/28637288
Original Reporter mxl (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

macOS Sierra 10.12.2 Beta (16C53a)
Xcode 8.1 (8B62)

Running on iPhone 5s with iOS 10.1.1 (14B150) and iPhone 5s (10.1) Simulator.

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, IRGen, Runtime
Assignee @jckarter
Priority Medium

md5: 295c363ef8049abec94b353ce64230da

is duplicated by:

  • SR-2867 With optimization on, type(of:) returns protocol instead of concrete type

relates to:

  • SR-2867 With optimization on, type(of:) returns protocol instead of concrete type

Issue Description:

Running this code:

protocol A: class {
}

class B: A {
}

let b = B()

class C<T> {
    func test(value: T) {
        print("\(type(of: value))")
        print("\(Mirror(reflecting: value).subjectType)")
    }
}

func test(a: A) {
    print("\(type(of: a))")
    print("\(Mirror(reflecting: a).subjectType)")
}

C<A>().test(value: b)
test(a: b)

using Debug configuration gives:

B
B
B
B

and using Release configuration gives:

A
B
B
B

@swift-ci
Copy link
Collaborator Author

swift-ci commented Dec 1, 2016

Comment by Michael Ledin (JIRA)

Also see http://stackoverflow.com/questions/40913036/static-vs-dynamic-type

@belkadan
Copy link
Contributor

belkadan commented Dec 9, 2016

@jckarter, @swiftix, another one. I maintain that the Debug behavior is correct.

@jckarter
Copy link
Member

jckarter commented Dec 9, 2016

I agree, the debug behavior is correct.

@jckarter
Copy link
Member

jckarter commented Dec 9, 2016

Oh, I missed that A is a protocol. The Release behavior is correct. C.test only has access to an opaque T, so it does not have access to the existential metatype operation on A.

@belkadan
Copy link
Contributor

belkadan commented Dec 9, 2016

That's not how type(of:) works. That has to always return the dynamic type.

@belkadan
Copy link
Contributor

belkadan commented Dec 9, 2016

Note that it's type(of: value), not type(of: T).

@jckarter
Copy link
Member

jckarter commented Dec 9, 2016

This is how concrete type(of:) works. It's a T -> T.Type operation. If an existential type A (really Any<A>) is substituted, you get Any<A>.Type, the concrete metatype of Any<A> (which we really spell A.Protocol), not the existential metatype Any<A.Type> (which we happen to spell A.Type). It's unsound to return an existential metatype. (We really need a FAQ we can point to...)

@jckarter
Copy link
Member

jckarter commented Dec 9, 2016

The language design at this seam is definitely untidy. Note that type(of: value as Any) will happen to give you the dynamic type of the thing inside value as an Any.Type.

@belkadan
Copy link
Contributor

belkadan commented Dec 9, 2016

Hm. That makes sense about the static type, but then there's no way to (directly) get the true dynamic type from inside the existential.

@jckarter
Copy link
Member

jckarter commented Dec 9, 2016

As a hack, you can do type(of: x as Any), since Any is an existential, though that loses the type information of the result, which is probably OK for reflection use cases like this. Perhaps it makes sense for type(of:) to always produce an Any.Type, but that would be a language change (and we'd need another means to get at static methods from an instance).

@jckarter
Copy link
Member

Trying a fix: #6395

@jckarter
Copy link
Member

Should be fixed in master now.

@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 IRGen LLVM IR generation runtime The Swift Runtime
Projects
None yet
Development

No branches or pull requests

3 participants