summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2008-06-18 15:39:36 +0000
committerMartin Odersky <odersky@gmail.com>2008-06-18 15:39:36 +0000
commit72da305329d3a8889e4e5f8d81a0ecad04b097ad (patch)
tree6b79b4d0d37b73444a712279fc4b08c5009fe45f
parent707e55c2271a6b35fb4a173106c2a36aa07cfe9a (diff)
downloadscala-72da305329d3a8889e4e5f8d81a0ecad04b097ad.tar.gz
scala-72da305329d3a8889e4e5f8d81a0ecad04b097ad.tar.bz2
scala-72da305329d3a8889e4e5f8d81a0ecad04b097ad.zip
gixed gilles' gadt problems. Added some tests
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala20
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala5
-rw-r--r--test/files/pos/gadt-gilles.scala37
-rw-r--r--test/files/pos/t0504.scala9
-rwxr-xr-xtest/files/pos/t0971.java4
-rw-r--r--test/files/run/t0883.check2
-rwxr-xr-xtest/files/run/t0883.scala13
-rwxr-xr-xtest/pending/run/t0508.scala13
-rwxr-xr-xtest/pending/run/t0889.scala9
10 files changed, 105 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index b1acd9f1d0..3221fa8601 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -3759,7 +3759,6 @@ A type's typeSymbol should never be inspected directly.
* @param variances The variances of type parameters; need to reverse
* solution direction for all contravariant variables.
* @param upper When `true' search for max solution else min.
- * @throws NoInstance
*/
def solve(tvars: List[TypeVar], tparams: List[Symbol],
variances: List[Int], upper: Boolean): Boolean = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 1cec94d0d0..c6e069bf01 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -1055,9 +1055,16 @@ trait Infer {
(lo, hi)
}
- def isInstantiatable(tvar: TypeVar) = {
- val (lo, hi) = instBounds(tvar)
- lo <:< hi
+ def isInstantiatable(tvars: List[TypeVar]) = {
+ def cloneTypeVar(tv: TypeVar) = {
+ val tv1 = TypeVar(tv.origin, new TypeConstraint(tv.constr.lobounds, tv.constr.hibounds))
+ tv1.constr.inst = tv.constr.inst
+ tv1
+ }
+ val tvars1 = tvars map cloneTypeVar
+ // Note: right now it's not clear that solving is complete, or how it can be made complete!
+ // So we should come back to this and investigate.
+ solve(tvars1, tvars1 map (_.origin.typeSymbol), tvars1 map (x => COVARIANT), false)
}
def instantiateTypeVar(tvar: TypeVar) {
@@ -1160,14 +1167,17 @@ trait Infer {
if (settings.debug.value) log("free type params (1) = " + tpparams)
var tvars = tpparams map freshVar
var tp = pattp.instantiateTypeParams(tpparams, tvars)
- if (!((tp <:< pt) && (tvars forall isInstantiatable))) {
+ if (!((tp <:< pt) && isInstantiatable(tvars))) {
tvars = tpparams map freshVar
tp = pattp.instantiateTypeParams(tpparams, tvars)
val ptparams = freeTypeParamsOfTerms.collect(pt)
if (settings.debug.value) log("free type params (2) = " + ptparams)
val ptvars = ptparams map freshVar
val pt1 = pt.instantiateTypeParams(ptparams, ptvars)
- if (!(isPopulated(tp, pt1) && (tvars forall isInstantiatable) && (ptvars forall isInstantiatable))) {
+ if (!(isPopulated(tp, pt1) && isInstantiatable(tvars ::: ptvars))) {
+ //println(tpparams)
+ //println(tvars map instBounds)
+ //println(ptvars map instBounds)
error(pos, "pattern type is incompatible with expected type"+foundReqMsg(pattp, pt))
return pattp
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 40db3dd4a8..9f1d11f425 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2977,8 +2977,9 @@ trait Typers { self: Analyzer =>
case Bind(_, _) =>
if (arg.symbol.isAbstractType)
arg.symbol setInfo // XXX, feedback. don't trackSymInfo here!
- TypeBounds(lub(List(arg.symbol.info.bounds.lo, tparam.info.bounds.lo)),
- glb(List(arg.symbol.info.bounds.hi, tparam.info.bounds.hi)))
+ TypeBounds(
+ lub(List(arg.symbol.info.bounds.lo, tparam.info.bounds.lo.subst(tparams, argtypes))),
+ glb(List(arg.symbol.info.bounds.hi, tparam.info.bounds.hi.subst(tparams, argtypes))))
case _ =>
}}
TypeTree(owntype) setOriginal(tree) // setPos tree.pos
diff --git a/test/files/pos/gadt-gilles.scala b/test/files/pos/gadt-gilles.scala
new file mode 100644
index 0000000000..662be9017d
--- /dev/null
+++ b/test/files/pos/gadt-gilles.scala
@@ -0,0 +1,37 @@
+object Test {
+ trait A[T]
+ trait B[U, V] extends A[U with V] // indirect constraint
+ trait C
+ trait D
+
+ val x: A[C with D] = new B[C, D] {}
+ val y: A[C with D] = x match { case b: B[u, v] => (new B[u, v] {}): A[u with v] } // OK
+
+
+ def f[T, U](p: A[T with U]): A[T with U] = p match { case b: B[u, v] => new A[u with v] {} } // Not OK
+}
+
+object Test1 {
+
+ trait T[U, V <: U]
+
+ def f(r: Any) = r match {
+
+ case t: T[u, v] => new T[u, v]{}
+
+ }
+
+}
+object Test2 {
+
+ trait T[U, V <: U]
+
+ val x: T[Int, Int] = new T[Int, Int]{}
+
+ x match {
+
+ case t: T[u, v] => new T[u, v]{}
+
+ }
+
+}
diff --git a/test/files/pos/t0504.scala b/test/files/pos/t0504.scala
new file mode 100644
index 0000000000..b2b0b85e43
--- /dev/null
+++ b/test/files/pos/t0504.scala
@@ -0,0 +1,9 @@
+package b {
+ class B
+}
+
+package a.b {
+ class A {
+ val x = new _root_.b.B
+ }
+}
diff --git a/test/files/pos/t0971.java b/test/files/pos/t0971.java
new file mode 100755
index 0000000000..d852ef698d
--- /dev/null
+++ b/test/files/pos/t0971.java
@@ -0,0 +1,4 @@
+class A {
+ int y = 1, z;
+ static Object x = new java.util.HashMap<Object , Object > () ;
+} \ No newline at end of file
diff --git a/test/files/run/t0883.check b/test/files/run/t0883.check
new file mode 100644
index 0000000000..2c94e48371
--- /dev/null
+++ b/test/files/run/t0883.check
@@ -0,0 +1,2 @@
+OK
+OK
diff --git a/test/files/run/t0883.scala b/test/files/run/t0883.scala
new file mode 100755
index 0000000000..5cd4418f5b
--- /dev/null
+++ b/test/files/run/t0883.scala
@@ -0,0 +1,13 @@
+case class Foo(name: String)
+case object Bar extends Foo("Bar")
+case class Baz extends Foo("Baz")
+object Test extends Application {
+ Foo("Bar") match {
+ case Bar => println("What?")
+ case _ => println("OK")
+ }
+ Foo("Baz") match {
+ case Baz() => println("What?")
+ case _ => println("OK")
+ }
+}
diff --git a/test/pending/run/t0508.scala b/test/pending/run/t0508.scala
new file mode 100755
index 0000000000..7ef6f8197f
--- /dev/null
+++ b/test/pending/run/t0508.scala
@@ -0,0 +1,13 @@
+object Test extends Application {
+
+ case class Foo(s: String, n: Int)
+
+ def foo[A, B, C](unapply1: A => Option[(B, C)], v: A) = {
+ unapply1(v) match {
+ case Some((fst, snd)) => println("first: " + fst, " second: " + snd)
+ case _ => println(":(")
+ }
+ }
+
+ foo(Foo.unapply, Foo("this might be fun", 10))
+}
diff --git a/test/pending/run/t0889.scala b/test/pending/run/t0889.scala
new file mode 100755
index 0000000000..db6076e8e2
--- /dev/null
+++ b/test/pending/run/t0889.scala
@@ -0,0 +1,9 @@
+object Test extends Application {
+
+ val a = List("a")
+
+ a match {
+ case Seq("a", "b", rest @ _*) => println("a, b, " + rest)
+ case Seq(first, rest @ _*) => println("first: " + first + ", rest: " + rest)
+ }
+}