summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-03-23 18:21:48 +0100
committerAdriaan Moors <adriaan.moors@epfl.ch>2012-03-26 17:42:37 +0200
commite0d1f15c244539ce7970c4a903eb49962eaa3569 (patch)
tree00329404ef91de96da25d7c34f11c7bede3eba12 /src/compiler
parenta532ba0600444b3564b6b015688ebc4cdf084ba6 (diff)
downloadscala-e0d1f15c244539ce7970c4a903eb49962eaa3569.tar.gz
scala-e0d1f15c244539ce7970c4a903eb49962eaa3569.tar.bz2
scala-e0d1f15c244539ce7970c4a903eb49962eaa3569.zip
[vpm] skolemize result type in translateMatch
... but not before, to avoid having skolems in typedMatchAnonFun cast result of missingCase (avoid skolem mismatch) relevant test cases: pos/existentials-harmful.scala, pos/gadt-gilles.scala, pos/t2683.scala, pos/virtpatmat_exist4.scala
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala22
2 files changed, 14 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index bbc36e01c9..aff8368f75 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -1649,7 +1649,7 @@ class Foo(x: Other) { x._1 } // no error in this order
def catchAll = matchFailGen map { matchFailGen =>
val scrutRef = if(scrutSym ne NoSymbol) REF(scrutSym) else EmptyTree // for alternatives
- LabelDef(nextCase, Nil, matchEnd APPLY (matchFailGen(scrutRef))) // need to jump to matchEnd with result generated by matchFailGen (could be `FALSE` for isDefinedAt)
+ LabelDef(nextCase, Nil, matchEnd APPLY (_asInstanceOf(matchFailGen(scrutRef), restpe))) // need to jump to matchEnd with result generated by matchFailGen (could be `FALSE` for isDefinedAt)
} toList
// catchAll.isEmpty iff no synthetic default case needed (the (last) user-defined case is a default)
// if the last user-defined case is a default, it will never jump to the next case; it will go immediately to matchEnd
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 95a1eafae2..000e5b78eb 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2144,15 +2144,15 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case Annotated(Ident(nme.synthSwitch), selector) => (selector, false)
case s => (s, true)
}
- val selector1 = checkDead(typed(selector, EXPRmode | BYVALmode, WildcardType))
- val selectorTp = packCaptured(selector1.tpe.widen)
- val casesTyped = typedCases(cases, selectorTp, resTp)
+ val selector1 = checkDead(typed(selector, EXPRmode | BYVALmode, WildcardType))
+ val selectorTp = packCaptured(selector1.tpe.widen)
+
+ val casesTyped = typedCases(cases, selectorTp, resTp)
val caseTypes = casesTyped map (c => packedType(c, context.owner).deconst)
- val (ownType0, needAdapt) = if (isFullyDefined(resTp)) (resTp, false) else weakLub(caseTypes)
- val ownType = ownType0.skolemizeExistential(context.owner, context.tree)
- val casesAdapted = if (!needAdapt) casesTyped else casesTyped map (adaptCase(_, mode, ownType))
- // val (owntype0, needAdapt) = ptOrLub(casesTyped map (x => repackExistential(x.tpe)))
- // val owntype = elimAnonymousClass(owntype0)
+ val (ownType, needAdapt) = if (isFullyDefined(resTp)) (resTp, false) else weakLub(caseTypes)
+
+ val casesAdapted = if (!needAdapt) casesTyped else casesTyped map (adaptCase(_, mode, ownType))
+
(selector1, selectorTp, casesAdapted, ownType, doTranslation)
}
@@ -2166,7 +2166,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
Match(selector1, casesAdapted) setType ownType // setType of the Match to avoid recursing endlessly
} else {
val scrutType = repeatedToSeq(elimAnonymousClass(selectorTp))
- MatchTranslator(this).translateMatch(selector1, casesAdapted, repeatedToSeq(ownType), scrutType, matchFailGen)
+ // we've packed the type for each case in prepareTranslateMatch so that if all cases have the same existential case, we get a clean lub
+ // here, we should open up the existential again
+ // relevant test cases: pos/existentials-harmful.scala, pos/gadt-gilles.scala, pos/t2683.scala, pos/virtpatmat_exist4.scala
+ MatchTranslator(this).translateMatch(selector1, casesAdapted, repeatedToSeq(ownType.skolemizeExistential(context.owner, context.tree)), scrutType, matchFailGen)
}
}
@@ -2247,6 +2250,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
val members = if (!isPartial) List(applyMethod) else List(applyMethod, isDefinedAtMethod)
+
typed(Block(List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, tree.pos)), New(anonClass.tpe)), mode, pt)
}