Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 5, 2025

Problem

SwiftSnapshot was failing to render:

  1. Generic Collection types like IdentifiedArray<Tagged<Attendee, UUID>, Attendee>
  2. Integer type variants like UInt64, Int64, Int32, etc.

This caused errors when used with projects like pointfreeco/syncups:

Failed to render value: Unsupported type: IdentifiedArray<Tagged<Attendee, UUID>, Attendee> 
at path: _syncUp → attendees
Failed to render value: Unsupported type: UInt64 at path: _syncUp → duration → _low

The issues occurred because:

  • Generic collections that don't cast to [Any] fell through to the reflection fallback, which couldn't properly handle them
  • Only Int was handled as a primitive type, leaving other integer variants unsupported

Solution

1. Generic Collection Support

Added Collection protocol detection in ValueRenderer to handle any type conforming to the Collection protocol. The renderer now:

  1. Detects Collection protocol conformance after checking specific types (Array, Dictionary, Set, Foundation types)
  2. Extracts all elements from the collection
  3. Renders each element recursively using existing rendering logic
  4. Wraps the result with the full type name including generic parameters

2. All Integer Type Variants

Added support for all Swift integer types: Int8, Int16, Int32, Int64, UInt, UInt8, UInt16, UInt32, UInt64

Examples

Generic Collection:

struct IdentifiedArray<ID: Hashable, Element>: Collection {
    // ... Collection implementation
}

let attendees = IdentifiedArray<Int, Person>([
    Person(id: 1, name: "Alice"),
    Person(id: 2, name: "Bob")
])

try SwiftSnapshotRuntime.export(instance: attendees, variableName: "team")

Generated code:

extension IdentifiedArray<Int, Person> {
    static let team: IdentifiedArray<Int, Person> = 
        IdentifiedArray<Int, Person>([
            Person(id: 1, name: "Alice"),
            Person(id: 2, name: "Bob")
        ])
}

Integer Types:

let duration: UInt64 = 18446744073709551615
// Generated: extension UInt64 { static let duration: UInt64 = UInt64(18_446_744_073_709_551_615) }

Changes

Core Implementation

  • ValueRenderer.swift:
    • Added renderCollection() method with full documentation
    • Added rendering methods for all integer type variants (Int8, Int16, Int32, Int64, UInt, UInt8, UInt16, UInt32, UInt64)
    • Collection check positioned after Foundation types to prevent conflicts with Data (which also conforms to Collection)
    • Updated rendering priority documentation

Tests

  • GenericCollectionTests.swift (new): 8 comprehensive tests covering:

    • Simple generic collections
    • Collections with complex nested types
    • Empty collections
    • Multiple type parameters
    • Regression tests for Array/Dictionary/Set
  • IntegerTypesTests.swift (new): 13 comprehensive tests covering:

    • All signed integer types (Int8, Int16, Int32, Int64)
    • All unsigned integer types (UInt, UInt8, UInt16, UInt32, UInt64)
    • Structs with mixed integer types
    • Arrays of specific integer types
    • Edge cases (negative numbers, zero, max values)
  • SwiftSnapshotTests.swift: Added inline verification test

Rendering Priority (Updated)

  1. Custom renderers (SnapshotRendererRegistry)
  2. Primitives (String, all integer types, Double, Float, Bool, Character)
  3. Optional handling
  4. Specific collections (Array, Dictionary, Set)
  5. Foundation types (Date, UUID, URL, Data, Decimal)
  6. Generic Collection types ← NEW
  7. Reflection fallback

Test Results

  • ✅ All 185 tests pass (172 existing + 8 generic collection + 13 integer type tests)
  • ✅ Verified with exact type from issue: IdentifiedArray<Tagged<Attendee, UUID>, Attendee>
  • ✅ UInt64 and all integer variants now supported

Backward Compatibility

This change is fully backward compatible:

  • No breaking changes to existing APIs
  • All existing Collection types (Array, Dictionary, Set, Data) continue to use their specialized renderers
  • New capabilities are purely additive

Fixes the reported issues with IdentifiedArray and integer types in the syncups project and enables SwiftSnapshot to work with any custom Collection type and all Swift integer variants.

Original prompt

I’m, trying it in side this project https://github.com/pointfreeco/syncups

And I have this issue
🟣 SwiftSnapshotCore/SwiftSnapshotRuntime.swift:247: Failed to render value: Unsupported type: IdentifiedArray<Tagged<Attendee, UUID>, Attendee> at path: _syncUp → attendees
🟣 SyncUps/SyncUpForm.swift:58: The operation couldn’t be completed. (SwiftSnapshotCore.SwiftSnapshotError error 0.)
Can you add support for generic types ?


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: mackoj <661647+mackoj@users.noreply.github.com>
Copilot AI changed the title I’m, trying it in side this project https://github.com/pointfreeco/syncups And I have this issue 🟣 SwiftSnapshotCore/SwiftSnapshotRuntime.swift:247: Failed to render value: Unsupported type: IdentifiedArray<Tagged<Attendee, UUID>, Attendee> at path: ... Add support for generic Collection types (IdentifiedArray and custom collections) Oct 5, 2025
Copilot AI requested a review from mackoj October 5, 2025 08:43
@mackoj
Copy link
Owner

mackoj commented Oct 5, 2025

@copilot it's almost passing just missing the support for

🟣 SwiftSnapshotCore/SwiftSnapshotRuntime.swift:247: Failed to render value: Unsupported type: UInt64 at path: _syncUp → duration → _low
🟣 SyncUps/SyncUpForm.swift:58: The operation couldn’t be completed. (SwiftSnapshotCore.SwiftSnapshotError error 0.)

…Int8, UInt16, UInt32, UInt64)

Co-authored-by: mackoj <661647+mackoj@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Oct 5, 2025

@copilot it's almost passing just missing the support for

🟣 SwiftSnapshotCore/SwiftSnapshotRuntime.swift:247: Failed to render value: Unsupported type: UInt64 at path: _syncUp → duration �...

Added support for all integer types including UInt64. The issue was that only Int was handled as a primitive type. Now all integer variants (Int8, Int16, Int32, Int64, UInt, UInt8, UInt16, UInt32, UInt64) are properly rendered.

Changes in commit 0f5c8e4:

  • Added 9 new rendering methods for integer types
  • Added 13 comprehensive tests
  • All 185 tests now pass

This should fix the UInt64 error you were seeing in the Duration's _low property.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • ocsp.apple.com
    • Triggering command: /usr/share/swift/usr/bin/swift-build (dns block)
    • Triggering command: /usr/share/swift/usr/bin/swift-test --filter IntegerTypesTests (dns block)
    • Triggering command: /usr/share/swift/usr/bin/swift-build --target SwiftSnapshotTests (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Add support for generic Collection types (IdentifiedArray and custom collections) Add support for generic Collection types and all integer type variants Oct 5, 2025
@mackoj mackoj marked this pull request as ready for review October 5, 2025 16:52
@mackoj mackoj merged commit bfef692 into main Oct 5, 2025
@mackoj mackoj deleted the copilot/fix-88cd3009-3814-4b90-8984-c1c1e88fb637 branch October 5, 2025 16:53
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.

2 participants