From b1b76515a66d94e9552f3ccde02cb4d1bacbc0ec Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 9 Dec 2014 16:26:18 +0100 Subject: Moved derivedTypeAlias method to TypeAlias --- src/dotty/tools/dotc/core/Substituters.scala | 40 +++++++-------- src/dotty/tools/dotc/core/TypeOps.scala | 8 +-- src/dotty/tools/dotc/core/Types.scala | 73 +++++++++++++--------------- src/dotty/tools/dotc/typer/Checking.scala | 38 +++++++-------- src/dotty/tools/dotc/typer/ProtoTypes.scala | 4 +- 5 files changed, 77 insertions(+), 86 deletions(-) (limited to 'src/dotty/tools') diff --git a/src/dotty/tools/dotc/core/Substituters.scala b/src/dotty/tools/dotc/core/Substituters.scala index 02d09d542..02810733a 100644 --- a/src/dotty/tools/dotc/core/Substituters.scala +++ b/src/dotty/tools/dotc/core/Substituters.scala @@ -18,8 +18,8 @@ trait Substituters { this: Context => tp case tp: RefinedType => tp.derivedRefinedType(subst(tp.parent, from, to, theMap), tp.refinedName, subst(tp.refinedInfo, from, to, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => - tp.derivedTypeAlias(subst(tp.lo, from, to, theMap)) + case tp: TypeAlias => + tp.derivedTypeAlias(subst(tp.alias, from, to, theMap)) case _ => (if (theMap != null) theMap else new SubstBindingMap(from, to)) .mapOver(tp) @@ -36,8 +36,8 @@ trait Substituters { this: Context => tp case tp: RefinedType => tp.derivedRefinedType(subst1(tp.parent, from, to, theMap), tp.refinedName, subst1(tp.refinedInfo, from, to, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => - tp.derivedTypeAlias(subst1(tp.lo, from, to, theMap)) + case tp: TypeAlias => + tp.derivedTypeAlias(subst1(tp.alias, from, to, theMap)) case _ => (if (theMap != null) theMap else new Subst1Map(from, to)) .mapOver(tp) @@ -56,8 +56,8 @@ trait Substituters { this: Context => tp case tp: RefinedType => tp.derivedRefinedType(subst2(tp.parent, from1, to1, from2, to2, theMap), tp.refinedName, subst2(tp.refinedInfo, from1, to1, from2, to2, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => - tp.derivedTypeAlias(subst2(tp.lo, from1, to1, from2, to2, theMap)) + case tp: TypeAlias => + tp.derivedTypeAlias(subst2(tp.alias, from1, to1, from2, to2, theMap)) case _ => (if (theMap != null) theMap else new Subst2Map(from1, to1, from2, to2)) .mapOver(tp) @@ -81,8 +81,8 @@ trait Substituters { this: Context => tp case tp: RefinedType => tp.derivedRefinedType(subst(tp.parent, from, to, theMap), tp.refinedName, subst(tp.refinedInfo, from, to, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => - tp.derivedTypeAlias(subst(tp.lo, from, to, theMap)) + case tp: TypeAlias => + tp.derivedTypeAlias(subst(tp.alias, from, to, theMap)) case _ => (if (theMap != null) theMap else new SubstMap(from, to)) .mapOver(tp) @@ -115,8 +115,8 @@ trait Substituters { this: Context => tp case tp: RefinedType => tp.derivedRefinedType(substDealias(tp.parent, from, to, theMap), tp.refinedName, substDealias(tp.refinedInfo, from, to, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => - tp.derivedTypeAlias(substDealias(tp.lo, from, to, theMap)) + case tp: TypeAlias => + tp.derivedTypeAlias(substDealias(tp.alias, from, to, theMap)) case _ => (if (theMap != null) theMap else new SubstDealiasMap(from, to)) .mapOver(tp) @@ -154,8 +154,8 @@ trait Substituters { this: Context => tp case tp: RefinedType => tp.derivedRefinedType(substSym(tp.parent, from, to, theMap), tp.refinedName, substSym(tp.refinedInfo, from, to, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => - tp.derivedTypeAlias(substSym(tp.lo, from, to, theMap)) + case tp: TypeAlias => + tp.derivedTypeAlias(substSym(tp.alias, from, to, theMap)) case _ => (if (theMap != null) theMap else new SubstSymMap(from, to)) .mapOver(tp) @@ -172,8 +172,8 @@ trait Substituters { this: Context => tp case tp: RefinedType => tp.derivedRefinedType(substThis(tp.parent, from, to, theMap), tp.refinedName, substThis(tp.refinedInfo, from, to, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => - tp.derivedTypeAlias(substThis(tp.lo, from, to, theMap)) + case tp: TypeAlias => + tp.derivedTypeAlias(substThis(tp.alias, from, to, theMap)) case _ => (if (theMap != null) theMap else new SubstThisMap(from, to)) .mapOver(tp) @@ -190,8 +190,8 @@ trait Substituters { this: Context => tp case tp: RefinedType => tp.derivedRefinedType(substThis(tp.parent, from, to, theMap), tp.refinedName, substThis(tp.refinedInfo, from, to, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => - tp.derivedTypeAlias(substThis(tp.lo, from, to, theMap)) + case tp: TypeAlias => + tp.derivedTypeAlias(substThis(tp.alias, from, to, theMap)) case _ => (if (theMap != null) theMap else new SubstRefinedThisMap(from, to)) .mapOver(tp) @@ -208,8 +208,8 @@ trait Substituters { this: Context => tp case tp: RefinedType => tp.derivedRefinedType(substParam(tp.parent, from, to, theMap), tp.refinedName, substParam(tp.refinedInfo, from, to, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => - tp.derivedTypeAlias(substParam(tp.lo, from, to, theMap)) + case tp: TypeAlias => + tp.derivedTypeAlias(substParam(tp.alias, from, to, theMap)) case _ => (if (theMap != null) theMap else new SubstParamMap(from, to)) .mapOver(tp) @@ -226,8 +226,8 @@ trait Substituters { this: Context => tp case tp: RefinedType => tp.derivedRefinedType(substParams(tp.parent, from, to, theMap), tp.refinedName, substParams(tp.refinedInfo, from, to, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => - tp.derivedTypeAlias(substParams(tp.lo, from, to, theMap)) + case tp: TypeAlias => + tp.derivedTypeAlias(substParams(tp.alias, from, to, theMap)) case _ => (if (theMap != null) theMap else new SubstParamsMap(from, to)) .mapOver(tp) diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 8bda49c94..bf5ba4e55 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -41,8 +41,8 @@ trait TypeOps { this: Context => asSeenFrom(tp.parent, pre, cls, theMap), tp.refinedName, asSeenFrom(tp.refinedInfo, pre, cls, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => - tp.derivedTypeAlias(asSeenFrom(tp.lo, pre, cls, theMap)) + case tp: TypeAlias => + tp.derivedTypeAlias(asSeenFrom(tp.alias, pre, cls, theMap)) case _ => (if (theMap != null) theMap else new AsSeenFromMap(pre, cls)) .mapOver(tp) @@ -71,8 +71,8 @@ trait TypeOps { this: Context => tp case tp: RefinedType => tp.derivedRefinedType(simplify(tp.parent, theMap), tp.refinedName, simplify(tp.refinedInfo, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => - tp.derivedTypeAlias(simplify(tp.lo, theMap)) + case tp: TypeAlias => + tp.derivedTypeAlias(simplify(tp.alias, theMap)) case AndType(l, r) => simplify(l, theMap) & simplify(r, theMap) case OrType(l, r) => diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 6e224d6f6..00c6af676 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -662,7 +662,7 @@ object Types { final def dealias(implicit ctx: Context): Type = this match { case tp: TypeRef => tp.info match { - case TypeBounds(lo, hi) if lo eq hi => hi.dealias + case TypeAlias(tp) => tp.dealias case _ => tp } case tp: TypeVar => @@ -739,7 +739,7 @@ object Types { def dependsOnRefinedThis(tp: Type): Boolean = tp.stripTypeVar match { case tp @ TypeRef(RefinedThis(rt), _) if rt refines this => tp.info match { - case TypeBounds(lo, hi) if lo eq hi => dependsOnRefinedThis(hi) + case TypeAlias(alias) => dependsOnRefinedThis(alias) case _ => true } case RefinedThis(rt) => rt refines this @@ -2402,11 +2402,6 @@ object Types { if ((lo eq this.lo) && (hi eq this.hi) && (variance == this.variance)) this else TypeBounds(lo, hi, variance) - /** pre: this is a type alias */ - def derivedTypeAlias(tp: Type, variance: Int = this.variance)(implicit ctx: Context) = - if (lo eq tp) this - else TypeAlias(tp, variance) - /** If this is an alias, a derived alias with the new variance, * Otherwise the type itself. */ @@ -2421,17 +2416,21 @@ object Types { def & (that: TypeBounds)(implicit ctx: Context): TypeBounds = { val v = this commonVariance that - if (v != 0 && (this.lo eq this.hi) && (that.lo eq that.hi)) - if (v > 0) derivedTypeAlias(this.hi & that.hi, v) - else derivedTypeAlias(this.lo | that.lo, v) + if (v != 0) { + val thisAlias = this.asInstanceOf[TypeAlias] + if (v > 0) thisAlias.derivedTypeAlias(this.hi & that.hi, v) + else thisAlias.derivedTypeAlias(this.lo | that.lo, v) + } else derivedTypeBounds(this.lo | that.lo, this.hi & that.hi, v) } def | (that: TypeBounds)(implicit ctx: Context): TypeBounds = { val v = this commonVariance that - if (v != 0 && (this.lo eq this.hi) && (that.lo eq that.hi)) - if (v > 0) derivedTypeAlias(this.hi | that.hi, v) - else derivedTypeAlias(this.lo & that.lo, v) + if (v != 0) { + val thisAlias = this.asInstanceOf[TypeAlias] + if (v > 0) thisAlias.derivedTypeAlias(this.hi | that.hi, v) + else thisAlias.derivedTypeAlias(this.lo & that.lo, v) + } else derivedTypeBounds(this.lo & that.lo, this.hi | that.hi, v) } @@ -2460,11 +2459,16 @@ object Types { } - class CachedTypeBounds(lo: Type, hi: Type) extends TypeBounds(lo, hi) { + class RealTypeBounds(lo: Type, hi: Type) extends TypeBounds(lo, hi) { override def computeHash = doHash(variance, lo, hi) } - abstract class TypeAlias(val alias: Type, override val variance: Int) extends TypeBounds(alias, alias) + abstract class TypeAlias(val alias: Type, override val variance: Int) extends TypeBounds(alias, alias) { + /** pre: this is a type alias */ + def derivedTypeAlias(tp: Type, variance: Int = this.variance)(implicit ctx: Context) = + if (lo eq tp) this + else TypeAlias(tp, variance) + } class CachedTypeAlias(alias: Type, variance: Int, hc: Int) extends TypeAlias(alias, variance) { myHash = hc @@ -2476,7 +2480,7 @@ object Types { if (lo eq hi) TypeAlias(lo, variance) else unique { assert(variance == 0) - new CachedTypeBounds(lo, hi) + new RealTypeBounds(lo, hi) } def empty(implicit ctx: Context) = apply(defn.NothingType, defn.AnyType) def upper(hi: Type, variance: Int = 0)(implicit ctx: Context) = apply(defn.NothingType, hi, variance) @@ -2486,7 +2490,7 @@ object Types { object TypeAlias { def apply(alias: Type, variance: Int = 0)(implicit ctx: Context) = ctx.uniqueTypeAliases.enterIfNew(alias, variance) - def unapply(tp: Type): Option[Type] = tp match { + def unapply(tp: TypeAlias): Option[Type] = tp match { case tp: TypeAlias => Some(tp.alias) case _ => None } @@ -2641,24 +2645,18 @@ object Types { case tp: RefinedType => tp.derivedRefinedType(this(tp.parent), tp.refinedName, this(tp.refinedInfo)) + case tp: TypeAlias => + val saved = variance + variance = variance * tp.variance + val alias1 = this(tp.alias) + variance = saved + tp.derivedTypeAlias(alias1) + case tp: TypeBounds => - def mapOverBounds = { - val lo = tp.lo - val hi = tp.hi - if (lo eq hi) { - val saved = variance - variance = variance * tp.variance - val lo1 = this(lo) - variance = saved - tp.derivedTypeAlias(lo1) - } else { - variance = -variance - val lo1 = this(lo) - variance = -variance - tp.derivedTypeBounds(lo1, this(hi)) - } - } - mapOverBounds + variance = -variance + val lo1 = this(tp.lo) + variance = -variance + tp.derivedTypeBounds(lo1, this(tp.hi)) case tp: MethodType => def mapOverMethod = { @@ -2908,12 +2906,7 @@ object Types { def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean = name.isTypeName && { val mbr = pre.member(name) - (mbr.symbol is Deferred) && { - mbr.info match { - case TypeBounds(lo, hi) => lo ne hi - case _ => false - } - } + (mbr.symbol is Deferred) && mbr.info.isInstanceOf[RealTypeBounds] } } diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala index 17cba1373..60f5372bb 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -63,26 +63,24 @@ object Checking { * break direct cycle with a LazyRef for legal, F-bounded cycles. */ def checkInfo(tp: Type): Type = tp match { + case tp @ TypeAlias(alias) => + try tp.derivedTypeAlias(apply(alias)) + finally { + where = "alias" + lastChecked = alias + } case tp @ TypeBounds(lo, hi) => - if (lo eq hi) - try tp.derivedTypeAlias(apply(lo)) - finally { - where = "alias" - lastChecked = lo - } - else { - val lo1 = try apply(lo) finally { - where = "lower bound" - lastChecked = lo - } - val saved = nestedCycleOK - nestedCycleOK = true - try tp.derivedTypeBounds(lo1, apply(hi)) - finally { - nestedCycleOK = saved - where = "upper bound" - lastChecked = hi - } + val lo1 = try apply(lo) finally { + where = "lower bound" + lastChecked = lo + } + val saved = nestedCycleOK + nestedCycleOK = true + try tp.derivedTypeBounds(lo1, apply(hi)) + finally { + nestedCycleOK = saved + where = "upper bound" + lastChecked = hi } case _ => tp @@ -277,7 +275,7 @@ trait Checking { tp.derivedRefinedType(tp.parent, tp.refinedName, checkFeasible(tp.refinedInfo, pos, where)) case tp @ TypeBounds(lo, hi) if !(lo <:< hi) => ctx.error(d"no type exists between low bound $lo and high bound $hi$where", pos) - tp.derivedTypeAlias(hi) + TypeAlias(hi) case _ => tp } diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala index 8d29916fa..98300f0b0 100644 --- a/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -373,8 +373,8 @@ object ProtoTypes { else tp.derivedSelect(wildApprox(tp.prefix, theMap)) case tp: RefinedType => // default case, inlined for speed tp.derivedRefinedType(wildApprox(tp.parent, theMap), tp.refinedName, wildApprox(tp.refinedInfo, theMap)) - case tp: TypeBounds if tp.lo eq tp.hi => // default case, inlined for speed - tp.derivedTypeAlias(wildApprox(tp.lo, theMap)) + case tp: TypeAlias => // default case, inlined for speed + tp.derivedTypeAlias(wildApprox(tp.alias, theMap)) case tp @ PolyParam(poly, pnum) => ctx.typerState.constraint.at(tp) match { case bounds: TypeBounds => wildApprox(WildcardType(bounds)) -- cgit v1.2.3