# Reading a computed property in a method consumes self but only in some cases?

**URL:** <https://forums.swift.org/t/reading-a-computed-property-in-a-method-consumes-self-but-only-in-some-cases/71444>\
**Category:** Using Swift\
**Tags:** ownership, generics, properties\
**Created:** [April 24, 2024, 4:40pm UTC](https://forums.swift.org/t/reading-a-computed-property-in-a-method-consumes-self-but-only-in-some-cases/71444 "2024-04-24T16:40:31Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![corbeling](https://avatars.discourse-cdn.com/v4/letter/c/6f9a4e/32.png) [@corbeling](https://forums.swift.org/u/corbeling)\
**Post date:** [April 24, 2024, 4:40pm UTC](https://forums.swift.org/t/reading-a-computed-property-in-a-method-consumes-self-but-only-in-some-cases/71444/1 "2024-04-24T16:40:31Z")

</div>

Hi folks!

I'm learning Swift and I've been playing around with `borrowing` and `consuming`, and I ran into something I don't quite understand.

It seems that in a generic struct that has a stored property with the generic type, reading a computed property inside a `borrowing` method consumes `self`. So eg. this contrived but minimal example won't compile:

```swift
struct Gleb<Base> {
  let base: Base
  var computed: Int { 666 }
  borrowing func doSomething() -> Int { computed }
}

```

```swift
/whee/bla.swift:59:18: error: 'self' is borrowed and cannot be consumed
  borrowing func doSomething() -> Int { computed }
                 ^
/whee/bla.swift:59:41: note: consumed here
  borrowing func doSomething() -> Int { computed }
                                        ^

```

Changing the property to `{ borrowing get { 666 } }` doesn't help.

All of these compile just fine:

```swift
class ClassyGleb<Base> {
  let base: Base
  var computed: Int { 666 }
  borrowing func doSomething() -> Int { computed }

  init(base: Base) {
    self.base = base
  }
}

struct Baseless {
  var computed: Int { 666 }
  borrowing func doSomething() -> Int { computed }
}

struct Funcy<Base> {
  let base: Base
  var computed: Int { 666 }
  func _computed() -> Int { computed }
  borrowing func doSomething() -> Int { _computed() }
}

```

What exactly is going on here? Why does storing a generically typed `base: Base` throw a wrench into things if you read computed properties from a `borrowing` method, but only if it's a struct? I've tried reading [SE-0377](https://github.com/apple/swift-evolution/blob/main/proposals/0377-parameter-ownership-modifiers.md) and [SE-0390](https://github.com/apple/swift-evolution/blob/main/proposals/0390-noncopyable-structs-and-enums.md), but either haven't successfully understood them or this behavior isn't covered in them.

```swift
❯ swift -version

swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0

```

---

<div class="post-metadata">

**Author:** ![corbeling](https://avatars.discourse-cdn.com/v4/letter/c/6f9a4e/32.png) [@corbeling](https://forums.swift.org/u/corbeling)\
**Post date:** [April 26, 2024, 1:41pm UTC](https://forums.swift.org/t/reading-a-computed-property-in-a-method-consumes-self-but-only-in-some-cases/71444/2 "2024-04-26T13:41:47Z")

</div>

There's clearly something I don't understand about ownership mechanics and how they relate to computed properties, because this happens with protocols too:

```swift
struct Example {
  protocol Proto {
    var count: Int { borrowing get }
  }
  
  func takeProto(_ p: borrowing some Proto) -> Int {
    p.count
  }
}

```

This fails to compile because `'p' is borrowed and cannot be consumed` even though I again tried with an explicit `borrowing get`.

This doesn't seem to fit any of the cases listed as a consuming operation in [SE-0390](https://github.com/apple/swift-evolution/blob/main/proposals/0390-noncopyable-structs-and-enums.md#consuming-operations):

- assigning a value to a new let or var binding, or setting an existing variable or property to the binding
- passing an argument to a consuming parameter of a function
- passing an argument to an init parameter that is not explicitly borrowing
- invoking a consuming method on a value, or accessing a property of the value through a consuming get or consuming set accessor
- explicitly consuming a value with the consume operator
- return-ing a value

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [April 26, 2024, 3:15pm UTC](https://forums.swift.org/t/reading-a-computed-property-in-a-method-consumes-self-but-only-in-some-cases/71444/3 "2024-04-26T15:15:35Z")

</div>

> [@corbeling](#):
>
> ```swift
> struct Example {
> protocol Proto {
> var count: Int { borrowing get }
> }
>   
> func takeProto(_ p: borrowing some Proto) -> Int {
> p.count
> }
> }
> 
> ```

That looks like a bug to me. This should work.

---

<div class="post-metadata">

**Author:** ![corbeling](https://avatars.discourse-cdn.com/v4/letter/c/6f9a4e/32.png) [@corbeling](https://forums.swift.org/u/corbeling)\
**Post date:** [April 26, 2024, 4:05pm UTC](https://forums.swift.org/t/reading-a-computed-property-in-a-method-consumes-self-but-only-in-some-cases/71444/6 "2024-04-26T16:05:07Z")

</div>

Ah, well that would make sense. Any idea if my original example should also work? Intuitively both of these cases feel like they _should_ be fine

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [April 26, 2024, 5:44pm UTC](https://forums.swift.org/t/reading-a-computed-property-in-a-method-consumes-self-but-only-in-some-cases/71444/7 "2024-04-26T17:44:36Z")

</div>

Yeah, I would expect all of your examples to compile. It compiles if the types themselves are `~Copyable`, so it should also compile if the types are Copyable but the parameter bindings have implicit copying suppressed with `borrowing`/`consuming` modifiers.

---

<div class="post-metadata">

**Author:** ![corbeling](https://avatars.discourse-cdn.com/v4/letter/c/6f9a4e/32.png) [@corbeling](https://forums.swift.org/u/corbeling)\
**Post date:** [April 26, 2024, 5:48pm UTC](https://forums.swift.org/t/reading-a-computed-property-in-a-method-consumes-self-but-only-in-some-cases/71444/8 "2024-04-26T17:48:25Z")

</div>

> <https://github.com/apple/swift/issues/73292>
>
> \### Description
> 
> I've found two cases of values getting consumed when reading co…mputed properties that seem like they're not correct behavior based on my reading of \[SE-0377\](https://github.com/apple/swift-evolution/blob/main/proposals/0377-parameter-ownership-modifiers.md) and \[SE-0390\](https://github.com/apple/swift-evolution/blob/main/proposals/0390-noncopyable-structs-and-enums.md).
> 
> Case 1 is a method with a \`borrowed some Proto\` parameter calling a getter on the borrowed value, and case 2 is a \`borrowing\` method in a \`struct A\<T\>\` that has a stored property \`v: T\`
> 
> \### Reproduction
> 
> \## Case 1: borrowed parameter with opaque type
> 
> \`\`\`swift
> struct Example {
> protocol Proto {
> // doesn't work with { borrowing get } either
> var count: Int { get }
> }
> 
> func takeProto(\_ p: borrowing some Proto) -\> Int {
> p.count
> }
> }
> \`\`\`
> 
> Result is
> \`\`\`
> error: 'p' is borrowed and cannot be consumed
> func takeProto(\_ p: borrowing some Proto) -\> Int {
> ^
> 
> note: consumed here
> p.count
> ^
> \`\`\`
> 
> Interestingly using \`p: borrowing any Proto\` leads to a different error. Should I make another issue for this as the error suggests?
> 
> \`\`\`
> error: usage of no-implicit-copy value that the compiler can't verify. This is a compiler bug. Please file a bug with a small example of the bug
> \`\`\`
> 
> 
> \## Case 2: borrowing method in a generic struct with stored property of generic type
> 
> \`\`\`swift
> struct Broken\<Base\> {
> let base: Base
> var compd: Int { 666 }
> borrowing func doSomething() -\> Int { compd }
> }
> \`\`\`
> 
> \`\`\`
> error: 'self' is borrowed and cannot be consumed
> borrowing func doSomething() -\> Int { compd }
> ^
> note: consumed here
> borrowing func doSomething() -\> Int { compd }
> ^
> \`\`\`
> 
> 
> \### Expected behavior
> 
> \## Case 1
> 
> Expected no error
> 
> 
> \## Case 2
> 
> Expected no error, like in the following cases that compile fine:
> 
> 
> \`\`\`swift
> class Class\<Base\> {
> let base: Base
> var computed: Int { 666 } 
> 
> borrowing func doSomething() -\> Int { computed }
> 
> init(base: Base) {
> self.base = base
> }
> }
> 
> struct NoProp\<Base\> {
> var computed: Int { 666 }
> borrowing func doSomething() -\> Int { computed }
> }
> 
> struct NotGeneric {
> var computed: Int { 666 }
> borrowing func doSomething() -\> Int { computed }
> }
> \`\`\`
> 
> 
> \### Environment
> 
> \`\`\`
> swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
> Target: arm64-apple-macosx14.0
> \`\`\`
> 
> \### Additional information
> 
> \[Forum post\](https://forums.swift.org/t/reading-a-computed-property-in-a-method-consumes-self-but-only-in-some-cases/71444))
