-
Notifications
You must be signed in to change notification settings - Fork 10.5k
ASTScope: Take start location into account when modeling local pattern bindings #34038
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
fbf9983
to
1d9d6ed
Compare
1d9d6ed
to
818b8be
Compare
@swift-ci Please smoke test |
@swift-ci Please test source compatibility |
818b8be
to
e4cd209
Compare
@swift-ci Please smoke test |
66bc234
to
da55293
Compare
@swift-ci Please smoke test |
da55293
to
a78e5a9
Compare
Bindings are not visible from inside their own initializer, eg this is invalid: var (x, y) = (y, x) The PatternEntryDeclScope which starts after the 'var' introduces x and y, and it contains the PatternEntryInitializerScope which starts after the '='. To model this properly in ASTScope, the PatternEntryInitializerScope overrides getLookupParent() to skip the PatternEntryDeclScope that contains it. I believe this is simpler than having PatternEntryDeclScope begin at the source location following the initializer, because it is hard to compute this source location in a way that works with invalid code, for example the 'var' might be nested inside of a BraceStmt with the closing '}' missing.
a78e5a9
to
40cbc22
Compare
… 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.
40cbc22
to
5461508
Compare
@swift-ci Please smoke test |
@swift-ci Please test source compatibility |
/// If true, nest scopes so a variable is out of scope before its declaration | ||
/// Does not handle capture rules for local functions properly. | ||
/// If false don't push uses down into subscopes after decls. | ||
static const bool handleUseBeforeDef = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the flag I've been talking about!
ASTScopeAssert(isLocalBinding || insertionPoint == parentScope, | ||
"Bindings at the top-level or members of types should " | ||
"not change the insertion point"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
// In local context, the PatternEntryDeclScope becomes the insertion point, so | ||
// that all any bindings introduecd by the pattern are in scope for subsequent | ||
// lookups. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice and clear!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
// CHECK-EXPANDED-NEXT: |-TypeAliasDeclScope {{.*}}, [15:1 - 15:15] | ||
// CHECK-EXPANDED-NEXT: `-PatternEntryDeclScope {{.*}}, [13:5 - 21:28] entry 0 'c' | ||
// CHECK-EXPANDED-NEXT: |-PatternEntryInitializerScope {{.*}}, [13:9 - 13:9] entry 0 'c' | ||
// CHECK-EXPANDED-NEXT: |-TypeAliasDeclScope {{.*}}, [15:1 - 15:15] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: It seems like the TypeAliasDeclScope got overindented along the way.
Today,
BraceStmtScope
introduces all of its local bindings without regard to source order. Instead, let's model pattern bindings properly, by having thePatternEntryDeclScope
introduce its bindings. Note that whilePatternEntryInitializerScope
is a child of thePatternEntryDeclScope
, it's lookup parent skips over thePatternEntryDeclScope
since bindings are not visible from their own initializer.For example,
The names
x
andy
are in scope immediately following(0, 0)
, and the namesu
andv
are in scope immediately followingfoo(x, y)
.Builds on top of #34039.