swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.6k stars 10.37k forks source link

[SR-5456] ObjectIdentifier(self) is not usable in initializer #48028

Open 6d44b555-049a-4a81-86f1-5537312bcad6 opened 7 years ago

6d44b555-049a-4a81-86f1-5537312bcad6 commented 7 years ago
Previous ID SR-5456
Radar rdar://problem/33398579
Original Reporter @kevints
Type Bug
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 042df8f2684872df6518e4a7f65168f5

Issue Description:

I want to include ObjectIdentifier(self) as a debugging identifer for some otherwise constant strings (for example, to label an associated DispatchQueue or to provide a debugDescription), but I can't actually access `ObjectIdentifier(self)` during initialization.

This code doesn't work:

import Dispatch

class A {
    // I want this to be a let constant as it's very important that all users of this instance use the same queue and I write it exactly once in the initializer
    private let sync: DispatchQueue

    init() {
        self.sync = DispatchQueue(label: "com.example.A.sync.\(ObjectIdentifier(self))")
    }
}

As a workaround I can make the variable an implicitly-unwrapped optional, but that doesn't really capture the semantics of what I want, as I still want the compiler to warn that I haven't initialized `sync` and I don't want to reassign after init.

// Works, ugly
class A {
    private var sync: DispatchQueue!

    init() {
        self.sync = DispatchQueue(label: "com.example.A.sync.\(ObjectIdentifier(self))")
    }
}

I think the solution might be to make ObjectIdentifier magical, as my object obviously has a memory address already when it's being inited.

6d44b555-049a-4a81-86f1-5537312bcad6 commented 7 years ago

@swift-ci create