diff options
author | Martin Odersky <odersky@gmail.com> | 2014-01-11 15:11:45 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-01-11 15:11:45 +0100 |
commit | d68e4f85e7dbddb6a42a4be202e765d445268be6 (patch) | |
tree | 049efedaf32657b3d3837e466a915d7fc5c5b26a /src/dotty/tools/dotc/typer/Namer.scala | |
parent | 0bf0d57f988b1fe3f29991f0cde6aaa1b996b0a2 (diff) | |
download | dotty-d68e4f85e7dbddb6a42a4be202e765d445268be6.tar.gz dotty-d68e4f85e7dbddb6a42a4be202e765d445268be6.tar.bz2 dotty-d68e4f85e7dbddb6a42a4be202e765d445268be6.zip |
Handling refined types.
A refined type P { refinement } is expanded to a class
class <refined> extends P { refinement }
for type-checking. The problem is that the parent P does not always have a constructor. So we need to leave the parent as a type and add a special case to classDefSig that handles it.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Namer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index fb075b40a..1ac95052a 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -321,7 +321,7 @@ class Namer { typer: Typer => } /** The completer of a symbol defined by a member def or import (except ClassSymbols) */ - class Completer(original: Tree)(implicit ctx: Context) extends LazyType { + class Completer(val original: Tree)(implicit ctx: Context) extends LazyType { protected def localContext(owner: Symbol) = ctx.fresh.withOwner(owner).withTree(original) @@ -336,8 +336,14 @@ class Namer { typer: Typer => assert(!original.isClassDef) typeDefSig(original, sym)(localContext(sym).withNewScope) case imp: Import => - val expr1 = typedAheadExpr(imp.expr, AnySelectionProto) - ImportType(tpd.SharedTree(expr1)) + try { + val expr1 = typedAheadExpr(imp.expr, AnySelectionProto) + ImportType(tpd.SharedTree(expr1)) + } catch { + case ex: CyclicReference => + typr.println(s"error while completing ${imp.expr}") + throw ex + } } def complete(denot: SymDenotation): Unit = @@ -365,17 +371,20 @@ class Namer { typer: Typer => /** The type of a parent constructor. Types constructor arguments * only if parent type contains uninstantiated type parameters. */ - def parentType(constr: untpd.Tree): Type = { - val (core, targs) = stripApply(constr) match { - case TypeApply(core, targs) => (core, targs) - case core => (core, Nil) + def parentType(constr: untpd.Tree): Type = + if (constr.isType) { // this case applies to desugared refined types + typedAheadType(constr).tpe + } else { + val (core, targs) = stripApply(constr) match { + case TypeApply(core, targs) => (core, targs) + case core => (core, Nil) + } + val Select(New(tpt), nme.CONSTRUCTOR) = core + val targs1 = targs map (typedAheadType(_)) + val ptype = typedAheadType(tpt).tpe appliedTo targs1.tpes + if (ptype.uninstantiatedTypeParams.isEmpty) ptype + else typedAheadExpr(constr).tpe } - val Select(New(tpt), nme.CONSTRUCTOR) = core - val targs1 = targs map (typedAheadType(_)) - val ptype = typedAheadType(tpt).tpe appliedTo targs1.tpes - if (ptype.uninstantiatedTypeParams.isEmpty) ptype - else typedAheadExpr(constr).tpe - } val selfInfo = if (self.isEmpty) NoType |