[Pitch] Ownership for Subscript Parameters

Hi all,

Here is a short "filling in gaps" pitch to enable inout, borrowing, and consuming parameters for subscripts. This will make the following ill-formed code valid:

struct X {
  subscript(oldValue: inout Int) -> Int {
    get {
      // ...
    }
    
    set {
      oldValue = newValue
      // set newValue
    }
  }
}

struct Y {
  subscript(resourceHandle: borrowing Resource) -> Data {
    get { ... }
    set { ... }
  }
}

struct Z {
  subscript(resourceHandle: consuming Resource) -> Span<UInt>{
    borrow { ... }
    mutate { ... }
  }
}

The implementation is at Implement subscript parameters of noncopyable type by DougGregor · Pull Request #91992 · swiftlang/swift · GitHub. Aside from "filling in gaps", this is some infrastructure I need for the implementation of keypaths that have non-copyable roots, but that's a separate proposal.

Doug

6 Likes

However, when the subscript argument is borrowing or inout, the argument must remain fixed for the duration of the call to doSomething(on:), so that the same index value is provided to both the get and the set.

This suggests the lifetime of a borrow or mutate result can depend on the lifetime of an argument. Can the lifetime of a get result depend on the lifetime of an argument, as it can for a method?

I have read the explanation in the proposal, but I don't quite understand why borrow is OK but get isn't. IIUC borrow is about the value (not the parameter) and there is nothing to prevent it from consuming the parameter in its semantics. Could you elaborate a bit?

EDIT: If the approach is to apply borrow accessor to the parameter too, then we'll have trouble in explaining why get/set accessor works with a borrowing parameter.