[async/await] The order matters for concurrent bindings with a tuple syntax

For the following example I'm expecting if one of the concurrent tasks has thrown an error, the rest unfinished tasks must be cancelled.

But it isn't what I see. If task2 has thrown first, the task1 will continue execution till completion. But it works as expecting in vice-verse, failing task1 first, results task2 cancellation.

The log in case if task2 has thrown first:

task1 BEGIN
task2 BEGIN
task2 completed
task2 catch CancellationError()
task2 END
task1 completed // It's not expecting to see this log
task1 catch CancellationError()
task1 END
Failed: CancellationError()

The log in case if task1 has thrown first (works as expected, see there is no 'task2 completed' log. As soon as task1 has thrown, the entire try await(,) throws as well.):

task1 BEGIN
task2 BEGIN
task1 completed
task1 catch CancellationError()
task1 END
Failed: CancellationError()
task2 catch CancellationError()
task2 END

Code is below:

async let t1 = task1()
async let t2 = task2()

do {
    _ = try await (t1, t2)
} catch {
    print("Failed: \(error)")
}

func task1() async throws -> Int {
    print("task1 BEGIN")
    defer { print("task1 END") }

    do {
      try await Task.sleep(nanoseconds: UInt64(3 * 1_000_000_000))

      print("task1 completed")
      throw CancellationError()
    } catch {
      print("task1 catch \(error)")
      throw error
    }
}

func task2() async throws -> Int {
    print("task2 BEGIN")
    defer { print("task2 END") }

    do {
      try await Task.sleep(nanoseconds: UInt64(1 * 1_000_000_000))

      print("task2 completed")
      throw CancellationError()
    } catch {
      print("task2 catch \(error)")
      throw error
    }
}
[async/await] The order matters for concurrent bindings with a tuple syntax
 
 
Q