From 891ecbfade5d91d38c7053792e0859e972bc45fb Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 1 Dec 2016 17:58:16 -0800 Subject: Revert existential infer part of #5376 It wasn't a good idea after all. Also removed some tracing code that I cannot imagine was ever used in a production compiler. It's still just a recompile away. Fixes scala/scala-dev#280 --- src/reflect/scala/reflect/internal/Types.scala | 73 ++++++++++++-------------- test/files/neg/t5729.check | 7 --- test/files/neg/t5729.scala | 6 --- test/pending/neg/t5729.check | 7 +++ test/pending/neg/t5729.scala | 6 +++ 5 files changed, 47 insertions(+), 52 deletions(-) delete mode 100644 test/files/neg/t5729.check delete mode 100644 test/files/neg/t5729.scala create mode 100644 test/pending/neg/t5729.check create mode 100644 test/pending/neg/t5729.scala diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index fa5a1a25ad..ad7e3ffe8f 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -91,7 +91,6 @@ trait Types private var explainSwitch = false private final val emptySymbolSet = immutable.Set.empty[Symbol] - private final val traceTypeVars = sys.props contains "scalac.debug.tvar" private final val breakCycles = settings.breakCycles.value /** In case anyone wants to turn on type parameter bounds being used * to seed type constraints. @@ -2826,13 +2825,13 @@ trait Types // now, pattern-matching returns the most recent constr object TypeVar { @inline final def trace[T](action: String, msg: => String)(value: T): T = { - if (traceTypeVars) { - val s = msg match { - case "" => "" - case str => "( " + str + " )" - } - Console.err.println("[%10s] %-25s%s".format(action, value, s)) - } + // Uncomment the following for a compiler that has some diagnostics about type inference + // I doubt this is ever useful in the wild, so a recompile will be needed +// val s = msg match { +// case "" => "" +// case str => "( " + str + " )" +// } +// Console.err.println("[%10s] %-25s%s".format(action, value, s)) value } @@ -2853,7 +2852,9 @@ trait Types val exclude = bounds.isEmptyBounds || (bounds exists typeIsNonClassType) if (exclude) new TypeConstraint - else TypeVar.trace("constraint", "For " + tparam.fullLocationString)(new TypeConstraint(bounds)) + else TypeVar.trace("constraint", "For " + tparam.fullLocationString)( + new TypeConstraint(bounds) + ) } else new TypeConstraint } @@ -2882,7 +2883,9 @@ trait Types else throw new Error("Invalid TypeVar construction: " + ((origin, constr, args, params))) ) - trace("create", "In " + tv.originLocation)(tv) + trace("create", "In " + tv.originLocation)( + tv + ) } private def createTypeVar(tparam: Symbol, untouchable: Boolean): TypeVar = createTypeVar(tparam.tpeHK, deriveConstraint(tparam), Nil, tparam.typeParams, untouchable) @@ -2986,7 +2989,9 @@ trait Types else if (newArgs.size == params.size) { val tv = TypeVar(origin, constr, newArgs, params) tv.linkSuspended(this) - TypeVar.trace("applyArgs", "In " + originLocation + ", apply args " + newArgs.mkString(", ") + " to " + originName)(tv) + TypeVar.trace("applyArgs", s"In $originLocation, apply args ${newArgs.mkString(", ")} to $originName")( + tv + ) } else TypeVar(typeSymbol).setInst(ErrorType) @@ -3005,31 +3010,20 @@ trait Types // only one of them is in the set of tvars that need to be solved, but // they share the same TypeConstraint instance - // When comparing to types containing skolems, remember the highest level - // of skolemization. If that highest level is higher than our initial - // skolemizationLevel, we can't re-use those skolems as the solution of this - // typevar, which means we'll need to repack our inst into a fresh existential. - // were we compared to skolems at a higher skolemizationLevel? - // EXPERIMENTAL: value will not be considered unless enableTypeVarExperimentals is true - // see SI-5729 for why this is still experimental - private var encounteredHigherLevel = false - private def shouldRepackType = encounteredHigherLevel - // // invariant: before mutating constr, save old state in undoLog // (undoLog is used to reset constraints to avoid piling up unrelated ones) - def setInst(tp: Type): this.type = { - if (tp eq this) { + def setInst(tp: Type): this.type = + if (tp ne this) { + undoLog record this + constr.inst = TypeVar.trace("setInst", s"In $originLocation, $originName=$tp")( + tp + ) + this + } else { log(s"TypeVar cycle: called setInst passing $this to itself.") - return this + this } - undoLog record this - // if we were compared against later typeskolems, repack the existential, - // because skolems are only compatible if they were created at the same level - val res = if (shouldRepackType) repackExistential(tp) else tp - constr.inst = TypeVar.trace("setInst", "In " + originLocation + ", " + originName + "=" + res)(res) - this - } def addLoBound(tp: Type, isNumericBound: Boolean = false) { assert(tp != this, tp) // implies there is a cycle somewhere (?) @@ -3208,8 +3202,7 @@ trait Types checkSubtype(tp, origin) else if (instValid) // type var is already set checkSubtype(tp, inst) - else { - trackHigherLevel(tp) + else isRelatable(tp) && { unifySimple || unifyFull(tp) || ( // only look harder if our gaze is oriented toward Any isLowerBound && ( @@ -3232,8 +3225,7 @@ trait Types if (suspended) tp =:= origin else if (instValid) checkIsSameType(tp) - else { - trackHigherLevel(tp) + else isRelatable(tp) && { val newInst = wildcardToTypeVarMap(tp) (constr isWithinBounds newInst) && { setInst(newInst) @@ -3257,9 +3249,12 @@ trait Types case _ => false } - private def trackHigherLevel(tp: Type): Unit = - if(!shouldRepackType && tp.exists(isSkolemAboveLevel)) - encounteredHigherLevel = true + + /** Can this variable be related in a constraint to type `tp`? + * This is not the case if `tp` contains type skolems whose + * skolemization level is higher than the level of this variable. + */ + def isRelatable(tp: Type) = !(tp exists isSkolemAboveLevel) override def normalize: Type = ( if (instValid) inst @@ -3307,7 +3302,7 @@ trait Types // to never be resumed with the current implementation assert(!suspended, this) TypeVar.trace("clone", originLocation)( - TypeVar(origin, constr.cloneInternal, typeArgs, params) // @M TODO: clone args/params? + TypeVar(origin, constr.cloneInternal, typeArgs, params) ) } } diff --git a/test/files/neg/t5729.check b/test/files/neg/t5729.check deleted file mode 100644 index 10c13db8b6..0000000000 --- a/test/files/neg/t5729.check +++ /dev/null @@ -1,7 +0,0 @@ -t5729.scala:5: error: ambiguous reference to overloaded definition, -both method join in object Test of type [S](in: Seq[T[S]])String -and method join in object Test of type (in: Seq[T[_]])Int -match argument types (Seq[T[_]]) - join(null: Seq[T[_]]) - ^ -one error found diff --git a/test/files/neg/t5729.scala b/test/files/neg/t5729.scala deleted file mode 100644 index 9fd9c9ffbb..0000000000 --- a/test/files/neg/t5729.scala +++ /dev/null @@ -1,6 +0,0 @@ -trait T[X] -object Test { - def join(in: Seq[T[_]]): Int = ??? - def join[S](in: Seq[T[S]]): String = ??? - join(null: Seq[T[_]]) -} \ No newline at end of file diff --git a/test/pending/neg/t5729.check b/test/pending/neg/t5729.check new file mode 100644 index 0000000000..10c13db8b6 --- /dev/null +++ b/test/pending/neg/t5729.check @@ -0,0 +1,7 @@ +t5729.scala:5: error: ambiguous reference to overloaded definition, +both method join in object Test of type [S](in: Seq[T[S]])String +and method join in object Test of type (in: Seq[T[_]])Int +match argument types (Seq[T[_]]) + join(null: Seq[T[_]]) + ^ +one error found diff --git a/test/pending/neg/t5729.scala b/test/pending/neg/t5729.scala new file mode 100644 index 0000000000..9fd9c9ffbb --- /dev/null +++ b/test/pending/neg/t5729.scala @@ -0,0 +1,6 @@ +trait T[X] +object Test { + def join(in: Seq[T[_]]): Int = ??? + def join[S](in: Seq[T[S]]): String = ??? + join(null: Seq[T[_]]) +} \ No newline at end of file -- cgit v1.2.3