-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Open
Labels
bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.A deviation from expected or documented behavior. Also: expected but undesirable behavior.triage neededThis issue needs more specific labelsThis issue needs more specific labels
Description
Description
When I use the attached
macro to declare an arbitrary name, and the decorated type implements Equatable
with my own implementation of the ==
method, sometimes my implemented ==
method is not called, and instead, the compiler-generated ==
is used. However, if I write it as extension TheType: Equatable
, this issue does not occur. Please see the attached package(zip file) or the reproduction code.
Reproduction
/// xxx
///
/// @AddArbitrary
/// struct Person {
/// let name: String
/// let age: Int
/// }
///
@attached(member, names: arbitrary)
public macro AddArbitrary() = #externalMacro(module: "TestArbitraryMacros", type: "AddArbitraryMacro")
// if I remove arbitrary, it will call custom `==`
//@attached(member, names: named(anyName))
//public macro AddArbitrary() = #externalMacro(module: "TestArbitraryMacros", type: "AddArbitraryMacro")
import SwiftCompilerPlugin
import SwiftSyntax
import SwiftSyntaxBuilder
import SwiftSyntaxMacros
public struct AddArbitraryMacro: MemberMacro {
public static func expansion(
of node: AttributeSyntax,
providingMembersOf declaration: some DeclGroupSyntax,
conformingTo protocols: [TypeSyntax],
in context: some MacroExpansionContext
) throws -> [DeclSyntax] {
guard declaration.is(StructDeclSyntax.self) || declaration.is(ClassDeclSyntax.self) else {
throw MacroExpansionErrorMessage("@AddArbitrary 只能应用于 class 或 struct")
}
let arbitraryMethod: DeclSyntax = """
static func anyName() {
print(111)
}
"""
return [arbitraryMethod]
}
}
struct MacroExpansionErrorMessage: Error, CustomStringConvertible {
let description: String
init(_ description: String) {
self.description = description
}
}
@main
struct TestArbitraryPlugin: CompilerPlugin {
let providingMacros: [Macro.Type] = [
AddArbitraryMacro.self,
]
}
import TestArbitrary
// If I conform to the Equatable protocol through an extension, there will be no issues.
// extension Person: Equatable {}
// called custom ==
@AddArbitrary
struct Person: Equatable {
let name: String
let age: Int
static func == (lhs: Person, rhs: Person) -> Bool {
print("called custom ==")
return lhs.name == rhs.name
}
}
Person.anyName()
let p1 = Person(name: "123", age: 12)
let p2 = Person(name: "123", age: 34)
print(p1 == p2)
// true
// called custom ==
var persons = [p1]
for element in [p2] {
if !persons.contains(element) {
persons.append(element)
}
}
print(persons)
// [TestArbitraryClient.Person(name: "123", age: 12), TestArbitraryClient.Person(name: "123", age: 34)]
// NOT call custom ==
Expected behavior
When I implement ==
myself, the self - implemented ==
will always be called instead of the one generated by the compiler. Don't be affected by arbitrary
.
Environment
Swift 6.2
Additional information
No response
Metadata
Metadata
Assignees
Labels
bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.A deviation from expected or documented behavior. Also: expected but undesirable behavior.triage neededThis issue needs more specific labelsThis issue needs more specific labels