Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 21, 2025

Fix CI build failures caused by incorrect @mainactor annotations and macOS platform compatibility issues.

Changes Completed ✅

  • Remove @MainActor from all protocol conformance extension declarations
  • Add nonisolated to all protocol requirement implementations
  • Mark string, text, attributedString, multiplyString, and multiplyText properties as nonisolated
  • Add macOS platform compatibility fixes
  • Fix macOS availability attributes and NSColor property names
  • Code review completed
  • Apply feedback from code review

Summary

Actor Isolation Fixes

Fixed actor isolation issues in ValueView.swift:

  1. Removed invalid @MainActor annotations from protocol conformance extensions (RawRepresentable, LosslessStringConvertible, CustomStringConvertible, ExpressibleByStringLiteral, ExpressibleByBooleanLiteral, ExpressibleByIntegerLiteral, ExpressibleByFloatLiteral)
  2. Marked protocol requirement implementations as nonisolated
  3. Marked helper properties (string, text, attributedString, multiplyString, multiplyText) as nonisolated to prevent "main actor-isolated property cannot be referenced from a nonisolated context" errors

These properties are safe to mark as nonisolated because ValueView is a Sendable enum with only value-type associated values.

macOS Platform Compatibility

Added cross-platform support to enable macOS builds:

LabeledValueView.swift:

  • Added platform-specific imports (UIKit for iOS/Catalyst, AppKit for macOS)
  • Guarded iOS-only APIs (hoverEffect, contextMenuPreview) with conditional compilation
  • Added platform-specific background colors (systemBackground for iOS, windowBackgroundColor for macOS)
  • Implemented platform-specific pasteboard handling (UIPasteboard for iOS, NSPasteboard for macOS)

AttributedString+String.swift:

  • Added platform-specific imports and PlatformColor typealias (UIColor/NSColor)
  • Added two foregroundColor overloads: one for PlatformColor and one for SwiftUI Color
  • Enables proper color handling across iOS and macOS platforms

ValueView.swift:

  • Replaced UIKit-specific color tokens (.secondaryLabel) with SwiftUI cross-platform colors (.secondary)

InlineArray+sugar.swift:

  • Added macOS 26.0 to all @available attributes alongside iOS 26.0 for InlineArray extensions and InlineArrayCollection struct
  • Ensures proper availability declarations for generic value parameters and InlineArray APIs

Color+values.swift:

  • Added proper @available attributes for macOS versions to NSColor-based properties
  • Fixed NSColor property names to match actual AppKit API:
    • .link.linkColor (macOS 10.10+)
    • .placeholderText.placeholderTextColor (macOS 10.10+)
    • .separator.separatorColor (macOS 10.14+)
    • .opaqueSeparator.opaqueSeparatorColor (macOS 10.14+)
    • Added availability guards for systemFill variants (macOS 10.15+)
  • Fixed color mappings: lightTextColor.white, darkTextColor.black

Security Summary

No security vulnerabilities were found or introduced by these changes.

Original prompt

Problem: The CI build is failing due to errors in Sources/QizhKit/UI/Debug/ValueView.swift where protocol conformances are declared with @mainactor in the conformance list (e.g., extension ValueView: @MainActor RawRepresentable) and their protocol-required initializers/properties are actor-isolated. This causes compiler errors: "unknown attribute 'MainActor'" and "main actor-isolated initializer/property cannot be used to satisfy nonisolated requirement from protocol". There is also a Swift compiler assertion crash during compilation.

Goal: Modify ValueView.swift to remove incorrect @MainActor annotations on the extensions and make protocol requirement implementations nonisolated so they satisfy nonisolated protocol requirements while keeping the core enum @MainActor isolation where appropriate.

Changes to make:

  1. Update the following extensions by removing @MainActor from the conformance declaration and marking protocol requirement implementations as nonisolated:

    • extension ValueView: RawRepresentable
      • add nonisolated to init?(rawValue: String) and var rawValue: String
    • extension ValueView: LosslessStringConvertible
      • add nonisolated to init?(_ description: String)
    • extension ValueView: CustomStringConvertible
      • add nonisolated to var description: String
    • extension ValueView: ExpressibleByStringLiteral
      • add nonisolated to init(stringLiteral:)
    • extension ValueView: ExpressibleByBooleanLiteral
      • add nonisolated to init(booleanLiteral:)
    • extension ValueView: ExpressibleByIntegerLiteral
      • add nonisolated to init(integerLiteral:)
    • extension ValueView: ExpressibleByFloatLiteral
      • add nonisolated to init(floatLiteral:)
  2. Keep the enum declaration @MainActor public enum ValueView: View, Sendable as-is to preserve main-actor isolation for the type's UI-related members.

  3. Ensure modifiers such as @inlinable and public remain on these members.

