Skip to content

Commit 9cda374

Browse files
authored
Merge pull request #19259 from DougGregor/validate-without-accessors
[Type checker] Move accessor creation out of validateDecl().
2 parents d72cbbc + 56cfd84 commit 9cda374

File tree

5 files changed

+40
-4
lines changed

5 files changed

+40
-4
lines changed

lib/Sema/CSApply.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
//===----------------------------------------------------------------------===//
1818

1919
#include "ConstraintSystem.h"
20+
#include "CodeSynthesis.h"
2021
#include "CSDiagnostics.h"
2122
#include "MiscDiagnostics.h"
2223
#include "TypeCheckProtocol.h"
@@ -4112,6 +4113,7 @@ namespace {
41124113
method = func;
41134114
} else if (auto var = dyn_cast<VarDecl>(foundDecl)) {
41144115
// Properties.
4116+
maybeAddAccessorsToStorage(tc, var);
41154117

41164118
// If this isn't a property on a type, complain.
41174119
if (!var->getDeclContext()->isTypeContext()) {

lib/Sema/CodeSynthesis.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1786,6 +1786,7 @@ static bool wouldBeCircularSynthesis(AbstractStorageDecl *storage,
17861786
void swift::triggerAccessorSynthesis(TypeChecker &TC,
17871787
AbstractStorageDecl *storage) {
17881788
auto VD = dyn_cast<VarDecl>(storage);
1789+
maybeAddAccessorsToStorage(TC, storage);
17891790

17901791
// Synthesize accessors for lazy, all checking already been performed.
17911792
bool lazy = false;

lib/Sema/TypeCheckDecl.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,7 +1496,7 @@ static void checkVarBehavior(VarDecl *decl, TypeChecker &TC) {
14961496
// No behavior, no problems.
14971497
if (!decl->hasBehavior())
14981498
return;
1499-
1499+
15001500
// Don't try to check the behavior if we already encountered an error.
15011501
if (decl->getType()->hasError())
15021502
return;
@@ -2262,9 +2262,6 @@ static void validateAbstractStorageDecl(TypeChecker &TC,
22622262
storage->setIsGetterMutating(computeIsGetterMutating(TC, storage));
22632263
storage->setIsSetterMutating(computeIsSetterMutating(TC, storage));
22642264

2265-
// Add any mandatory accessors now.
2266-
maybeAddAccessorsToStorage(TC, storage);
2267-
22682265
// Everything else about the accessors can wait until finalization.
22692266
// This will validate all the accessors.
22702267
TC.DeclsToFinalize.insert(storage);
@@ -2274,9 +2271,15 @@ static void finalizeAbstractStorageDecl(TypeChecker &TC,
22742271
AbstractStorageDecl *storage) {
22752272
TC.validateDecl(storage);
22762273

2274+
// Add any mandatory accessors now.
2275+
maybeAddAccessorsToStorage(TC, storage);
2276+
22772277
for (auto accessor : storage->getAllAccessors()) {
22782278
// Are there accessors we can safely ignore here, like maybe observers?
22792279
TC.validateDecl(accessor);
2280+
2281+
// Finalize the accessors as well.
2282+
TC.DeclsToFinalize.insert(accessor);
22802283
}
22812284
}
22822285

@@ -2373,6 +2376,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23732376
void visitBoundVariable(VarDecl *VD) {
23742377
TC.validateDecl(VD);
23752378

2379+
// Set up accessors.
2380+
maybeAddAccessorsToStorage(TC, VD);
2381+
23762382
// Check the behavior.
23772383
checkVarBehavior(VD, TC);
23782384

@@ -4606,6 +4612,7 @@ void TypeChecker::requestMemberLayout(ValueDecl *member) {
46064612
// because if they never get validated at all then conformance checkers
46074613
// will complain about selector mismatches.
46084614
if (storage->isObjC()) {
4615+
maybeAddAccessorsToStorage(*this, storage);
46094616
for (auto accessor : storage->getAllAccessors()) {
46104617
requestMemberLayout(accessor);
46114618
}

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,13 @@ bool OverrideMatcher::checkOverride(ValueDecl *baseDecl,
861861
if (!shouldDiagnose && baseDecl->isSettable(dc)){
862862
auto matchASD = cast<AbstractStorageDecl>(baseDecl);
863863
if (matchASD->isSetterAccessibleFrom(dc)) {
864+
// Match sure we've created the setter.
865+
if (!matchASD->getSetter()) {
866+
maybeAddAccessorsToStorage(
867+
*static_cast<TypeChecker *>(ctx.getLazyResolver()),
868+
matchASD);
869+
}
870+
864871
auto matchSetterAccessScope = matchASD->getSetter()
865872
->getFormalAccessScope(dc);
866873
auto requiredSetterAccessScope =
@@ -1753,8 +1760,14 @@ OverriddenDeclsRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
17531760

17541761
// Check the various overridden storage declarations.
17551762
SmallVector<OverrideMatch, 2> matches;
1763+
ASTContext &ctx = decl->getASTContext();
17561764
for (auto overridden : overridingASD->getOverriddenDecls()) {
17571765
auto baseASD = cast<AbstractStorageDecl>(overridden);
1766+
if (auto lazyResolver = ctx.getLazyResolver()) {
1767+
maybeAddAccessorsToStorage(*static_cast<TypeChecker *>(lazyResolver),
1768+
baseASD);
1769+
}
1770+
17581771
auto kind = accessor->getAccessorKind();
17591772

17601773
// If the base doesn't consider this an opaque accessor,

test/CircularReferences/objc.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,16 @@
1010
class A {
1111
@objc func foo() { }
1212
}
13+
14+
15+
@objc class B {
16+
@objc dynamic subscript(i: Int) -> B {
17+
return self
18+
}
19+
}
20+
21+
class C: B {
22+
override subscript(i: Int) -> B {
23+
return super[i]
24+
}
25+
}

0 commit comments

Comments
 (0)