Skip to content

Commit 92b8d63

Browse files
committed
[Sema] Always install property wrappers during qualified lookup
Revert the property wrappers part of dd51251. Every part of the qualified lookup stack needs to synthesize property wrapper members, otherwise we'll be subject to the relativistic effects of semantic lookups in different files. Besides, Codable was the main source of cycles and circularity under the old scheme. Resolves rdar://59531889
1 parent 0f0a908 commit 92b8d63

File tree

4 files changed

+67
-40
lines changed

4 files changed

+67
-40
lines changed

lib/AST/NameLookup.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,6 +1534,34 @@ bool DeclContext::lookupQualified(Type type,
15341534
return lookupQualified(nominalTypesToLookInto, member, options, decls);
15351535
}
15361536

1537+
static void installPropertyWrapperMembersIfNeeded(NominalTypeDecl *target,
1538+
DeclNameRef member) {
1539+
auto &Context = target->getASTContext();
1540+
auto baseName = member.getBaseName();
1541+
if (!member.isSimpleName() || baseName.isSpecial())
1542+
return;
1543+
1544+
if ((!baseName.getIdentifier().str().startswith("$") &&
1545+
!baseName.getIdentifier().str().startswith("_")) ||
1546+
baseName.getIdentifier().str().size() <= 1) {
1547+
return;
1548+
}
1549+
1550+
// $- and _-prefixed variables can be generated by properties that have
1551+
// attached property wrappers.
1552+
auto originalPropertyName =
1553+
Context.getIdentifier(baseName.getIdentifier().str().substr(1));
1554+
for (auto member : target->lookupDirect(originalPropertyName)) {
1555+
if (auto var = dyn_cast<VarDecl>(member)) {
1556+
if (var->hasAttachedPropertyWrapper()) {
1557+
auto sourceFile = var->getDeclContext()->getParentSourceFile();
1558+
if (sourceFile && sourceFile->Kind != SourceFileKind::Interface)
1559+
(void)var->getPropertyWrapperBackingProperty();
1560+
}
1561+
}
1562+
}
1563+
}
1564+
15371565
bool DeclContext::lookupQualified(ArrayRef<NominalTypeDecl *> typeDecls,
15381566
DeclNameRef member,
15391567
NLOptions options,
@@ -1584,6 +1612,7 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
15841612

15851613
// Visit all of the nominal types we know about, discovering any others
15861614
// we need along the way.
1615+
auto &ctx = DC->getASTContext();
15871616
bool wantProtocolMembers = (options & NL_ProtocolMembers);
15881617
while (!stack.empty()) {
15891618
auto current = stack.back();
@@ -1592,6 +1621,11 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
15921621
if (tracker)
15931622
tracker->addUsedMember({current, member.getBaseName()},isLookupCascading);
15941623

1624+
// Make sure we've resolved property wrappers, if we need them.
1625+
if (ctx.areSemanticQueriesEnabled()) {
1626+
installPropertyWrapperMembersIfNeeded(current, member);
1627+
}
1628+
15951629
// Look for results within the current nominal type and its extensions.
15961630
bool currentIsProtocol = isa<ProtocolDecl>(current);
15971631
auto flags = OptionSet<NominalTypeDecl::LookupDirectFlags>();

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include "swift/AST/NameLookup.h"
2323
#include "swift/AST/NameLookupRequests.h"
2424
#include "swift/AST/ProtocolConformance.h"
25-
#include "swift/AST/SourceFile.h"
2625
#include "swift/Basic/TopCollection.h"
2726
#include <algorithm>
2827

@@ -230,47 +229,10 @@ convertToUnqualifiedLookupOptions(NameLookupOptions options) {
230229
return newOptions;
231230
}
232231

233-
static void installPropertyWrapperMembersIfNeeded(NominalTypeDecl *target,
234-
DeclName member) {
235-
if (!target) return;
236-
237-
auto &Context = target->getASTContext();
238-
auto baseName = member.getBaseName();
239-
if (!member.isSimpleName() || baseName.isSpecial())
240-
return;
241-
242-
if ((!baseName.getIdentifier().str().startswith("$") &&
243-
!baseName.getIdentifier().str().startswith("_")) ||
244-
baseName.getIdentifier().str().size() <= 1) {
245-
return;
246-
}
247-
248-
// $- and _-prefixed variables can be generated by properties that have
249-
// attached property wrappers.
250-
auto originalPropertyName =
251-
Context.getIdentifier(baseName.getIdentifier().str().substr(1));
252-
for (auto member : target->lookupDirect(originalPropertyName)) {
253-
if (auto var = dyn_cast<VarDecl>(member)) {
254-
if (var->hasAttachedPropertyWrapper()) {
255-
auto sourceFile = var->getDeclContext()->getParentSourceFile();
256-
if (sourceFile && sourceFile->Kind != SourceFileKind::Interface)
257-
(void)var->getPropertyWrapperBackingProperty();
258-
}
259-
}
260-
}
261-
}
262-
263232
LookupResult TypeChecker::lookupUnqualified(DeclContext *dc, DeclNameRef name,
264233
SourceLoc loc,
265234
NameLookupOptions options) {
266235
auto ulOptions = convertToUnqualifiedLookupOptions(options);
267-
268-
// Make sure we've resolved implicit members, if we need them.
269-
if (auto *current = dc->getInnermostTypeContext()) {
270-
installPropertyWrapperMembersIfNeeded(current->getSelfNominalTypeDecl(),
271-
name.getFullName());
272-
}
273-
274236
auto &ctx = dc->getASTContext();
275237
auto descriptor = UnqualifiedLookupDescriptor(name, dc, loc, ulOptions);
276238
auto lookup = evaluateOrDefault(ctx.evaluator,
@@ -365,7 +327,6 @@ LookupResult TypeChecker::lookupMember(DeclContext *dc,
365327
// Make sure we've resolved implicit members, if we need them.
366328
if (auto *current = type->getAnyNominal()) {
367329
current->synthesizeSemanticMembersIfNeeded(name.getFullName());
368-
installPropertyWrapperMembersIfNeeded(current, name.getFullName());
369330
}
370331

371332
LookupResultBuilder builder(result, dc, options);
@@ -445,7 +406,6 @@ LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc,
445406
// Make sure we've resolved implicit members, if we need them.
446407
if (auto *current = type->getAnyNominal()) {
447408
current->synthesizeSemanticMembersIfNeeded(name.getFullName());
448-
installPropertyWrapperMembersIfNeeded(current, name.getFullName());
449409
}
450410

451411
if (!dc->lookupQualified(type, name, subOptions, decls))
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@propertyWrapper
2+
public struct WrapGod<T> {
3+
private var value: T
4+
5+
public init(wrappedValue: T) {
6+
value = wrappedValue
7+
}
8+
9+
public var wrappedValue: T {
10+
get { value }
11+
set { value = newValue }
12+
}
13+
14+
public var projectedValue: T {
15+
get { value }
16+
set { value = newValue }
17+
}
18+
}
19+
20+
class BaseClass {
21+
@WrapGod final var value: Int = 42
22+
init() {}
23+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -verify -O -primary-file %s %S/Inputs/property_wrappers_multi_file_2.swift -c -o %t/use.o
3+
// RUN: %target-swift-frontend %s -verify -O -primary-file %S/Inputs/property_wrappers_multi_file_2.swift %s -c -o %t/def.o
4+
5+
final class Subclass: BaseClass {
6+
override init() {
7+
super.init()
8+
$value = 42
9+
}
10+
}

0 commit comments

Comments
 (0)