Hi!
I've been excited to use macros in Swift and started by looking at the examples repo. I used @MyOptionSet
as a baseline because it adds conformance to a protocol and @CustomCodable
to learn how to find properties decorated with another macro.
With this information I created CustomHashable/CustomHashable.swift at main · JosephDuffy/CustomHashable · GitHub. Running swift test -Xswiftc -Xfrontend -Xswiftc -dump-macro-expansions
shows it outputting the generated code I would expect:
@__swiftmacro_19CustomHashableTests0aB26StructWithExcludedProperty0aB0fMm_.swift
------------------------------
func hash(into hasher: inout Hasher) {
hasher.combine(firstProperty)
hasher.combine(secondProperty)
}
static func ==(lhs: CustomHashableStructWithExcludedProperty, rhs: CustomHashableStructWithExcludedProperty) -> Bool {
lhs.firstProperty == rhs.firstProperty
&& lhs.secondProperty == rhs.secondProperty
}
------------------------------
However when I run a test to ensure the excluded property is not included it fails, seemingly because Swift is using the synthesised implementation of Hashable
.
If I add a non-hashable property or try to use this macro with a class it fails to compile, so it doesn't seem to be picking up these functions when checking if the type conforms to the protocol.
If the explicit conformance is removed and the type is moved to another module the tests don't compile with the error: global function 'XCTAssertEqual(_:_:_:file:line:)' requires that 'CustomHashableStructWithMultipleProperties' conform to 'Equatable' XCTAssertEqual(value1, value1)
.
Updating the macro to add a different functions (e.g. static func isEqual
) and calling that directly does work, so the new functions are being added to the type.
Is this something that's expected to work? Or maybe there's something silly I've overlooked. I've tried this with swift-DEVELOPMENT-SNAPSHOT-2023-04-27-a
and swift-DEVELOPMENT-SNAPSHOT-2023-04-25-a
with the same results.