Commit 330080c
fix(iOS): make jsinspector-modern tracing state types move-only for Swift C++ interop (#57605)
Summary:
The nightly-tests job `[ios] react-native-unistyles` fails on Xcode 26.3 with:
```
error: no matching function for call to '__construct_at'
note: in instantiation of member function 'std::vector<...RuntimeSamplingProfile>::vector' requested here
note: in implicit copy constructor for 'facebook::react::jsinspector_modern::tracing::TraceRecordingState' first required here
```
while compiling the **Swift** files of the Unistyles pod. The same failure hits any library built with Swift C++ interop (`-cxx-interoperability-mode=default`) — in practice, every Nitro-based library — against the prebuilt React Native core.
### The error
`TraceRecordingState` and `HostTracingProfile` hold `std::vector`s of move-only types (`RuntimeSamplingProfile` and `FrameTimingSequence` explicitly delete their copy constructors). Here's the C++ subtlety: `std::vector<T>`'s copy constructor is **declared for every `T`** — it only becomes ill-formed when *instantiated*. So the implicit copy constructors of these two structs are not implicitly deleted; they exist as declared-but-broken constructors that hard-error the moment anything asks for a copy.
### Why React Native compiles fine today
Nothing in RN ever asks. Every usage passes these types by reference; the single constructions move. A pure C++ (or ObjC++) build never instantiates the implicit copy constructors, so this code has always compiled — and always would, no matter how much C++ CI you throw at it. The defect is unobservable from within C++.
### What fails, and why now
The prebuilt-core headers now ship as real clang modules. A Swift target with C++ interop imports them (directly or transitively — e.g. via a module member whose `#ifdef __cplusplus` body opens because interop builds modules with C++ enabled), and Swift's ClangImporter surfaces the C++ value types to Swift as copyable. When the consumer's generated interop code then uses such a type as a Swift value — for a Nitro-based library, the nitrogen-generated `*_cxx.swift` bridging does exactly this — the compiler **synthesizes a copy of the type, instantiating the ill-formed implicit copy constructor**. That is the "ask" that plain C++ never makes; on Xcode 26.3 it hard-errors the entire module import, killing every Swift file in the consumer. (Newer Swift toolchains treat such types as non-copyable instead of failing.)
Before the prebuilt-modules work there was no Swift-visible module containing these headers, so no interop consumer ever imported these types — which is why this surfaces now despite the C++ being unchanged.
We deliberately did **not** fix this by removing headers from the module maps: the guarded-C++-in-modules pattern is shared by ~30 legitimately modular headers and is benign in all but this one shape, and experiments showed the type is reachable through multiple independent module surfaces (removing one member just moved the error to the next path).
### The fix
Declare the truth: make both types explicitly move-only.
```cpp
TraceRecordingState(const TraceRecordingState &) = delete;
TraceRecordingState &operator=(const TraceRecordingState &) = delete;
TraceRecordingState(TraceRecordingState &&) = default;
TraceRecordingState &operator=(TraceRecordingState &&) = default;
```
With the copy constructor explicitly deleted, Swift's importer sees a non-copyable type and imports it as such instead of instantiating a broken copy. It is also simply more correct C++: these types were never copyable in practice, and the explicit deletion turns any future accidental copy into a clear compile error at the call site instead of a template backtrace.
Declaring special members makes `HostTracingProfile` a non-aggregate, so its one designated-initializer construction site (`HostTargetTraceRecording.cpp`) is converted to member-wise assignment.
A sweep of the affected header surface (`std::vector`/`std::map`/`std::deque` of move-only element types) found exactly these two types; a follow-up adds a `headers-verify.js` gate that imports the shipped modules under Swift C++ interop at prebuild time, so the next type with this shape fails RN's own CI instead of community nightlies.
## Changelog:
[IOS] [FIXED] - Fix Swift C++-interop build failure (implicit copy constructor of TraceRecordingState/HostTracingProfile) for libraries using cxx interop with prebuilt React Native core
Pull Request resolved: #57605
Test Plan:
On a fresh RN-nightly app with stock `react-native-unistyles@3.3.0` + `react-native-nitro-modules`, prebuilt core (`RCT_USE_RN_DEP=1 RCT_USE_PREBUILT_RNCORE=1`), Xcode 26.3:
- **Red**: stock headers reproduce the CI failure exactly (`__construct_at` → `TraceRecordingState`). Fixing only `TraceRecordingState` then surfaces the identical failure on `HostTracingProfile` — confirming the shape, not the type, is the bug.
- **Green**: with both headers fixed (stock module maps, nothing else changed): BUILD SUCCEEDED — zero `__construct_at`, zero `shadowNodeFromValue`, zero module errors.
- All RN-internal usages audited: references and moves only; no behavior change. Plain C++/ObjC++ compilation unaffected by construction.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reviewed By: fabriziocucci
Differential Revision: D112802806
Pulled By: cipolleschi
fbshipit-source-id: d2ae201c1fbb4de040f51ebc88263c7347b5979b1 parent 514f104 commit 330080c
12 files changed
Lines changed: 134 additions & 8 deletions
File tree
- packages/react-native/ReactCommon/jsinspector-modern
- tracing
- scripts/cxx-api/api-snapshots
Lines changed: 10 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
74 | 77 | | |
75 | 78 | | |
76 | 79 | | |
| |||
Lines changed: 14 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
26 | 39 | | |
27 | 40 | | |
28 | | - | |
| 41 | + | |
29 | 42 | | |
30 | 43 | | |
31 | 44 | | |
| |||
Lines changed: 11 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
34 | 45 | | |
35 | 46 | | |
36 | 47 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11305 | 11305 | | |
11306 | 11306 | | |
11307 | 11307 | | |
| 11308 | + | |
| 11309 | + | |
| 11310 | + | |
11308 | 11311 | | |
| 11312 | + | |
| 11313 | + | |
11309 | 11314 | | |
11310 | 11315 | | |
11311 | 11316 | | |
11312 | 11317 | | |
| 11318 | + | |
11313 | 11319 | | |
11314 | 11320 | | |
11315 | 11321 | | |
| |||
11402 | 11408 | | |
11403 | 11409 | | |
11404 | 11410 | | |
| 11411 | + | |
11405 | 11412 | | |
| 11413 | + | |
11406 | 11414 | | |
| 11415 | + | |
| 11416 | + | |
11407 | 11417 | | |
11408 | 11418 | | |
11409 | 11419 | | |
11410 | 11420 | | |
| 11421 | + | |
11411 | 11422 | | |
11412 | 11423 | | |
11413 | 11424 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10928 | 10928 | | |
10929 | 10929 | | |
10930 | 10930 | | |
| 10931 | + | |
| 10932 | + | |
| 10933 | + | |
10931 | 10934 | | |
| 10935 | + | |
| 10936 | + | |
10932 | 10937 | | |
10933 | 10938 | | |
10934 | 10939 | | |
10935 | 10940 | | |
| 10941 | + | |
10936 | 10942 | | |
10937 | 10943 | | |
10938 | 10944 | | |
| |||
11025 | 11031 | | |
11026 | 11032 | | |
11027 | 11033 | | |
| 11034 | + | |
11028 | 11035 | | |
| 11036 | + | |
11029 | 11037 | | |
| 11038 | + | |
| 11039 | + | |
11030 | 11040 | | |
11031 | 11041 | | |
11032 | 11042 | | |
11033 | 11043 | | |
| 11044 | + | |
11034 | 11045 | | |
11035 | 11046 | | |
11036 | 11047 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11158 | 11158 | | |
11159 | 11159 | | |
11160 | 11160 | | |
| 11161 | + | |
| 11162 | + | |
| 11163 | + | |
11161 | 11164 | | |
| 11165 | + | |
| 11166 | + | |
11162 | 11167 | | |
11163 | 11168 | | |
11164 | 11169 | | |
11165 | 11170 | | |
| 11171 | + | |
11166 | 11172 | | |
11167 | 11173 | | |
11168 | 11174 | | |
| |||
11255 | 11261 | | |
11256 | 11262 | | |
11257 | 11263 | | |
| 11264 | + | |
11258 | 11265 | | |
| 11266 | + | |
11259 | 11267 | | |
| 11268 | + | |
| 11269 | + | |
11260 | 11270 | | |
11261 | 11271 | | |
11262 | 11272 | | |
11263 | 11273 | | |
| 11274 | + | |
11264 | 11275 | | |
11265 | 11276 | | |
11266 | 11277 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13139 | 13139 | | |
13140 | 13140 | | |
13141 | 13141 | | |
| 13142 | + | |
| 13143 | + | |
| 13144 | + | |
13142 | 13145 | | |
| 13146 | + | |
| 13147 | + | |
13143 | 13148 | | |
13144 | 13149 | | |
13145 | 13150 | | |
13146 | 13151 | | |
| 13152 | + | |
13147 | 13153 | | |
13148 | 13154 | | |
13149 | 13155 | | |
| |||
13236 | 13242 | | |
13237 | 13243 | | |
13238 | 13244 | | |
| 13245 | + | |
13239 | 13246 | | |
| 13247 | + | |
13240 | 13248 | | |
| 13249 | + | |
| 13250 | + | |
13241 | 13251 | | |
13242 | 13252 | | |
13243 | 13253 | | |
13244 | 13254 | | |
| 13255 | + | |
13245 | 13256 | | |
13246 | 13257 | | |
13247 | 13258 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12824 | 12824 | | |
12825 | 12825 | | |
12826 | 12826 | | |
| 12827 | + | |
| 12828 | + | |
| 12829 | + | |
12827 | 12830 | | |
| 12831 | + | |
| 12832 | + | |
12828 | 12833 | | |
12829 | 12834 | | |
12830 | 12835 | | |
12831 | 12836 | | |
| 12837 | + | |
12832 | 12838 | | |
12833 | 12839 | | |
12834 | 12840 | | |
| |||
12921 | 12927 | | |
12922 | 12928 | | |
12923 | 12929 | | |
| 12930 | + | |
12924 | 12931 | | |
| 12932 | + | |
12925 | 12933 | | |
| 12934 | + | |
| 12935 | + | |
12926 | 12936 | | |
12927 | 12937 | | |
12928 | 12938 | | |
12929 | 12939 | | |
| 12940 | + | |
12930 | 12941 | | |
12931 | 12942 | | |
12932 | 12943 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13002 | 13002 | | |
13003 | 13003 | | |
13004 | 13004 | | |
| 13005 | + | |
| 13006 | + | |
| 13007 | + | |
13005 | 13008 | | |
| 13009 | + | |
| 13010 | + | |
13006 | 13011 | | |
13007 | 13012 | | |
13008 | 13013 | | |
13009 | 13014 | | |
| 13015 | + | |
13010 | 13016 | | |
13011 | 13017 | | |
13012 | 13018 | | |
| |||
13099 | 13105 | | |
13100 | 13106 | | |
13101 | 13107 | | |
| 13108 | + | |
13102 | 13109 | | |
| 13110 | + | |
13103 | 13111 | | |
| 13112 | + | |
| 13113 | + | |
13104 | 13114 | | |
13105 | 13115 | | |
13106 | 13116 | | |
13107 | 13117 | | |
| 13118 | + | |
13108 | 13119 | | |
13109 | 13120 | | |
13110 | 13121 | | |
| |||
0 commit comments