Question about _enclosingInstance function in property wrappers

Swift has the following undocumented feature, which was added as part of @Douglas_Gregor and @Joe_Groff 's original proposal to add property wrappers, and was something discussed in the "future direction" section which got implemented as an undocumented feature of property wrappers:

    public static subscript<Root>(
        _enclosingInstance instance: Root,
        wrapped rootKeyPath: ReferenceWritableKeyPath<Root, Value>,
        storage wrapperKeyPath: ReferenceWritableKeyPath<Root, Self>
    ) -> Value

When we asked about this a few years ago, someone said they were probably waiting until this could be updated to just a WritableKeyPath (allowing for an inout struct) before making it an official language feature.

So... where are we at with this now in mid-2022? Is anyone aware of any plans or proposals to make this API official anytime soon, or are we still blocked by a lack of inout structs? Would it be worthwhile to make a follow-up pitch to get this made official at this point? Thanks.

10 Likes

I did hit a situation where I wanted this feature: getting the enclosing self would have saved one object allocation per wrapped property.

In my case, this hypothetical feature would only have been useful when Root is an object type, so the WritableKeyPath approach wouldn’t have been necessary — but that approach presumably also would not have prevented me from solving my problem.

I'd really like to see this as I have multiple multiple scenarios what require access to the enclosing object:

  1. UIResponder property wrapper that needs access to UIResponder.next
  2. NSManagedObject property wrapper that needs access to NSManagedObject.primitiveValue(forKey:) this also requires access to the property name so it can be passed on.

You might be interested in what I have done regarding pt. 1 UIEnvironment/UIEnvironment.swift at 406f2faea6c5cb81a4c378bde5d4d00b9b334977 ¡ nonameplum/UIEnvironment ¡ GitHub

1 Like

It’s never been made official because we’ve struggled to generalize it. The biggest problem is that it only really works with classes, because for most patterns with enclosing value types it’s an exclusivity violation to try to provide access to both self and a property of self to the same function. Our tentative conclusion is that this sort of stuff usually can’t be formally abstracted, and it only works if you expand it out in source. That is, we think it might be beyond what’s reasonable to do with property wrappers, and we’re leaning towards saying that macros are the right way to handle it in the future.

11 Likes