[Pitch] Task Cancellation Shields

i have another edge case behavioral question. note, this is odd and probably a rather 'unrealistic' scenario, but IMO the corner cases help illuminate the semantics.

if a parent Task is nested within both a shielded block and a child task and then used within the child, does that 'see through' the shield? e.g.

@MainActor
func child_referencing_parent() async {
  var parent: Task<Void, Never>!
  let t = Task { @MainActor in
    let parent: Task<Void, Never> = parent

    Task.isCancelled // false
    parent.isCancelled // false

    parent.cancel()

    Task.isCancelled // true
    parent.isCancelled // true

    await withTaskCancellationShield {
      Task.isCancelled // false
      parent.isCancelled // false

      async let child: Void = {
        Task.isCancelled // false – now refers to the child task, which is not cancelled
        parent.isCancelled // ??
        // ^ is this true b/c the query is in the child task that has no shield 'up'
        // or false b/c we're still 'scoped' under the outer shield?
      }()
      await child
    }
  }
  parent = t
  await parent.value
}
3 Likes