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/core/TypeOps.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/core/TypeOps.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeOps.scala | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 72b0c87c4..54846087f 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -232,11 +232,16 @@ trait TypeOps { this: Context => // TODO: Make standalone object. } case _ => } + tp1 match { + case tp1: RecType => + tp1.rebind(approximateOr(tp1.parent, tp2)) case tp1: TypeProxy if !isClassRef(tp1) => approximateUnion(next(tp1) | tp2) case _ => tp2 match { + case tp2: RecType => + tp2.rebind(approximateOr(tp1, tp2.parent)) case tp2: TypeProxy if !isClassRef(tp2) => approximateUnion(tp1 | next(tp2)) case _ => @@ -252,16 +257,32 @@ trait TypeOps { this: Context => // TODO: Make standalone object. if (ctx.featureEnabled(defn.LanguageModuleClass, nme.keepUnions)) tp else tp match { case tp: OrType => - approximateOr(tp.tp1, tp.tp2) + approximateOr(tp.tp1, tp.tp2) // Maybe refactor using liftToRec? case tp @ AndType(tp1, tp2) => tp derived_& (approximateUnion(tp1), approximateUnion(tp2)) case tp: RefinedType => tp.derivedRefinedType(approximateUnion(tp.parent), tp.refinedName, tp.refinedInfo) + case tp: RecType => + tp.rebind(approximateUnion(tp.parent)) case _ => tp } } + /** Not currently needed: + * + def liftToRec(f: (Type, Type) => Type)(tp1: Type, tp2: Type)(implicit ctx: Context) = { + def f2(tp1: Type, tp2: Type): Type = tp2 match { + case tp2: RecType => tp2.rebind(f(tp1, tp2.parent)) + case _ => f(tp1, tp2) + } + tp1 match { + case tp1: RecType => tp1.rebind(f2(tp1.parent, tp2)) + case _ => f2(tp1, tp2) + } + } + */ + private def enterArgBinding(formal: Symbol, info: Type, cls: ClassSymbol, decls: Scope) = { val lazyInfo = new LazyType { // needed so we do not force `formal`. def complete(denot: SymDenotation)(implicit ctx: Context): Unit = { |