summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2013-04-26 03:03:22 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-04-26 03:03:22 -0700
commit5819b78c25c9cba25fc84018d3905fe265bb4e18 (patch)
tree40c26ea0a04b968e82b9c99013daf752a93cd439
parentf33af58f3b6538398da6974275099fb18560e92d (diff)
parent7b4e450e9b746a9289f6d429cdee73bffa5cd733 (diff)
downloadscala-5819b78c25c9cba25fc84018d3905fe265bb4e18.tar.gz
scala-5819b78c25c9cba25fc84018d3905fe265bb4e18.tar.bz2
scala-5819b78c25c9cba25fc84018d3905fe265bb4e18.zip
Merge pull request #2430 from paulp/issue/4365
SI-4365 nondeterministic failure in asSeenFrom
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeMaps.scala40
-rw-r--r--test/files/pos/t4365/a_1.scala18
-rw-r--r--test/files/pos/t4365/b_1.scala22
3 files changed, 72 insertions, 8 deletions
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
index 0f9db31ec1..4227699da2 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
@@ -525,15 +525,39 @@ private[internal] trait TypeMaps {
val TypeRef(_, rhsSym, rhsArgs) = rhs
require(lhsSym.safeOwner == rhsSym, s"$lhsSym is not a type parameter of $rhsSym")
- // Find the type parameter position; we'll use the corresponding argument
- val argIndex = rhsSym.typeParams indexOf lhsSym
-
- if (argIndex >= 0 && argIndex < rhsArgs.length) // @M! don't just replace the whole thing, might be followed by type application
- appliedType(rhsArgs(argIndex), lhsArgs mapConserve this)
- else if (rhsSym.tpe_*.parents exists typeIsErroneous) // don't be too zealous with the exceptions, see #2641
+ // Find the type parameter position; we'll use the corresponding argument.
+ // Why are we checking by name rather than by equality? Because for
+ // reasons which aren't yet fully clear, we can arrive here holding a type
+ // parameter whose owner is rhsSym, and which shares the name of an actual
+ // type parameter of rhsSym, but which is not among the type parameters of
+ // rhsSym. One can see examples of it at SI-4365.
+ val argIndex = rhsSym.typeParams indexWhere (lhsSym.name == _.name)
+ // don't be too zealous with the exceptions, see #2641
+ if (argIndex < 0 && rhs.parents.exists(typeIsErroneous))
ErrorType
- else
- abort(s"something is wrong: cannot make sense of type application\n $lhs\n $rhs")
+ else {
+ // It's easy to get here when working on hardcore type machinery (not to
+ // mention when not doing so, see above) so let's provide a standout error.
+ def own_s(s: Symbol) = s.nameString + " in " + s.safeOwner.nameString
+ def explain =
+ sm"""| sought ${own_s(lhsSym)}
+ | classSym ${own_s(rhsSym)}
+ | tparams ${rhsSym.typeParams map own_s mkString ", "}
+ |"""
+
+ if (argIndex < 0)
+ abort(s"Something is wrong: cannot find $lhs in applied type $rhs\n" + explain)
+ else {
+ val targ = rhsArgs(argIndex)
+ // @M! don't just replace the whole thing, might be followed by type application
+ val result = appliedType(targ, lhsArgs mapConserve this)
+ def msg = s"Created $result, though could not find ${own_s(lhsSym)} among tparams of ${own_s(rhsSym)}"
+ if (!rhsSym.typeParams.contains(lhsSym))
+ devWarning(s"Inconsistent tparam/owner views: had to fall back on names\n$msg\n$explain")
+
+ result
+ }
+ }
}
// 0) @pre: `classParam` is a class type parameter
diff --git a/test/files/pos/t4365/a_1.scala b/test/files/pos/t4365/a_1.scala
new file mode 100644
index 0000000000..6f3405b1ff
--- /dev/null
+++ b/test/files/pos/t4365/a_1.scala
@@ -0,0 +1,18 @@
+import scala.collection._
+
+trait SeqViewLike[+A,
+ +Coll,
+ +This <: SeqView[A, Coll] with SeqViewLike[A, Coll, This]]
+ extends Seq[A] with GenSeqViewLike[A, Coll, This]
+{
+
+ trait Transformed[+B] extends super[GenSeqViewLike].Transformed[B]
+
+ abstract class AbstractTransformed[+B] extends Seq[B] with Transformed[B] {
+ def underlying: Coll = error("")
+ }
+
+ trait Reversed extends Transformed[A] with super[GenSeqViewLike].Reversed
+
+ protected def newReversed: Transformed[A] = new AbstractTransformed[A] with Reversed
+}
diff --git a/test/files/pos/t4365/b_1.scala b/test/files/pos/t4365/b_1.scala
new file mode 100644
index 0000000000..e5b5687185
--- /dev/null
+++ b/test/files/pos/t4365/b_1.scala
@@ -0,0 +1,22 @@
+import scala.collection._
+
+trait GenSeqViewLike[+A,
+ +Coll,
+ +This <: GenSeqView[A, Coll] with GenSeqViewLike[A, Coll, This]]
+extends GenSeq[A] {
+self =>
+
+ trait Transformed[+B] {
+ def length: Int = 0
+ def apply(idx: Int): B = error("")
+ }
+
+ trait Reversed extends Transformed[A] {
+ def iterator: Iterator[A] = createReversedIterator
+
+ private def createReversedIterator: Iterator[A] = {
+ self.foreach(_ => ())
+ null
+ }
+ }
+}