Repository: apple/swift
File: test/SILOptimizer/lifetime_dependence/lifetime_dependence_closure.swift (Swift)

Code before:
  @_lifetime(borrow self, copy ne)
  static func staticTransferDependingOnSelf(ne: NE) -> NE { ne }
  @_lifetime(borrow self, copy ne)
  func transferDependingOnSelf(ne: NE) -> NE { ne }
}

do {
  let _ = transfer // OK
  let _: (NE) -> NE = transfer // OK
  let _: @_lifetime(copy ne) (_ ne: NE) -> NE = transfer // OK
  let _: @_lifetime(copy ne) (_ ne: NE) -> NE = S.staticTransfer // OK, method is static
  let _: (_ ne: NE) -> NE = S.staticTransferDependingOnSelf
  // expected-error@-1{{lifetime-dependent value escapes its scope}}
  // expected-note@-2{{it depends on the lifetime of argument 'ne'}}
  // expected-note@-3{{this use causes the lifetime-dependent value to escape}}
  // expected-error@-4{{lifetime-dependent value escapes its scope}}
  // expected-note@-5{{it depends on the lifetime of this parent value}}
  // expected-note@-6{{this use causes the lifetime-dependent value to escape}}

  // Non-static methods are not supported yet
  let s = S()
  let _: @_lifetime(copy ne) (_ ne: NE) -> NE = s.transfer
  // expected-error@-1{{lifetime-dependent value escapes its scope}}
  // expected-note@-2{{it depends on the lifetime of argument 'ne'}}
  // expected-note@-3{{this use causes the lifetime-dependent value to escape}}
  let _: @_lifetime(copy ne) (_ ne: NE) -> NE = s.transferDependingOnSelf
  // expected-error@-1{{lifetime-dependent value escapes its scope}}
  // expected-note@-2{{it depends on the lifetime of argument 'ne'}}
  // expected-note@-3{{this use causes the lifetime-dependent value to escape}}
  // expected-error@-4{{lifetime-dependent value escapes its scope}}
  // expected-note@-5{{it depends on a closure capture; this is not yet supported}}
  // expected-note@-6{{this use causes the lifetime-dependent value to escape}}
}


Review comment (bug):
Please include this test as well:

```
func foo(_ closure: @_lifetime(copy span) (_ span: Span<Int>) -> Span<Int>, _ span: Span<Int>) -> Span<Int> {
  return closure(span)
}

class Holder {
  @_lifetime(copy span)
  static func correct(_ span: Span<Int>) -> Span<Int> {
    return span
  }
  
  @_lifetime(borrow span)
  static func incorrect(_ span: Span<Int>) -> Span<Int> {
    return span
  }
}

func bar(_ span: Span<Int>) {
  _ = foo(Holder.incorrect, span) // Conversion error
  print(foo(Holder.correct, span).count)
}

func baz1() -> @_lifetime(copy span) (_ span: Span<Int>) -> Span<Int> {
  return Holder.correct
}

func baz2() -> @_lifetime(copy span) (_ span: Span<Int>) -> Span<Int> {
  return Holder.incorrect  // Conversion error
}
```

Code after:
  static func staticTransferBorrowingNE(ne: NE) -> NE { ne }
  func transfer(ne: NE) -> NE { ne }
  @_lifetime(borrow self, copy ne)
  func transferDependingOnSelf(ne: NE) -> NE { ne }
}

do {
  typealias Transfer = @_lifetime(copy ne) (_ ne: NE) -> NE
  let _ = transfer // OK
  let _: (NE) -> NE = transfer // OK
  let _: Transfer = transfer // OK
  let _: Transfer = S.staticTransfer // OK, method is static

  // Non-static methods are not supported yet
  let s = S()
  let _: Transfer = s.transfer
  // expected-error@-1{{lifetime-dependent value escapes its scope}}
  // expected-note@-2{{it depends on the lifetime of argument 'ne'}}
  // expected-note@-3{{this use causes the lifetime-dependent value to escape}}
  let _: Transfer = s.transferDependingOnSelf
  // expected-error@-1{{lifetime-dependent value escapes its scope}}
  // expected-note@-2{{it depends on the lifetime of argument 'ne'}}
  // expected-note@-3{{this use causes the lifetime-dependent value to escape}}
  // expected-error@-4{{lifetime-dependent value escapes its scope}}
  // expected-note@-5{{it depends on a closure capture; this is not yet supported}}
  // expected-note@-6{{this use causes the lifetime-dependent value to escape}}
}