diff options
author | Martin Odersky <odersky@gmail.com> | 2016-06-29 19:04:03 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-07-11 13:34:58 +0200 |
commit | 850dc6f2fb3b6228f2586ce0790621e80f664afe (patch) | |
tree | 3100de85088553b62f1652435049f4bb24f8f2fb /src/dotty/tools/dotc/printing/PlainPrinter.scala | |
parent | cdb4a1cb986f25eddf411dfc45aeb20dd994f7d5 (diff) | |
download | dotty-850dc6f2fb3b6228f2586ce0790621e80f664afe.tar.gz dotty-850dc6f2fb3b6228f2586ce0790621e80f664afe.tar.bz2 dotty-850dc6f2fb3b6228f2586ce0790621e80f664afe.zip |
Introduce recursive types
Map self-references in refinements to recursive types. This
commit does this for refinement types appearing in source.
We still have to do it for unpickled refinements.
Test apply-equiv got moved to pending because it simulates
the old higher-kinded type encoding in source, which relies
on the old representation in terms of self-referential refinement
types. The plan is not to adapt this encoding to the new
representation, but to replace it with a different encoding
that makes critical use of the added power of recursive types.
Use recursive types also when unpickling from Scala 2.x.
Add mapInfo method to Denotations.
Diffstat (limited to 'src/dotty/tools/dotc/printing/PlainPrinter.scala')
-rw-r--r-- | src/dotty/tools/dotc/printing/PlainPrinter.scala | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala index 7053a0ea3..59f1608db 100644 --- a/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -13,6 +13,8 @@ import scala.annotation.switch class PlainPrinter(_ctx: Context) extends Printer { protected[this] implicit def ctx: Context = _ctx.addMode(Mode.Printing) + private var openRecs: List[RecType] = Nil + protected def maxToTextRecursions = 100 protected final def controlled(op: => Text): Text = @@ -58,6 +60,8 @@ class PlainPrinter(_ctx: Context) extends Printer { } else tp + private def selfRecName(n: Int) = s"z$n" + /** Render elements alternating with `sep` string */ protected def toText(elems: Traversable[Showable], sep: String) = Text(elems map (_ toText this), sep) @@ -130,6 +134,12 @@ class PlainPrinter(_ctx: Context) extends Printer { val parent :: (refined: List[RefinedType @unchecked]) = refinementChain(tp).reverse toTextLocal(parent) ~ "{" ~ Text(refined map toTextRefinement, "; ").close ~ "}" + case tp: RecType => + try { + openRecs = tp :: openRecs + "{" ~ selfRecName(openRecs.length) ~ " => " ~ toTextGlobal(tp.parent) ~ "}" + } + finally openRecs = openRecs.tail case AndType(tp1, tp2) => changePrec(AndPrec) { toText(tp1) ~ " & " ~ toText(tp2) } case OrType(tp1, tp2) => @@ -232,6 +242,10 @@ class PlainPrinter(_ctx: Context) extends Printer { toText(value) case MethodParam(mt, idx) => nameString(mt.paramNames(idx)) + case tp: RecThis => + val idx = openRecs.reverse.indexOf(tp.binder) + if (idx >= 0) selfRecName(idx + 1) + else "{...}.this" // TODO move underlying type to an addendum, e.g. ... z3 ... where z3: ... case tp: RefinedThis => s"${nameString(tp.binder.typeSymbol)}{...}.this" case tp: SkolemType => |