Skip to content

Commit 6c18ffb

Browse files
authored
Merge pull request #67882 from hborla/extension-macro-availability
[Macros] Always consider pre-macro-expansion conformances as subsumed by other conformance entry kinds, before considering availability.
2 parents 33eedc1 + 309e340 commit 6c18ffb

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
@@ -568,20 +568,6 @@ ConformanceLookupTable::Ordering ConformanceLookupTable::compareConformances(
568568
ConformanceEntry *lhs,
569569
ConformanceEntry *rhs,
570570
bool &diagnoseSuperseded) {
571-
// If only one of the conformances is unconditionally available on the
572-
// current deployment target, pick that one.
573-
//
574-
// FIXME: Conformance lookup should really depend on source location for
575-
// this to be 100% correct.
576-
// FIXME: When a class and an extension with the same availability declare the
577-
// same conformance, this silently takes the class and drops the extension.
578-
if (lhs->getDeclContext()->isAlwaysAvailableConformanceContext() !=
579-
rhs->getDeclContext()->isAlwaysAvailableConformanceContext()) {
580-
return (lhs->getDeclContext()->isAlwaysAvailableConformanceContext()
581-
? Ordering::Before
582-
: Ordering::After);
583-
}
584-
585571
ConformanceEntryKind lhsKind = lhs->getRankingKind();
586572
ConformanceEntryKind rhsKind = rhs->getRankingKind();
587573

@@ -599,6 +585,20 @@ ConformanceLookupTable::Ordering ConformanceLookupTable::compareConformances(
599585
}
600586
}
601587

588+
// If only one of the conformances is unconditionally available on the
589+
// current deployment target, pick that one.
590+
//
591+
// FIXME: Conformance lookup should really depend on source location for
592+
// this to be 100% correct.
593+
// FIXME: When a class and an extension with the same availability declare the
594+
// same conformance, this silently takes the class and drops the extension.
595+
if (lhs->getDeclContext()->isAlwaysAvailableConformanceContext() !=
596+
rhs->getDeclContext()->isAlwaysAvailableConformanceContext()) {
597+
return (lhs->getDeclContext()->isAlwaysAvailableConformanceContext()
598+
? Ordering::Before
599+
: Ordering::After);
600+
}
601+
602602
// If one entry is fixed and the other is not, we have our answer.
603603
if (lhs->isFixed() != rhs->isFixed()) {
604604
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
@@ -1423,6 +1423,26 @@ public struct AlwaysAddConformance: ExtensionMacro {
14231423
}
14241424
}
14251425

1426+
public struct ConditionallyAvailableConformance: ExtensionMacro {
1427+
public static func expansion(
1428+
of node: AttributeSyntax,
1429+
attachedTo decl: some DeclGroupSyntax,
1430+
providingExtensionsOf type: some TypeSyntaxProtocol,
1431+
conformingTo protocols: [TypeSyntax],
1432+
in context: some MacroExpansionContext
1433+
) throws -> [ExtensionDeclSyntax] {
1434+
let decl: DeclSyntax =
1435+
"""
1436+
@available(macOS 99, *)
1437+
extension \(raw: type.trimmedDescription): Equatable {}
1438+
"""
1439+
1440+
return [
1441+
decl.cast(ExtensionDeclSyntax.self)
1442+
]
1443+
}
1444+
}
1445+
14261446
public struct AlwaysAddCodable: ExtensionMacro {
14271447
public static func expansion(
14281448
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)