Hey all,
I’m kinda trying to see if this is a real bug (feels like one), or am I “Holding it wrong” before I send a FB.
Small isolated repro example here:
But here are the main portions of it:
public protocol Storable {
static var tableName: String { get }
}
public protocol MyModel: Storable {}
extension Storable {
public static func deleteOne(key: String) -> Bool { true }
}
I have a protocol with a static deleteOne(key:) method on it.
Then, I have a macro which conforms a type to this protocol, like so:
@attached(extension, conformances: MyModel)
public macro Model() = #externalMacro(module: "MacroBugMacros", type: "ModelMacro")
public struct ModelMacro: ExtensionMacro {
public static func expansion(
of node: AttributeSyntax,
attachedTo declaration: some DeclGroupSyntax,
providingExtensionsOf type: some TypeSyntaxProtocol,
conformingTo protocols: [TypeSyntax],
in context: some MacroExpansionContext
) throws -> [ExtensionDeclSyntax] {
let ext: DeclSyntax = "extension \(type.trimmed): MyModel {}"
guard let extDecl = ext.as(ExtensionDeclSyntax.self) else { return [] }
return [extDecl]
}
}
When I attach the macro to a file, it doesn’t seem to see the static function. But If I attach the protocol “by hand”, it works correctly.
// File: NewFile.swift
@Model
struct Item: Sendable {
static let tableName = "items"
let slug: String
}
// File: main.swift
_ = Item.deleteOne(key: "item-1")
// ❌ error: referencing static method 'deleteOne(key:)' on 'Storable'
// requires that 'Item' conform to 'Storable'
// Workaround
// Declare conformance directly on the struct instead of via the macro extension:
// @Model
// struct Item: MyModel, Sendable { ... } // ✅ works
I believe @stephencelis & @mbrandonw had a similar bug in TCA Macros IIRC but might be wrong.
If anyone has any ideas I’d love to hear
Thanks!