Skip to content

Commit c5edc45

Browse files
committed
ASTScope: PatternEntryDeclScope changes the insertion point for local bindings
This gives us the desired behavior, where local bindings are in scope after their definition. Note that BraceStmt still introduces all bindings at the beginning, but now we change BraceStmt to only introduce local functions and types, allowing us to disable parse-time lookup.
1 parent cecbf21 commit c5edc45

File tree

2 files changed

+20
-20
lines changed

2 files changed

+20
-20
lines changed

lib/AST/ASTScopeCreation.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@
3838
using namespace swift;
3939
using namespace ast_scope;
4040

41-
/// If true, nest scopes so a variable is out of scope before its declaration
42-
/// Does not handle capture rules for local functions properly.
43-
/// If false don't push uses down into subscopes after decls.
44-
static const bool handleUseBeforeDef = false;
45-
4641
#pragma mark source range utilities
4742
static bool rangeableIsIgnored(const Decl *d) { return d->isImplicit(); }
4843
static bool rangeableIsIgnored(const Expr *d) {
@@ -746,11 +741,11 @@ class NodeAdder
746741
if (auto *var = patternBinding->getSingleVar())
747742
scopeCreator.addChildrenForKnownAttributes(var, parentScope);
748743

749-
const bool isInTypeDecl = parentScope->isATypeDeclScope();
744+
const bool isLocalBinding = patternBinding->getDeclContext()->isLocalContext();
750745

751746
const DeclVisibilityKind vis =
752-
isInTypeDecl ? DeclVisibilityKind::MemberOfCurrentNominal
753-
: DeclVisibilityKind::LocalVariable;
747+
isLocalBinding ? DeclVisibilityKind::LocalVariable
748+
: DeclVisibilityKind::MemberOfCurrentNominal;
754749
auto *insertionPoint = parentScope;
755750
for (auto i : range(patternBinding->getNumPatternEntries())) {
756751
insertionPoint =
@@ -759,9 +754,12 @@ class NodeAdder
759754
insertionPoint, patternBinding, i, vis)
760755
.getPtrOr(insertionPoint);
761756
}
762-
// If in a type decl, the type search will find these,
763-
// but if in a brace stmt, must continue under the last binding.
764-
return isInTypeDecl ? parentScope : insertionPoint;
757+
758+
ASTScopeAssert(isLocalBinding || insertionPoint == parentScope,
759+
"Bindings at the top-level or members of types should "
760+
"not change the insertion point");
761+
762+
return insertionPoint;
765763
}
766764

767765
NullablePtr<ASTScopeImpl> visitEnumElementDecl(EnumElementDecl *eed,
@@ -1041,11 +1039,13 @@ PatternEntryDeclScope::expandAScopeThatCreatesANewInsertionPoint(
10411039
scopeCreator.addChildrenForAllLocalizableAccessorsInSourceOrder(var, this);
10421040
});
10431041

1044-
ASTScopeAssert(!handleUseBeforeDef,
1045-
"next line is wrong otherwise; would need a use scope");
1042+
// In local context, the PatternEntryDeclScope becomes the insertion point, so
1043+
// that all any bindings introduecd by the pattern are in scope for subsequent
1044+
// lookups.
1045+
if (vis == DeclVisibilityKind::LocalVariable)
1046+
return {this, "All code that follows is inside this scope"};
10461047

1047-
return {getParent().get(), "When not handling use-before-def, succeeding "
1048-
"code just goes in the same scope as this one"};
1048+
return {getParent().get(), "Global and type members do not introduce scopes"};
10491049
}
10501050

10511051
void

test/NameLookup/scope_map_top_level.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ var i: Int = b.my_identity()
3131
// CHECK-EXPANDED-NEXT: `-NominalTypeBodyScope {{.*}}, [4:11 - 4:13]
3232
// CHECK-EXPANDED-NEXT: `-TopLevelCodeScope {{.*}}, [6:1 - 21:28]
3333
// CHECK-EXPANDED-NEXT: `-BraceStmtScope {{.*}}, [6:1 - 21:28]
34-
// CHECK-EXPANDED-NEXT: |-PatternEntryDeclScope {{.*}}, [6:5 - 6:15] entry 0 'a'
35-
// CHECK-EXPANDED-NEXT: `-PatternEntryInitializerScope {{.*}}, [6:15 - 6:15] entry 0 'a'
34+
// CHECK-EXPANDED-NEXT: `-PatternEntryDeclScope {{.*}}, [6:5 - 21:28] entry 0 'a'
35+
// CHECK-EXPANDED-NEXT: |-PatternEntryInitializerScope {{.*}}, [6:15 - 6:15] entry 0 'a'
3636
// CHECK-EXPANDED-NEXT: `-TopLevelCodeScope {{.*}}, [8:1 - 21:28]
3737
// CHECK-EXPANDED-NEXT: `-BraceStmtScope {{.*}}, [8:1 - 21:28]
3838
// CHECK-EXPANDED-NEXT: `-GuardStmtScope {{.*}}, [8:1 - 21:28]
@@ -46,9 +46,9 @@ var i: Int = b.my_identity()
4646
// CHECK-EXPANDED-NEXT: `-BraceStmtScope {{.*}}, [11:18 - 11:19]
4747
// CHECK-EXPANDED-NEXT: `-TopLevelCodeScope {{.*}}, [13:1 - 21:28]
4848
// CHECK-EXPANDED-NEXT: `-BraceStmtScope {{.*}}, [13:1 - 21:28]
49-
// CHECK-EXPANDED-NEXT: |-PatternEntryDeclScope {{.*}}, [13:5 - 13:9] entry 0 'c'
50-
// CHECK-EXPANDED-NEXT: `-PatternEntryInitializerScope {{.*}}, [13:9 - 13:9] entry 0 'c'
51-
// CHECK-EXPANDED-NEXT: |-TypeAliasDeclScope {{.*}}, [15:1 - 15:15]
49+
// CHECK-EXPANDED-NEXT: `-PatternEntryDeclScope {{.*}}, [13:5 - 21:28] entry 0 'c'
50+
// CHECK-EXPANDED-NEXT: |-PatternEntryInitializerScope {{.*}}, [13:9 - 13:9] entry 0 'c'
51+
// CHECK-EXPANDED-NEXT: |-TypeAliasDeclScope {{.*}}, [15:1 - 15:15]
5252
// CHECK-EXPANDED-NEXT: |-ExtensionDeclScope {{.*}}, [17:14 - 19:1]
5353
// CHECK-EXPANDED-NEXT: `-ExtensionBodyScope {{.*}}, [17:15 - 19:1]
5454
// CHECK-EXPANDED-NEXT: `-AbstractFunctionDeclScope {{.*}}, [18:3 - 18:43] 'my_identity()'

0 commit comments

Comments
 (0)