diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-04-28 12:25:21 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-04-28 12:52:45 +0200 |
commit | f59be7a7838d763de4b49e5be6b848754f1f7c17 (patch) | |
tree | 8a2e1c00c9d90ed2400e66126753077359782ad9 /src/compiler | |
parent | 464c9fedd2e3339d3f858213067b07a5b9a28b93 (diff) | |
download | scala-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.scala | 34 |
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) |