# Sending to TaskGroup child task

**URL:** <https://forums.swift.org/t/sending-to-taskgroup-child-task/76405>\
**Category:** Using Swift\
**Created:** [December 5, 2024, 9:17pm UTC](https://forums.swift.org/t/sending-to-taskgroup-child-task/76405 "2024-12-05T21:17:38Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![adam-fowler](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/adam-fowler/32/9266_2.png) [@adam-fowler](https://forums.swift.org/u/adam-fowler)\
**Post date:** [December 5, 2024, 9:17pm UTC](https://forums.swift.org/t/sending-to-taskgroup-child-task/76405/1 "2024-12-05T21:17:38Z")

</div>

I have been looking into `sending` parameters from [SE-0430](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0430-transferring-parameters-and-results.md). By marking a function parameter as sending I can pass it into a Task

```swift
class NonSendable {
    init() {}
}

func sendToTask(_ t: sending NonSendable) {
    Task {
        print(t)
    }
}

```

But I cannot do the same for a child task of TaskGroup

```swift
func sendToChildTask(_ t: sending NonSendable) async {
    await withTaskGroup(of: Void.self) { group in
        group.addTask {
            print(t)
        }
    }
}

```

The above code produces the error `Passing closure as a 'sending' parameter risks causing data races between code in the current task and concurrent execution of the closure`

Is there a reason I can't do this with child tasks?

It appears to be related to the closure provided to `withTaskGroup` because I can create an instance of `NonSendable` inside that closure and then able to pass it into the child task.

---

<div class="post-metadata">

**Author:** ![KeithBauerANZ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/keithbaueranz/32/27897_2.png) [@KeithBauerANZ](https://forums.swift.org/u/KeithBauerANZ)\
**Post date:** [December 6, 2024, 6:12am UTC](https://forums.swift.org/t/sending-to-taskgroup-child-task/76405/2 "2024-12-06T06:12:04Z")

</div>

You might find useful information in [Sending, inout sending, Mutex](https://forums.swift.org/t/sending-inout-sending-mutex/76373) in which I recently asked similar questions and got helpful answers!

I think in this case, it's because the compiler doesn't know how many times the closure passed to `withTaskGroup` will be called — if `withTaskGroup` called it twice, it would alias your NonSendable value.

---

<div class="post-metadata">

**Author:** ![adam-fowler](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/adam-fowler/32/9266_2.png) [@adam-fowler](https://forums.swift.org/u/adam-fowler)\
**Post date:** [December 7, 2024, 1:12pm UTC](https://forums.swift.org/t/sending-to-taskgroup-child-task/76405/3 "2024-12-07T13:12:38Z")

</div>

Looks like this was already reported. [Wrong error when passing `sending` closure to `TaskGroup` · Issue #76242 · swiftlang/swift · GitHub](https://github.com/swiftlang/swift/issues/76242)

I think it is because the closure provided to `withTaskGroup` is not tagged `sending`.

---

<div class="post-metadata">

**Author:** ![KeithBauerANZ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/keithbaueranz/32/27897_2.png) [@KeithBauerANZ](https://forums.swift.org/u/KeithBauerANZ)\
**Post date:** [December 8, 2024, 8:53pm UTC](https://forums.swift.org/t/sending-to-taskgroup-child-task/76405/4 "2024-12-08T20:53:35Z")

</div>

> [@adam-fowler](#):
>
> I think it is because the closure provided to `withTaskGroup` is not tagged `sending`.

You can confirm this doesn't help by wrapping up `withTaskGroup`:

```swift
open class NonSendable {}

@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
public func withTaskGroup2<ChildTaskResult, GroupResult>(
    of childTaskResultType: ChildTaskResult.Type,
    returning returnType: GroupResult.Type = GroupResult.self,
    isolation: isolated (any Actor)? = #isolation,
    body: sending (inout TaskGroup<ChildTaskResult>) async -> GroupResult
) async -> GroupResult where ChildTaskResult : Sendable {
    // no warning:
    await withTaskGroup(of: childTaskResultType, returning: returnType, isolation: isolation, body: body)
}

func sendToChildTask(_ t: sending NonSendable) async {
    await withTaskGroup2(of: Void.self) { group in
        // same warning:
        group.addTask {
            print(t)
        }
    }
}

```
