A question on non escapable types

I was playing around with non escapable types and am running into this error:

struct Foo: ~Copyable, ~Escapable {
}

struct FooData: ~Copyable, ~Escapable {
  @_lifetime(borrow foo)
  fileprivate init(foo: borrowing Foo) {
  }
}

struct FooDataContainer: ~Copyable, ~Escapable {
  @_lifetime(borrow data)
  init(
    data: borrowing FooData
  ) {
  }
}

@_lifetime(borrow foo)
func process1(_ foo: borrowing Foo) -> FooData {
  return FooData(foo: foo)
}

@_lifetime(borrow foo)
func process2(_ foo: borrowing Foo) -> FooDataContainer {
  // ERROR: Lifetime-dependent value escapes its scope
  return FooDataContainer(data: FooData(foo: foo))
}

I'm guessing this is because FooData only exists in the body of process2, but what I'm really trying to express is that FooDataContainer should have a lifetime that is the borrow of foo. Is there a way to pass this data from FooData to FooDataContainer? Is there another way to implement this pattern?

FooDataContainer most likely wants to use @_lifetime(copy data)since it is probably going to store a value of FooData. This has the behavior of the container inheriting the lifetime of FooData instead of being nested underneath its lifetime which is why this error occurs.

process2 -> depends on
  foo

FooData -> depends on
  foo

FooDataContainer -> depends on
  FooData -> depends on
    foo

is effectively what your original code looks like where we create a borrow “scope” of the data for the container which is a level greater than that of process2 but instead copy data looks like:

process2 -> depends on
  foo

FooData -> depends on
  foo

FooDataContainer == FooData -> depends on
  foo
1 Like

Ah that's it, simple! Thanks!