@@ -74,6 +74,10 @@ struct MutableSpan<T>: ~Escapable, ~Copyable {
7474 }
7575}
7676
77+ extension MutableSpan {
78+ mutating func update( ) { }
79+ }
80+
7781extension Array {
7882 @_lifetime ( borrow self)
7983 borrowing func span( ) -> Span < Element > {
@@ -516,6 +520,68 @@ func testReassignToBorrowBad(span: inout Span<Int>, array: [Int]) { // expected-
516520 reassign ( dest: & span, source: array. span ( ) )
517521} // expected-note{{this use causes the lifetime-dependent value to escape}}
518522
523+ // =============================================================================
524+ // Copied dependence on mutable captures
525+ // =============================================================================
526+
527+ func runClosure( _ body: ( ) -> ( ) ) { }
528+
529+ func testNoEscapeClosureCaptureMutation( spanArg: consuming MutableSpan < Int > ) {
530+ var spanCapture = spanArg
531+ runClosure {
532+ spanCapture. update ( )
533+ }
534+ _ = spanCapture
535+ }
536+
537+ func testNoEscapeClosureCaptureMutationDirect( spanArg: consuming MutableSpan < Int > ) {
538+ var spanCapture = spanArg;
539+ {
540+ spanCapture. update ( )
541+ } ( )
542+ _ = spanCapture
543+ }
544+
545+ func testNoEscapClosureCaptureUnsupported( spanArg: Span < Int > , array: consuming [ Int ] ) {
546+ var spanCapture = spanArg // expected-error{{lifetime-dependent variable 'spanCapture' escapes its scope}}
547+ // expected-note@-2{{it depends on a closure capture; this is not yet supported}}
548+ _ = spanCapture;
549+ runClosure {
550+ spanCapture = array. span ( )
551+ } // expected-note{{this use causes the lifetime-dependent value to escape}}
552+ }
553+
554+ func testNoEscapClosureCaptureUnsupportedDirect( spanArg: Span < Int > , array: consuming [ Int ] ) {
555+ var spanCapture = spanArg // expected-error{{lifetime-dependent variable 'spanCapture' escapes its scope}}
556+ // expected-note@-2{{it depends on a closure capture; this is not yet supported}}
557+ _ = spanCapture;
558+ {
559+ spanCapture = array. span ( )
560+ } ( ) // expected-note{{this use causes the lifetime-dependent value to escape}}
561+ }
562+
563+ // 'spanBox' escapes to 'closure' before it is captured by 'escapedSpan'. The 'inout_aliasable' capture is considered
564+ // escaping because the closure contains a 'begin_access [dynamic]'.
565+ func testNoEscapClosureCaptureHasEscaped( spanArg: Span < Int > , array: consuming [ Int ] ) {
566+ // expected-error@-1{{lifetime-dependent variable 'spanArg' escapes its scope}}
567+ // expected-note@-2{{it depends on the lifetime of argument 'spanArg'}}
568+ // expected-note@-3{{it depends on a closure capture; this is not yet supported}}
569+ var spanBox = spanArg // expected-error{{lifetime-dependent variable 'spanBox' escapes its scope}}
570+ // expected-note@-1{{it depends on a closure capture; this is not yet supported}}
571+ // expected-note@-2{{this use causes the lifetime-dependent value to escape}}
572+ let closure = { spanBox } // expected-note{{this use causes the lifetime-dependent value to escape}}
573+
574+ let escapedSpan = {
575+ spanBox = array. span ( ) // expected-error{{lifetime-dependent value escapes its scope}}
576+ // expected-note@-1{{this use causes the lifetime-dependent value to escape}}
577+ return closure ( ) // expected-error{{lifetime-dependent value escapes its scope}}
578+ // expected-note@-1{{it depends on the lifetime of this parent value}}
579+ // expected-note@-2{{this use causes the lifetime-dependent value to escape}}
580+ } ( )
581+ _ = consume array
582+ _ = escapedSpan
583+ }
584+
519585// =============================================================================
520586// Scoped dependence on property access
521587// =============================================================================
0 commit comments