| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
pattern matching on case classes where pattern
is not known to be a subclass of the unapply's argument type
used to result in code like:
```
if (x1.isInstanceOf[Foo]) {
val x2 = x1.asInstanceOf[Foo]
if (x2 != null) { // redundant
...
}
}
```
this wastes byte code on the redundant null check
with this patch, when previous type tests imply
the variable cannot be null, there's no null check
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Caught out by the different semantics of isInstanceOf and
pattern matching.
trait K { case class CC(name: String) }
object Foo extends K
object Bar extends K
Foo.CC("a") == Bar.CC("a")
That expression is supposed to be false, and with this
commit it is once again.
|
|
|
|
|
|
| |
The call to `Option#get` on the result of the
unapply method was unpositioned and ended up
with the position of the `match`.
|
|
|
|
|
|
|
| |
This was part of the introduction of ProductN, which had
to go back into pandora's box because of issues with cycles
during typing. These should have been reverted along
with it.
|
|
|
|
|
|
|
| |
Thanks to the hotspot DTrace probes. I'm not sure why
this checkfile changed, but hopefully it's innocuous.
Review by @VladUreche for the checkfile and @gkossakowski
so he can tell me how much faster.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
To facilitate debugging pattern matches, we store the values for
sub-patterns of extractor (synthetic or user-defined) patterns in local variables.
When performing an optimized build, and when possible, we don't do store but inline them directly.
For soundness, SI-5158, SI-6070, we must always store the values of mutable case class fields.
(Specifying -optimize is the only way to suppress emitting these local variables.
An unoptimized build will always generate them, which was deemed the right default during the meeting.)
(updated flags for t4425 to get consistent runs on optimized and non-optimized partest runs
by always passing -optimize)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Also closes SI-5158 (debuggability), SI-6070 (soundness).
To improve both debuggability and soundness,
we now store the result of an extractor (user-defined and synthetic)
in local variables.
For the case class case, this also fixes the soundness bug SI-6070,
as this prevents post-match mutation of bound variables.
The core of the refactoring consisted of introducing the PreserveSubPatBinders
trait, which introduces local variables instead of substituting symbols
for the RHS of those variables (so this can be seen as reverting the premature optimization
of inline the case-class getters into the case body).
Since TreeMakerToCond fuses the substitutions performed in a match to find out
which symbolic values binders evaluate to, masquerade PreserveSubPatBinders's
binding of subPatBinders and subPatRefs as the corresponding substitution.
Consider `case class Foo(bar: Int)`, then `case y@Foo(x) => println(x)`
gives rise to `{val x = y.bar; println(x)}` (instead of `println(y.bar)`),
and `subPatternsAsSubstitution` pretends we still replace `x` by `y.bar`,
instead of storing it in a local variable so that the rest of the analysis need not be modified.
Misc notes:
- correct type for seq-subpattern
- more error resilience (ill-typed patterns sometimes slip past the typechecker -- reopened SI-4425)
TODO: come up with a more abstract framework for expressing bound symbols and their values
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
turn switches with guards into guard-free switches by collecting all cases
that are (possibly) guarded by different guards but that switch on the same constant,
and pushing the implied if-then-else into the collapsed case body
```
case C if G1 => B1
case C if Gi => Bi
case C if GN => BN
```
becomes
```
case C => if (G1) B1
else if (Gi) Bi
else if (GN) BN
else default() // not necessary if GN == EmptyTree
```
default() is a jump to the default case; to enable this, we wrap a default() { } labeldef
around the last case's body (the user-defined default or the synthetic case that throws the matcherror)
so we can jump to the default case after the last guard is checked
(assuming unreachability is checked, once we ended up in a non-default case,
one of the guards either matches or we go to the default case)
the unreachability analysis is minimal -- we simply check (after rewriting to guard-free form)
that:
- there are no duplicate cases
- the default case comes last
misc notes:
- can't jump in exception handlers (TODO: a more fine-grained analysis on when we need to jump)
- work around SI-6015 (test file run/t5830.scala crashed the inliner)
- propagate type of case body to label def of default case
(needed for existentials, see e.g., t2683)
- the default(){} LabelDef breaks SelectiveANFTransform -- workaround: don't write guarded switches in CPS code
(do the above transformation manually)
|
| |
|
|
|
|
| |
Wonder if we should have a special area for high-turnover checkfiles.
|
|
|
|
| |
No boxing, no MODULE$ indirection.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
workaround for inliner bug in run/t3835
see SI-5672 for the optimizer bug
tiny switches (2 cases or less) don't make sense anyway,
so this is not a big deal
the annotDepMethType.flags contained -Xexperimental,
which causes Any* to be considered as a valid return type,
before we weren't exposed to this, because the product methods
used (tiny) switches; with this change, they went back to pattern matches
in any case, the -Xexperimental was intended to turn on dependent method types,
not Any* as valid type (I can only assume), and they are now on by default
the other tests were affected by our refusal to emit tiny switches
|
|
|
|
|
|
|
| |
some tests (unreachability, exhaustivity, @switch annotation checking) are still run under -Xoldpatmat,
but that will change before we go into RC mode (then the test/ partest of this commit will be reverted)
removed irrelevant dependency on patmat
|
|
|
|
|
| |
Looks like we will need blood, toil, tears, and sweat. No review.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Finished giving case classes a ProductN parent, and flipped it on. The
"finish" part involved not breaking existing code where case classes
manually extend the appropriate ProductN. (Like, Tuple 1-22.)
- Generalized most of SyntheticMethods to ease method creation and class
manipulation in general.
- Fixed bugs related to the above, like the fact that this used to be a
compile error:
scala> case class Foo() extends Serializable
<console>:28: error: trait Serializable is inherited twice
case class Foo() extends Serializable
^
It feels like there's a better way to eliminate the duplicate parents,
but after spending a lot of time chasing my tail in that peril-fraught
zone between namer and typer, I don't see an easy path to improve on
it. Closes SI-1799. For that modification to Typers, review by odersky.
|
|
Created infrastructure for testing icode + settings/partest yak shaving.
See enclosed test files/run/inline-ex-handlers.scala. To compare
optimized and unoptimized icode after a given phase, all you need in a
partest source file is this:
import scala.tools.partest.IcodeTest
object Test extends IcodeTest {
override def printIcodeAfterPhase = "inlineExceptionHandlers"
}
Other things can be done, see IcodeTest.scala. Review by ureche.
|