From 7ca40215f51a7a008dd1856b9813eabfd8121d8d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 14 Nov 2013 18:27:17 +0100 Subject: Making as seenfrom reduce types. Adding operattions select, derivedSelect which reduce combinations of typerefs over refinement types. --- src/dotty/tools/dotc/core/TypeOps.scala | 22 ++++++---------------- src/dotty/tools/dotc/core/Types.scala | 32 ++++++++++++++++---------------- 2 files changed, 22 insertions(+), 32 deletions(-) (limited to 'src/dotty/tools/dotc/core') diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 8d05a4324..c48a8e715 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -20,26 +20,12 @@ trait TypeOps { this: Context => toPrefix(pre.baseType(cls).normalizedPrefix, cls.owner, thiscls) } - ctx.debugTraceIndented(s"$tp.asSeenFrom($pre, $cls)") { // !!! DEBUG + ctx.conditionalTraceIndented(TypeOps.track , s"asSeen ${tp.show} from (${pre.show}, ${cls.show})", show = true) { // !!! DEBUG tp match { case tp: NamedType => val sym = tp.symbol if (sym.isStatic) tp - else { - val tp1 = tp.derivedNamedType(asSeenFrom(tp.prefix, pre, cls, theMap)) - // Here's an explanation why we short-circuit instantiated type parameters. - // Say you have This is translated to: - // - // class List[type T] ==> class List { type T; val hd: T } - // xs: List[Int] ==> List { type T = Int } - // - // Then with the line above, xs.hd would have type xs.T - // - // But in Scala 2.x, its type is Int, which is the dealiased version - // of xs.T. With the logic below, we get the same outcome as for 2.x. - if ((tp1 ne tp) && (sym is (TypeParam, butNot = Deferred))) tp1.dealias // todo: why not TypeArgument? - else tp1 - } + else tp.derivedSelect(asSeenFrom(tp.prefix, pre, cls, theMap)) case ThisType(thiscls) => toPrefix(pre, cls, thiscls) case _: BoundType | NoPrefix => @@ -179,3 +165,7 @@ trait TypeOps { this: Context => } } +object TypeOps { + + var track = false // !!!DEBUG +} diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 14ebba57d..03b55736c 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -679,18 +679,18 @@ object Types { } /** The type , reduced if possible */ - def typeSelect(name: TypeName)(implicit ctx: Context): Type = - lookupRefined(this, name) orElse TypeRef(this, name) + def select(name: Name)(implicit ctx: Context): Type = { + val res = lookupRefined(this, name) + if (res.exists) res else NamedType(this, name) + } /** The type with given symbol, reduced if possible */ - def typeSelect(name: TypeName, sym: TypeSymbol)(implicit ctx: Context): Type = - lookupRefined(this, name) orElse TypeRef.withSym(this, name, sym) - - /** The type , reduced if possible */ - def typeSelect(sym: TypeSymbol)(implicit ctx: Context): Type = - typeSelect(sym.name, sym) + def select(sym: Symbol)(implicit ctx: Context): Type = { + val res = lookupRefined(this, sym.name) + if (res.exists) res else NamedType.withSym(this, sym) + } - private def lookupRefined(pre: Type, name: TypeName)(implicit ctx: Context): Type = pre.stripTypeVar match { + private def lookupRefined(pre: Type, name: Name)(implicit ctx: Context): Type = pre.stripTypeVar match { case pre: RefinedType => if (pre.refinedName ne name) lookupRefined(pre.parent, name) else pre.refinedInfo match { @@ -1456,6 +1456,10 @@ object Types { if (prefix eq this.prefix) this else newLikeThis(prefix) + def derivedSelect(prefix: Type)(implicit ctx: Context): Type = + if (prefix eq this.prefix) this + else prefix select this.name + /** Create a NamedType of the same kind as this type, if possible, * but with a new prefix. For HasFixedSym instances another such * instance is only created if the symbol's owner is a base class of @@ -2335,12 +2339,8 @@ object Types { /** Map this function over given type */ def mapOver(tp: Type): Type = tp match { - case tp: TypeRef => - val tp1 = tp.reduceTypeRef - if (tp1 ne tp) this(tp1) else tp.derivedNamedType(this(tp.prefix)) - - case tp: TermRef => - tp.derivedNamedType(this(tp.prefix)) + case tp: NamedType => + tp.derivedSelect(this(tp.prefix)) case _: ThisType | _: BoundType => tp @@ -2444,7 +2444,7 @@ object Types { def foldOver(x: T, tp: Type): T = tp match { case tp: TypeRef => - val tp1 = tp.reduceTypeRef + val tp1 = tp.reduceTypeRef // !!! needed? this(x, if (tp1 ne tp) tp1 else tp.prefix) case tp: TermRef => -- cgit v1.2.3