[swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance
Brent Royal-Gordon
brent at architechies.com
Thu Aug 10 17:29:28 CDT 2017
> On Aug 10, 2017, at 3:40 AM, Haravikk via swift-evolution <swift-evolution at swift.org> wrote:
>
> This is not the same as a default protocol implementation
Actually, I could easily imagine that a future version of Swift with macro support might do this with a default protocol implementation:
extension Equatable {
#generated static func == (lhs: Self, rhs: Self) -> Bool {
switch self {
case let self as Struct:
let propertyPairs = properties.map { property in
guard let property = property as? Property<Generated.Equatable> else {
throw SynthesisError.invalidType(property, expected: Generated.Equatable.self)
}
return DependentExpressionPair<Generated.Equatable, SameType>(
original: Expression { lhs.#property },
dependent: Expression { rhs.#property }
)
}
return FunctionBlock { return #equated(propertyPairs) }
case let self as Enum:
guard !all.isEmpty else {
throw SynthesisError.invalid(self, message: "is an empty enum")
}
let cases: SwitchBody<(Generated.Self, Generated.Self)> = all.map { aCase in
let valueCaptures = aCase.associatedValues.map { value in
guard let value = value as? AssociatedValue<Generated.Equatable> else {
throw SynthesisError.invalidType(value, expected: Generated.Equatable.self)
}
return DependentExpressionPair<Generated.Equatable, SameType>(
original: Variable(type: value.type),
dependent: Variable(type: value.type)
)
}
return SwitchBody {
case let (
#aCase.pattern(capturingInto: valueCaptures.map(\.original)),
#aCase.pattern(capturingInto: valueCaptures.map(\.dependent))
):
return #equated(valueCaptures)
}
}.joined()
return FunctionBlock { switch (lhs, rhs) { #cases } }
default:
throw SynthesisError.invalid(self, message: "is not a struct or enum")
}
}
}
private #func equated(_ exprPairs: [DependentExpressionPair<Generated.Equatable, SameType>]) -> Expression<Generated.Bool> {
return exprPairs.map { pair in
Expression { #pair.original == #pair.dependent }
}
.reduce(Expression { true }) { earlier, this in
Expression { #earlier && #this }
}
}
If the only difference were whether the default implementation was generated by a macro or not, would you still think auto-derivation should be marked with a keyword?
--
Brent Royal-Gordon
Architechies
More information about the swift-evolution
mailing list