From 671e6e03c7e096eda0c27262ae8605fa7af76f59 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 12 Sep 2013 13:28:06 -0700 Subject: Corrects behavior of finalResultType. The implementation had come to depend on finalResultType accidentally doing things beyond its charter - in particular, widening types. After hunting down and fixing the call sites depending on the bugs, I was able to rewrite the method to do only what it's supposed to do. I threw in a different way of writing it entirely to suggest how some correctness might be obtained in the future. It's a lot harder for a method written like this to break. --- src/compiler/scala/tools/nsc/ast/TreeDSL.scala | 2 +- src/compiler/scala/tools/nsc/transform/Erasure.scala | 2 +- src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala | 2 +- src/compiler/scala/tools/nsc/transform/TailCalls.scala | 2 +- src/compiler/scala/tools/nsc/transform/UnCurry.scala | 9 +++++---- src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala | 2 +- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 4 ++-- 7 files changed, 12 insertions(+), 11 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala index d7a32c3be0..53304bee30 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala @@ -192,7 +192,7 @@ trait TreeDSL { } class DefSymStart(val sym: Symbol) extends SymVODDStart with DefCreator { - def symType = sym.tpe.finalResultType + def symType = sym.tpe_*.finalResultType def tparams = sym.typeParams map TypeDef def vparamss = mapParamss(sym)(ValDef) } diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index c74fc620ca..48eb570654 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -268,7 +268,7 @@ abstract class Erasure extends AddInterfaces else abbrvTag(sym).toString } else if (sym.isDerivedValueClass) { - val unboxed = sym.derivedValueClassUnbox.info.finalResultType + val unboxed = sym.derivedValueClassUnbox.tpe_*.finalResultType val unboxedSeen = (tp memberType sym.derivedValueClassUnbox).finalResultType def unboxedMsg = if (unboxed == unboxedSeen) "" else s", seen within ${sym.simpleName} as $unboxedSeen" logResult(s"Erasure of value class $sym (underlying type $unboxed$unboxedMsg) is") { diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 1c32721444..ca8065b519 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -234,7 +234,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { if (extensionBody.tpe <:< extensionMono.finalResultType) extensionBody else - gen.mkCastPreservingAnnotations(extensionBody, extensionMono.finalResultType) // SI-7818 e.g. mismatched existential skolems + gen.mkCastPreservingAnnotations(extensionBody, extensionMono.finalResultType) // SI-7818 e.g. mismatched existential skolems // Record the extension method. Later, in `Extender#transformStats`, these will be added to the companion object. extensionDefs(companion) += atPos(tree.pos)(DefDef(extensionMeth, castBody)) diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index 6f422fcc90..b471d16ddd 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -156,7 +156,7 @@ abstract class TailCalls extends Transform { private def mkLabel() = { val label = method.newLabel(newTermName("_" + method.name), method.pos) val thisParam = method.newSyntheticValueParam(currentClass.typeOfThis) - label setInfo MethodType(thisParam :: method.tpe.params, method.tpe.finalResultType) + label setInfo MethodType(thisParam :: method.tpe.params, method.tpe_*.finalResultType) if (isEligible) label substInfo (method.tpe.typeParams, tparams) diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 16c803e2e8..93a36f8f01 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -158,11 +158,12 @@ abstract class UnCurry extends InfoTransform */ private def nonLocalReturnTry(body: Tree, key: Symbol, meth: Symbol) = { localTyper typed { - val extpe = nonLocalReturnExceptionType(meth.tpe.finalResultType) + val restpe = meth.tpe_*.finalResultType + val extpe = nonLocalReturnExceptionType(restpe) val ex = meth.newValue(nme.ex, body.pos) setInfo extpe - val argType = meth.tpe.finalResultType withAnnotation (AnnotationInfo marker UncheckedClass.tpe) + val argType = restpe withAnnotation (AnnotationInfo marker UncheckedClass.tpe) val pat = gen.mkBindForCase(ex, NonLocalReturnControlClass, List(argType)) - val rhs = ( + val rhs = ( IF ((ex DOT nme.key)() OBJ_EQ Ident(key)) THEN ((ex DOT nme.value)()) ELSE (Throw(Ident(ex))) @@ -739,7 +740,7 @@ abstract class UnCurry extends InfoTransform case p if rpsymbols(p.symbol) => toArrayType(p.symbol.tpe) case p => p.symbol.tpe } - val forwresult = dd.symbol.tpe.finalResultType + val forwresult = dd.symbol.tpe_*.finalResultType val forwformsyms = map2(forwformals, flatparams)((tp, oldparam) => currentClass.newValueParameter(oldparam.name, oldparam.symbol.pos).setInfo(tp) ) diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 263b5ad784..787c7ebf63 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -413,7 +413,7 @@ trait MethodSynthesis { // starts compiling (instead of failing like it's supposed to) because the typer // expects to be able to identify escaping locals in typedDefDef, and fails to // spot that brand of them. In other words it's an artifact of the implementation. - val tpt = atPos(derivedSym.pos.focus)(derivedSym.tpe.finalResultType match { + val tpt = atPos(derivedSym.pos.focus)(derivedSym.tpe_*.finalResultType.widen match { case ExistentialType(_, _) => TypeTree() case _ if mods.isDeferred => TypeTree() case tp => TypeTree(tp) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 629513ada3..1f5ad3534e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -363,7 +363,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper check(owner, scope, pt, tree setType tp1.typeSymbol.classBound) else if (owner == NoSymbol) tree setType packSymbols(hiddenSymbols.reverse, tp1) - else if (!phase.erasedTypes) { // privates + else if (!isPastTyper) { // privates val badSymbol = hiddenSymbols.head SymbolEscapesScopeError(tree, badSymbol) } else tree @@ -2103,7 +2103,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case PolyType(_, restpe) => paramssTypes(restpe) case _ => Nil } - def resultType = meth.tpe.finalResultType + def resultType = meth.tpe_*.finalResultType def nthParamPos(n1: Int, n2: Int) = try ddef.vparamss(n1)(n2).pos catch { case _: IndexOutOfBoundsException => meth.pos } -- cgit v1.2.3