Missing reinitialization of closure capture after consume for closures executed only once

In the following code:

struct Context: ~Copyable {
  let projects: RwLock<NonCopyableArray<Project>>
  // ...

  public mutating func addProject(_ project: consuming Project) async {
    await self.projects.write { projects in
      projects.append(project)
      self.currentProjectIndex = projects.count - 1
    }
  }
}

struct Project: ~Copyable {
  // ...
}

final class RwLock<T: ~Copyable> {
  func write(_ cb: (inout T) async throws -> Void) async rethrows {
   // ...
  }
}

struct NonCopyableArray: ~Copyable {
  // ...
}

I get the following error:

error: missing reinitialization of closure capture 'project' after consume
 7 |   }
 8 |
 9 |   public mutating func addProject(_ project: consuming Project) async {
   |                                     `- error: missing reinitialization of closure capture 'project' after consume
10 |     await self.projects.write { projects in
11 |       projects.append(project)
   |                `- note: consumed here
12 |       self.currentProjectIndex = projects.count - 1
13 |     }

I assume this is because currently there seems to be no way to declare a function callback that it will be called only once, so swift thinks the value of project might be consumed more than once.

Is there currently any elegant solution for this problem?

Not “currently”. Storing an Optional and using take() is probably your best bet.

That's what I ended up doing.

Would be nice if we could somehow declare that the function consumes the value, or tell to the compiler it will only be executed only once.

1 Like