File to modify:

  • Sources/QizhKit/UI/Debug/ValueView.swift (ref: 6cea7b9)

Provide the updated file content with the described changes.

Example patch (showing the intended edits):

--- a/Sources/QizhKit/UI/Debug/ValueView.swift
+++ b/Sources/QizhKit/UI/Debug/ValueView.swift
@@
-extension ValueView: @mainactor RawRepresentable {

  • @inlinable public init?(rawValue: String) {
  •    self = .string(rawValue)
    
  • }
  • @inlinable public var rawValue: String {
  •    string
    
  • }
    -}
    +extension ValueView: RawRepresentable {
  • @inlinable public nonisolated init?(rawValue: String) {
  •    self = .string(rawValue)
    
  • }
  • @inlinable public nonisolated var rawValue: String {
  •    string
    
  • }
    +}
    @@
    -extension ValueView: @mainactor LosslessStringConvertible {
  • public init?(_ description: String) {
  •    self = .string(description)
    
  • }
    -}
    +extension ValueView: LosslessStringConvertible {
  • public nonisolated init?(_ description: String) {
  •    self = .string(description)
    
  • }
    +}
    @@
    -extension ValueView: @mainactor CustomStringConvertible {
  • public var description: String {
  •    string
    
  • }
    -}
    +extension ValueView: CustomStringConvertible {
  • public nonisolated var description: String {
  •    string
    
  • }
    +}
    @@
    -extension ValueView: @mainactor ExpressibleByStringLiteral {
  • public init(stringLiteral value: String) {
  •    self = .string(value)
    
  • }
    -}
    +extension ValueView: ExpressibleByStringLiteral {
  • public nonisolated init(stringLiteral value: String) {
  •    self = .string(value)
    
  • }
    +}
    @@
    -extension ValueView: @mainactor ExpressibleByBooleanLiteral {
  • public init(booleanLiteral value: Bool) {
  •    self = .bool(value)
    
  • }
    -}
    +extension ValueView: ExpressibleByBooleanLiteral {
  • public nonisolated init(booleanLiteral value: Bool) {
  •    self = .bool(value)
    
  • }
    +}
    @@
    -extension ValueView: @mainactor ExpressibleByIntegerLiteral {
  • public init(integerLiteral value: Int) {
  •    self = .integer(value)
    
  • }
    -}
    +extension ValueView: ExpressibleByIntegerLiteral {
  • public nonisolated init(integerLiteral value: Int) {
  •    self = .integer(value)
    
  • }
    +}
    @@
    -extension ValueView: @mainactor ExpressibleByFloatLiteral {
  • public init(floatLiteral value: Double) {
  •    self = .floatingPoint(value)
    
  • }
    -}
    +extension ValueView: ExpressibleByFloatLiteral {
  • public nonisolated init(floatLiteral value: Double) {
  •    self = .floatingPoint(value)
    
  • }
    +}

Please create a pull request with these changes on repository qizh/QizhKit. The ref for the current failing run is 6cea7b9. Do not modify other files.

This pull request was created as a result of the following prompt from Copilot chat.

Problem: The CI build is failing due to errors in Sources/QizhKit/UI/Debug/ValueView.swift where protocol conformances are declared with @mainactor in the conformance list (e.g., extension ValueView: @MainActor RawRepresentable) and their protocol-required initializers/properties are actor-isolated. This causes compiler errors: "unknown attribute 'MainActor'" and "main actor-isolated initializer/property cannot be used to satisfy nonisolated requirement from protocol". There is also a Swift compiler assertion crash during compilation.

Goal: Modify ValueView.swift to remove incorrect @MainActor annotations on the extensions and make protocol requirement implementations nonisolated so they satisfy nonisolated protocol requirements while keeping the core enum @MainActor isolation where appropriate.

