# Property Wrappers: Access to both enclosing 'self' and wrapper instance

**URL:** <https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526>\
**Category:** Using Swift\
**Tags:** propertywrapper\
**Created:** [January 13, 2020, 4:36pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526 "2020-01-13T16:36:09Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ebg](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ebg/32/23208_2.png) [@ebg](https://forums.swift.org/u/ebg)\
**Post date:** [January 13, 2020, 4:36pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/1 "2020-01-13T16:36:09Z")

</div>

A key missing (public) feature of Property Wrappers is referencing the enclosing self; that is, the object that owns the property which it's wrapping.

Here's an example question from StackOverflow exploring some alternatives: [Can a Swift Property Wrapper reference the owner of the property its wrapping?](https://stackoverflow.com/questions/56686026/can-a-swift-property-wrapper-reference-the-owner-of-the-property-its-wrapping).

It's is also referenced as a future direction in [SE-0258: Referencing the enclosing 'self' in a wrapper type](https://github.com/apple/swift-evolution/blob/master/proposals/0258-property-wrappers.md#referencing-the-enclosing-self-in-a-wrapper-type). This design was actually implemented but not made public for the Combine framework:

```swift
static subscript<EnclosingSelf>(
      _enclosingInstance observed: EnclosingSelf,
      wrapped wrappedKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Value>,
      storage storageKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Self>
    ) -> Value

```

I've implemented this method, but there's one big downside as far as I can tell: while the subscript method does provide access to the enclosing self, the subscript method is static, so you don't have access to the instance of the property wrapper. This means that if you provide a custom init to your wrapper like so:

```swift
init(_ str: String) {
    self.str = str
}
private let str: String

```

and initialize it as such:

```swift
@Wrapper("helloWorld") var someProperty: Int?

```

in the implementation of the static subscript you cannot access the wrapper's private instance variable str. You can imagine a lot of uses of simultaneously referencing both the enclosing self instance and the wrapper instance, like implementing your own theming system.

I'm wondering if I'm overlooking some way here of accessing the wrapper instance in this static subscript?

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [January 13, 2020, 5:34pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/2 "2020-01-13T17:34:37Z")

</div>

I‘m not sure I fully understand you but if you want to get back the property wrapper itself then this should do the trick.

```swift
observed[keyPath: storageKeyPath].str

```

Anyways, this is private API and subject to change so I would avoid relying on it if you want to prevent breakage in the future.

---

<div class="post-metadata">

**Author:** ![ebg](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ebg/32/23208_2.png) [@ebg](https://forums.swift.org/u/ebg)\
**Post date:** [January 13, 2020, 7:56pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/3 "2020-01-13T19:56:30Z")

</div>

Yes, that's what I'm looking for, thank you! But, I'm having trouble getting the compiler to pass. This wrapper implementation alone compiles just fine:

```swift
@propertyWrapper
public final class Wrapper {
    
    public static subscript<EnclosingSelf>(
      _enclosingInstance observed: EnclosingSelf,
      wrapped wrappedKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Int?>,
      storage storageKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Self>
    ) -> Int? {
      get {
        return observed[keyPath: storageKeyPath].stored
      }
      set {
        let oldValue = observed[keyPath: storageKeyPath].stored
        if newValue != oldValue {
            // TODO: call wrapper instance with enclosing self
        }
        observed[keyPath: storageKeyPath].stored = newValue
      }
    }
    
    public var wrappedValue: Int? {
      get { fatalError("called wrappedValue getter") }
      set { fatalError("called wrappedValue setter") }
    }
    
    public init(str: String) {
        self.str = str
    }
    
    // MARK: - Private
    
    private let str: String
    private var stored: Int?
}

```

But when I add it to a class, the compiler fails for an unknown reason:

```swift
open class TestView: UIView {
    @Wrapper(str: "HelloWorld") public var testProp: Int?
}

/** 
    Swift Compiler Error
    Type '_' has no member 'testProp'
*/

```

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [January 13, 2020, 8:22pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/4 "2020-01-13T20:22:16Z")

</div>

Try to swap Self with Wrapper and check if it works then. If it does, file a bug at [bugs.swift.org](http://bugs.swift.org). This could be related to Self on classes not properly respecting final keyword. If it does not work then it must be something else.

---

<div class="post-metadata">

**Author:** ![ebg](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ebg/32/23208_2.png) [@ebg](https://forums.swift.org/u/ebg)\
**Post date:** [January 13, 2020, 8:52pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/5 "2020-01-13T20:52:17Z")

</div>

Changing `Self` to `Wrapper` worked, thanks!!

---

<div class="post-metadata">

**Author:** ![ebg](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ebg/32/23208_2.png) [@ebg](https://forums.swift.org/u/ebg)\
**Post date:** [January 13, 2020, 9:00pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/6 "2020-01-13T21:00:12Z")

</div>

> <https://github.com/apple/swift/issues/54460>
>
> | | |
> |------------------|-----------------|…
> |Previous ID | SR-12023 |
> |Radar | None |
> |Original Reporter | ebg (JIRA User) |
> |Type | Bug |
> |Status | Resolved |
> |Resolution | Duplicate |
>         
> \<details\>
> \<summary\>Additional Detail from JIRA\</summary\>
> 
> | | |
> |------------------|-----------------|
> |Votes | 1 |
> |Component/s | Compiler |
> |Labels | Bug, TypeChecker |
> |Assignee | None |
> |Priority | Medium |
> 
>    
> 
> md5: 807330616794d991a0e0b64873f80e22
> 
> \</details\>
> 
> 
> 
> 
> \*\*duplicates\*\*:  
> \* \[SR-11176\](https://bugs.swift.org/browse/SR-11176) Covariant 'Self' type cannot be referenced from a stored property initializer  
> \* \[SR-11414\](https://bugs.swift.org/browse/SR-11414) Final class type and Self should be treated as equivalent in class body  
> 
> 
> \*\*Issue Description:\*\*
> 
> 
> See forum thread for more details:
> 
> \<https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526\>
> 
> This property wrapper compiles, but not when used:
> 
> \`\`\` java
> @propertyWrapper
> public final class Wrapper {
>     
> public static subscript\<EnclosingSelf\>(
> \_enclosingInstance observed: EnclosingSelf,
> wrapped wrappedKeyPath: ReferenceWritableKeyPath\<EnclosingSelf, Int?\>,
> storage storageKeyPath: ReferenceWritableKeyPath\<EnclosingSelf, Self\>
> ) -\> Int? {
> get {
> return observed\[keyPath: storageKeyPath\].stored
> }
> set {
> let oldValue = observed\[keyPath: storageKeyPath\].stored
> if newValue != oldValue {
> // TODO: call wrapper instance with enclosing self
> }
> observed\[keyPath: storageKeyPath\].stored = newValue
> }
> }
>     
> public var wrappedValue: Int? {
> get { fatalError("called wrappedValue getter") }
> set { fatalError("called wrappedValue setter") }
> }
>     
> public init(str: String) {
> self.str = str
> }
>     
> // MARK: - Private
>     
> private let str: String
> private var stored: Int?
> }
> \`\`\`
> 
> When used, the compiler fails:
> 
> \`\`\` java
> open class TestView: UIView {
> @Wrapper(str: "HelloWorld") public var testProp: Int?
> }
> 
> /\*\* 
> Swift Compiler Error
> Type '\_' has no member 'testProp'
> \*/
> \`\`\`
> 
> Replacing \\\`Self\\\` with \\\`Wrapper\\\` in the code fixes the issue. If I keep \\\`Self\\\`, I can also change the class to a struct to fix the issue.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [January 13, 2020, 9:46pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/7 "2020-01-13T21:46:19Z")

</div>

@suyashsrijan regarding your comment on Jira. Shouldn‘t this example still pass because the class is marked as final?

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [January 13, 2020, 10:01pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/8 "2020-01-13T22:01:59Z")

</div>

Yeah, `Self` and `TypeName` should be equivalent in a `final` class, but it's just not supported at the moment (I opened a [PR](https://github.com/apple/swift/pull/23430) then forgot about it, so sorry about that. I'll try to find some time soon). I think there's a dup for this, so I'll update the JIRA ticket when I find it.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [January 13, 2020, 10:31pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/9 "2020-01-13T22:31:41Z")

</div>

Possibly this one? [https://bugs.swift.org/browse/SR-11176](https://bugs.swift.org/browse/SR-11176)

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [January 13, 2020, 10:33pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/10 "2020-01-13T22:33:37Z")

</div>

Yeah or [[SR-11414] Final class type and Self should be treated as equivalent in class body · Issue #53815 · apple/swift · GitHub](https://bugs.swift.org/browse/SR-11414). Seems like there are a few dupes!

---

<div class="post-metadata">

**Author:** ![vitamin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vitamin/32/11098_2.png) [@vitamin](https://forums.swift.org/u/vitamin)\
**Post date:** [April 7, 2020, 4:01pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/11 "2020-04-07T16:01:03Z")

</div>

> [@DevAndArtist](#):
>
> this is private API and subject to change

What's a private API...? From what I can tell looking at [Swift's source for PropertyWrappers](https://github.com/apple/swift/blob/master/lib/Sema/TypeCheckPropertyWrapper.cpp), this is supported right in the base of Swift, if not described in the docs. I mean, it seems to compile and run without even importing Foundation.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [April 7, 2020, 4:04pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/12 "2020-04-07T16:04:06Z")

</div>

As you said it, it's undocumented implementation which also happens to be prefixed with an underscore which by Swift standards considered as "hands off" or simply _private_.

---

<div class="post-metadata">

**Author:** ![vitamin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vitamin/32/11098_2.png) [@vitamin](https://forums.swift.org/u/vitamin)\
**Post date:** [April 7, 2020, 6:00pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/13 "2020-04-07T18:00:20Z")

</div>

I see, well I hope that they make an official way to pass the keypath of a wrapped property into the wrapper, soon-ish.

---

<div class="post-metadata">

**Author:** ![robnik](https://avatars.discourse-cdn.com/v4/letter/r/46a35a/32.png) [@robnik](https://forums.swift.org/u/robnik)\
**Post date:** [April 22, 2020, 5:08pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/14 "2020-04-22T17:08:03Z")

</div>

I want to use this feature. I see it's "private" but I'm not sure what that means. Are both of these possible, or just #1?

1. It could change and force me to rewrite some code if I want to compile my app again.
2. It could change and break deployed apps in the App Store.

#1 is fine with me. #2 I need to avoid.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [April 22, 2020, 5:11pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/15 "2020-04-22T17:11:53Z")

</div>

I don't think #2 will happen, but I'm not a compiler expert (could bitcode compilation affect this somehow?).

#1 is more likely, but I don't think it "will change", it rather gets removed and somehow reattached to the new feature in the future for backwards compatibility with existing code Apple already published.

With 99% I'd say you're safe to use it already.

---

<div class="post-metadata">

**Author:** ![robnik](https://avatars.discourse-cdn.com/v4/letter/r/46a35a/32.png) [@robnik](https://forums.swift.org/u/robnik)\
**Post date:** [April 22, 2020, 6:44pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/16 "2020-04-22T18:44:54Z")

</div>

I was worrying about #2 because I thought with Swift 5 ABI stability apps are no longer deployed bundled with a static version of the standard library. So something like this could be there in one version of iOS and disappear in the next. ??

---

<div class="post-metadata">

**Author:** ![robnik](https://avatars.discourse-cdn.com/v4/letter/r/46a35a/32.png) [@robnik](https://forums.swift.org/u/robnik)\
**Post date:** [April 22, 2020, 7:49pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/17 "2020-04-22T19:49:43Z")

</div>

May be a moot point anyway. I can't get that static subscript in the property wrapper to compile without crashing the compiler.

---

<div class="post-metadata">

**Author:** ![cukr](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cukr/32/889_2.png) [@cukr](https://forums.swift.org/u/cukr)\
**Post date:** [April 23, 2020, 8:41am UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/18 "2020-04-23T08:41:49Z")

</div>

> [@robnik](#):
>
> I can't get that static subscript in the property wrapper to compile without crashing the compiler

Do you mean that there are compilation errors, or compiler literally crashes? Compiler shouldn't ever crash, so that's a bug you can file at [bugs.swift.org](http://bugs.swift.org)

---

<div class="post-metadata">

**Author:** ![robnik](https://avatars.discourse-cdn.com/v4/letter/r/46a35a/32.png) [@robnik](https://forums.swift.org/u/robnik)\
**Post date:** [April 23, 2020, 2:21pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/19 "2020-04-23T14:21:57Z")

</div>

Yes, it literally crashes. I was making the property wrapper type a class. Once I made it a struct, it stopped crashing and worked. I will file a bug soon.

Unfortunately for my case, I also wanted to be able to turn the keypaths into a strings, to store data in dynamic things like CKRecords and SQL insert/update statements, and there is apparently no way to get a string from those ReferenceWritableKeyPaths. (Correct?) Grrr.

---

<div class="post-metadata">

**Author:** ![1oo7](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/1oo7/32/17598_2.png) [@1oo7](https://forums.swift.org/u/1oo7)\
**Post date:** [October 28, 2020, 5:05pm UTC](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526/20 "2020-10-28T17:05:24Z")

</div>

Why does only work when wrapping properties of a class? When I wrap properties of a struct, then the property wrapper's `wrappedValue` function gets called instead of `static subscript<EnclosingSelf>(_enclosingInstance observed: EnclosingSelf, wrapped wrappedKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Value>, storage storageKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Self>) -> Value`. I tried changing the keypath types to `WritableKeyPath` but it still doesn't work.

Please advise. We really need this functionality to work!

[Next page](https://forums.swift.org/t/property-wrappers-access-to-both-enclosing-self-and-wrapper-instance/32526.md?page=2)
