Skip to content

MistDemoApp fails to build: NoteEditView/RecordDetailView have no accessible initializers (Swift 6.3) #419

Description

@leogdion

Summary

The MistDemoApp target in Examples/MistDemo fails to compile. This is pre-existing on v1.0.0-beta.3 (not introduced by any in-flight feature branch) and reproduces on every branch based on it. It surfaced with the Swift 6.3.2 toolchain; it may not appear on older toolchains, which is likely why CI hasn't flagged it.

MistDemoApp is a separate SwiftPM product from MistDemoKit, so MistDemoKit/MistDemoTests still build and test fine. But a plain swift build / swift test from Examples/MistDemo builds the whole package graph and therefore fails on MistDemoApp.

Environment

  • Apple Swift 6.3.2 (swift-6.3.2-RELEASE), target arm64-apple-macosx28.0 (macOS 26/Darwin 27)
  • Examples/MistDemo package, target MistDemoApp

Errors (clean build of the MistDemoApp target)

Sources/MistDemoApp/Views/QueryView.swift:52:9:  error: 'RecordDetailView' cannot be constructed because it has no accessible initializers
Sources/MistDemoApp/Views/QueryView.swift:69:9:  error: 'NoteEditView' cannot be constructed because it has no accessible initializers
Sources/MistDemoApp/Views/QueryView.swift:69:29: error: cannot infer contextual base in reference to member 'create'
Sources/MistDemoApp/Views/RecordDetailView.swift:78:9:  error: 'NoteEditView' cannot be constructed because it has no accessible initializers
Sources/MistDemoApp/Views/RecordDetailView.swift:78:29: error: cannot infer contextual base in reference to member 'edit'

The cannot infer contextual base in reference to member 'create'/'edit' errors are cascades: because NoteEditView(...) can't be constructed, the compiler can't infer the Mode type for the .create / .edit(note) argument.

Root cause

Both views declare non-private stored properties and @State private var stored properties:

Views/NoteEditView.swift

internal struct NoteEditView: View {
  internal enum Mode { case create; case edit(Note) }
  internal let mode: Mode
  internal let onSaved: (Note) -> Void
  @Environment(CloudKitStore.self) private var service
  @State private var title: String = ""
  @State private var indexText: String = "0"
  // …several more @State private var…
}

Views/RecordDetailView.swift

internal struct RecordDetailView: View {
  @State internal var note: Note
  internal let onChange: () -> Void
  @State private var showEditSheet = false
  // …several more @State private var…
}

Swift derives the access level of the synthesized memberwise initializer from the most restrictive stored property. The @State private var members drop the synthesized init to private, so it is only visible within the same file. NoteEditView is constructed from QueryView.swift and RecordDetailView.swift, and RecordDetailView from QueryView.swift — different files — hence "no accessible initializers". (This is consistent with the repo's explicit-ACL policy: these views should be declaring their inits explicitly.)

Call sites for reference:

  • QueryView.swift:52 RecordDetailView(note: note, onChange: { … })
  • QueryView.swift:69 NoteEditView(mode: .create) { _ in … }
  • RecordDetailView.swift:78 NoteEditView(mode: .edit(note)) { updated in … }

Proposed fix

Add an explicit internal init to each view exposing only the non-@State inputs (the @State vars keep their in-line defaults). Mirror the existing pattern in Views/CompositionDisclosure.swift:75.

NoteEditView (plain let properties → direct assignment):

internal init(mode: Mode, onSaved: @escaping (Note) -> Void) {
  self.mode = mode
  self.onSaved = onSaved
}

RecordDetailView (note is @State → initialize the backing store):

internal init(note: Note, onChange: @escaping () -> Void) {
  self._note = State(initialValue: note)
  self.onChange = onChange
}

Check the other MistDemoApp views for the same pattern (any internal/public view with @State private var members that is constructed from another file) and give them explicit inits too.

Reproduce

cd Examples/MistDemo
swift package clean
swift build --target MistDemoApp   # fails with the errors above

Verify the fix

cd Examples/MistDemo
swift build            # whole package, including MistDemoApp
swift build --target MistDemoApp
swift test             # should now build & run without removing the App target

Notes

  • Not caused by the current feature branches — git diff origin/v1.0.0-beta.3 <branch> -- Examples/MistDemo/Sources/MistDemoApp/ is empty for refactor/cyclomatic-complexity-encoding, fix/fieldvalue-timestamp, and feature/openapi-request-options.
  • Because this blocks a full swift test, unrelated MistDemo test work has been verified by building MistDemoKit/MistDemoTests directly (they don't depend on MistDemoApp).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions