Skip to content

Commit 00c6741

Browse files
authored
Merge pull request #65509 from DougGregor/stored-property-aux-decls
Walk auxiliary declarations when gathering stored properties
2 parents 38f2e6c + aff9751 commit 00c6741

File tree

3 files changed

+77
-12
lines changed

3 files changed

+77
-12
lines changed

lib/Sema/TypeCheckStorage.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,23 @@ static void computeLoweredStoredProperties(NominalTypeDecl *decl,
169169
static void enumerateStoredPropertiesAndMissing(
170170
NominalTypeDecl *decl,
171171
IterableDeclContext *implDecl,
172-
llvm::function_ref<void(VarDecl *)> addStoredProperty,
172+
llvm::function_ref<void(VarDecl *)> _addStoredProperty,
173173
llvm::function_ref<void(MissingMemberDecl *)> addMissing) {
174+
// Add a variable as a stored properties.
175+
llvm::SmallSet<VarDecl *, 8> knownStoredProperties;
176+
auto addStoredProperty = [&](VarDecl *var) {
177+
if (!var->isStatic() && var->hasStorage()) {
178+
if (knownStoredProperties.insert(var).second)
179+
_addStoredProperty(var);
180+
}
181+
};
182+
174183
// If we have a distributed actor, find the id and actorSystem
175184
// properties. We always want them first, and in a specific
176185
// order.
177-
VarDecl *distributedActorId = nullptr;
178-
VarDecl *distributedActorSystem = nullptr;
179186
if (decl->isDistributedActor()) {
187+
VarDecl *distributedActorId = nullptr;
188+
VarDecl *distributedActorSystem = nullptr;
180189
ASTContext &ctx = decl->getASTContext();
181190
for (auto *member : implDecl->getMembers()) {
182191
if (auto *var = dyn_cast<VarDecl>(member)) {
@@ -201,17 +210,14 @@ static void enumerateStoredPropertiesAndMissing(
201210

202211
for (auto *member : implDecl->getMembers()) {
203212
if (auto *var = dyn_cast<VarDecl>(member)) {
204-
if (!var->isStatic() && var->hasStorage()) {
205-
// Skip any properties that we already emitted explicitly
206-
if (var == distributedActorId)
207-
continue;
208-
if (var == distributedActorSystem)
209-
continue;
210-
211-
addStoredProperty(var);
212-
}
213+
addStoredProperty(var);
213214
}
214215

216+
member->visitAuxiliaryDecls([&](Decl *auxDecl) {
217+
if (auto auxVar = dyn_cast<VarDecl>(auxDecl))
218+
addStoredProperty(auxVar);
219+
});
220+
215221
if (auto missing = dyn_cast<MissingMemberDecl>(member))
216222
if (missing->getNumberOfFieldOffsetVectorEntries() > 0)
217223
addMissing(missing);

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,29 @@ extension PropertyWrapperMacro: AccessorMacro, Macro {
406406
}
407407
}
408408

409+
extension PropertyWrapperMacro: PeerMacro {
410+
public static func expansion(
411+
of node: AttributeSyntax,
412+
providingPeersOf declaration: some DeclSyntaxProtocol,
413+
in context: some MacroExpansionContext
414+
) throws -> [DeclSyntax] {
415+
guard let varDecl = declaration.as(VariableDeclSyntax.self),
416+
let binding = varDecl.bindings.first,
417+
let identifier = binding.pattern.as(IdentifierPatternSyntax.self)?.identifier,
418+
binding.accessor == nil,
419+
let type = binding.typeAnnotation?.type
420+
else {
421+
return []
422+
}
423+
424+
return [
425+
"""
426+
var _\(raw: identifier.trimmedDescription): MyWrapperThingy<\(type)>
427+
"""
428+
]
429+
}
430+
}
431+
409432
public struct WrapAllProperties: MemberAttributeMacro {
410433
public static func expansion(
411434
of node: AttributeSyntax,

test/Macros/macro_expand_peers.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ struct Main {
128128
}
129129
print(result2)
130130
// CHECK-EXEC: hahaha global
131+
132+
// CHECK-EXEC: MyWrapperThingy<Swift.Int>(storage: 5)
133+
print(S3(x: 5))
131134
}
132135
}
133136

@@ -156,3 +159,36 @@ struct S2 {
156159
}
157160
#endif
158161
}
162+
163+
// Stored properties generated by a peer macro
164+
@attached(accessor)
165+
@attached(peer, names: prefixed(_))
166+
macro myPropertyWrapper() =
167+
#externalMacro(module: "MacroDefinition", type: "PropertyWrapperMacro")
168+
169+
struct Date { }
170+
171+
struct MyWrapperThingy<T> {
172+
var storage: T
173+
174+
var wrappedValue: T {
175+
get {
176+
print("Getting value \(storage)")
177+
return storage
178+
}
179+
180+
set {
181+
print("Setting value \(newValue)")
182+
storage = newValue
183+
}
184+
}
185+
}
186+
187+
struct S3 {
188+
@myPropertyWrapper
189+
var x: Int = 0
190+
191+
init(x: Int) {
192+
self._x = MyWrapperThingy(storage: x)
193+
}
194+
}

0 commit comments

Comments
 (0)