summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-03-05 09:57:35 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-03-05 18:41:05 +0100
commitacd74cae0935d79cedbeb2bec719174b7cf54e5e (patch)
tree347a3a62a59fdf3d57fcee76e07a7b609437afae /src
parentb98cc582fb8e06a6b7049e6688a80c8b38daba98 (diff)
downloadscala-acd74cae0935d79cedbeb2bec719174b7cf54e5e.tar.gz
scala-acd74cae0935d79cedbeb2bec719174b7cf54e5e.tar.bz2
scala-acd74cae0935d79cedbeb2bec719174b7cf54e5e.zip
SI-7214 outer check based on dealiased pattern type.
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.
Diffstat (limited to 'src')
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 76d6ec80be..81e0457916 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -5354,7 +5354,9 @@ trait Types extends api.Types { self: SymbolTable =>
case _ =>
NoType
}
- patType match {
+ // See the test for SI-7214 for motivation for dealias. Later `treeCondStrategy#outerTest`
+ // generates an outer test based on `patType.prefix` with automatically dealises.
+ patType.dealias match {
case TypeRef(pre, sym, args) =>
val pre1 = maybeCreateDummyClone(pre, sym)
(pre1 ne NoType) && isPopulated(copyTypeRef(patType, pre1, sym, args), selType)