summaryrefslogtreecommitdiff
path: root/src/scalap
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-03-06 15:58:58 +0100
committerAdriaan Moors <adriaan.moors@epfl.ch>2012-03-09 09:10:38 +0100
commit29bcadefb451bbf546e6f763027dac16f5b6f51b (patch)
treeba825b7dd0d3a1c8ed286a3275bcc1c17ff77cb9 /src/scalap
parent0cffdf38d9e2d88e66d8649d317f8815716b2748 (diff)
downloadscala-29bcadefb451bbf546e6f763027dac16f5b6f51b.tar.gz
scala-29bcadefb451bbf546e6f763027dac16f5b6f51b.tar.bz2
scala-29bcadefb451bbf546e6f763027dac16f5b6f51b.zip
SI-5189 fixed: safe type infer for constr pattern
several fixes to the standard library due to - the safer type checker this fix gives us (thus, some casts had to be inserted) - SI-5548 - type inference gets a bit more complicated, it needs help (chainl1 in combinator.Parsers) To deal with the type slack between actual (run-time) types and statically known types, for each abstract type T, reflect its variance as a skolem that is upper-bounded by T (covariant position), or lower-bounded by T (contravariant). Consider the following example: class AbsWrapperCov[+A] case class Wrapper[B](x: Wrapped[B]) extends AbsWrapperCov[B] def unwrap[T](x: AbsWrapperCov[T]): Wrapped[T] = x match { case Wrapper(wrapped) => // Wrapper's type parameter must not be assumed to be equal to T, // it's *upper-bounded* by it wrapped // : Wrapped[_ <: T] } this method should type check if and only if Wrapped is covariant in its type parameter before inferring Wrapper's type parameter B from x's type AbsWrapperCov[T], we must take into account that x's actual type is: AbsWrapperCov[Tactual] forSome {type Tactual <: T} since AbsWrapperCov is covariant in A -- in other words, we must not assume we know T exactly, all we know is its upper bound since method application is the only way to generate this slack between run-time and compile-time types (TODO: right!?), we can simply replace skolems that represent method type parameters as seen from the method's body by other skolems that are (upper/lower)-bounded by that type-parameter skolem (depending on the variance position of the skolem in the statically assumed type of the scrutinee, pt) this type slack is introduced by adaptConstrPattern: before it calls inferConstructorInstance, it creates a new context that holds the new existential skolems the context created by adaptConstrPattern must not be a CaseDef, since that confuses instantiateTypeVar and the whole pushTypeBounds/restoreTypeBounds dance (CaseDef contexts remember the bounds of the type params that we clobbered during GADT typing) typedCase deskolemizes the existential skolems back to the method skolems, since they don't serve any further purpose (except confusing the old pattern matcher) typedCase is now better at finding that context (using nextEnclosing)
Diffstat (limited to 'src/scalap')
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/Rules.scala2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/scalap/scala/tools/scalap/scalax/rules/Rules.scala b/src/scalap/scala/tools/scalap/scalax/rules/Rules.scala
index 43f9c20b1d..70926208b3 100644
--- a/src/scalap/scala/tools/scalap/scalax/rules/Rules.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/Rules.scala
@@ -130,7 +130,7 @@ trait StateRules {
def rep(in : S, t : T) : Result[S, T, X] = {
if (finished(t)) Success(in, t)
else rule(in) match {
- case Success(out, f) => rep(out, f(t))
+ case Success(out, f) => rep(out, f(t)) // SI-5189 f.asInstanceOf[T => T]
case Failure => Failure
case Error(x) => Error(x)
}