scala/scala — pull request #866 by adriaanm (2012-07-11 12:23:28+00:00)
Title: SI-6011 switches: unreachability, guard-free form

A complete overhaul. The original implementation in SI-5830 (#821) was pretty buggy.

Collapse guarded cases that switch on the same constant (the last case may be unguarded).

Cases with patterns A and B switch on the same constant iff for all values x that match A also match B and vice versa.
(This roughly corresponds to equality on trees modulo alpha renaming and reordering of alternatives.)

The rewrite only applies if some of the cases are guarded (this must be checked before invoking this method).

The rewrite proceeds by grouping the cases into subsequences of overlapping cases
(since for any input, and when disregarding their guards, they either all match or they don't).
They are then merged into one case with their guards pushed into the body as follows (with P representing the overlapping pattern):

`{case P if(G_i) => B_i }*` is rewritten to `case P => {if(G_i) B_i}*`

The rewrite fails (and returns Nil) when:
1. there is a subsequence of overlapping cases that has an unguarded case in the middle;
only the last case may be un-guarded

2. there are overlapping cases that differ (tested by `caseImplies`)
cases with patterns A and B are overlapping if for SOME value x, A matches x implies B matches y OR vice versa <-- note the difference with case equality defined above
for example `case 'a' | 'b' =>` and `case 'b' =>` are different and overlapping (overlapping and equality disregard guards)

Also closes SI-6048 (duplicate).