summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-10-07 12:16:33 +0000
committerMartin Odersky <odersky@gmail.com>2011-10-07 12:16:33 +0000
commitbcd155beb93be6bfda46e9578f7a9014e4842bd6 (patch)
treec1097970cb1bdfec9997005a700dd1ab613203df /src/compiler
parent77aae5843ab901340aa410e7c7dd20034238ef7e (diff)
downloadscala-bcd155beb93be6bfda46e9578f7a9014e4842bd6.tar.gz
scala-bcd155beb93be6bfda46e9578f7a9014e4842bd6.tar.bz2
scala-bcd155beb93be6bfda46e9578f7a9014e4842bd6.zip
Fallback on stale type parameters in forInterac...
Fallback on stale type parameters in forInteractive mode. Should not be necessary bit unfortunately we cannot control all the calls we might get from different threads in the IDE. So it's better to be robust here. Partial fix of ticket #1000531
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index ead767f76a..a7a5efe21a 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -3647,15 +3647,37 @@ A type's typeSymbol should never be inspected directly.
// have to deconst because it may be a Class[T].
pre.baseType(symclazz).deconst match {
case TypeRef(_, basesym, baseargs) =>
- def instParam(ps: List[Symbol], as: List[Type]): Type =
+
+ def instParam(ps: List[Symbol], as: List[Type]): Type =
if (ps.isEmpty) {
- settings.uniqid.value = true
- println("confused with params: " + sym + " in " + sym.owner + " not in " + ps + " of " + basesym)
- throwError
+ if (forInteractive) {
+ val saved = settings.uniqid.value
+ try {
+ settings.uniqid.value = true
+ println("*** stale type parameter: " + tp + sym.locationString + " cannot be instantiated from " + pre.widen)
+ println("*** confused with params: " + sym + " in " + sym.owner + " not in " + ps + " of " + basesym)
+ println("*** stacktrace = ")
+ new Error().printStackTrace()
+ } finally settings.uniqid.value = saved
+ instParamRelaxed(basesym.typeParams, baseargs)
+ } else throwError
} else if (sym eq ps.head)
// @M! don't just replace the whole thing, might be followed by type application
appliedType(as.head, args mapConserve (this)) // @M: was as.head
- else instParam(ps.tail, as.tail);
+ else instParam(ps.tail, as.tail)
+
+ /** Relaxed version of instParams which matches on names not symbols.
+ * This is a last fallback in interactive mode because races in calls
+ * from the IDE to the compiler may in rare cases lead to symbols referring
+ * to type parameters that are no longer current.
+ */
+ def instParamRelaxed(ps: List[Symbol], as: List[Type]): Type =
+ if (ps.isEmpty) throwError
+ else if (sym.name == ps.head.name)
+ // @M! don't just replace the whole thing, might be followed by type application
+ appliedType(as.head, args mapConserve (this)) // @M: was as.head
+ else instParamRelaxed(ps.tail, as.tail)
+
//Console.println("instantiating " + sym + " from " + basesym + " with " + basesym.typeParams + " and " + baseargs+", pre = "+pre+", symclazz = "+symclazz);//DEBUG
if (sameLength(basesym.typeParams, baseargs)) {
instParam(basesym.typeParams, baseargs)
@@ -3670,7 +3692,6 @@ A type's typeSymbol should never be inspected directly.
capturedParams = capturedParams union tparams
toInstance(qtpe, clazz)
case t =>
- println("bad type: "+t)
throwError
}
} else toInstance(base(pre, clazz).prefix, clazz.owner)