Skip to content
This repository
Browse code

Move escaping local logic into VarianceValidator.

  • Loading branch information...
commit 069359240a902cc989553123a61db3f6abe8fd1a 1 parent 882f8e6
Paul Phillips paulp authored
16 src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1449,18 +1449,10 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
1449 1449 checkMigration(sym, tree.pos)
1450 1450 checkCompileTimeOnly(sym, tree.pos)
1451 1451
1452   - if (sym eq NoSymbol) {
1453   - unit.warning(tree.pos, "Select node has NoSymbol! " + tree + " / " + tree.tpe)
1454   - }
1455   - else if (currentClass != sym.owner && sym.hasLocalFlag) {
1456   - var o = currentClass
1457   - var hidden = false
1458   - while (!hidden && o != sym.owner && o != sym.owner.moduleClass && !o.isPackage) {
1459   - hidden = o.isTerm || o.isPrivateLocal
1460   - o = o.owner
1461   - }
1462   - if (!hidden) varianceValidator.escapedLocals += sym
1463   - }
  1452 + if (sym eq NoSymbol)
  1453 + devWarning("Select node has NoSymbol! " + tree + " / " + tree.tpe)
  1454 + else if (sym.hasLocalFlag)
  1455 + varianceValidator.checkForEscape(sym, currentClass)
1464 1456
1465 1457 def checkSuper(mix: Name) =
1466 1458 // term should have been eliminated by super accessors
18 src/reflect/scala/reflect/internal/Variances.scala
@@ -8,6 +8,7 @@ package internal
8 8
9 9 import Variance._
10 10 import scala.collection.{ mutable, immutable }
  11 +import scala.annotation.tailrec
11 12
12 13 /** See comments at scala.reflect.internal.Variance.
13 14 */
@@ -18,14 +19,25 @@ trait Variances {
18 19 * TODO - eliminate duplication with varianceInType
19 20 */
20 21 class VarianceValidator extends Traverser {
21   - val escapedLocals = mutable.HashSet[Symbol]()
  22 + private val escapedLocals = mutable.HashSet[Symbol]()
  23 +
  24 + /** Is every symbol in the owner chain between `site` and the owner of `sym`
  25 + * either a term symbol or private[this]? If not, add `sym` to the set of
  26 + * esacped locals.
  27 + * @pre sym.hasLocalFlag
  28 + */
  29 + @tailrec final def checkForEscape(sym: Symbol, site: Symbol) {
  30 + if (site == sym.owner || site == sym.owner.moduleClass || site.isPackage) () // done
  31 + else if (site.isTerm || site.isPrivateLocal) checkForEscape(sym, site.owner) // ok - recurse to owner
  32 + else escapedLocals += sym
  33 + }
22 34
23 35 protected def issueVarianceError(base: Symbol, sym: Symbol, required: Variance): Unit = ()
24 36
25 37 // Flip occurrences of type parameters and parameters, unless
26 38 // - it's a constructor, or case class factory or extractor
27 39 // - it's a type parameter of tvar's owner.
28   - private def isFlipped(sym: Symbol, tvar: Symbol) = (
  40 + def shouldFlip(sym: Symbol, tvar: Symbol) = (
29 41 sym.isParameter
30 42 && !sym.owner.isConstructor
31 43 && !sym.owner.isCaseApplyOrUnapply
@@ -56,7 +68,7 @@ trait Variances {
56 68 */
57 69 def relativeVariance(tvar: Symbol): Variance = {
58 70 def nextVariance(sym: Symbol, v: Variance): Variance = (
59   - if (isFlipped(sym, tvar)) v.flip
  71 + if (shouldFlip(sym, tvar)) v.flip
60 72 else if (isLocalOnly(sym)) Bivariant
61 73 else if (!sym.isAliasType) v
62 74 else if (sym.isOverridingSymbol) Invariant

0 comments on commit 0693592

Please sign in to comment.
Something went wrong with that request. Please try again.