Is it safe to match against a Regex from multiple threads simultaneously?

For Regexes that don’t change for the life of my (Swift 6) app, it seems wasteful to create them just before each use and them throw them away immediately after. So I am looking to hoist them to higher scopes and create them just once, where possible.

This is fine if there’s a known isolation domain (e.g., @MainActor), but sometimes there isn’t one, as in the trivial example case of an extension to String shown below.

(Yes, I could stop using an extension and instead make multiple plain functions, with one copy of the code in each isolation domain where I want to use it, but that duplication is not appealing for large chunks of code.)

If I “force” it to work by declaring the Regex to be nonisolated(unsafe), then it will build, but I’m left wondering if it’s actually safe. Assume all I ever do with this Regex is match against it using methods like (firstMatch(), String's contains(), replacing(), etc.)

Is matching against a Regex a read-only operation that is safe to do from multiple threads simultaneously? Or is that unsafe annotation an accurate description of this practice?

// Without the "(unsafe)" part, Swift 6 complains: 'nonisolated'
// can not be applied to variable with non-'Sendable' type 
// 'Regex<(Substring, Substring)>'
nonisolated(unsafe)
let twiddleRegex : Regex<(Substring, Substring)> = 
    try! Regex("(foo|bar)").ignoresCase()

extension String {
    var twiddled : String {
        return self.replacing(twiddleRegex) { match in
            match.1.uppercased()
        }
    }
}

print("Foo test bar test".twiddled) // FOO test BAR test
1 Like

I guess the question is really, why isn't Regex Sendable? It feels to me that a Regex should be a true value, and I don't see a conceptual reason it shouldn't be Sendable.

The original proposal doesn't mention Sendable at all; perhaps it was simply that nobody thought about it?

It's not very obvious to me from the source just how much work making it Sendable might be: swift-experimental-string-processing/Sources/_StringProcessing/Regex/Core.swift at main · swiftlang/swift-experimental-string-processing · GitHub

1 Like

Here's a previous thread on the subject: Should Regex be Sendable?

Seems like it's quite a big problem to make it Sendable, given the design.

2 Likes