Skip to content

Commit b7a53f9

Browse files
committed
[Macros] Handle the case where an extension macro conformance has a null
type repr because it was deserialized.
1 parent b03d8df commit b7a53f9

File tree

5 files changed

+39
-2
lines changed

5 files changed

+39
-2
lines changed

lib/Sema/TypeCheckMacros.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,6 +1714,10 @@ ResolveExtensionMacroConformances::evaluate(Evaluator &evaluator,
17141714

17151715
typeExpr->setType(MetatypeType::get(resolved));
17161716
protocols.push_back(resolved);
1717+
} else {
1718+
// If there's no type repr, we already have a resolved instance
1719+
// type, e.g. because the type expr was deserialized.
1720+
protocols.push_back(typeExpr->getInstanceType());
17171721
}
17181722
}
17191723

test/Macros/Inputs/macro_library.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public struct ObservationRegistrar<Subject: Observable> {
2828
names: named(_registrar), named(addObserver), named(removeObserver), named(withTransaction), named(Storage), named(_storage)
2929
)
3030
@attached(memberAttribute)
31+
@attached(extension, conformances: Observable)
3132
public macro Observable() = #externalMacro(module: "MacroDefinition", type: "ObservableMacro")
3233

3334
@attached(accessor)

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,30 @@ public struct ObservableMacro: MemberMacro, MemberAttributeMacro {
11951195

11961196
}
11971197

1198+
extension ObservableMacro: ExtensionMacro {
1199+
public static func expansion(
1200+
of node: AttributeSyntax,
1201+
attachedTo decl: some DeclGroupSyntax,
1202+
providingExtensionsOf type: some TypeSyntaxProtocol,
1203+
conformingTo protocols: [TypeSyntax],
1204+
in context: some MacroExpansionContext
1205+
) throws -> [ExtensionDeclSyntax] {
1206+
if (protocols.isEmpty) {
1207+
return []
1208+
}
1209+
1210+
let decl: DeclSyntax =
1211+
"""
1212+
extension \(raw: type.trimmedDescription): Observable {
1213+
}
1214+
"""
1215+
1216+
return [
1217+
decl.cast(ExtensionDeclSyntax.self)
1218+
]
1219+
}
1220+
}
1221+
11981222
public struct ObservablePropertyMacro: AccessorMacro {
11991223
public static func expansion(
12001224
of node: AttributeSyntax,

test/Macros/macro_expand_peers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -disable-availability-checking -DTEST_DIAGNOSTICS
1010

1111
// Check with the imported macro library vs. the local declaration of the macro.
12-
// RUN: %target-swift-frontend -swift-version 5 -emit-module -o %t/macro_library.swiftmodule %S/Inputs/macro_library.swift -module-name macro_library -load-plugin-library %t/%target-library-name(MacroDefinition)
12+
// RUN: %target-swift-frontend -enable-experimental-feature ExtensionMacros -swift-version 5 -emit-module -o %t/macro_library.swiftmodule %S/Inputs/macro_library.swift -module-name macro_library -load-plugin-library %t/%target-library-name(MacroDefinition)
1313

1414
// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -disable-availability-checking -DIMPORT_MACRO_LIBRARY -I %t -DTEST_DIAGNOSTICS
1515

test/Macros/macro_expand_primary.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// RUN: %empty-directory(%t)
44
// RUN: %empty-directory(%t-scratch)
55
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath
6-
// RUN: %target-swift-frontend -swift-version 5 -emit-module -o %t/macro_library.swiftmodule %S/Inputs/macro_library.swift -module-name macro_library -load-plugin-library %t/%target-library-name(MacroDefinition)
6+
// RUN: %target-swift-frontend -enable-experimental-feature ExtensionMacros -swift-version 5 -emit-module -o %t/macro_library.swiftmodule %S/Inputs/macro_library.swift -module-name macro_library -load-plugin-library %t/%target-library-name(MacroDefinition)
77
// RUN: %target-swift-frontend -swift-version 5 -typecheck -I%t -verify -primary-file %s %S/Inputs/macro_expand_other.swift -verify-ignore-unknown -load-plugin-library %t/%target-library-name(MacroDefinition) -dump-macro-expansions > %t/expansions-dump.txt 2>&1
88
// RUN: %FileCheck -check-prefix=CHECK-DUMP %s < %t/expansions-dump.txt
99

@@ -86,6 +86,14 @@ func test() {
8686
observeDog()
8787
}
8888

89+
@Observable
90+
class Person {
91+
init() {}
92+
}
93+
94+
// CHECK-DUMP: extension Person: Observable {
95+
// CHECK-DUMP: }
96+
8997

9098
@freestanding(declaration, names: named(Foo)) macro useIdentifier(_ value: String) = #externalMacro(module: "MacroDefinition", type: "UseIdentifierMacro")
9199

0 commit comments

Comments
 (0)