summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-04-28 12:25:21 +0200
committerJason Zaugg <jzaugg@gmail.com>2013-04-28 12:52:45 +0200
commitf59be7a7838d763de4b49e5be6b848754f1f7c17 (patch)
tree8a2e1c00c9d90ed2400e66126753077359782ad9 /src/compiler
parent464c9fedd2e3339d3f858213067b07a5b9a28b93 (diff)
downloadscala-f59be7a7838d763de4b49e5be6b848754f1f7c17.tar.gz
scala-f59be7a7838d763de4b49e5be6b848754f1f7c17.tar.bz2
scala-f59be7a7838d763de4b49e5be6b848754f1f7c17.zip
SI-7429 Fix checkinit build failure in Contexts
The recent refactoring in Contexts resulted in an uninitialized field access. This wasn't deadly, as it was already compensating for this by expecting a null value for `outer` during in the body of the constructor of Contexts when extended by NoContext. This commit reworks that code a little to avoid dereferencing the overriden `outer` field. A similar mistake in `ImportContext` is also corrected.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala34
1 files changed, 13 insertions, 21 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 538b3b3b6c..c26ad3e61d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -21,10 +21,7 @@ trait Contexts { self: Analyzer =>
object NoContext
extends Context(EmptyTree, NoSymbol, EmptyScope, NoCompilationUnit,
- outer = null /*We can't pass NoContext here, overriden below*/) {
-
- override val outer = this
-
+ null) { // We can't pass the uninitialized `this`. Instead, we treat null specially in `Context#outer`
enclClass = this
enclMethod = this
@@ -161,10 +158,13 @@ trait Contexts { self: Analyzer =>
* @param tree Tree associated with this context
* @param owner The current owner
* @param scope The current scope
- * @param outer The next outer context.
+ * @param _outer The next outer context.
*/
class Context private[typechecker](val tree: Tree, val owner: Symbol, val scope: Scope,
- val unit: CompilationUnit, val outer: Context) {
+ val unit: CompilationUnit, _outer: Context) {
+ private def outerIsNoContext = _outer eq null
+ final def outer: Context = if (outerIsNoContext) NoContext else _outer
+
/** The next outer context whose tree is a template or package definition */
var enclClass: Context = _
@@ -199,9 +199,10 @@ trait Contexts { self: Analyzer =>
private var _undetparams: List[Symbol] = List()
+ protected def outerDepth = if (outerIsNoContext) 0 else outer.depth
+
val depth: Int = {
- val increasesDepth = isRootImport || (outer eq null) || (outer.scope != scope)
- def outerDepth = if (outer eq null) 0 else outer.depth
+ val increasesDepth = isRootImport || outerIsNoContext || (outer.scope != scope)
( if (increasesDepth) 1 else 0 ) + outerDepth
}
@@ -1138,22 +1139,15 @@ trait Contexts { self: Analyzer =>
/** A `Context` focussed on an `Import` tree */
trait ImportContext extends Context {
- private def makeImpInfo = {
- val info = new ImportInfo(tree.asInstanceOf[Import], outer.depth)
- if (settings.lint && !info.isRootImport) // excludes java.lang/scala/Predef imports
+ private val impInfo: ImportInfo = {
+ val info = new ImportInfo(tree.asInstanceOf[Import], outerDepth)
+ if (settings.lint && !isRootImport) // excludes java.lang/scala/Predef imports
allImportInfos(unit) ::= info
info
}
-
- private var _impInfo: ImportInfo = null // hand rolled lazy val, we don't need/want synchronization.
- private def impInfo: ImportInfo = {
- if (_impInfo eq null) _impInfo = makeImpInfo
- _impInfo
- }
-
override final def imports = impInfo :: super.imports
override final def firstImport = Some(impInfo)
- override final def isRootImport = impInfo.isRootImport
+ override final def isRootImport = !tree.pos.isDefined
override final def toString = s"ImportContext { $impInfo; outer.owner = ${outer.owner} }"
}
@@ -1227,8 +1221,6 @@ trait Contexts { self: Analyzer =>
def isExplicitImport(name: Name): Boolean =
tree.selectors exists (_.rename == name.toTermName)
- final def isRootImport: Boolean = !tree.pos.isDefined
-
/** The symbol with name `name` imported from import clause `tree`.
*/
def importedSymbol(name: Name): Symbol = importedSymbol(name, requireExplicit = false)