summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-10-06 10:00:13 +0000
committerPaul Phillips <paulp@improving.org>2011-10-06 10:00:13 +0000
commit0afd6d1b192900f2a0cda3a8fa3d8498ded91d5f (patch)
treed019e2cd31e06a0663b7dda825b7a6d1eef61516 /src
parent1e0f7dcb4fcc216afff4b88555d5751bbcc9a58d (diff)
downloadscala-0afd6d1b192900f2a0cda3a8fa3d8498ded91d5f.tar.gz
scala-0afd6d1b192900f2a0cda3a8fa3d8498ded91d5f.tar.bz2
scala-0afd6d1b192900f2a0cda3a8fa3d8498ded91d5f.zip
Closing soundness hole in variance checking.
See SI-5060. Review by odersky.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 3b9cf88a00..b3e1e3feb8 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -762,6 +762,9 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
/** 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
+ // need to be checked.
+ var inRefinement = false
def varianceString(variance: Int): String =
if (variance == 1) "covariant"
@@ -845,12 +848,17 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
validateVariances(parents, variance)
case RefinedType(parents, decls) =>
validateVariances(parents, variance)
+ val saved = inRefinement
+ inRefinement = true
for (sym <- decls)
validateVariance(sym.info, if (sym.isAliasType) NoVariance else variance)
+ inRefinement = saved
case TypeBounds(lo, hi) =>
validateVariance(lo, -variance)
validateVariance(hi, variance)
case MethodType(formals, result) =>
+ if (inRefinement)
+ validateVariances(formals map (_.tpe), -variance)
validateVariance(result, variance)
case NullaryMethodType(result) =>
validateVariance(result, variance)
@@ -887,9 +895,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
// ModuleDefs need not be considered because they have been eliminated already
case ValDef(_, _, _, _) =>
validateVariance(tree.symbol)
- case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
+ case DefDef(_, _, tparams, vparamss, _, _) =>
validateVariance(tree.symbol)
- traverseTrees(tparams); traverseTreess(vparamss)
+ traverseTrees(tparams)
+ traverseTreess(vparamss)
case Template(_, _, _) =>
super.traverse(tree)
case _ =>