Skip to content

Stop qualifying wallet calls with the app module name - #1296

Merged
zancas merged 2 commits into
devfrom
ios_drop_module_qualifier
Aug 23, 2026
Merged

Stop qualifying wallet calls with the app module name#1296
zancas merged 2 commits into
devfrom
ios_drop_module_qualifier

Conversation

@zancas

@zancas zancas commented Aug 22, 2026

Copy link
Copy Markdown
Member

Stacked on #1295. Review that one first; this branch contains its two commits.

The failure

ios-integration-test / build-for-testing fails:

ios/RPCModule.swift:678:15: error: cannot find 'Zingo' in scope
** TEST BUILD FAILED **

Four sites, at lines 678, 689, 698, and 707.

Why

RPCModule.swift is compiled into the ZingoTests target as well as the app target. project.pbxproj lists it in the ZingoTests Sources phase beside zingo.swift, zingo_nym_proxy_ffi.swift, and NymTransportModule.swift. Inside that target the module is named ZingoTests, so Zingo resolves to nothing and the qualifier fails.

Those four are the only qualified calls in the file. Every other call into the generated binding is unqualified, try initNew(...) and its like, because zingo.swift is compiled into whichever target needs it, putting its functions in the current module. This drops the qualifier and follows the file's own style.

Why this is safe

Each free function differs from the instance method beside it in its argument labels: attachMixnet(socks5Addr:exitNode:) against attachMixnet(_:exitNode:resolve:reject:), disableMixnet() against disableMixnet(_:reject:), and so on. Swift also requires an explicit self for an instance member inside an escaping closure, so a wrong resolution would be a compile error rather than a silent call to the wrong function.

How this went unseen

The iOS lane reads skipping on #1276 and on #1293, because fail-all reaped it while the Android integration buckets were red. #1295 turns those buckets green, which lets the lane run again. That is why this is stacked there rather than opened against dev: on dev the buckets are still red and the lane would be reaped before it could prove the fix.

Verification

None locally. There is no macOS here, so this rests entirely on the iOS lane in this pull request's own run. If the lane still fails, the next thing to look at is whether RPCModule.swift belongs in the ZingoTests target at all.

🤖 Generated with Claude Code

The iOS test build fails with "cannot find 'Zingo' in scope" at four sites in
RPCModule.swift. The file is compiled into the ZingoTests target as well as the
app, and inside ZingoTests the module is named ZingoTests, so the Zingo
qualifier resolves to nothing.

The four calls are the only ones in the file that qualify. Every other call into
the generated binding is unqualified, `try initNew(...)` and its like, because
zingo.swift is compiled into whichever target needs it and its functions are
therefore in the current module. Dropping the qualifier follows the file's own
style and compiles in both targets.

There is no ambiguity to fear. Each free function differs from the instance
method beside it in its argument labels, and Swift requires an explicit self for
an instance member inside an escaping closure, so a wrong resolution would be a
compile error rather than a silent call to the wrong function.

The lane that catches this only runs when the Android integration buckets are
green, which is why the break went unseen since it landed: fail-all reaped the
iOS job on every red run.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Base automatically changed from send_tests_learn_mixnet_rule to dev August 22, 2026 03:34
Dropping the module qualifier traded one error for its mirror. RPCModule.swift
is compiled into both the Zingo and ZingoTests targets, so a qualified call
must name two modules at once: Zingo. fails in ZingoTests, and unqualified
fails in Zingo, where the class's own methods shadow the globals.

The collision goes instead. The four bridge methods gain a Bridge suffix, so
nothing shadows setBroadcastCandidates, attachMixnet, enableMixnet, or
disableMixnet, and the unqualified calls resolve to the generated globals in
either target. Their @objc selectors are untouched, and those are what
RPCModuleBridge.m binds, so JavaScript sees no change.

The arrangement that made this possible is ZIN-69.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@zancas
zancas merged commit eb4ad35 into dev Aug 23, 2026
45 of 62 checks passed
@zancas
zancas deleted the ios_drop_module_qualifier branch August 23, 2026 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant