Zettelkasten for Programmers: Documenting Confusing with Swift.SendableMetatype
I was reading the SendableMetatype docs because the new NotificationCenter messages I was catching up on use that in the API headers.
I was reading the SendableMetatype docs because the new NotificationCenter messages I was catching up on use that in the API headers.
I learned threee new things when I read Doug Gregor’s “Improving the usability of C libraries in Swift” blog post that may also affect your daily life importing C libraries:
.h files;SWIFT_NAME annotation can be used to make free C functions act like methods on objects;Until today, I was under the impression that you can make C functions sound a little bit nicer and add argument labels with SWIFT_NAME mostly, but this is something on a different level.
One Example to turn a free function into a method:[#20260123webgpu][]
WGPU_EXPORT void wgpuQueueWriteBuffer(
WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size)
WGPU_FUNCTION_ATTRIBUTE SWIFT_NAME("WGPUQueueImpl.writeBuffer(self:buffer:bufferOffset:data:size:)");
That’s what got me interested: object-oriented conventions from C, expressed in Swift’s notation! Where does the type come from? Usually, you just get opaque pointers.
The WGPUQueueImpl typealias is generated as well with a different annotation – that’s now becoming a reference-counting wrapper around WGPUQueue instead of an opaque pointer. The heavy lifting of this is done by a parameterized annotation, SWIFT_SHARED_REFERENCE(increment, decrement), to which you pass function names to increment and decrement the refcount.
The annotation, if you would apply it manually in the header, would look like this:
// Original typedef is:
// typedef struct WGPUQueueImpl* WGPUQueue WGPU_OBJECT_ATTRIBUTE;
typedef struct
SWIFT_SHARED_REFERENCE(wgpuGroupAddRef, wgpuGroupRelease)
WGPUQueueImpl* WGPUQueue WGPU_OBJECT_ATTRIBUTE;
… making the generated Swift interface:
// Original generated typealias would've been:
// public typealias WGPUGroup = OpaquePointer
public class WGPUGroupImpl { }
public typealias WGPUGroup = WGPUGroupImpl
Now the secret ingredient to make this bearable is to not copy the header files, but to use a YAML “sidecar” file to instruct clang to generate a different API. Combining the generated type declaration and the method example from above:
- Name: WGPUGroupImpl
SwiftImportAs: reference
SwiftReleaseOp: wgpuGroupRelease
SwiftRetainOp: wgpuGroupAddRef
- Name: wgpuQueueWriteBuffer
SwiftName: WGPUQueueImpl.writeBuffer(self:buffer:bufferOffset:data:size:)
clang supports API notes in a YAML file to annotate .h files without having to change the .h files themselves for module imports. That’s so neat: with that you can wrap C libraries in Swift without having to maintain a copy of the headers.
Clang will search for API notes files next to module maps only when passed the
-fapinotes-modulesoption.
Next to methods, properties also work with SWIFT_NAME annotations:
- Name: wgpuQuerySetGetCount
SwiftName: getter:WGPUQuerySetImpl.count(self:)
- Name: wgpuQuerySetGetType
SwiftName: getter:WGPUQuerySetImpl.type(self:)
Depending on the C API, this can be a game-changer in terms of Swift language ergonomics for you and your team. No more manual refcounting (which, if limited to e.g. a function scope, isn’t that bad thanks to defer, but can get hairy when you need to escape and keep references alive for longer), proper Swift types instead of opaque pointers, and methods and properties on these types instead of namespaced free functions. Lovely.
Xcode 26 introduced a bug where for some people, me included, Metal shaders won’t compile because the Metal toolchain won’t be managed by Xcode properly, no matter how often you reinstall the toolchain. Some fixes include moving the toolchain into a folder Xcode can see without having to mount anything. Others replace the ExportMetadata.plist exposed version.
I can fix this by mounting the Metal toolchain’s disk image manually. That sucks, but doesn’t break on every update of Xcode or Metal and doesn’t require any fiddling with the files or finding out the expected version string.
So that I don’t forget to do this after rebooting, I wrote a Launch Service that does this after reboot, when /Volumes/ changes, and every 5min for good measure :)
The code: https://codeberg.org/ctietze/metal-toolchain-launchd-automount
If you’re not comfortable fiddling with Launch Services/launchd, the repo includes basic shell scripts to install/uninstall the service for you.
My Xcode 26.2 still suffers from an inability to compile Metal shader files because it can’t find the Metal toolchain: error: cannot execute tool ‘metal’ due to missing Metal Toolchain; use: xcodebuild -downloadComponent MetalToolchain That command also doesn’t do anything to fix this for me. But I did have success mounting the .dmg file with the toolchain manually.
Welcome to 2026, and a new year of Emacs Blog Carnival post! To start the Gregorian calendar year fresh, the blogging/writing/thinking prompt of this month is: This year, I’ll … What will you do differently in Emacs this year? Or will you just get started? Why? What are you excited about to explore and tinker with? What do you want to perfect?

Happy 2026! Let’s start the year with something fun. The internet shortly became the place of love and joy and sharing that I remember it for: a volunteer who found all (?) Urban Sketching groups in Germany, official and unofficial, reached out to me to send social media links and contact details he found so I include them on the spartan overview page I maintained.