summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2010-02-26 09:42:50 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2010-02-26 09:42:50 +0000
commit93f8dd3a4ee6b16221f77c19c0589154f83507b9 (patch)
tree20011037e2030706534d07d48987225870b6f2a7
parentcc9e8eda3364dcb7bf5b92a3d3824b66c85ef05f (diff)
downloadscala-93f8dd3a4ee6b16221f77c19c0589154f83507b9.tar.gz
scala-93f8dd3a4ee6b16221f77c19c0589154f83507b9.tar.bz2
scala-93f8dd3a4ee6b16221f77c19c0589154f83507b9.zip
closes #2956
the problem was that corresponds on Seq's does not check length of sequences before testing the predicate, whereas in some cases that predicate relied on this invariant (when it was doing substitution)
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala10
-rw-r--r--test/files/pos/t2956/BeanDefinitionVisitor.java6
-rwxr-xr-xtest/files/pos/t2956/t2956.scala7
3 files changed, 19 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 509f9b3835..94600f9c56 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -3159,7 +3159,7 @@ A type's typeSymbol should never be inspected directly.
def subst(tp: Type, sym: Symbol, from: List[Symbol], to: List[T]): Type =
if (from.isEmpty) tp
- else if (to.isEmpty) error("Unexpected substitution on '%s': from = %s but to == Nil".format(tp, from))
+ // else if (to.isEmpty) error("Unexpected substitution on '%s': from = %s but to == Nil".format(tp, from))
else if (matches(from.head, sym)) toType(tp, to.head)
else subst(tp, sym, from.tail, to.tail)
@@ -3215,7 +3215,7 @@ A type's typeSymbol should never be inspected directly.
override def apply(tp: Type): Type = if (from.isEmpty) tp else {
def subst(sym: Symbol, from: List[Symbol], to: List[Symbol]): Symbol =
if (from.isEmpty) sym
- else if (to.isEmpty) error("Unexpected substitution on '%s': from = %s but to == Nil".format(sym, from))
+ // else if (to.isEmpty) error("Unexpected substitution on '%s': from = %s but to == Nil".format(sym, from))
else if (matches(from.head, sym)) to.head
else subst(sym, from.tail, to.tail)
tp match {
@@ -3864,10 +3864,10 @@ A type's typeSymbol should never be inspected directly.
tp1.isImplicit == tp2.isImplicit)
case (PolyType(tparams1, res1), PolyType(tparams2, res2)) =>
// assert((tparams1 map (_.typeParams.length)) == (tparams2 map (_.typeParams.length)))
- (tparams1 corresponds tparams2)(_.info =:= _.info.substSym(tparams2, tparams1)) && // @M looks like it might suffer from same problem as #2210
+ (tparams1.length == tparams2.length) && (tparams1 corresponds tparams2)(_.info =:= _.info.substSym(tparams2, tparams1)) && // @M looks like it might suffer from same problem as #2210
res1 =:= res2.substSym(tparams2, tparams1)
case (ExistentialType(tparams1, res1), ExistentialType(tparams2, res2)) =>
- (tparams1 corresponds tparams2)(_.info =:= _.info.substSym(tparams2, tparams1)) && // @M looks like it might suffer from same problem as #2210
+ (tparams1.length == tparams2.length) && (tparams1 corresponds tparams2)(_.info =:= _.info.substSym(tparams2, tparams1)) && // @M looks like it might suffer from same problem as #2210
res1 =:= res2.substSym(tparams2, tparams1)
case (TypeBounds(lo1, hi1), TypeBounds(lo2, hi2)) =>
lo1 =:= lo2 && hi1 =:= hi2
@@ -3991,6 +3991,7 @@ A type's typeSymbol should never be inspected directly.
// assert((tparams1 map (_.typeParams.length)) == (tparams2 map (_.typeParams.length)))
// @M looks like it might suffer from same problem as #2210
return (
+ (tparams1.length == tparams2.length) && // corresponds does not check length of two sequences before checking the predicate
(tparams1 corresponds tparams2)(_.info =:= _.info.substSym(tparams2, tparams1)) &&
res1 =:= res2.substSym(tparams2, tparams1)
)
@@ -4001,6 +4002,7 @@ A type's typeSymbol should never be inspected directly.
case ExistentialType(tparams2, res2) =>
// @M looks like it might suffer from same problem as #2210
return (
+ (tparams1.length == tparams2.length) && // corresponds does not check length of two sequences before checking the predicate -- faster & needed to avoid crasher in #2956
(tparams1 corresponds tparams2)(_.info =:= _.info.substSym(tparams2, tparams1)) &&
res1 =:= res2.substSym(tparams2, tparams1)
)
diff --git a/test/files/pos/t2956/BeanDefinitionVisitor.java b/test/files/pos/t2956/BeanDefinitionVisitor.java
new file mode 100644
index 0000000000..2ff5daa253
--- /dev/null
+++ b/test/files/pos/t2956/BeanDefinitionVisitor.java
@@ -0,0 +1,6 @@
+import java.util.Map;
+public class BeanDefinitionVisitor {
+ @SuppressWarnings("unchecked")
+ protected void visitMap(Map<?, ?> mapVal) {
+ }
+}
diff --git a/test/files/pos/t2956/t2956.scala b/test/files/pos/t2956/t2956.scala
new file mode 100755
index 0000000000..eb6e817465
--- /dev/null
+++ b/test/files/pos/t2956/t2956.scala
@@ -0,0 +1,7 @@
+import scala.collection.JavaConversions._
+
+class Outer {
+ protected class Inner extends BeanDefinitionVisitor {
+ protected def visitMap(mapVal: Map[_, _]): Unit = ()
+ }
+} \ No newline at end of file