SI-7459 Handle pattern binders used as prefixes in TypeTrees.#3490
SI-7459 Handle pattern binders used as prefixes in TypeTrees.#3490retronym wants to merge 2 commits intoscala:masterfrom
Conversation
|
Looks like an unhappy owner chain: |
|
And now for the other last 10%: import scala.concurrent._
import scala.util._
class Test {
(null: Any) match {
case s @ Some(_) => ???
case f @ _ =>
() => f
???
}
} |
Match translation was incorrect for:
case t => new t.C
case D(t) => new d.C
We would end up with Types in TypeTrees referring to the wrong symbols, e.g:
// t7459a.scala
((x0$1: this.LM) => {
case <synthetic> val x1: this.LM = x0$1;
case4(){
matchEnd3(new tttt.Node[Any]())
};
matchEnd3(x: Any){
x
}
Or:
// t7459b.scala
((x0$1: CC) => {
case <synthetic> val x1: CC = x0$1;
case4(){
if (x1.ne(null))
matchEnd3(new tttt.Node[Any]())
else
case5()
};
This commit:
- Changes `bindSubPats` to traverse types, as well as terms,
in search of references to bound symbols
- Changes `Substitution` to reuse `Tree#substituteSymbols` rather
than the home-brew substitution from `Tree`s to `Tree`s, if the
`to` trees are all `Ident`s
I had to dance around the awkward handling of "swatches" (exception
handlers that can be implemented with JVM native type switches) by
duplicating trees to avoid seeing the results of `substituteSymbols`
in `caseDefs` after we abandon that approach if we detect the
patterns are too complex late in the game.
|
Life wasn't meant to be easy. Closing for now. The difficulty arises from using Here's another messy swing at it which also gets all the new tests passing. https://github.com/retronym/scala/compare/ticket/7459-reloaded |
|
I was also thinking that we should remove the mutation during analysis. It's another instance of jumping in head first to figure out how deep the pool is -- assuming we can abort mid-flight before we hit the bottom. |
|
That's a dangerous habit in our swimming pool. I was wrangling similar problems in typers recently when it bailed out of names/defaults and left a trail of destruction in the owners of locally defined symbols. |
|
My big find in that latest branch, BTW, was using Although it would probably be cleaner to just emit eager binders for anything used in a single type. I got lost trying to implement that, though. |
|
Anyway, this change can land in 2.11.1, so lets refocus on the others for now. |
|
I'll put my speedos back in the drawer. |
Match translation was incorrect for:
We would end up with Types in TypeTrees referring to the wrong symbols, e.g:
Or:
// t7459b.scala
((x0$1: CC) => {
case val x1: CC = x0$1;
case4(){
if (x1.ne(null))
matchEnd3(new tttt.NodeAny)
else
case5()
};
This commit:
bindSubPatsto traverse types, as well as terms,in search of references to bound symbols
Substitutionto reuseTree#substituteSymbolsratherthan the home-brew substitution from
Trees toTrees, if thetotrees are allIdentsI had to dance around the awkward handling of "swatches" (exception
handlers that can be implemented with JVM native type switches) by
duplicating trees to avoid seeing the results of
substituteSymbolsin
caseDefsafter we abandon that approach if we detect thepatterns are too complex late in the game.