From 518635385ac1ba14aa230de3e431793331300546 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Fri, 22 Nov 2013 16:28:51 +0100 Subject: SI-7872 Plug a variance exploit in refinement types Refinement types are collapsed to a TypeTree with an original during type checking; this was enough to evade variance validation in refchecks. This commit: - validates the original of `TypeTree`s in refchecks - changes VarianceValidator to recurse into: - the originals of `TypeTree`s - `TypTree` (to cover, e.g. `CompoundTypeTree` / `SelectFromTypeTree`) It also finds an unreported variance violation in an existing test case, variances.scala. This looks to be legitimate. --- src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 2 ++ src/reflect/scala/reflect/internal/Variances.scala | 10 ++++++++++ 2 files changed, 12 insertions(+) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 84531608e0..38065d5ea8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1762,6 +1762,8 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans | TypeDef(_, _, _, _) => if (result.symbol.isLocal || result.symbol.isTopLevel) varianceValidator.traverse(result) + case tt @ TypeTree() if tt.original != null => + varianceValidator.traverse(tt.original) // See SI-7872 case _ => } result diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala index 5280467055..cd09e83cd3 100644 --- a/src/reflect/scala/reflect/internal/Variances.scala +++ b/src/reflect/scala/reflect/internal/Variances.scala @@ -162,6 +162,16 @@ trait Variances { traverseTreess(vparamss) case Template(_, _, _) => super.traverse(tree) + case CompoundTypeTree(templ) => + super.traverse(tree) + + // SI-7872 These two cases make sure we don't miss variance exploits + // in originals, e.g. in `foo[({type l[+a] = List[a]})#l]` + case tt @ TypeTree() if tt.original != null => + super.traverse(tt.original) + case tt : TypTree => + super.traverse(tt) + case _ => } } -- cgit v1.2.3