I think detached task initially wasn't required to explicitly mention self but was later changed.
Questions
Does detached task have a self requirement because of how it interacts with actors (it doesn't inherit the context and could run on a different executor)?
Is there a way to reliably detect data races? TSAN sometimes catches it and sometimes seems to miss data races. (not sure others face this issue or I am missing something)
Does anybody have a source where this was decided (if it was formally decided)?
I could not find it through a quick search but I'm sure it was in one of the SE reviews of the initial concurrency Task primitives.
I believe the argument made was that "Task{} runs on the enclosing actor so causing weird retain cycles is less of an issue, you're on the actor and it must be alive already anyway", while Task.detached does not run on the enclosing actor so it's the same amount of problematic as random escaping closures. At least that's how i foggy remember it, I don't think I was very involved in this discussion. Maybe others remember or can find the discussion.
In practice I've run into retain cycles often just using Task {} because that's the first thing I reach for when setting up listening loops to AsyncStreams. Would it be better to use Task.detached{} instead? Still, I've been hesitant to do that because I wanted to capture the task locals and such. I find the implicit self to be frustrating and wish we didn't allow it.
Hm. I still can’t find any discussion about this in the forums (and there aren't too many results if you search for something like "detached implicit self", so I feel it should be findable).
Personally, I don't find this argument convincing. My understanding was always that implicit self capture exists because most tasks (whether detached or not) are not expected to be long-running/infinite, so any retain cycles would resolve automatically on task completion. I don't see why long-running/infinite tasks should be more or less lilely to be detached (if anything, maybe more likely?).
(By the way, asyncDetached still exists today in SourceCompatibilityShims.swift and still has the attribute).
(There also used to be func detach(priority:operation:), which did not have the attribute. IIRC, this was the name before asyncDetached, so maybe it's not relevant to this discussion?