Skip to content

Import the embedded Foundation shim in AdvertisementData - #49

Merged
colemancda merged 1 commit into
masterfrom
fix/embedded-foundation-uuid
Jul 21, 2026
Merged

Import the embedded Foundation shim in AdvertisementData#49
colemancda merged 1 commit into
masterfrom
fix/embedded-foundation-uuid

Conversation

@colemancda

Copy link
Copy Markdown
Member

Problem

AdvertisementData.swift decodes the 128-bit service class UUID lists into UUID, but only imports Bluetooth and BluetoothGAP. Under Embedded Swift that leaves the type with no declaring module in scope:

error: struct 'UUID' cannot be used in an embedded function not marked
'@export(interface)' because 'FoundationEmbedded' was not imported by this file

Why CI doesn't catch it

The embedded job builds --target GATT on its own. BluetoothGAP isn't in the graph, so the whole #if canImport(BluetoothGAP) block compiles out and the offending lines are never type-checked.

It only surfaces once something else in the dependency graph pulls BluetoothGAP in — a package building a GATT server, for instance. In that configuration the block is live and the module fails to build (13 errors, all in this file).

Might be worth adding a matrix case that builds a small consumer rather than the target alone, otherwise this class of bug stays invisible.

Fix

Adds the same conditional Foundation import that BluetoothGAP itself uses for the type it hands back — see Sources/BluetoothGAP/GAPCompleteListOf128BitServiceClassUUIDs.swift.

Verification

  • Embedded, in a dependency graph that includes BluetoothGAP: 13 errors → 0
  • swift build --target GATT --swift-sdk swift-6.3.3-RELEASE_wasm-embedded: clean
  • swift build --traits BluetoothGATT: clean
  • swift test: 7/7 passing

The last two matter because adding a Foundation import is exactly the kind of change that can regress a non-embedded build.

The 128-bit service class UUID lists decode into `UUID`, but this file only
imported Bluetooth and BluetoothGAP, so under Embedded Swift the type had no
declaring module in scope:

    struct 'UUID' cannot be used in an embedded function not marked
    '@export(interface)' because 'FoundationEmbedded' was not imported

It goes unnoticed building the target on its own, since BluetoothGAP isn't
present and the `canImport(BluetoothGAP)` block compiles out. It only shows up
once something else in the graph pulls BluetoothGAP in - a GATT server, for
instance - which is how the embedded CI matrix misses it.

Uses the same conditional import BluetoothGAP itself uses for the type it
hands back.
@github-code-quality

Copy link
Copy Markdown

Code Coverage Overview

Languages: Swift

Swift / code-coverage/llvm-cov

The overall coverage in commit 42d4397 in the fix/embedded-foundat... branch remains at 76%, unchanged from commit 6d3db71 in the master branch.

@colemancda
colemancda merged commit 0371b92 into master Jul 21, 2026
39 checks passed
@colemancda
colemancda deleted the fix/embedded-foundation-uuid branch July 21, 2026 20:38
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