# Should Regex be Sendable?

**URL:** <https://forums.swift.org/t/should-regex-be-sendable/69529>\
**Category:** Discussion\
**Tags:** sendable, regex\
**Created:** [January 19, 2024, 2:04pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529 "2024-01-19T14:04:48Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [January 19, 2024, 2:04pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/1 "2024-01-19T14:04:48Z")

</div>

While reading [[Pitch] Predicate Regex Support](https://forums.swift.org/t/pitch-predicate-regex-support/69361), I noticed that `Regex<T>` is not `Sendable`.

In light of the restrictions on non-sendable types coming to the language, I think it should be. I think it is fairly standard practice to define a regex as a global constant, and to use it from a variety of concurrent contexts.

My understanding is that the basic implementation of `Regex<T>` is thread-safe: that it contains a compiled, immutable program. When you look for a match, an executor is created, which interprets the instructions encoded in the regex and contains all of the mutable state related to the matching operation.

AFAICT there are a few minor API issues with Regex which prevents it from being Sendable:

- It may contain captures with transformation closures, and those closures are not marked `@Sendable`.

- `CustomConsumingRegexComponent` would need to refine `Sendable`, since they are stored in the Regex and their logic is invoked as part of the matching process.

- It may also be necessary to make the `RegexComponent` protocol refine `Sendable` (I don't _think_ that's necessary, since it has a `.regex` computed property which is the only thing that is really necessary to incorporate it in to another regex, but I haven't worked through all the details).

Currently, these are all places where non-thread-safe behaviour may be introduced as part of a Regex match, and fixing them would be potentially source-breaking.

With this thread, I'd like to do a few things:

1. Make the community aware of the issue. It seems we may be getting close to Swift 6, and I think this needs addressing as part of that overall effort. Pretty-much everything else in the standard library has been audited for sendability AFAIK.

2. To discuss these changes. I think they are very reasonable, and vastly preferable to the alternative of a non-Sendable `Regex<T>`, but others may disagree.

3. To ask the Regex authors if there are other sources of non-Sendable behaviour that they are aware of.

Thanks

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [January 19, 2024, 5:20pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/2 "2024-01-19T17:20:47Z")

</div>

I’ll note that someone could be doing something stateful with their closures, so this would be a source-breaking change. I agree that a Sendable Regex makes sense though…

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [January 19, 2024, 5:25pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/3 "2024-01-19T17:25:33Z")

</div>

> [@jrose](#):
>
> I’ll note that someone could be doing something stateful with their closures…

Yeah, that seems to be the crux of the problem - `Regex`s can call out to arbitrary other code. All of those would need to be `Sendable` first, before `Regex` could be.

Although maybe `Regex` could conditionally conform to `Sendable` when all its dependencies do?

---

<div class="post-metadata">

**Author:** ![carlynorama](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/carlynorama/32/27072_2.png) [@carlynorama](https://forums.swift.org/u/carlynorama)\
**Post date:** [January 19, 2024, 5:39pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/4 "2024-01-19T17:39:03Z")

</div>

Would it be enough for a Regex to emit a sendable property? Like a classic string version of the Regex that leaves out `transform`s, or would that be too lossy/in fact harder to implement?

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [January 19, 2024, 7:01pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/5 "2024-01-19T19:01:43Z")

</div>

I think that'd be a sharp edge, given not all `Regex`es can be expressed in traditional regex string form. It'd be all too easy for folks to cargo-cult use of such a "Sendable workaround" without understanding the ramifications.

Granted it is an oft-requested feature otherwise, just for debugging purposes if nothing else. It's easy to see the appeal for `Regex`-to-string conversion, and I think it's perfectly valid for debugging and similar purposes - but I don't see a way to prevent it likely being abused for sending (if `Regex` doesn't support `Sendable` directly).

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [January 19, 2024, 7:21pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/6 "2024-01-19T19:21:42Z")

</div>

There's nothing fundamentally wrong with the transform closures, or including custom regex components expressed using Swift code. But they need to `Sendable` for the overall regex to be `Sendable`.

They don't even need to be pure functions - they can use shared mutable state, so long as they take proper precautions for concurrent operation (e.g. using locks or atomics).

Considering what the `transform` closure and custom regex components are supposed to do, I don't think it's unreasonable to require them to be `Sendable`.

For instance, the capture's `transform` is there to integrate with other parsers, so a regex can return a `Double` rather than a `Substring`. That's a really nice feature. Typically string parsers don't access shared mutable state, instead just taking the string and possibly some flags as their inputs.

---

<div class="post-metadata">

**Author:** ![nnnnnnnn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nnnnnnnn/32/264_2.png) [@nnnnnnnn](https://forums.swift.org/u/nnnnnnnn)\
**Post date:** [January 19, 2024, 10:56pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/7 "2024-01-19T22:56:11Z")

</div>

Thanks for bringing this issue up, @Karl! I think your description of the problem is spot on: it's common to define regexes as globals—which makes sense; they act like little functions—and it should therefore be safe to use them as globals in a concurrent context.

There are a few different solutions here, any of which would require going through the evolution process:

1. Making `Regex` itself sendable would require the two changes you mentioned, with `Capture`/`transform` closures being marked `@Sendable` and the `CustomConsumingRegexComponent` being marked as extending the `Sendable` protocol. From my understanding, those changes wouldn't be source-breaking (since sendability checking still only emits warnings) and since `Sendable` is only a marker protocol, and doesn't have any ABI presence, wouldn't require availability or cause library evolution issues.

2. Introducing a parallel, `SendableRegex` type is also possible. This would require duplicating some of the `RegexComponent` infrastructure, but probably not everything, and would require the same changes in the new structure as those in solution #1. (This doesn't really seem worth it to me.)

3. Providing a sendable wrapper for a regex at runtime is akin to #2, but the creation step for a regex would be the same as it is now. We could do this sendable checking during compilation (edit: the compilation within the regex instance, not the Swift compiler), so that it wouldn't need to be repeated each time a regex. Unfortunately, we'd need to rule out any regex that had a transform or a custom component, so the set of sendable regexes would be smaller than the total, and this would discourage using some powerful `Regex` features.

Before moving forward, I think it's important to have a better understanding about what kinds of non-sendable transforms and custom components are out there. Of those, some may be legitimate, and some may already be fragile or implementation-dependent.

Two other related notes:

- There's a compilation step the first time a regex is used that is already protected via atomics.
- There's recent work (to support the predicate regex) to [generate a literal pattern string](https://github.com/apple/swift-experimental-string-processing/pull/670) when possible—these are of course sendable, but represent a subset of all sendable regexes (and would require re-compilation)

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [January 20, 2024, 1:54am UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/8 "2024-01-20T01:54:38Z")

</div>

> [@nnnnnnnn](#):
>
> Making `Regex` itself sendable would require the two changes you mentioned, with `Capture`/`transform` closures being marked `@Sendable` and the `CustomConsumingRegexComponent` being marked as extending the `Sendable` protocol. From my understanding, those changes wouldn't be source-breaking (since sendability checking still only emits warnings) and since `Sendable` is only a marker protocol, and doesn't have any ABI presence, wouldn't require availability or cause library evolution issues.

It would be source breaking, but not ABI breaking (someone may be using non-sendable capture/transform closures today, and they would no longer be able to compile).

---

<div class="post-metadata">

**Author:** ![xedin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/xedin/32/309_2.png) [@xedin](https://forums.swift.org/u/xedin)\
**Post date:** [January 24, 2024, 2:27am UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/9 "2024-01-24T02:27:31Z")

</div>

Just my two cents, making Regex unconditionally Sendable with changes to Capture/transform @nnnnnnnn mentioned might prove to be restrictive just like in case of key path where all their captures are required to be Sendable which means that the code that has nothing to do with concurrency still has to provide Sendable types which is not always possible.

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [January 24, 2024, 4:10am UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/10 "2024-01-24T04:10:49Z")

</div>

> [@xedin](#):
>
> …which means that the code that has nothing to do with concurrency still has to provide Sendable types which is not always possible.

Yeah, I've been pondering this too. Requiring `Sendable` unconditionally feels concerningly blunt.

That said, it seems that it somewhat hinges on whether it's considered acceptable to have stateful capture / transform closures to begin with. I tend to assume it is, but then I can't recall ever _actually_ doing that. Are there known use-cases like that?

---

<div class="post-metadata">

**Author:** ![FranzBusch](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/franzbusch/32/19447_2.png) [@FranzBusch](https://forums.swift.org/u/FranzBusch)\
**Post date:** [January 24, 2024, 11:22am UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/11 "2024-01-24T11:22:32Z")

</div>

We have faced a similar problem in the various `AsyncSequence` algorithms that take a closure in the standard library and `swift-async-algorithms`. The problem is that the concrete `AsyncSequence` types want to be `Sendable` if both their base async sequences and the supplied closure is `Sendable`. However, we can only be generic over the `Sendable` conformance of the base async sequence; hence, we have to enforce `@Sendable` on the closures. This allows us to make the types `Sendable` however it limits their functionality a bit in the context of actors if the `AsyncSequence` never escapes the actor.

Sometimes I wish functions would be concrete types inside Swift so they can participate in protocol conformances and generics.

---

<div class="post-metadata">

**Author:** ![dnadoba](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dnadoba/32/11438_2.png) [@dnadoba](https://forums.swift.org/u/dnadoba)\
**Post date:** [January 24, 2024, 12:23pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/12 "2024-01-24T12:23:28Z")

</div>

Functions can participate in protocol conformances (well, they can just conform to `Sendable`) and can be used in generics. For Example:

```swift
struct Box<Value> {
    var value: Value
}

extension Box: Sendable where Value: Sendable {}

func assertSendable(_ sendable: (some Sendable).Type) {}

assertSendable(Box<() -> Void>.self) // warning: Type '() -> Void' does not conform to the 'Sendable' protocol
assertSendable(Box<@Sendable () -> Void>.self)

```

What is missing is a type constrain that allows to specify the shape of a function so that we can actually call it and not just pass it around.  
Something like this:

```swift
struct Foo<Function> where Function: () -> Void { // error: Type 'Function' constrained to non-protocol, non-class type '() -> Void'
    var function: Function
}

```

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [April 12, 2024, 1:51am UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/13 "2024-04-12T01:51:36Z")

</div>

> [@nnnnnnnn](#):
>
> 1. Making `Regex` itself sendable would require the two changes you mentioned, with `Capture`/`transform` closures being marked `@Sendable` and the `CustomConsumingRegexComponent` being marked as extending the `Sendable` protocol.

Is it correct, then, that for a regex which doesn’t make use of any of this machinery, it would be safe to ‘smuggle’ it across isolation boundaries using unsafe mechanisms, or is that a misunderstanding?

---

<div class="post-metadata">

**Author:** ![bdkjones](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bdkjones/32/13872_2.png) [@bdkjones](https://forums.swift.org/u/bdkjones)\
**Post date:** [May 27, 2024, 7:52am UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/14 "2024-05-27T07:52:51Z")

</div>

I just spent a lot of time fleshing out some text transformations in a Swift Playground using `Regex`. I copied this code over to an app I'm working on and was suddenly bombarded with multiple:

```swift
`'someRegex' is not concurrency-safe because it is not either conforming to 'Sendable' or isolated to a global actor; this is an error in Swift 6.

```

That ticked me off because I just _knew_ I should have handled the text transformations by hand rather than relying on the swanky new API. `Regex` is indeed pleasant to work with, but it never even occurred to me that it wouldn't be `Sendable`. If I had known that first, I wouldn't have wasted my time with it.

If you decide against making it `Sendable`, I think that absolutely cripples its usefulness. Whatever you do, please fix it before Swift 6.

---

<div class="post-metadata">

**Author:** ![p\_wrzes](https://avatars.discourse-cdn.com/v4/letter/p/6de8d8/32.png) [@p\_wrzes](https://forums.swift.org/u/p_wrzes)\
**Post date:** [August 3, 2024, 1:19pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/15 "2024-08-03T13:19:03Z")

</div>

**_Edit: nevermind, see the comment below_**

This feels like one of the rough edges that still need to be handled properly with the new concurrency model.

Just for now though, I've used this ( **very temporary** ) workaround to silence the warnings:

```swift
// TODO: Remove this wrapper when Regex conforms to Sendable.
public struct RegexWrapper<T>: @unchecked Sendable {
    
    public let value: Regex<T>
    
    public init(_ value: Regex<T>) {
        self.value = value
    }
}

```

It can be used like: `let regex = RegexWrapper(/^1234$/)` and then `regex.value.doSomething(...)`

One other thing I find annoying is that you can only use `@unchecked Sendable` on classes and structs, but there is no way of disabling strict concurrency per field, or a file, or generally in a lot of other places in case you know there is no risk of data races, but the compiler doesn't.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [August 3, 2024, 2:37pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/16 "2024-08-03T14:37:20Z")

</div>

In the mean time, you can declare regex constants as `nonisolated(unsafe)`.

```swift
// Compiling with -swift-version 6

nonisolated(unsafe) // <---
public let MyRegex = /[0-9]+/

actor MyActor {
  func matches(_ input: String) -> Bool {
    input.firstMatch(of: MyRegex) != nil // okay.
  }
}

```

This also works for regex builders, which is where you might add custom logic via closures.

```swift
// Compiling with -swift-version 6

import RegexBuilder

nonisolated(unsafe) // <---
public let MyRegex = Regex {
  Capture(
    {
      OneOrMore { .digit }
    },
    transform: { Double($0) }
  )
}

actor MyActor {
  func match(_ input: String) -> Double? {
    input.firstMatch(of: MyRegex)?.1 // okay.
  }
}

```

This means you are promising that your regex does not have non-sendable shared state (it's _unsafe_, so the compiler isn't checking for you), but for most regexes that should be an easy determination to make. Especially if you just have a Regex literal - it's not even possible for it to contain non-sendable shared state.

Eventually it would be nice if the compiler checked this for you and made it _safely_ non-isolated.

---

<div class="post-metadata">

**Author:** ![p\_wrzes](https://avatars.discourse-cdn.com/v4/letter/p/6de8d8/32.png) [@p\_wrzes](https://forums.swift.org/u/p_wrzes)\
**Post date:** [August 3, 2024, 2:55pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/17 "2024-08-03T14:55:45Z")

</div>

Ah thanks, I had the impression that `nonisolated(unsafe)` can only be used in actors as they are isolating their fields and that's the only place I've seen `nonisolated` used in the tutorials. This really helps!

---

<div class="post-metadata">

**Author:** ![Jon889](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon889/32/3139_2.png) [@Jon889](https://forums.swift.org/u/Jon889)\
**Post date:** [February 13, 2026, 2:59pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/18 "2026-02-13T14:59:39Z")

</div>

So is there an update to make Regex work well with Swift 6?

---

<div class="post-metadata">

**Author:** ![Cyberbeni](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cyberbeni/32/46241_2.png) [@Cyberbeni](https://forums.swift.org/u/Cyberbeni)\
**Post date:** [February 13, 2026, 5:19pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/19 "2026-02-13T17:19:29Z")

</div>

It works well with Swift 6 for me.

Inside actor, constant property: [And remember that.](https://codeberg.org/Cyberbeni/Wiring/src/commit/91315572c07be47eb40b8ab12207c7d55e483475/Sources/Wiring/Features/Presence/NetworkPresenceDetector.swift#L18)

Inside nonisolated function, initializing a new one when using it: [Masses too comfortable, and.](https://codeberg.org/Cyberbeni/auth.home.arpa/src/commit/6436ca4e361f36e408303abfe035b8859aef1a3a/Sources/auth_home_arpa/Routes/Routes+Login.swift#L37)

---

<div class="post-metadata">

**Author:** ![Stan\_Smida](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stan_smida/32/10999_2.png) [@Stan\_Smida](https://forums.swift.org/u/Stan_Smida)\
**Post date:** [February 13, 2026, 8:33pm UTC](https://forums.swift.org/t/should-regex-be-sendable/69529/20 "2026-02-13T20:33:04Z")

</div>

Shape and some generic constraints are also there. At least for non-generic functions.

```swift
struct Function<each Parameter, Result> {

    let body: @Sendable (repeat each Parameter) -> Result

    func callAsFunction(_ parameters: repeat each Parameter) -> Result {
        return body(repeat each parameters)
    }
}

extension Function: Sendable where repeat each Parameter: Sendable, Result: Sendable {

}

class NonSendable {}

func foo(_ value: Any) {
    print(String(describing: value))
}

func bar() -> String {
    "Hello world"
}

func baz(qux: NonSendable, corge: String) -> (String, NonSendable) {
    (corge, qux)
}

let fooF = Function(body: foo)
let barF = Function(body: bar)
let bazF = Function(body: baz)

let bazResult = bazF(NonSendable(), barF())
fooF(bazResult) // ("Hello world", NonSendable)

func assertSendable<T>(_: T) where T: Sendable {

}

func takeGreetingGenerator<T>(_ f: Function<T>) where T: StringProtocol {
    print(f())
}

takeGreetingGenerator(barF) // Hello world
assertSendable(barF)
assertSendable(bazF) // Error: Type 'NonSendable' does not conform to the 'Sendable' protocol

```
