Mutating a property wrapper

Hey all,

I want to write a property wrapper with a copy-on-write container and a mutating method, and use it like this:

struct.$property.mutate()

I expected that it would be enough to use _modify in the projectedValue:

public var projectedValue: Self {
    get { self }
    _modify { yield &self }
}

The problem is that copy-on-write happens on every mutation. It looks like the Swift compiler generates the following property:

var $property: PropertyWrapper {
    get { _property.projectedValue }
    set { _property.projectedValue = newValue }
}

While I expect it to be:

var $property: PropertyWrapper {
    get { _property.projectedValue }
    _modify { yield _&property.projectedValue }
}

Is it the expected behavior or a bug in the compiler?

Purified example

Property wrapper:

@propertyWrapper
public struct PropertyWrapper {
    public var projectedValue: Self {
        get { self }
        _modify { yield &self }
    }

    public var wrappedValue: Int {
        get { box.value }
        set { box.value = newValue }
    }

    private var box: Box

    public init(wrappedValue: Int) {
        self.box = Box(value: wrappedValue)
    }

    public mutating func needsCopyOnWrite() -> Bool {
        !isKnownUniquelyReferenced(&box)
    }
}

private final class Box {
    var value: Int

    init(value: Int) {
        self.value = value
    }
}

Usage:

struct Struct {
    @PropertyWrapper
    var property: Int

    var propertyWrapper: PropertyWrapper {
        get { _property.projectedValue }
        _modify { yield &_property.projectedValue }
    }
}

var s = Struct(property: 123)

print(s.$property.needsCopyOnWrite()) // true
print(s.propertyWrapper.needsCopyOnWrite()) // false

P.S. Why I need such property wrapper: to have a polymorphic property of a protocol type and to have a method for mutating the property specifying the concrete type in-place.

Artem