summaryrefslogtreecommitdiff
path: root/src
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 /src
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
Diffstat (limited to 'src')
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeMaps.scala40
1 files changed, 32 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