Skip to content

Commit

Permalink
Merge pull request #19259 from DougGregor/validate-without-accessors
Browse files Browse the repository at this point in the history
[Type checker] Move accessor creation out of validateDecl().
  • Loading branch information
DougGregor committed Sep 12, 2018
2 parents d72cbbc + 56cfd84 commit 9cda374
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 4 deletions.
2 changes: 2 additions & 0 deletions lib/Sema/CSApply.cpp
Expand Up @@ -17,6 +17,7 @@
//===----------------------------------------------------------------------===//

#include "ConstraintSystem.h"
#include "CodeSynthesis.h"
#include "CSDiagnostics.h"
#include "MiscDiagnostics.h"
#include "TypeCheckProtocol.h"
Expand Down Expand Up @@ -4112,6 +4113,7 @@ namespace {
method = func;
} else if (auto var = dyn_cast<VarDecl>(foundDecl)) {
// Properties.
maybeAddAccessorsToStorage(tc, var);

// If this isn't a property on a type, complain.
if (!var->getDeclContext()->isTypeContext()) {
Expand Down
1 change: 1 addition & 0 deletions lib/Sema/CodeSynthesis.cpp
Expand Up @@ -1786,6 +1786,7 @@ static bool wouldBeCircularSynthesis(AbstractStorageDecl *storage,
void swift::triggerAccessorSynthesis(TypeChecker &TC,
AbstractStorageDecl *storage) {
auto VD = dyn_cast<VarDecl>(storage);
maybeAddAccessorsToStorage(TC, storage);

// Synthesize accessors for lazy, all checking already been performed.
bool lazy = false;
Expand Down
15 changes: 11 additions & 4 deletions lib/Sema/TypeCheckDecl.cpp
Expand Up @@ -1496,7 +1496,7 @@ static void checkVarBehavior(VarDecl *decl, TypeChecker &TC) {
// No behavior, no problems.
if (!decl->hasBehavior())
return;

// Don't try to check the behavior if we already encountered an error.
if (decl->getType()->hasError())
return;
Expand Down Expand Up @@ -2262,9 +2262,6 @@ static void validateAbstractStorageDecl(TypeChecker &TC,
storage->setIsGetterMutating(computeIsGetterMutating(TC, storage));
storage->setIsSetterMutating(computeIsSetterMutating(TC, storage));

// Add any mandatory accessors now.
maybeAddAccessorsToStorage(TC, storage);

// Everything else about the accessors can wait until finalization.
// This will validate all the accessors.
TC.DeclsToFinalize.insert(storage);
Expand All @@ -2274,9 +2271,15 @@ static void finalizeAbstractStorageDecl(TypeChecker &TC,
AbstractStorageDecl *storage) {
TC.validateDecl(storage);

// Add any mandatory accessors now.
maybeAddAccessorsToStorage(TC, storage);

for (auto accessor : storage->getAllAccessors()) {
// Are there accessors we can safely ignore here, like maybe observers?
TC.validateDecl(accessor);

// Finalize the accessors as well.
TC.DeclsToFinalize.insert(accessor);
}
}

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

// Set up accessors.
maybeAddAccessorsToStorage(TC, VD);

// Check the behavior.
checkVarBehavior(VD, TC);

Expand Down Expand Up @@ -4606,6 +4612,7 @@ void TypeChecker::requestMemberLayout(ValueDecl *member) {
// because if they never get validated at all then conformance checkers
// will complain about selector mismatches.
if (storage->isObjC()) {
maybeAddAccessorsToStorage(*this, storage);
for (auto accessor : storage->getAllAccessors()) {
requestMemberLayout(accessor);
}
Expand Down
13 changes: 13 additions & 0 deletions lib/Sema/TypeCheckDeclOverride.cpp
Expand Up @@ -861,6 +861,13 @@ bool OverrideMatcher::checkOverride(ValueDecl *baseDecl,
if (!shouldDiagnose && baseDecl->isSettable(dc)){
auto matchASD = cast<AbstractStorageDecl>(baseDecl);
if (matchASD->isSetterAccessibleFrom(dc)) {
// Match sure we've created the setter.
if (!matchASD->getSetter()) {
maybeAddAccessorsToStorage(
*static_cast<TypeChecker *>(ctx.getLazyResolver()),
matchASD);
}

auto matchSetterAccessScope = matchASD->getSetter()
->getFormalAccessScope(dc);
auto requiredSetterAccessScope =
Expand Down Expand Up @@ -1753,8 +1760,14 @@ OverriddenDeclsRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {

// Check the various overridden storage declarations.
SmallVector<OverrideMatch, 2> matches;
ASTContext &ctx = decl->getASTContext();
for (auto overridden : overridingASD->getOverriddenDecls()) {
auto baseASD = cast<AbstractStorageDecl>(overridden);
if (auto lazyResolver = ctx.getLazyResolver()) {
maybeAddAccessorsToStorage(*static_cast<TypeChecker *>(lazyResolver),
baseASD);
}

auto kind = accessor->getAccessorKind();

// If the base doesn't consider this an opaque accessor,
Expand Down
13 changes: 13 additions & 0 deletions test/CircularReferences/objc.swift
Expand Up @@ -10,3 +10,16 @@
class A {
@objc func foo() { }
}


@objc class B {
@objc dynamic subscript(i: Int) -> B {
return self
}
}

class C: B {
override subscript(i: Int) -> B {
return super[i]
}
}

0 comments on commit 9cda374

Please sign in to comment.