Types that must be MainActor, but cannot be MainActor due to protocol conformance

I agree that "add nonisolated and then wrap in assumeIsolated" is a very ugly incantation. What speaks to me about SE-0423 and @preconcurrency is that it replaces that kind of "chant" with a clearly spelled explanation of what's happening, which is also very easy to remove once it's no longer necessary. I do expect people to add it too much, but the compiler even gives you a warning when you don't need it, helping avoid it becoming a vestigial cut-and-paste chant. (I don't know whose idea that was, but they clearly care about us very much and learned from our previous experiences. :hugs:)

I do expect to see a similar pattern to implicitly unwrapped optionals. People used ! types a lot, in bizarre ways that were completely unnecessary. (I still don't get why people thought marking every property in a simple struct with ! was of any value, but I saw it constantly.) But, as the underlying libraries got audited, IUOs have steadily faded from our code, and I don't see our new developers copying them any more.

It took years, yes. And I think we should expect at least as long for @preconcurrency to fade. But that's ok. It was fine, and it'll be fine again. Choices like SE-0423 are a big deal IMO because they explicitly put a box around the issue, give it a name, and make it easy to remove like we removed all the ! marks before. We should continue to be on the lookout for other situations where people have to write weird code just to work around a current problem, and apply similar solutions.

I'm sure I'm not the first to say it, but I think Swift 5.10 is a Swift 3 moment. Before Swift 3, Swift promised a lot, but struggled to really deliver. It was seriously debatable whether it was worth the trouble. With Swift 3, IMO, Swift became a real language. There were still lots of issues that took years to smooth out, but its promise was finally real. Swift Concurrency up to this point has been similar. Lots of promise, but in practice I've spent much more time fighting with it than getting real value out of it. I think 5.10, as a preview of Swift 6, changes that.

The fact that converting to concurrency=complete has, in just a few hours, exposed real threading bugs in our code, as well as finding a long-existing mistake in UIKit, tells me we are on the right track now.

I just need a built-in pattern for serial transactions and a semaphore, please. :smile: