-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Try/hygienic desugaring #68
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
Adds a new scheme by which a TypeTree() can refer for its type to the symbol of some other type. Applies the scheme to setter parameters, replacing the previous ad-hoc solution.
To get truly hygienic desugared trees, we need a derived type tree scheme that's more flexible than just the previous two choices of info-of-symbol and typeref-of-symbol. The new scheme based on DerivedTypeTrees allows arbitrary methods to derive the type tree's type.
Made desugaring hygienic. Trees that are derived from some other tree are no longer stored as simple untyped Ident trees, but as TypeTrees that know how to derive their types from some other type. Test cases in pos: hygiene.scala, t0054.scala and t0085.scala. The comment in hygiene.scala points to the difficulties we are facing. In particular, we need type trees that can rebind some references of a source type to local occurrences with the same name. t0054.scala is similar to hygiene.scala. t0085.scala is trickier, but also related. Essentially the problem there is that we have a class that inherits its outer class. In this case it is important to resolve an identifier in the right context. The identifier added to the copy method of a case class must be resolved outside the class (just like the same identifier in the constructor of that case class).
/cc @densh |
*/ | ||
abstract class DerivedTypeTree extends TypeTree(EmptyTree) { | ||
|
||
private var myWatched: Tree = EmptyTree |
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.
Can we get away with copy on write instead of mutability here?
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.
It's only used for diagnostics anyway. Could delete the field it, at the risk of less helpful debug output.
Otherwise LGTM |
@@ -18,6 +18,7 @@ class tests extends CompilerTest { | |||
|
|||
val posDir = "./tests/pos/" | |||
val negDir = "./tests/neg/" | |||
val newDir = "./tests/new/" |
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.
What does this mean?
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.
It's a staging area for new tests. Should be empty normally. My workflow is the following:
- Pull in some tests to new
- Run new_all in tests.
- Triage into pos, invalid/pos, pending/pos, depending on test outcomes and bug fixes.
@gzm0 Yes, let's close. |
Desugaring is now hygienic.
Desugaring involves copying things in new scopes. Example: Constructor parameters of an implicit case class are copied to (1) the apply method in the companion object (2) the copy method in the class itself, (3) the implicit wrapper in the enclosing scope, and (4) type parameters are also copied to the unapply method in the companion object. It is important that the types of these parameters are all resolved in the same context as the constructor parameter. Otherwise name clashes can result, or, what's worse, things can be resolved in the wrong context. A particular bad case arises if an inner class inherits some generic instance of its outer class. In that case it makes a big difference whether something is resolved in the class or outside of it.
At the same time, we cannot simply copy full types, because the local copies might contain references to redefined type parameters and term parameters which need to be re-bound.
The present pull request achieves all that. And except for some general logic, it is local to Desugar, no cooperation of Namer or Typer is needed. As a bonus, we get a more principled treatment of getter parameters which does not require Namer cooperation.