Skip to content

ASTScope: Simplify representation of closures #33981

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

slavapestov
Copy link
Contributor

@slavapestov slavapestov commented Sep 17, 2020

Let's use a ClosureParametersScope for all closures, even those
without an 'in' keyword. This eliminates the need for the
ClosureBodyScope and WholeClosureScope.

Also, let's move the lookup of capture list bindings from
CaptureParametersScope to CaptureListScope. This eliminates the
need for CaptureParametersScope to store a reference to the
capture list, which allows us to remove the AbstractClosureScope
base class entirely.

Let's use a ClosureParametersScope for all closures, even those
without an 'in' keyword. This eliminates the need for the
ClosureBodyScope and WholeClosureScope.

Also, let's move the lookup of capture list bindings from
CaptureParametersScope to CaptureListScope. This eliminates the
need for CaptureParametersScope to store a reference to the
capture list, which allows us to remove the AbstractClosureScope
base class entirely.
@slavapestov slavapestov force-pushed the simplify-astscope-closure-representation branch from 45f6cd2 to 3801d16 Compare September 17, 2020 18:47
@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test

@slavapestov
Copy link
Contributor Author

@swift-ci Please test source compatibility

@davidungar
Copy link
Contributor

davidungar commented Sep 17, 2020

Just from reading the PR description, it sounds like maybe it would be good to split this up into 2 PRs, one for each paragraph of the description.
A couple of other general thoughts: default initializers for closure parameters, and generic type parameters for closures. I'm guessing that neither of these is allowed today. But if they were allowed tomorrow, would you have to undo the simplification here?

Comment on lines +399 to +403
if (auto *closure = dyn_cast<ClosureExpr>(E)) {
scopeCreator
.ifUniqueConstructExpandAndInsert<ClosureParametersScope>(
parent, closure);
return {false, E};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before, the code separated out finding the closures from constructing the scopes for them. But here, they are combined. Now, the class name on line 390 isn't quite right. But more to the point, I don't think it serves clarity to combine the enumeration (i.e. finding) with the handling. I would prefer the forEachClosureIn form. When I look at lines 386-390 in the old version, I can see what's going on for each closure without reading through all the code in ClosureFinder.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’d have to pass in two lambdas, one to handle capture lists and one to handle closure expressions. It didn’t seem worth it at that point.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My quick read didn't catch that. Thanks! So that class would have to be named BuildScopesForContainedClosuresAndCaptureLists. And that name still has a bit of a bad smell to my nose. Maybe passing in two lambdas would be better.

Copy link
Contributor

@davidungar davidungar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the simplification, but worry it may be too simple and might have to be undone in the future if missing combinations of features get added to Swift. I haven't thought it through, though.

@slavapestov
Copy link
Contributor Author

Default argument values can’t see other parameters, and generic parameters would get their own scope that begins at the generic parameter list and not after the “in”.

@davidungar
Copy link
Contributor

Default argument values can’t see other parameters, and generic parameters would get their own scope that begins at the generic parameter list and not after the “in”.

Generic constraints can see prior generic parameters, at least in some cases, so maybe someday default argument values will be able to see prior arguments. (but maybe not) I

WRT generic parameters, in the old scheme, the generic param scope matrushka could have gone in the "whole closure" scope (assuming closures could be generic).

I guess what I'm thinking is that I wish closures were more like functions. But I can't say that my hallucinations are enough to object too much to this simplification.

@slavapestov
Copy link
Contributor Author

Let’s have the scope tree reflect the language we have, not the language we think we want or might have in the future :-)

@slavapestov slavapestov merged commit 992ffa6 into swiftlang:master Sep 18, 2020
@davidungar
Copy link
Contributor

Let’s have the scope tree reflect the language we have, not the language we think we want or might have in the future :-)

Yes, there's value in minimalism. I also find value in symmetry. Not always obvious to me which to favor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants