Skip to content

Commit fd53040

Browse files
committed
ASTScope: Refactor DeclAttribute scopes
DifferentiableAttr, SpecializeAttr and CustomAttr create scopes because lookups can be performed from inside them. Previously we would sort DifferentiableAttr and SpecializeAttr by source order, but we consider that a declaration may also have more than one _kind_ of attribute requiring special handling. The case where this comes up is properties that have both a DifferentiableAttr and CustomAttr. This fixes test failures in AutoDiff tests with subsequent commits in this PR.
1 parent 54aef7f commit fd53040

File tree

3 files changed

+62
-114
lines changed

3 files changed

+62
-114
lines changed

include/swift/AST/ASTScope.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -990,17 +990,19 @@ class DefaultArgumentInitializerScope final : public ASTScopeImpl {
990990

991991
class AttachedPropertyWrapperScope final : public ASTScopeImpl {
992992
public:
993-
VarDecl *const decl;
993+
CustomAttr *attr;
994+
VarDecl *decl;
995+
994996
/// Because we have to avoid request cycles, we approximate the test for an
995997
/// AttachedPropertyWrapper with one based on source location. We might get
996998
/// false positives, that that doesn't hurt anything. However, the result of
997999
/// the conservative source range computation doesn't seem to be stable. So
9981000
/// keep the original here, and use it for source range queries.
999-
10001001
const SourceRange sourceRangeWhenCreated;
10011002

1002-
AttachedPropertyWrapperScope(VarDecl *e)
1003-
: decl(e), sourceRangeWhenCreated(getSourceRangeOfVarDecl(e)) {
1003+
AttachedPropertyWrapperScope(CustomAttr *attr, VarDecl *decl)
1004+
: attr(attr), decl(decl),
1005+
sourceRangeWhenCreated(attr->getTypeRepr()->getSourceRange()) {
10041006
ASTScopeAssert(sourceRangeWhenCreated.isValid(),
10051007
"VarDecls must have ranges to be looked-up");
10061008
}
@@ -1016,7 +1018,10 @@ class AttachedPropertyWrapperScope final : public ASTScopeImpl {
10161018
NullablePtr<const void> addressForPrinting() const override { return decl; }
10171019
virtual NullablePtr<DeclContext> getDeclContext() const override;
10181020

1019-
static SourceRange getSourceRangeOfVarDecl(const VarDecl *);
1021+
NullablePtr<DeclAttribute> getDeclAttributeIfAny() const override {
1022+
return attr;
1023+
}
1024+
NullablePtr<const void> getReferrent() const override;
10201025

10211026
private:
10221027
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);

lib/AST/ASTScope.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,19 +91,6 @@ NullablePtr<ClosureExpr> ASTScopeImpl::getClosureIfClosureScope() const {
9191
return nullptr;
9292
}
9393

94-
// Conservative, because using precise info would be circular
95-
SourceRange
96-
AttachedPropertyWrapperScope::getSourceRangeOfVarDecl(const VarDecl *const vd) {
97-
SourceRange sr;
98-
for (auto *attr : vd->getAttrs().getAttributes<CustomAttr>()) {
99-
if (sr.isInvalid())
100-
sr = attr->getTypeRepr()->getSourceRange();
101-
else
102-
sr.widen(attr->getTypeRepr()->getSourceRange());
103-
}
104-
return sr;
105-
}
106-
10794
SourceManager &ASTScopeImpl::getSourceManager() const {
10895
return getASTContext().SourceMgr;
10996
}

lib/AST/ASTScopeCreation.cpp

Lines changed: 52 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,6 @@ template <typename Rangeable>
6161
static SourceRange getRangeableSourceRange(const Rangeable *const p) {
6262
return p->getSourceRange();
6363
}
64-
static SourceRange getRangeableSourceRange(const SpecializeAttr *a) {
65-
return a->getRange();
66-
}
67-
static SourceRange getRangeableSourceRange(const DifferentiableAttr *a) {
68-
return a->getRange();
69-
}
7064
static SourceRange getRangeableSourceRange(const ASTNode n) {
7165
return n.getSourceRange();
7266
}
@@ -404,27 +398,6 @@ class ScopeCreator final {
404398
expr->walk(ClosureFinder(*this, parent));
405399
}
406400

407-
private:
408-
// A safe way to discover this, without creating a circular request.
409-
// Cannot call getAttachedPropertyWrappers.
410-
static bool hasAttachedPropertyWrapper(VarDecl *vd) {
411-
return AttachedPropertyWrapperScope::getSourceRangeOfVarDecl(vd).isValid();
412-
}
413-
414-
public:
415-
/// If the pattern has an attached property wrapper, create a scope for it
416-
/// so it can be looked up.
417-
418-
void
419-
addAnyAttachedPropertyWrappersToScopeTree(PatternBindingDecl *patternBinding,
420-
ASTScopeImpl *parent) {
421-
patternBinding->getPattern(0)->forEachVariable([&](VarDecl *vd) {
422-
if (hasAttachedPropertyWrapper(vd))
423-
constructExpandAndInsertUncheckable<AttachedPropertyWrapperScope>(
424-
parent, vd);
425-
});
426-
}
427-
428401
public:
429402
/// Create the matryoshka nested generic param scopes (if any)
430403
/// that are subscopes of the receiver. Return
@@ -447,34 +420,8 @@ class ScopeCreator final {
447420
addChildrenForAllLocalizableAccessorsInSourceOrder(AbstractStorageDecl *asd,
448421
ASTScopeImpl *parent);
449422

450-
void
451-
forEachSpecializeAttrInSourceOrder(Decl *declBeingSpecialized,
452-
function_ref<void(SpecializeAttr *)> fn) {
453-
std::vector<SpecializeAttr *> sortedSpecializeAttrs;
454-
for (auto *attr : declBeingSpecialized->getAttrs()) {
455-
if (auto *specializeAttr = dyn_cast<SpecializeAttr>(attr))
456-
sortedSpecializeAttrs.push_back(specializeAttr);
457-
}
458-
// TODO: rm extra copy
459-
for (auto *specializeAttr : sortBySourceRange(sortedSpecializeAttrs))
460-
fn(specializeAttr);
461-
}
462-
463-
void forEachDifferentiableAttrInSourceOrder(
464-
Decl *decl, function_ref<void(DifferentiableAttr *)> fn) {
465-
std::vector<DifferentiableAttr *> sortedDifferentiableAttrs;
466-
for (auto *attr : decl->getAttrs())
467-
if (auto *diffAttr = dyn_cast<DifferentiableAttr>(attr))
468-
// NOTE(TF-835): Skipping implicit `@differentiable` attributes is
469-
// necessary to avoid verification failure in
470-
// `ASTScopeImpl::verifyThatChildrenAreContainedWithin`.
471-
// Perhaps this check may no longer be necessary after TF-835: robust
472-
// `@derivative` attribute lowering.
473-
if (!diffAttr->isImplicit())
474-
sortedDifferentiableAttrs.push_back(diffAttr);
475-
for (auto *diffAttr : sortBySourceRange(sortedDifferentiableAttrs))
476-
fn(diffAttr);
477-
}
423+
void addChildrenForKnownAttributes(ValueDecl *decl,
424+
ASTScopeImpl *parent);
478425

479426
public:
480427

@@ -796,8 +743,8 @@ class NodeAdder
796743
visitPatternBindingDecl(PatternBindingDecl *patternBinding,
797744
ASTScopeImpl *parentScope,
798745
ScopeCreator &scopeCreator) {
799-
scopeCreator.addAnyAttachedPropertyWrappersToScopeTree(patternBinding,
800-
parentScope);
746+
if (auto *var = patternBinding->getSingleVar())
747+
scopeCreator.addChildrenForKnownAttributes(var, parentScope);
801748

802749
const bool isInTypeDecl = parentScope->isATypeDeclScope();
803750

@@ -881,28 +828,51 @@ ScopeCreator::addToScopeTreeAndReturnInsertionPoint(ASTNode n,
881828

882829
void ScopeCreator::addChildrenForAllLocalizableAccessorsInSourceOrder(
883830
AbstractStorageDecl *asd, ASTScopeImpl *parent) {
884-
// Accessors are always nested within their abstract storage
885-
// declaration. The nesting may not be immediate, because subscripts may
886-
// have intervening scopes for generics.
887-
888-
// Create scopes for `@differentiable` attributes.
889-
forEachDifferentiableAttrInSourceOrder(
890-
asd, [&](DifferentiableAttr *diffAttr) {
891-
ifUniqueConstructExpandAndInsert<DifferentiableAttributeScope>(
892-
parent, diffAttr, asd);
893-
});
894-
895-
AbstractStorageDecl *enclosingAbstractStorageDecl =
896-
parent->getEnclosingAbstractStorageDecl().get();
897-
898831
asd->visitParsedAccessors([&](AccessorDecl *ad) {
899-
assert(enclosingAbstractStorageDecl == ad->getStorage());
900-
(void) enclosingAbstractStorageDecl;
901-
832+
assert(asd == ad->getStorage());
902833
this->addToScopeTree(ad, parent);
903834
});
904835
}
905836

837+
void ScopeCreator::addChildrenForKnownAttributes(ValueDecl *decl,
838+
ASTScopeImpl *parent) {
839+
SmallVector<DeclAttribute *, 2> relevantAttrs;
840+
841+
for (auto *attr : decl->getAttrs()) {
842+
if (isa<DifferentiableAttr>(attr)) {
843+
if (!attr->isImplicit())
844+
relevantAttrs.push_back(attr);
845+
}
846+
847+
if (isa<SpecializeAttr>(attr))
848+
relevantAttrs.push_back(attr);
849+
850+
if (isa<CustomAttr>(attr))
851+
relevantAttrs.push_back(attr);
852+
}
853+
854+
// Decl::getAttrs() is a linked list with head insertion, so the
855+
// attributes are in reverse source order.
856+
std::reverse(relevantAttrs.begin(), relevantAttrs.end());
857+
858+
for (auto *attr : relevantAttrs) {
859+
if (auto *diffAttr = dyn_cast<DifferentiableAttr>(attr)) {
860+
ifUniqueConstructExpandAndInsert<DifferentiableAttributeScope>(
861+
parent, diffAttr, decl);
862+
} else if (auto *specAttr = dyn_cast<SpecializeAttr>(attr)) {
863+
if (auto *afd = dyn_cast<AbstractFunctionDecl>(decl)) {
864+
ifUniqueConstructExpandAndInsert<SpecializeAttributeScope>(
865+
parent, specAttr, afd);
866+
}
867+
} else if (auto *customAttr = dyn_cast<CustomAttr>(attr)) {
868+
if (auto *vd = dyn_cast<VarDecl>(decl)) {
869+
ifUniqueConstructExpandAndInsert<AttachedPropertyWrapperScope>(
870+
parent, customAttr, vd);
871+
}
872+
}
873+
}
874+
}
875+
906876
#pragma mark creation helpers
907877

908878
void ASTScopeImpl::addChild(ASTScopeImpl *child, ASTContext &ctx) {
@@ -1172,19 +1142,7 @@ TopLevelCodeScope::expandAScopeThatCreatesANewInsertionPoint(ScopeCreator &
11721142

11731143
void AbstractFunctionDeclScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
11741144
ScopeCreator &scopeCreator) {
1175-
// Create scopes for specialize attributes
1176-
scopeCreator.forEachSpecializeAttrInSourceOrder(
1177-
decl, [&](SpecializeAttr *specializeAttr) {
1178-
scopeCreator.ifUniqueConstructExpandAndInsert<SpecializeAttributeScope>(
1179-
this, specializeAttr, decl);
1180-
});
1181-
// Create scopes for `@differentiable` attributes.
1182-
scopeCreator.forEachDifferentiableAttrInSourceOrder(
1183-
decl, [&](DifferentiableAttr *diffAttr) {
1184-
scopeCreator
1185-
.ifUniqueConstructExpandAndInsert<DifferentiableAttributeScope>(
1186-
this, diffAttr, decl);
1187-
});
1145+
scopeCreator.addChildrenForKnownAttributes(decl, this);
11881146

11891147
// Create scopes for generic and ordinary parameters.
11901148
// For a subscript declaration, the generic and ordinary parameters are in an
@@ -1330,13 +1288,12 @@ void VarDeclScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
13301288

13311289
void SubscriptDeclScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
13321290
ScopeCreator &scopeCreator) {
1333-
auto *sub = decl;
1291+
scopeCreator.addChildrenForKnownAttributes(decl, this);
13341292
auto *leaf = scopeCreator.addNestedGenericParamScopesToTree(
1335-
sub, sub->getGenericParams(), this);
1336-
auto *params =
1337-
scopeCreator.constructExpandAndInsertUncheckable<ParameterListScope>(
1338-
leaf, sub->getIndices(), sub->getAccessor(AccessorKind::Get));
1339-
scopeCreator.addChildrenForAllLocalizableAccessorsInSourceOrder(sub, params);
1293+
decl, decl->getGenericParams(), this);
1294+
scopeCreator.constructExpandAndInsertUncheckable<ParameterListScope>(
1295+
leaf, decl->getIndices(), decl->getAccessor(AccessorKind::Get));
1296+
scopeCreator.addChildrenForAllLocalizableAccessorsInSourceOrder(decl, leaf);
13401297
}
13411298

13421299
void CaptureListScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
@@ -1364,10 +1321,8 @@ void DefaultArgumentInitializerScope::
13641321
void AttachedPropertyWrapperScope::
13651322
expandAScopeThatDoesNotCreateANewInsertionPoint(
13661323
ScopeCreator &scopeCreator) {
1367-
for (auto *attr : decl->getAttrs().getAttributes<CustomAttr>()) {
1368-
if (auto *expr = attr->getArg())
1324+
if (auto *expr = attr->getArg())
13691325
scopeCreator.addToScopeTree(expr, this);
1370-
}
13711326
}
13721327

13731328
#pragma mark expandScope
@@ -1595,6 +1550,7 @@ GET_REFERRENT(CaptureListScope, getExpr())
15951550
GET_REFERRENT(ClosureParametersScope, getExpr())
15961551
GET_REFERRENT(SpecializeAttributeScope, specializeAttr)
15971552
GET_REFERRENT(DifferentiableAttributeScope, differentiableAttr)
1553+
GET_REFERRENT(AttachedPropertyWrapperScope, attr)
15981554
GET_REFERRENT(GenericTypeOrExtensionScope, portion->getReferrentOfScope(this));
15991555

16001556
const Decl *

0 commit comments

Comments
 (0)