summaryrefslogtreecommitdiff
path: root/test/files/run/t7214.scala
Commit message (Collapse)AuthorAgeFilesLines
* Pattern matcher: extractors become name-based.Paul Phillips2013-08-171-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | An extractor is no longer required to return Option[T], and can instead return anything which directly contains methods with these signatures: def isEmpty: Boolean def get: T If the type of get contains methods with the names of product selectors (_1, _2, etc.) then the type and arity of the extraction is inferred from the type of get. If it does not contain _1, then it is a single value extractor analogous like Option[T]. This has significant benefits and opens new territory: - an AnyVal based Option-like class can be used which leverages null as None, and no allocations are necessary - for primitive types the benefit is squared (see below) - the performance difference between case classes and extractors should now be largely eliminated - this in turn allows us to recapture great swaths of memory which are currently squandered (e.g. every TypeRef has fields for pre and args, even though these are more than half the time NoPrefix and Nil) Here is a primitive example: final class OptInt(val x: Int) extends AnyVal { def get: Int = x def isEmpty = x == Int.MinValue // or whatever is appropriate } // This boxes TWICE: Int => Integer => Some(Integer) def unapply(x: Int): Option[Int] // This boxes NONCE def unapply(x: Int): OptInt As a multi-value example, after I contribute some methods to TypeRef: def isEmpty = false def get = this def _1 = pre def _2 = sym def _3 = args Then it's extractor becomes def unapply(x: TypeRef) = x Which, it need hardly be said, involves no allocations.
* SI-7214 outer check based on dealiased pattern type.Jason Zaugg2013-03-051-0/+57
A Typed Pattern (_: T) is more than `.isInstanceOf`: if `T` is a path dependent type, the scrutinee's $outer reference is also compared against the prefix of `T`. The code that synthesises this is split into two places. `needsOuterCheck` determines whether to add this check, based on the type `T`, and the type of the scrutinee. If it gives the go-ahead, `treeCondStrategy.outerCheck` synthesizes the check. The new test case demonstrates the problems caused by the failure to dealias in `needsOuterCheck`: it could either wrongly lead to synthesis of an outer test (which would crash), or wrongly omit the outer test (meaning overly liberal matching.) A simple `dealias` remedies this. `dealiasWiden` is *not* appropriate here; we need to keep hold of singleton types. I'll also note that there is already a little slack between these methods, as commented: > ExplicitOuter replaces `Select(q, outerSym) OBJ_EQ expectedPrefix` > by `Select(q, > outerAccessor(outerSym.owner)) OBJ_EQ expectedPrefix` > if there's an outer accessor, otherwise the condition becomes `true` > TODO: can we improve needsOuterTest so there's always an outerAccessor? So this is probably a fragile area that warrants a careful review with a view to design improvements.