diff options
author | Martin Odersky <odersky@gmail.com> | 2014-03-12 17:02:47 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-03-12 17:05:13 +0100 |
commit | 66291018e0512b2d4e7d6bac017ab47b95939275 (patch) | |
tree | 3ea52f67edcf42c860207ec806d38959654f4f57 /src/dotty/tools/dotc/typer/Namer.scala | |
parent | 7fa78597bf58a7759303095121a432cb258f447c (diff) | |
download | dotty-66291018e0512b2d4e7d6bac017ab47b95939275.tar.gz dotty-66291018e0512b2d4e7d6bac017ab47b95939275.tar.bz2 dotty-66291018e0512b2d4e7d6bac017ab47b95939275.zip |
Fix constructor completion problem detected in t0054
Constructors need to be completed in the context which immediately encloses
a class. Otherwise type references in the constructor see the wrong types,
as is demonstrated in t0054. The difficulty here is that the inner class B
nested in A also extends from A. Then it makes a difference whether the constructor
parameter types of B are resolved in the context of B or in the context of A.
Added explanation for context handling of constructors.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Namer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 9c8522b83..2c5022726 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -216,9 +216,18 @@ class Namer { typer: Typer => checkNoConflict(name) val deferred = if (lacksDefinition(tree)) Deferred else EmptyFlags val method = if (tree.isInstanceOf[DefDef]) Method else EmptyFlags + + // to complete a constructor, move one context further out -- this + // is the context enclosing the class. Note that the context in which a + // constructor is recorded and the context in which it is completed are + // different: The former must have the class as owner (because the + // constructor is owned by the class), the latter must not (because + // constructor parameters are interpreted as if they are outside the class). + val cctx = if (tree.name == nme.CONSTRUCTOR) ctx.outer else ctx + record(ctx.newSymbol( ctx.owner, name, tree.mods.flags | deferred | method, - adjustIfModule(new Completer(tree), tree), + adjustIfModule(new Completer(tree)(cctx), tree), privateWithinClass(tree.mods), tree.pos)) case tree: Import => record(ctx.newSymbol( |