diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-04-26 03:03:22 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-04-26 03:03:22 -0700 |
commit | 5819b78c25c9cba25fc84018d3905fe265bb4e18 (patch) | |
tree | 40c26ea0a04b968e82b9c99013daf752a93cd439 /src | |
parent | f33af58f3b6538398da6974275099fb18560e92d (diff) | |
parent | 7b4e450e9b746a9289f6d429cdee73bffa5cd733 (diff) | |
download | scala-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.scala | 40 |
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 |