diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-10-10 11:24:14 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-10-10 15:57:01 +1000 |
commit | 91c34cedc9ee54244f6b49dda691cbe0be182037 (patch) | |
tree | 94a4e6a33b6d7966d83526d881cd008ce744cc66 /src/compiler/scala | |
parent | 22233f40f641815fe7b9304bb386ee27c8422603 (diff) | |
download | scala-91c34cedc9ee54244f6b49dda691cbe0be182037.tar.gz scala-91c34cedc9ee54244f6b49dda691cbe0be182037.tar.bz2 scala-91c34cedc9ee54244f6b49dda691cbe0be182037.zip |
SI-3439 Fix use of implicit constructor params in super call
When typechecking the primary constructor body, the symbols of
constructor parameters of a class are owned by the class's owner.
This is done make scoping work; you shouldn't be able to refer to
class members in that position.
However, other parts of the compiler weren't so happy about
this arrangement. The enclosed test case shows that our
checks for invalid, top-level implicits was spuriously triggered,
and implicit search itself would fail.
Furthermore, we had to hack `Run#compiles` to special case
top-level early-initialized symbols. See SI-7264 / 86e6e9290.
This commit:
- introduces an intermediate local dummy term symbol which
will act as the owner for constructor parameters and early
initialized members
- adds this to the `Run#symSource` map if it is top level
- simplifies `Run#compiles` accordingly
- tests this all in a top-level class, and one nested in
another class.
Diffstat (limited to 'src/compiler/scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/Global.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 4 |
2 files changed, 5 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 452081cff1..76d8b7e5ef 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1232,13 +1232,12 @@ class Global(var currentSettings: Settings, var reporter: Reporter) /** does this run compile given class, module, or case factory? */ // NOTE: Early initialized members temporarily typechecked before the enclosing class, see typedPrimaryConstrBody! - // Here we work around that wrinkle by claiming that a top-level, early-initialized member is compiled in + // Here we work around that wrinkle by claiming that a early-initialized member is compiled in // *every* run. This approximation works because this method is exclusively called with `this` == `currentRun`. def compiles(sym: Symbol): Boolean = if (sym == NoSymbol) false else if (symSource.isDefinedAt(sym)) true - else if (sym.isTopLevel && sym.isEarlyInitialized) true - else if (!sym.isTopLevel) compiles(sym.enclosingTopLevelClass) + else if (!sym.isTopLevel) compiles(sym.enclosingTopLevelClassOrDummy) else if (sym.isModuleClass) compiles(sym.sourceModule) else false diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index aae2d24b32..70acb03584 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1516,7 +1516,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val cbody1 = treeCopy.Block(cbody, preSuperStats, superCall1) val clazz = context.owner assert(clazz != NoSymbol, templ) - val cscope = context.outer.makeNewScope(ctor, context.outer.owner) + val dummy = context.outer.owner.newLocalDummy(templ.pos) + val cscope = context.outer.makeNewScope(ctor, dummy) + if (dummy.isTopLevel) currentRun.symSource(dummy) = currentUnit.source.file val cbody2 = { // called both during completion AND typing. val typer1 = newTyper(cscope) // XXX: see about using the class's symbol.... |