Skip to content

Commit 4ad0b12

Browse files
authored
Merge pull request #67884 from hborla/5.9.0-extension-macro-availability
[5.9.0][Macros] Always consider pre-macro-expansion conformances as subsumed by other conformance entry kinds, before considering availability.
2 parents 0b85f99 + df11fde commit 4ad0b12

File tree

3 files changed

+43
-14
lines changed

3 files changed

+43
-14
lines changed

lib/AST/ConformanceLookupTable.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -565,20 +565,6 @@ ConformanceLookupTable::Ordering ConformanceLookupTable::compareConformances(
565565
ConformanceEntry *lhs,
566566
ConformanceEntry *rhs,
567567
bool &diagnoseSuperseded) {
568-
// If only one of the conformances is unconditionally available on the
569-
// current deployment target, pick that one.
570-
//
571-
// FIXME: Conformance lookup should really depend on source location for
572-
// this to be 100% correct.
573-
// FIXME: When a class and an extension with the same availability declare the
574-
// same conformance, this silently takes the class and drops the extension.
575-
if (lhs->getDeclContext()->isAlwaysAvailableConformanceContext() !=
576-
rhs->getDeclContext()->isAlwaysAvailableConformanceContext()) {
577-
return (lhs->getDeclContext()->isAlwaysAvailableConformanceContext()
578-
? Ordering::Before
579-
: Ordering::After);
580-
}
581-
582568
ConformanceEntryKind lhsKind = lhs->getRankingKind();
583569
ConformanceEntryKind rhsKind = rhs->getRankingKind();
584570

@@ -596,6 +582,20 @@ ConformanceLookupTable::Ordering ConformanceLookupTable::compareConformances(
596582
}
597583
}
598584

585+
// If only one of the conformances is unconditionally available on the
586+
// current deployment target, pick that one.
587+
//
588+
// FIXME: Conformance lookup should really depend on source location for
589+
// this to be 100% correct.
590+
// FIXME: When a class and an extension with the same availability declare the
591+
// same conformance, this silently takes the class and drops the extension.
592+
if (lhs->getDeclContext()->isAlwaysAvailableConformanceContext() !=
593+
rhs->getDeclContext()->isAlwaysAvailableConformanceContext()) {
594+
return (lhs->getDeclContext()->isAlwaysAvailableConformanceContext()
595+
? Ordering::Before
596+
: Ordering::After);
597+
}
598+
599599
// If one entry is fixed and the other is not, we have our answer.
600600
if (lhs->isFixed() != rhs->isFixed()) {
601601
auto isReplaceableOrMarker = [](ConformanceEntry *entry) -> bool {

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,6 +1461,26 @@ public struct AlwaysAddConformance: ExtensionMacro {
14611461
}
14621462
}
14631463

1464+
public struct ConditionallyAvailableConformance: ExtensionMacro {
1465+
public static func expansion(
1466+
of node: AttributeSyntax,
1467+
attachedTo decl: some DeclGroupSyntax,
1468+
providingExtensionsOf type: some TypeSyntaxProtocol,
1469+
conformingTo protocols: [TypeSyntax],
1470+
in context: some MacroExpansionContext
1471+
) throws -> [ExtensionDeclSyntax] {
1472+
let decl: DeclSyntax =
1473+
"""
1474+
@available(macOS 99, *)
1475+
extension \(raw: type.trimmedDescription): Equatable {}
1476+
"""
1477+
1478+
return [
1479+
decl.cast(ExtensionDeclSyntax.self)
1480+
]
1481+
}
1482+
}
1483+
14641484
public struct AlwaysAddCodable: ExtensionMacro {
14651485
public static func expansion(
14661486
of node: AttributeSyntax,

test/Macros/macro_expand_extensions.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,12 @@ struct TestUndocumentedEncodable {}
156156
// CHECK-DIAGS: error: conformance to 'Codable' (aka 'Decodable & Encodable') is not covered by macro 'UndocumentedEncodable'
157157

158158
#endif
159+
160+
@attached(extension, conformances: Equatable)
161+
macro AvailableEquatable() = #externalMacro(module: "MacroDefinition", type: "ConditionallyAvailableConformance")
162+
163+
@available(macOS 99, *)
164+
@AvailableEquatable
165+
struct TestAvailability {
166+
static let x : any Equatable.Type = TestAvailability.self
167+
}

0 commit comments

Comments
 (0)