Changes to make:

  1. Update the following extensions by removing @MainActor from the conformance declaration and marking protocol requirement implementations as nonisolated:

    • extension ValueView: RawRepresentable
      • add nonisolated to init?(rawValue: String) and var rawValue: String
    • extension ValueView: LosslessStringConvertible
      • add nonisolated to init?(_ description: String)
    • extension ValueView: CustomStringConvertible
      • add nonisolated to var description: String
    • extension ValueView: ExpressibleByStringLiteral
      • add nonisolated to init(stringLiteral:)
    • extension ValueView: ExpressibleByBooleanLiteral
      • add nonisolated to init(booleanLiteral:)
    • extension ValueView: ExpressibleByIntegerLiteral
      • add nonisolated to init(integerLiteral:)
    • extension ValueView: ExpressibleByFloatLiteral
      • add nonisolated to init(floatLiteral:)
  2. Keep the enum declaration @MainActor public enum ValueView: View, Sendable as-is to preserve main-actor isolation for the type's UI-related members.

  3. Ensure modifiers such as @inlinable and public remain on these members.

File to modify:

  • Sources/QizhKit/UI/Debug/ValueView.swift (ref: 6cea7b9)

Provide the updated file content with the described changes.

Example patch (showing the intended edits):

--- a/Sources/QizhKit/UI/Debug/ValueView.swift
+++ b/Sources/QizhKit/UI/Debug/ValueView.swift
@@
-extension ValueView: @mainactor RawRepresentable {

  • @inlinable public init?(rawValue: String) {
  •    self = .string(rawValue)
    
  • }
  • @inlinable public var rawValue: String {
  •    string
    
  • }
    -}
    +extension ValueView: RawRepresentable {
  • @inlinable public nonisolated init?(rawValue: String) {
  •    self = .string(rawValue)
    
  • }
  • @inlinable public nonisolated var rawValue: String {
  •    string
    
  • }
    +}
    @@
    -extension ValueView: @mainactor LosslessStringConvertible {
  • public init?(_ description: String) {
  •    self = .string(description)
    
  • }
    -}
    +extension ValueView: LosslessStringConvertible {
  • public nonisolated init?(_ description: String) {
  •    self = .string(description)
    
  • }
    +}
    @@
    -extension ValueView: @mainactor CustomStringConvertible {
  • public var description: String {
  •    string
    
  • }
    -}
    +extension ValueView: CustomStringConvertible {
  • public nonisolated var description: String {
  •    string
    
  • }
    +}
    @@
    -extension ValueView: @mainactor ExpressibleByStringLiteral {
  • public init(stringLiteral value: String) {
  •    self = .string(value)
    
  • }
    -}
    +extension ValueView: ExpressibleByStringLiteral {
  • public nonisolated init(stringLiteral value: String) {
  •    self = .string(value)
    
  • }
    +}
    @@
    -extension ValueView: @mainactor ExpressibleByBooleanLiteral {
  • public init(booleanLiteral value: Bool) {
  •    self = .bool(value)
    
  • }
    -}
    +extension ValueView: ExpressibleByBooleanLiteral {
  • public nonisolated init(booleanLiteral value: Bool) {
  •    self = .bool(value)
    
  • }
    +}
    @@
    -extension ValueView: @mainactor ExpressibleByIntegerLiteral {
  • public init(integerLiteral value: Int) {
  •    self = .integer(value)
    
  • }
    -}
    +extension ValueView: ExpressibleByIntegerLiteral {
  • public nonisolated init(integerLiteral value: Int) {
  •    self = .integer(value)
    
  • }
    +}
    @@
    -extension ValueView: @mainactor ExpressibleByFloatLiteral {
  • public init(floatLiteral value: Double) {
  •    self = .floatingPoint(value)
    
  • }
    -}
    +extension ValueView: ExpressibleByFloatLiteral {
  • public nonisolated init(floatLiteral value: Double) {
  •    self = .floatingPoint(value)
    
  • }
    +}

Please create a pull request with these changes on repository qizh/QizhKit. The ref for the current failing run is 6cea7b9. Do not modify other files.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Fix CI build errors in ValueView.swift related to MainActor Fix invalid @MainActor syntax in ValueView protocol conformances Nov 21, 2025
Copilot AI requested a review from qizh November 21, 2025 19:59
Copy link
Owner

@qizh qizh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope it won't break anything

@qizh qizh marked this pull request as ready for review November 21, 2025 20:01
Copilot AI review requested due to automatic review settings November 21, 2025 20:01
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes invalid Swift 6 syntax by removing @MainActor from protocol conformance declarations and marking protocol requirement implementations as nonisolated. The original syntax extension ValueView: @MainActor ProtocolName is invalid in Swift 6.

