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 | |
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')
-rw-r--r-- | src/dotty/tools/dotc/ast/Desugar.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 35 |
2 files changed, 23 insertions, 15 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index 0f158cbb5..b82bd47f6 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -721,8 +721,7 @@ object desugar { * The result is used for validity checking, is thrown away afterwards. */ def refinedTypeToClass(tree: RefinedTypeTree)(implicit ctx: Context): TypeDef = { - val parent = New(tree.tpt, Nil) - val impl = Template(emptyConstructor, parent :: Nil, EmptyValDef, tree.refinements) + val impl = Template(emptyConstructor, tree.tpt :: Nil, EmptyValDef, tree.refinements) TypeDef(Modifiers(), tpnme.REFINE_CLASS, impl) } 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 |