diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2010-02-26 09:42:50 +0000 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2010-02-26 09:42:50 +0000 |
commit | 93f8dd3a4ee6b16221f77c19c0589154f83507b9 (patch) | |
tree | 20011037e2030706534d07d48987225870b6f2a7 | |
parent | cc9e8eda3364dcb7bf5b92a3d3824b66c85ef05f (diff) | |
download | scala-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.scala | 10 | ||||
-rw-r--r-- | test/files/pos/t2956/BeanDefinitionVisitor.java | 6 | ||||
-rwxr-xr-x | test/files/pos/t2956/t2956.scala | 7 |
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 |