Key Changes

  • Removed @MainActor from 7 protocol conformance extension declarations (RawRepresentable, LosslessStringConvertible, CustomStringConvertible, ExpressibleByStringLiteral, ExpressibleByBooleanLiteral, ExpressibleByIntegerLiteral, ExpressibleByFloatLiteral)
  • Added nonisolated keyword to all protocol requirement implementations to satisfy nonisolated protocol requirements
  • Preserved @inlinable and public modifiers on affected members

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@qizh
Copy link
Owner

qizh commented Nov 21, 2025

@codex apply your suggestions. Make sure CI can build the code you've changed with no errors.

@chatgpt-codex-connector
Copy link

Summary

Testing

  • ⚠️ swift test (fails on Linux because the SwiftUI module is unavailable)

View task →

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Copy link
Owner

@qizh qizh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks okay, but should be tested

@qizh
Copy link
Owner

qizh commented Nov 21, 2025

@copilot

  1. Sources/QizhKit/UI/Debug/LabeledValueView.swift
  • Add platform imports and guard iOS-only APIs (hoverEffect / contextMenuPreview / UIPasteboard). Replace systemBackground usage.

Replace or update the file parts as follows (showing the changed sections):

At the top (imports):

#if os(iOS) || targetEnvironment(macCatalyst)
import UIKit
#elseif os(macOS)
import AppKit
#endif
import SwiftUI

Where you apply contentShape / hoverEffect / fixedHeight, replace with platform-guarded modifiers:

    #if os(iOS) || targetEnvironment(macCatalyst)
    .contentShape([.contextMenuPreview, .hoverEffect, .interaction, .dragPreview], shape)
    .hoverEffect(.highlight)
    #else
    // contextMenuPreview & hoverEffect are iOS-only APIs
    .contentShape([.interaction, .dragPreview], shape)
    #endif
    .fixedHeight()

Where you set the background using .systemBackground, change to platform-aware Color:

    #if os(iOS) || targetEnvironment(macCatalyst)
    .background(Color(.systemBackground), in: shape)
    #elseif os(macOS)
    .background(Color(NSColor.windowBackgroundColor), in: shape)
    #endif

Where you set the pasteboard in the copy button action:

    #if os(iOS) || targetEnvironment(macCatalyst)
    UIPasteboard.general.string = valueView.string
    #elseif os(macOS)
    let pasteboard = NSPasteboard.general
    pasteboard.clearContents()
    pasteboard.setString(valueView.string, forType: .string)
    #endif
  1. Sources/QizhKit/Extensions/AttributedString+/AttributedString+String.swift
  • Add platform imports, PlatformColor alias, and two overloads for foregroundColor so callers can use UIColor/NSColor or SwiftUI.Color.

Replace the file content (or at least the header and extension) with modifications like:

#if os(iOS) || targetEnvironment(macCatalyst)
import UIKit
public typealias PlatformColor = UIColor
#elseif os(macOS)
import AppKit
public typealias PlatformColor = NSColor
#endif
import SwiftUI

extension AttributedString {
    @inlinable public func foregroundColor(_ color: PlatformColor) -> AttributedString {
        transformingAttributes(\.foregroundColor) { foregroundColor in
            // Convert platform color into SwiftUI Color
            foregroundColor.value = Color(color)
        }
    }

    @inlinable public func foregroundColor(_ color: Color) -> AttributedString {
        transformingAttributes(\.foregroundColor) { foregroundColor in
            foregroundColor.value = color
        }
    }
}

Notes:

  • Color(platformColor) resolves to the platform initializer (Color(UIColor) on iOS, Color(NSColor) on macOS). If your Swift toolchain does not expose that initializer name in that form, change the conversion to use the explicit initializers: Color(uiColor:) or Color(nsColor:) in platform-specific blocks.
  1. Sources/QizhKit/UI/Debug/ValueView.swift
  • Replace usage of UIKit color tokens (e.g. .secondaryLabel) with SwiftUI Color (.secondary), and use the new AttributedString.foregroundColor(Color) overload.

Replace instances like:

String.comaspace.asAttributedString().foregroundColor(.secondaryLabel)

with:

String.comaspace.asAttributedString().foregroundColor(.secondary)

Search and replace other UIKit-specific names:

  • .secondaryLabel -> .secondary
  • .systemBackground (when used as ShapeStyle) -> use Color(.systemBackground) on iOS and Color(NSColor.windowBackgroundColor) on macOS as shown above.

Testing and notes

  • After applying the edits, run the macOS build locally:
    • swift build (or use xcodebuild / xcode-select with the macOS SDK)
    • Or in Xcode select the macOS target and build
  • Also build the iOS target (or run CI) to make sure iOS paths still compile.

