diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-12-11 16:08:33 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-12-11 20:06:08 +0100 |
commit | 110fde017ee32b7387393dad9b859fd89e900650 (patch) | |
tree | df0be7e74493af0643316b37a950b34e54c214d6 /src | |
parent | 0304e00168393d47e18dbb4d2c634d51bab1383a (diff) | |
download | scala-110fde017ee32b7387393dad9b859fd89e900650.tar.gz scala-110fde017ee32b7387393dad9b859fd89e900650.tar.bz2 scala-110fde017ee32b7387393dad9b859fd89e900650.zip |
SI-6780 Refactor Context#implicitss
- split out a method for the part concernted with implicits from
the current context
- leaving the outer code to handle caching, cycle detection,
and recursion up the context chain.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index b7a942fc0d..2b4417a80d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -832,12 +832,11 @@ trait Contexts { self: Analyzer => * filtered out later by `eligibleInfos` (SI-4270 / 9129cfe9), as they don't type-check. */ def implicitss: List[List[ImplicitInfo]] = { - val imports = this.imports val nextOuter = this.nextOuter def withOuter(is: List[ImplicitInfo]): List[List[ImplicitInfo]] = is match { case Nil => nextOuter.implicitss - case _ => is :: nextOuter.implicitss + case _ => is :: nextOuter.implicitss } val CycleMarker = NoRunId - 1 @@ -846,38 +845,42 @@ trait Contexts { self: Analyzer => withOuter(Nil) } else if (implicitsRunId != currentRunId) { implicitsRunId = CycleMarker - implicitsCache = List() - var canCache = true - val newImplicits: List[ImplicitInfo] = - if (owner != nextOuter.owner && owner.isClass && !owner.isPackageClass && !inSelfSuperCall) { - if (!owner.isInitialized) { canCache = false; Nil } - else savingEnclClass(this) { - // !!! In the body of `class C(implicit a: A) { }`, `implicitss` returns `List(List(a), List(a), List(<predef..)))` - // it handled correctly by implicit search, which considers the second `a` to be shadowed, but should be - // remedied nonetheless. - collectImplicits(owner.thisType.implicitMembers, owner.thisType) - } - } else if (scope != nextOuter.scope && !owner.isPackageClass) { - debuglog("collect local implicits " + scope.toList)//DEBUG - collectImplicits(scope, NoPrefix) - } else if (firstImport != nextOuter.firstImport) { - assert(imports.tail.headOption == nextOuter.firstImport, (imports, nextOuter.imports)) - collectImplicitImports(imports.head) - } else if (owner.isPackageClass) { - // the corresponding package object may contain implicit members. - collectImplicits(owner.tpe.implicitMembers, owner.tpe) - } else List() - - if (canCache) { - implicitsRunId = currentRunId - implicitsCache = newImplicits - } else implicitsRunId = NoRunId - - withOuter(newImplicits) + implicits(nextOuter) match { + case None => + implicitsRunId = NoRunId + withOuter(Nil) + case Some(is) => + implicitsRunId = currentRunId + implicitsCache = is + withOuter(is) + } } else withOuter(implicitsCache) } + /** @return None if a cycle is detected, or Some(infos) containing the in-scope implicits at this context */ + private def implicits(nextOuter: Context): Option[List[ImplicitInfo]] = { + val imports = this.imports + if (owner != nextOuter.owner && owner.isClass && !owner.isPackageClass && !inSelfSuperCall) { + if (!owner.isInitialized) None + else savingEnclClass(this) { + // !!! In the body of `class C(implicit a: A) { }`, `implicitss` returns `List(List(a), List(a), List(<predef..)))` + // it handled correctly by implicit search, which considers the second `a` to be shadowed, but should be + // remedied nonetheless. + Some(collectImplicits(owner.thisType.implicitMembers, owner.thisType)) + } + } else if (scope != nextOuter.scope && !owner.isPackageClass) { + debuglog("collect local implicits " + scope.toList)//DEBUG + Some(collectImplicits(scope, NoPrefix)) + } else if (firstImport != nextOuter.firstImport) { + assert(imports.tail.headOption == nextOuter.firstImport, (imports, nextOuter.imports)) + Some(collectImplicitImports(imports.head)) + } else if (owner.isPackageClass) { + // the corresponding package object may contain implicit members. + Some(collectImplicits(owner.tpe.implicitMembers, owner.tpe)) + } else Some(Nil) + } + // // Imports and symbol lookup // |