Skip to content

JNI: preserve synchronous actor witnesses with standard constraints - #14

Merged
teamhimeh merged 1 commit into
qoncept-forkfrom
codex/fix-actor-property-standard-constraints
Oct 23, 2026
Merged

teamhimeh merged 1 commit into
qoncept-forkfrom
codex/fix-actor-property-standard-constraints

Conversation

@teamhimeh

@teamhimeh teamhimeh commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

JNI extraction treats an immutable actor property as asynchronous when its protocol inherits AnyObject or Sendable, including their Swift.-qualified spellings. These standard constraints introduce no actor isolation, but are absent from SwiftExtract's built-in Swift symbol table, so the synchronous protocol-witness check rejects them.

For example:

public protocol Identified: AnyObject, Sendable {
  var identifier: Int64 { get }
}

public actor Record: Identified {
  public let identifier: Int64

  public init(identifier: Int64) {
    self.identifier = identifier
  }
}

Previously, the generated actor getter returned CompletableFuture<Long>. With this change, Java callers can read the synchronous witness directly:

try (var arena = SwiftArena.ofConfined()) {
    Record record = Record.init(42, arena);
    long identifier = record.getIdentifier(); // 42
}

The Swift thunk continues to read (record as any Identified).identifier, preserving synchronous access across module boundaries.

Changes

  • Recognize AnyObject, Swift.AnyObject, Sendable, and Swift.Sendable as nonisolating standard constraints during actor-property witness discovery.
  • Apply this exception only when lookup is unresolved or resolves to the Swift module. Locally declared protocols named Sendable retain their actual isolation checks.
  • Cover each spelling, combined and inherited constraints, and an actor-isolated local Sendable in extraction regressions. Check both synchronous Java signatures and protocol-based Swift downcalls in generator regressions.
  • Add a JNI sample actor whose protocol inherits both constraints and a Java runtime test that reads its getter as a long.

Validation

  • Confirmed the positive extraction and generator regressions fail before the fix and pass afterward; the local Sendable isolation regression passes before and after.
  • swift test --disable-experimental-prebuilts --disable-sandbox --jobs 4: full Swift test suite passed. One existing test requiring Android API 34/35 platform data was skipped.
  • ./gradlew :Samples:SwiftJavaExtractJNISampleApp:test --no-daemon: all 296 Java tests passed with no failures or skips, including the new synchronous actor getter test.
  • Compiled a separate two-module Swift 6 example: the protocol-witness read succeeds, while direct synchronous access to the actor's stored property fails with the expected isolation diagnostic. All five standard-constraint spellings used by the regressions also typecheck in Swift 6.
  • swift-format lint --strict on changed Swift files and git diff --check passed.

Tested with Apple Swift 6.4 and JetBrains Runtime 25.0.2 on macOS.

Dependency

This follows #4. The base branch already contains actor-property witness discovery and protocol-based thunk dispatch; this diff extends the handling of inherited standard constraints.

Treat the standard AnyObject and Sendable constraints as nonisolating during actor-property witness discovery, without bypassing isolation on locally declared protocols with the same name. Add extraction, generator, and JNI runtime regressions for synchronous getters.
@teamhimeh
teamhimeh force-pushed the codex/fix-actor-property-standard-constraints branch from e5d844f to b0b577d Compare October 23, 2026 08:49
teamhimeh added a commit that referenced this pull request Oct 23, 2026
…cies

docs: extend upstream PR dependency map through origin #14
@teamhimeh
teamhimeh merged commit d5ec3fd into qoncept-fork Oct 23, 2026
32 of 42 checks passed
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