diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Analyzer.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 13 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/SymbolTable.scala | 1 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Variances.scala (renamed from src/compiler/scala/tools/nsc/typechecker/Variances.scala) | 31 |
4 files changed, 25 insertions, 21 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala index 5e8bb3e424..d4d6def3cb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala @@ -16,7 +16,6 @@ trait Analyzer extends AnyRef with Typers with Infer with Implicits - with Variances with EtaExpansion with SyntheticMethods with Unapplies diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index eeb76dced2..704aebc50b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -38,7 +38,7 @@ import scala.language.postfixOps * * @todo Check whether we always check type parameter bounds. */ -abstract class RefChecks extends InfoTransform with scala.reflect.internal.transform.RefChecks with Variances { +abstract class RefChecks extends InfoTransform with scala.reflect.internal.transform.RefChecks { val global: Global // need to repeat here because otherwise last mixin defines global as // SymbolTable. If we had DOT this would not be an issue @@ -844,7 +844,16 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans // Variance Checking -------------------------------------------------------- - val varianceValidator = new VarianceValidator + object varianceValidator extends VarianceValidator { + private def tpString(tp: Type) = tp match { + case ClassInfoType(parents, _, clazz) => "supertype "+intersectionType(parents, clazz.owner) + case _ => "type "+tp + } + override def issueVarianceError(base: Symbol, sym: Symbol, required: Variance) { + currentRun.currentUnit.error(base.pos, + s"${sym.variance} $sym occurs in $required position in ${tpString(base.info)} of $base") + } + } // Forward reference checking --------------------------------------------------- diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index 540338dca7..e9ab7fa45d 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -15,6 +15,7 @@ abstract class SymbolTable extends macros.Universe with Names with Symbols with Types + with Variances with Kinds with ExistentialsAndSkolems with FlagSets diff --git a/src/compiler/scala/tools/nsc/typechecker/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala index 66eb415b10..6560f088c5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Variances.scala +++ b/src/reflect/scala/reflect/internal/Variances.scala @@ -3,22 +3,25 @@ * @author Martin Odersky */ -package scala.tools.nsc -package typechecker +package scala.reflect +package internal -import scala.reflect.internal.Variance, scala.reflect.internal.Variance._ +import Variance._ import scala.collection.{ mutable, immutable } /** See comments at scala.reflect.internal.Variance. */ trait Variances { - val global: Global - import global._ - import definitions.uncheckedVarianceClass + self: SymbolTable => + /** Used in Refchecks. + * TODO - eliminate duplication with varianceInType + */ class VarianceValidator extends Traverser { val escapedPrivateLocals = mutable.HashSet[Symbol]() + protected def issueVarianceError(base: Symbol, sym: Symbol, required: Variance): Unit = () + /** Validate variance of info of symbol `base` */ private def validateVariance(base: Symbol) { // A flag for when we're in a refinement, meaning method parameter types @@ -82,18 +85,10 @@ trait Variances { validateVariance(tp.normalize, variance) else if (!sym.variance.isInvariant) { val v = relativeVariance(sym) + val requiredVariance = v * variance - if (!v.isBivariant && sym.variance != v * variance) { - //Console.println("relativeVariance(" + base + "," + sym + ") = " + v);//DEBUG - def tpString(tp: Type) = tp match { - case ClassInfoType(parents, _, clazz) => "supertype "+intersectionType(parents, clazz.owner) - case _ => "type "+tp - } - currentRun.currentUnit.error(base.pos, - sym.variance + " " + sym + - " occurs in " + (v * variance) + - " position in " + tpString(base.info) + " of " + base); - } + if (!v.isBivariant && sym.variance != requiredVariance) + issueVarianceError(base, sym, requiredVariance) } validateVariance(pre, variance) // @M for higher-kinded typeref, args.isEmpty @@ -126,7 +121,7 @@ trait Variances { validateVariances(tparams map (_.info), variance) validateVariance(result, variance) case AnnotatedType(annots, tp, selfsym) => - if (!annots.exists(_ matches uncheckedVarianceClass)) + if (!annots.exists(_ matches definitions.uncheckedVarianceClass)) validateVariance(tp, variance) } |