Skip to content

sending a non-Sendable value and erasing it bypasses data race safety checks #83124

@ph1ps

Description

@ph1ps

Description

The provided example is racy.
It seems like returning a non-Sendable class as sending and also nil-ing out the value bypasses data race safety checks.

Reproduction

class NS {
  var value = 0
}

struct Box {
  var value: NS?

  mutating func take() -> sending NS {
    if let value {
      self.value = nil
      return value
    } else {
      preconditionFailure("Consumed twice")
    }
  }
}

func race() async {
  let ns = NS()
  var box1 = Box(value: ns)
  var box2 = Box(value: ns)
  await withTaskGroup { taskGroup in
    let ns1 = box1.take()
    let ns2 = box2.take()
    taskGroup.addTask {
      ns1.value += 1
    }
    taskGroup.addTask {
      ns2.value += 1
    }
  }
}

Expected behavior

Compiler should produce an error.

Environment

swift-driver version: 1.120.5 Apple Swift version 6.1.2 (swiftlang-6.1.2.1.2 clang-1700.0.13.5)
Target: arm64-apple-macosx15.0

Additional information

Discussion on the forum: https://forums.swift.org/t/taskgroup-and-sending-closures/77700/16

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.triage neededThis issue needs more specific labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions