From ae3e18c81517db5df656caf105bc09e0aab3f4a1 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 15 Aug 2013 10:16:21 +0200 Subject: Fixes CyclicReference on enter ClassCompleters need to allow access to the class decls scope before the class is completed. --- src/dotty/tools/dotc/typer/Namer.scala | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src/dotty/tools/dotc/typer/Namer.scala') diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 514badb5e..12c812c22 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -111,7 +111,7 @@ class Namer { typer: Typer => val sym = tree match { case tree: TypeDef if tree.isClassDef => ctx.enter(ctx.newClassSymbol( - ctx.owner, tree.name, tree.mods.flags, new Completer(tree), + ctx.owner, tree.name, tree.mods.flags, new ClassCompleter(tree), privateWithinClass(tree.mods), tree.pos, ctx.source.file)) case tree: MemberDef => ctx.enter(ctx.newSymbol( @@ -208,7 +208,7 @@ class Namer { typer: Typer => result } - /** The completer of a symbol defined by a member def or import */ + /** The completer of a symbol defined by a member def or import (except ClassSymbols) */ class Completer(original: Tree)(implicit ctx: Context) extends LazyType { def complete(denot: SymDenotation): Unit = { @@ -223,8 +223,7 @@ class Namer { typer: Typer => nestedTyper(sym) = typer1 typer1.defDefSig(tree, sym)(localContext.withTyper(typer1)) case tree: TypeDef => - if (tree.isClassDef) classDefSig(tree, sym.asClass)(localContext) - else typeDefSig(tree, sym)(localContext.withNewScope) + typeDefSig(tree, sym)(localContext.withNewScope) case imp: Import => val expr1 = typedAheadExpr(imp.expr, AnySelectionProto) ImportType(tpd.SharedTree(expr1)) @@ -234,6 +233,16 @@ class Namer { typer: Typer => } } + /** The completer for a symbol defined by a class definition */ + class ClassCompleter(original: TypeDef, override val decls: MutableScope = newScope)(implicit ctx: Context) + extends ClassCompleterWithDecls(decls) { + override def complete(denot: SymDenotation): Unit = { + val cls = denot.symbol.asClass + def localContext = ctx.fresh.withOwner(cls) + cls.info = classDefSig(original, cls, decls)(localContext) + } + } + /** Typecheck tree during completion, and remember result in typedtree map */ private def typedAheadImpl(tree: Tree, pt: Type)(implicit ctx: Context): tpd.Tree = typedTree.getOrElseUpdate(tree, typer.typedExpanded(tree, pt)) @@ -324,7 +333,7 @@ class Namer { typer: Typer => } /** The type signature of a ClassDef with given symbol */ - def classDefSig(cdef: TypeDef, cls: ClassSymbol)(implicit ctx: Context): Type = { + def classDefSig(cdef: TypeDef, cls: ClassSymbol, decls: MutableScope)(implicit ctx: Context): Type = { def parentType(constr: untpd.Tree): Type = { val Trees.Select(Trees.New(tpt), _) = methPart(constr) @@ -335,7 +344,6 @@ class Namer { typer: Typer => val TypeDef(_, _, impl @ Template(_, parents, self, body)) = cdef - val decls = newScope val (params, rest) = body span { case td: TypeDef => td.mods is Param case td: ValDef => td.mods is ParamAccessor -- cgit v1.2.3