diff options
author | Paul Phillips <paulp@improving.org> | 2011-10-06 10:00:13 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-10-06 10:00:13 +0000 |
commit | 0afd6d1b192900f2a0cda3a8fa3d8498ded91d5f (patch) | |
tree | d019e2cd31e06a0663b7dda825b7a6d1eef61516 /src | |
parent | 1e0f7dcb4fcc216afff4b88555d5751bbcc9a58d (diff) | |
download | scala-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.scala | 13 |
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 _ => |