Example git workflow to apply these changes and open a PR:

  • git checkout -b fix/macos-platform-apis
  • Edit the three files with the patches above
  • git add Sources/QizhKit/UI/Debug/LabeledValueView.swift
    Sources/QizhKit/Extensions/AttributedString+/AttributedString+String.swift
    Sources/QizhKit/UI/Debug/ValueView.swift
  • git commit -m "Fix macOS build: guard iOS-only APIs, use AppKit pasteboard/colors, add AttributedString color overloads"
  • git push origin fix/macos-platform-apis
  • Open a PR against main. In PR description include:
    • "Fixes macOS compilation errors from CI job 56083356410 (ref 941b8bf). Replaces iOS-only APIs (hoverEffect, contextMenuPreview, UIPasteboard), uses NSColor/AppKit where appropriate, and introduces AttributedString foregroundColor overloads."

Copy link
Contributor Author

Copilot AI commented Nov 21, 2025

@copilot

  1. Sources/QizhKit/UI/Debug/LabeledValueView.swift
    ...

Working on the macOS platform compatibility fixes now. Will add platform guards for iOS-only APIs and update color handling.

Copilot AI changed the title Fix invalid @MainActor syntax in ValueView protocol conformances Fix invalid @MainActor syntax and add macOS platform compatibility Nov 21, 2025
Copilot AI requested a review from qizh November 21, 2025 20:37
Copy link
Owner

@qizh qizh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks okay, hopefully would work

@qizh
Copy link
Owner

qizh commented Nov 22, 2025

The Swift build job is failing due to two main reasons:

1. Usage of APIs only available in macOS 26/iOS 26 or newer

Several structs, methods, and subscripts in Sources/QizhKit/Extensions/Collection+/InlineArray+sugar.swift use features (like generic value parameters and InlineArray) that require macOS 26/iOS 26 or newer. The recommended fix is to:

  • Add appropriate @available attributes to all affected structs, methods, initializers, and subscripts.
  • If code must run on earlier OS versions, use if #available(..., *) { ... } checks and provide alternatives when needed.

Example Fix:

@available(macOS 26.0, iOS 26.0, *)
public struct InlineArrayCollection<let N: Int, Element>: RandomAccessCollection {
    // ... your code ...
    @available(macOS 26.0, iOS 26.0, *)
    public subscript(pos: Int) -> Element {
        base[pos]
    }
    // ...
}

If you cannot support earlier OS versions, it's sufficient to annotate everything involved with @available(macOS 26.0, iOS 26.0, *).

2. 'NSColor' has no member errors in Color+values.swift

Several properties like .link, .placeholderText, .separator, etc. are not available on all platforms/OS versions. To fix this:

  • Gate these properties using if #available checks and/or #if os(macOS)/#if os(iOS) platform checks so they're only defined when available.
  • You may need to conditionalize the entire block or provide fallback implementations.

Example Fix:

#if os(macOS)
import AppKit

@available(macOS 10.15, *)
static let link = Color(nsColor: NSColor.link)
// Repeat for other colors, using appropriate @available and platform guards
#endif

Or, for each missing property:

#if os(macOS)
@available(macOS 10.15, *)
static let separator = Color(nsColor: NSColor.separator)
#endif

If these properties are not available on macOS, you'll need to remove or conditionally define them.


Solution Summary

  1. Annotate relevant code with correct @available attributes in InlineArray+sugar.swift.
  2. Add platform and availability checks for color definitions in Color+values.swift.

Copy link
Contributor Author

Copilot AI commented Nov 22, 2025

The Swift build job is failing due to two main reasons:

1. Usage of APIs only available in macOS 26/iOS 26 or newer

...

Fixed in commits dcff037, 6294bd9, and eeaea5e.

InlineArray+sugar.swift: Added macOS 26.0 to all availability attributes and removed redundant subscript annotation.

Color+values.swift: Added proper availability guards and fixed NSColor property names:

  • .link.linkColor (macOS 10.10+)
  • .placeholderText.placeholderTextColor (macOS 10.10+)
  • .separator.separatorColor (macOS 10.14+)
  • .opaqueSeparator.opaqueSeparatorColor (macOS 10.14+)
  • systemFill variants (macOS 10.15+)
  • lightTextColor.white, darkTextColor.black

All availability and NSColor member errors should now be resolved.

Copilot AI requested a review from qizh November 22, 2025 09:47
@qizh qizh added postponed Will review or work on this later duplicate A copy of something labels Nov 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

duplicate A copy of something postponed Will review or work on this later

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants