Permalink
Browse files

Moved Variances into SymbolTable.

So I can centralize all the redundant variance code.
  • Loading branch information...
1 parent 36ec5ff commit 91d8584fde15140972f7d6037d632bc24fc50f94 @paulp paulp committed Dec 31, 2012
@@ -16,7 +16,6 @@ trait Analyzer extends AnyRef
with Typers
with Infer
with Implicits
- with Variances
with EtaExpansion
with SyntheticMethods
with Unapplies
@@ -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 ---------------------------------------------------
@@ -15,6 +15,7 @@ abstract class SymbolTable extends macros.Universe
with Names
with Symbols
with Types
+ with Variances
with Kinds
with ExistentialsAndSkolems
with FlagSets
@@ -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)
}

0 comments on commit 91d8584

Please sign in to comment.