Skip to content

Commit 816b316

Browse files
authored
Merge pull request #4671 from DougGregor/scope-map-fixes
2 parents 68a6c22 + cb8dd98 commit 816b316

File tree

10 files changed

+166
-16
lines changed

10 files changed

+166
-16
lines changed

include/swift/AST/ASTScope.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ enum class ASTScopeKind : uint8_t {
6161
Preexpanded,
6262
/// A source file, which is the root of a scope.
6363
SourceFile,
64+
/// The generic parameters of an extension declaration.
65+
ExtensionGenericParams,
6466
/// The body of a type or extension thereof.
6567
TypeOrExtensionBody,
6668
/// The generic parameters of a declaration.
@@ -170,8 +172,12 @@ class ASTScope {
170172
mutable unsigned nextElement;
171173
} sourceFile;
172174

175+
/// An extension declaration, for
176+
/// \c kind == ASTScopeKind::ExtensionGenericParams.
177+
ExtensionDecl *extension;
178+
173179
/// An iterable declaration context, which covers nominal type declarations
174-
/// and extensions.
180+
/// and extension bodies.
175181
///
176182
/// For \c kind == ASTScopeKind::TypeOrExtensionBody.
177183
IterableDeclContext *iterableDeclContext;
@@ -304,6 +310,11 @@ class ASTScope {
304310
/// Constructor that initializes a preexpanded node.
305311
ASTScope(const ASTScope *parent, ArrayRef<ASTScope *> children);
306312

313+
ASTScope(const ASTScope *parent, ExtensionDecl *extension)
314+
: ASTScope(ASTScopeKind::ExtensionGenericParams, parent) {
315+
this->extension = extension;
316+
}
317+
307318
ASTScope(const ASTScope *parent, IterableDeclContext *idc)
308319
: ASTScope(ASTScopeKind::TypeOrExtensionBody, parent) {
309320
this->iterableDeclContext = idc;

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3527,6 +3527,10 @@ class ProtocolDecl : public NominalTypeDecl {
35273527
/// FIXME: protocol extensions will introduce a where clause here as well.
35283528
GenericParamList *createGenericParams(DeclContext *dc);
35293529

3530+
/// Create the generic parameters of this protocol if the haven't been
3531+
/// created yet.
3532+
void createGenericParamsIfMissing();
3533+
35303534
// Implement isa/cast/dyncast/etc.
35313535
static bool classof(const Decl *D) {
35323536
return D->getKind() == DeclKind::Protocol;

include/swift/AST/LazyResolver.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ class LazyResolver {
8989
/// Resolve the inherited protocols of a given protocol.
9090
virtual void resolveInheritedProtocols(ProtocolDecl *protocol) = 0;
9191

92+
/// Bind an extension to its extended type.
93+
virtual void bindExtension(ExtensionDecl *ext) = 0;
94+
9295
/// Resolve the type of an extension.
9396
///
9497
/// This can be called to ensure that the members of an extension can be
@@ -156,6 +159,10 @@ class DelegatingLazyResolver : public LazyResolver {
156159
Principal.resolveInheritedProtocols(protocol);
157160
}
158161

162+
void bindExtension(ExtensionDecl *ext) override {
163+
Principal.bindExtension(ext);
164+
}
165+
159166
void resolveExtension(ExtensionDecl *ext) override {
160167
Principal.resolveExtension(ext);
161168
}

lib/AST/ASTScope.cpp

Lines changed: 93 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ void ASTScope::expand() const {
184184
break;
185185
}
186186

187+
case ASTScopeKind::ExtensionGenericParams: {
188+
// Create a child node.
189+
if (ASTScope *child = createIfNeeded(this, extension))
190+
addChild(child);
191+
break;
192+
}
193+
187194
case ASTScopeKind::TypeOrExtensionBody:
188195
for (auto member : iterableDeclContext->getMembers()) {
189196
// Create a child node for this declaration.
@@ -228,18 +235,35 @@ void ASTScope::expand() const {
228235
patternBinding.decl->getPatternList()[patternBinding.entry];
229236

230237
// Create a child for the initializer, if present.
238+
ASTScope *initChild = nullptr;
231239
if (patternEntry.getInit() &&
232-
patternEntry.getInit()->getSourceRange().isValid())
233-
addChild(new (ctx) ASTScope(ASTScopeKind::PatternInitializer, this,
234-
patternBinding.decl, patternBinding.entry));
240+
patternEntry.getInit()->getSourceRange().isValid()) {
241+
initChild = new (ctx) ASTScope(ASTScopeKind::PatternInitializer, this,
242+
patternBinding.decl, patternBinding.entry);
243+
}
235244

236245
// Create children for the accessors of any variables in the pattern that
237246
// have them.
238247
patternEntry.getPattern()->forEachVariable([&](VarDecl *var) {
239-
if (hasAccessors(var))
248+
if (hasAccessors(var)) {
249+
// If there is an initializer child that precedes this node (the
250+
// normal case), add teh initializer child first.
251+
if (initChild &&
252+
ctx.SourceMgr.isBeforeInBuffer(
253+
patternBinding.decl->getInit(patternBinding.entry)->getEndLoc(),
254+
var->getBracesRange().Start)) {
255+
addChild(initChild);
256+
initChild = nullptr;
257+
}
258+
240259
addChild(new (ctx) ASTScope(this, var));
260+
}
241261
});
242262

263+
// If an initializer child remains, add it now.
264+
if (initChild)
265+
addChild(initChild);
266+
243267
// If the pattern binding is in a local context, we nest the remaining
244268
// pattern bindings.
245269
if (patternBinding.decl->getDeclContext()->isLocalContext()) {
@@ -583,6 +607,7 @@ static bool parentDirectDescendedFromLocalDeclaration(const ASTScope *parent,
583607
case ASTScopeKind::AbstractFunctionDecl:
584608
case ASTScopeKind::AbstractFunctionParams:
585609
case ASTScopeKind::GenericParams:
610+
case ASTScopeKind::ExtensionGenericParams:
586611
case ASTScopeKind::TypeOrExtensionBody:
587612
case ASTScopeKind::Accessors:
588613
// Keep looking.
@@ -638,6 +663,7 @@ static bool parentDirectDescendedFromAbstractStorageDecl(
638663
return (parent->getAbstractStorageDecl() == decl);
639664

640665
case ASTScopeKind::SourceFile:
666+
case ASTScopeKind::ExtensionGenericParams:
641667
case ASTScopeKind::TypeOrExtensionBody:
642668
case ASTScopeKind::DefaultArgument:
643669
case ASTScopeKind::AbstractFunctionBody:
@@ -686,6 +712,7 @@ static bool parentDirectDescendedFromAbstractFunctionDecl(
686712
return (parent->getAbstractFunctionDecl() == decl);
687713

688714
case ASTScopeKind::SourceFile:
715+
case ASTScopeKind::ExtensionGenericParams:
689716
case ASTScopeKind::TypeOrExtensionBody:
690717
case ASTScopeKind::LocalDeclaration:
691718
case ASTScopeKind::PatternBinding:
@@ -791,8 +818,17 @@ ASTScope *ASTScope::createIfNeeded(const ASTScope *parent, Decl *decl) {
791818
// Always handled by a pattern-binding declaration.
792819
return nullptr;
793820

794-
case DeclKind::Extension:
795-
return new (ctx) ASTScope(parent, cast<ExtensionDecl>(decl));
821+
case DeclKind::Extension: {
822+
auto ext = cast<ExtensionDecl>(decl);
823+
824+
// If we already have a scope of the (possible) generic parameters,
825+
// add the body.
826+
if (parent->getKind() == ASTScopeKind::ExtensionGenericParams)
827+
return new (ctx) ASTScope(parent, cast<IterableDeclContext>(ext));
828+
829+
// Otherwise, form the extension's generic parameters scope.
830+
return new (ctx) ASTScope(parent, ext);
831+
}
796832

797833
case DeclKind::TopLevelCode: {
798834
// Drop top-level statements containing just an IfConfigStmt.
@@ -808,6 +844,10 @@ ASTScope *ASTScope::createIfNeeded(const ASTScope *parent, Decl *decl) {
808844
return new (ctx) ASTScope(parent, topLevelCode);
809845
}
810846

847+
case DeclKind::Protocol:
848+
cast<ProtocolDecl>(decl)->createGenericParamsIfMissing();
849+
SWIFT_FALLTHROUGH;
850+
811851
case DeclKind::Class:
812852
case DeclKind::Enum:
813853
case DeclKind::Struct: {
@@ -821,9 +861,6 @@ ASTScope *ASTScope::createIfNeeded(const ASTScope *parent, Decl *decl) {
821861
return new (ctx) ASTScope(parent, nominal);
822862
}
823863

824-
case DeclKind::Protocol:
825-
return new (ctx) ASTScope(parent, cast<ProtocolDecl>(decl));
826-
827864
case DeclKind::TypeAlias: {
828865
// If we have a generic typealias and our parent isn't describing our
829866
// generic parameters, build the generic parameter scope.
@@ -1089,6 +1126,7 @@ bool ASTScope::isContinuationScope() const {
10891126
switch (getKind()) {
10901127
case ASTScopeKind::Preexpanded:
10911128
case ASTScopeKind::SourceFile:
1129+
case ASTScopeKind::ExtensionGenericParams:
10921130
case ASTScopeKind::TypeOrExtensionBody:
10931131
case ASTScopeKind::GenericParams:
10941132
case ASTScopeKind::AbstractFunctionDecl:
@@ -1143,6 +1181,7 @@ void ASTScope::enumerateContinuationScopes(
11431181
switch (continuation->getKind()) {
11441182
case ASTScopeKind::Preexpanded:
11451183
case ASTScopeKind::SourceFile:
1184+
case ASTScopeKind::ExtensionGenericParams:
11461185
case ASTScopeKind::DefaultArgument:
11471186
case ASTScopeKind::AbstractFunctionBody:
11481187
case ASTScopeKind::PatternInitializer:
@@ -1217,6 +1256,9 @@ ASTContext &ASTScope::getASTContext() const {
12171256
case ASTScopeKind::SourceFile:
12181257
return sourceFile.file->getASTContext();
12191258

1259+
case ASTScopeKind::ExtensionGenericParams:
1260+
return extension->getASTContext();
1261+
12201262
case ASTScopeKind::TypeOrExtensionBody:
12211263
return getParent()->getASTContext();
12221264

@@ -1287,13 +1329,27 @@ SourceRange ASTScope::getSourceRangeImpl() const {
12871329

12881330
return SourceRange();
12891331

1332+
case ASTScopeKind::ExtensionGenericParams: {
1333+
// The generic parameters of an extension are available from the trailing
1334+
// 'where' (if present) or from the start of the body.
1335+
SourceLoc startLoc;
1336+
if (auto trailingWhere = extension->getTrailingWhereClause())
1337+
startLoc = trailingWhere->getWhereLoc();
1338+
else
1339+
startLoc = extension->getBraces().Start;
1340+
1341+
return SourceRange(startLoc, extension->getEndLoc());
1342+
}
1343+
12901344
case ASTScopeKind::TypeOrExtensionBody:
12911345
if (auto ext = dyn_cast<ExtensionDecl>(iterableDeclContext))
12921346
return ext->getBraces();
12931347

12941348
return cast<NominalTypeDecl>(iterableDeclContext)->getBraces();
12951349

12961350
case ASTScopeKind::GenericParams:
1351+
// Explicitly-written generic parameters are in scope following their
1352+
// definition.
12971353
return SourceRange(genericParams.params->getParams()[genericParams.index]
12981354
->getEndLoc(),
12991355
genericParams.decl->getEndLoc());
@@ -1595,6 +1651,7 @@ DeclContext *ASTScope::getDeclContext() const {
15951651
case ASTScopeKind::TopLevelCode:
15961652
return topLevelCode;
15971653

1654+
case ASTScopeKind::ExtensionGenericParams:
15981655
case ASTScopeKind::GenericParams:
15991656
case ASTScopeKind::AbstractFunctionParams:
16001657
case ASTScopeKind::PatternBinding:
@@ -1658,6 +1715,21 @@ SmallVector<ValueDecl *, 4> ASTScope::getLocalBindings() const {
16581715
// No local declarations.
16591716
break;
16601717

1718+
case ASTScopeKind::ExtensionGenericParams:
1719+
// Bind this extension, if we haven't done so already.
1720+
if (!extension->getExtendedType())
1721+
if (auto resolver = extension->getASTContext().getLazyResolver())
1722+
resolver->bindExtension(extension);
1723+
1724+
// If there are generic parameters, add them.
1725+
for (auto genericParams = extension->getGenericParams();
1726+
genericParams;
1727+
genericParams = genericParams->getOuterParameters()) {
1728+
for (auto param : genericParams->getParams())
1729+
result.push_back(param);
1730+
}
1731+
break;
1732+
16611733
case ASTScopeKind::GenericParams:
16621734
result.push_back(genericParams.params->getParams()[genericParams.index]);
16631735
break;
@@ -1765,6 +1837,18 @@ void ASTScope::print(llvm::raw_ostream &out, unsigned level,
17651837
printRange();
17661838
break;
17671839

1840+
case ASTScopeKind::ExtensionGenericParams:
1841+
printScopeKind("ExtensionGenericParams");
1842+
printAddress(extension);
1843+
out << " extension of '";
1844+
if (auto typeRepr = extension->getExtendedTypeLoc().getTypeRepr())
1845+
typeRepr->print(out);
1846+
else
1847+
extension->getExtendedType()->print(out);
1848+
out << "'";
1849+
printRange();
1850+
break;
1851+
17681852
case ASTScopeKind::TypeOrExtensionBody: {
17691853
printScopeKind("TypeOrExtensionBody");
17701854
if (auto ext = dyn_cast<ExtensionDecl>(iterableDeclContext)) {

lib/AST/Decl.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -919,15 +919,23 @@ VarDecl *PatternBindingEntry::getAnchoringVarDecl() const {
919919
}
920920

921921
SourceRange PatternBindingEntry::getSourceRange() const {
922+
ASTContext *ctx = nullptr;
923+
922924
SourceLoc endLoc;
923925
getPattern()->forEachVariable([&](VarDecl *var) {
924926
auto accessorsEndLoc = var->getBracesRange().End;
925-
if (accessorsEndLoc.isValid()) endLoc = accessorsEndLoc;
927+
if (accessorsEndLoc.isValid()) {
928+
endLoc = accessorsEndLoc;
929+
if (!ctx) ctx = &var->getASTContext();
930+
}
926931
});
927932

928933
// Check the initializer.
929-
if (endLoc.isInvalid())
930-
endLoc = getOrigInitRange().End;
934+
SourceLoc initEndLoc = getOrigInitRange().End;
935+
if (initEndLoc.isValid() &&
936+
(endLoc.isInvalid() ||
937+
(ctx && ctx->SourceMgr.isBeforeInBuffer(endLoc, initEndLoc))))
938+
endLoc = initEndLoc;
931939

932940
// Check the pattern.
933941
if (endLoc.isInvalid())
@@ -2028,9 +2036,8 @@ void NominalTypeDecl::computeType() {
20282036
//
20292037
// If this protocol has been deserialized, it already has generic parameters.
20302038
// Don't add them again.
2031-
if (!getGenericParams())
2032-
if (auto proto = dyn_cast<ProtocolDecl>(this))
2033-
setGenericParams(proto->createGenericParams(proto));
2039+
if (auto proto = dyn_cast<ProtocolDecl>(this))
2040+
proto->createGenericParamsIfMissing();
20342041

20352042
// If we still don't have a declared type, don't crash -- there's a weird
20362043
// circular declaration issue in the code.
@@ -2942,6 +2949,11 @@ GenericParamList *ProtocolDecl::createGenericParams(DeclContext *dc) {
29422949
return result;
29432950
}
29442951

2952+
void ProtocolDecl::createGenericParamsIfMissing() {
2953+
if (!getGenericParams())
2954+
setGenericParams(createGenericParams(this));
2955+
}
2956+
29452957
/// Returns the default witness for a requirement, or nullptr if there is
29462958
/// no default.
29472959
ConcreteDeclRef ProtocolDecl::getDefaultWitness(ValueDecl *requirement) const {

lib/AST/NameLookup.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ static DeclVisibilityKind getLocalDeclVisibilityKind(const ASTScope *scope) {
420420
case ASTScopeKind::TopLevelCode:
421421
llvm_unreachable("no local declarations?");
422422

423+
case ASTScopeKind::ExtensionGenericParams:
423424
case ASTScopeKind::GenericParams:
424425
return DeclVisibilityKind::GenericParameter;
425426

lib/Sema/TypeChecker.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,10 @@ static void bindExtensionDecl(ExtensionDecl *ED, TypeChecker &TC) {
389389
extendedNominal->addExtension(ED);
390390
}
391391

392+
void TypeChecker::bindExtension(ExtensionDecl *ext) {
393+
::bindExtensionDecl(ext, *this);
394+
}
395+
392396
static void typeCheckFunctionsAndExternalDecls(TypeChecker &TC) {
393397
unsigned currentFunctionIdx = 0;
394398
unsigned currentExternalDef = TC.Context.LastCheckedExternalDefinition;

lib/Sema/TypeChecker.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,8 @@ class TypeChecker final : public LazyResolver {
975975
validateDecl(VD, true);
976976
}
977977

978+
virtual void bindExtension(ExtensionDecl *ext) override;
979+
978980
virtual void resolveExtension(ExtensionDecl *ext) override {
979981
validateExtension(ext);
980982
checkInheritanceClause(ext);

test/NameBinding/scope_map.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ func localPatternsWithSharedType() {
193193
// CHECK-EXPANDED: SourceFile{{.*}}scope_map.swift{{.*}}expanded
194194
// CHECK-EXPANDED-NEXT: TypeOrExtensionBody {{.*}} 'S0' [4:11 - 6:1] expanded
195195
// CHECK-EXPANDED-NEXT: `-TypeOrExtensionBody {{.*}} 'InnerC0' [5:17 - 5:19] expanded
196+
// CHECK-EXPANDED-NEXT: -ExtensionGenericParams {{.*}} extension of 'S0' [8:14 - 9:1] expanded
196197
// CHECK-EXPANDED-NEXT: -TypeOrExtensionBody {{.*}} extension of 'S0' [8:14 - 9:1] expanded
197198
// CHECK-EXPANDED-NEXT: |-TypeOrExtensionBody {{.*}} 'C0' [11:10 - 12:1] expanded
198199
// CHECK-EXPANDED-NEXT: -TypeOrExtensionBody {{.*}} 'E0' [14:9 - 17:1] expanded

0 commit comments

Comments
 (0)