Capturing difference with typealias

Users:
  I’m updating more code to beta 6 and have noticed a strange difference when calling functions with closure parameters where that closure is declared with a typealias. Take this class:

typealias Closure = () -> Void

class Thing {
    var array: [String] =
    
    func doClosure(closure: Closure) {
        array.append("closure")
    }
    
    func doManualClosure(manualClosure: () -> Void) {
        array.append("manualClosure")
    }
    
    func append() {
        doClosure {
            doClosure {
                
            }
        }
    }
    
    func appendManual() {
        doManualClosure {
            doManualClosure {
                
            }
        }
    }
}

There’s an error triggered by the doClosure call inside a doClosure call saying that I need an explicit self capture. However, the same pattern in appendManual() builds just fine. I’m guessing this is a bug?

Jon

Another general question I have is how the self requirement in general has changed. I’m noticing several instances where my previous @noescape closures, which of course had that attribute removed, are now requiring self when they didn’t before and aren’t marked @escaping either. So I guess my question is, should there ever be an instance where a closure not marked @escaping requires the use of self?

Jon

···

On Aug 19, 2016, at 5:46 PM, Jon Shier <jon@jonshier.com> wrote:

Users:
  I’m updating more code to beta 6 and have noticed a strange difference when calling functions with closure parameters where that closure is declared with a typealias. Take this class:

typealias Closure = () -> Void

class Thing {
   var array: [String] =

   func doClosure(closure: Closure) {
       array.append("closure")
   }

   func doManualClosure(manualClosure: () -> Void) {
       array.append("manualClosure")
   }

   func append() {
       doClosure {
           doClosure {

           }
       }
   }

   func appendManual() {
       doManualClosure {
           doManualClosure {

           }
       }
   }
}

There’s an error triggered by the doClosure call inside a doClosure call saying that I need an explicit self capture. However, the same pattern in appendManual() builds just fine. I’m guessing this is a bug?

Jon

Hi Jon,

In beta 6, non-escaping is now the default, and you must use the @escaping attribute to declare a parameter as escaping.

Unfortunately, there were a few bugs in how this attribute was implemented.

I checked in a fix to the swift-3.0-branch today: Sema: Three fixes for the new @escaping attribute · apple/swift@c1214fe · GitHub

After the above patch, it will no longer make a difference if the function type is written directly (as in doManualClosure) or a typealias (a in doClosure). In both cases, the closure should be non-escaping, unless explicitly declared @escaping. However in beta 6 you see the bug where the closure in doClosure() is escaping, even though no explicit @escaping attribute was specified, because it was written with a typealias.

If you have time, please test the next snapshot when it is released, or build Swift from swift-3.0-branch (or master) today, to see if it behaves as you expect.

Sorry for the confusion.

Slava

···

On Aug 19, 2016, at 5:27 PM, Jon Shier via swift-users <swift-users@swift.org> wrote:

Another general question I have is how the self requirement in general has changed. I’m noticing several instances where my previous @noescape closures, which of course had that attribute removed, are now requiring self when they didn’t before and aren’t marked @escaping either. So I guess my question is, should there ever be an instance where a closure not marked @escaping requires the use of self?

Jon

On Aug 19, 2016, at 5:46 PM, Jon Shier <jon@jonshier.com> wrote:

Users:
  I’m updating more code to beta 6 and have noticed a strange difference when calling functions with closure parameters where that closure is declared with a typealias. Take this class:

typealias Closure = () -> Void

class Thing {
  var array: [String] =

  func doClosure(closure: Closure) {
      array.append("closure")
  }

  func doManualClosure(manualClosure: () -> Void) {
      array.append("manualClosure")
  }

  func append() {
      doClosure {
          doClosure {

          }
      }
  }

  func appendManual() {
      doManualClosure {
          doManualClosure {

          }
      }
  }
}

There’s an error triggered by the doClosure call inside a doClosure call saying that I need an explicit self capture. However, the same pattern in appendManual() builds just fine. I’m guessing this is a bug?

Jon

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users