diff options
author | Paul Phillips <paulp@improving.org> | 2013-03-04 08:34:56 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-03-04 12:35:58 -0800 |
commit | c10df64f4d05d5c01c027c4f519715cf7fb44e1e (patch) | |
tree | 125a9028c123d13c9476f3029980a3b48085c129 /src/compiler/scala/tools/nsc/typechecker/Contexts.scala | |
parent | 305a987da0df292b75a16aae9c698df155af0a8c (diff) | |
download | scala-c10df64f4d05d5c01c027c4f519715cf7fb44e1e.tar.gz scala-c10df64f4d05d5c01c027c4f519715cf7fb44e1e.tar.bz2 scala-c10df64f4d05d5c01c027c4f519715cf7fb44e1e.zip |
Add some logging to sinful typevar methods.
These super-mutation-oriented methods should enthusiastically
communicate what they are doing, especially when they encounter
anything unexpected. None of this work should be taken as an
endorsement of any of the worked-upon code.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Contexts.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index eb91251930..26e39d3d1b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -8,6 +8,7 @@ package typechecker import scala.collection.mutable import scala.annotation.tailrec +import scala.reflect.internal.util.shortClassOfInstance /** * @author Martin Odersky @@ -175,6 +176,7 @@ trait Contexts { self: Analyzer => if ((owner eq NoSymbol) || (owner.isClass) || (owner.isMethod)) this else outer.enclClassOrMethod + def enclosingCaseDef = nextEnclosing(_.tree.isInstanceOf[CaseDef]) def undetparamsString = if (undetparams.isEmpty) "" else undetparams.mkString("undetparams=", ", ", "") @@ -584,23 +586,39 @@ trait Contexts { self: Analyzer => } def pushTypeBounds(sym: Symbol) { + sym.info match { + case tb: TypeBounds => if (!tb.isEmptyBounds) log(s"Saving $sym info=$tb") + case info => devWarning(s"Something other than a TypeBounds seen in pushTypeBounds: $info is a ${shortClassOfInstance(info)}") + } savedTypeBounds ::= ((sym, sym.info)) } def restoreTypeBounds(tp: Type): Type = { - var current = tp - for ((sym, info) <- savedTypeBounds) { - debuglog("resetting " + sym + " to " + info) - sym.info match { - case TypeBounds(lo, hi) if (hi <:< lo && lo <:< hi) => - current = current.instantiateTypeParams(List(sym), List(lo)) -//@M TODO: when higher-kinded types are inferred, probably need a case PolyType(_, TypeBounds(...)) if ... => - case _ => - } - sym.setInfo(info) + def restore(): Type = savedTypeBounds.foldLeft(tp) { case (current, (sym, savedInfo)) => + def bounds_s(tb: TypeBounds) = if (tb.isEmptyBounds) "<empty bounds>" else s"TypeBounds(lo=${tb.lo}, hi=${tb.hi})" + //@M TODO: when higher-kinded types are inferred, probably need a case PolyType(_, TypeBounds(...)) if ... => + val tb @ TypeBounds(lo, hi) = sym.info.bounds + val isUnique = lo <:< hi && hi <:< lo + val isPresent = current contains sym + def saved_s = bounds_s(savedInfo.bounds) + def current_s = bounds_s(sym.info.bounds) + + if (isUnique && isPresent) + devWarningResult(s"Preserving inference: ${sym.nameString}=$hi in $current (based on $current_s) before restoring $sym to saved $saved_s")( + current.instantiateTypeParams(List(sym), List(hi)) + ) + else if (isPresent) + devWarningResult(s"Discarding inferred $current_s because it does not uniquely determine $sym in")(current) + else + logResult(s"Discarding inferred $current_s because $sym does not appear in")(current) + } + try restore() + finally { + for ((sym, savedInfo) <- savedTypeBounds) + sym setInfo debuglogResult(s"Discarding inferred $sym=${sym.info}, restoring saved info")(savedInfo) + + savedTypeBounds = Nil } - savedTypeBounds = List() - current } private var implicitsCache: List[List[ImplicitInfo]] = null |