aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2014-12-17 10:34:38 +0100
committerodersky <odersky@gmail.com>2014-12-17 10:34:38 +0100
commit3a68e50073e9c4cef06c44e1dec7e3e492eb3274 (patch)
tree570c7ab8cd4fd88351a212192ad6de05c6887d6e /src/dotty
parentca03148fd5ba8b83cfa949f033eeaa82d45a9842 (diff)
parent7c1e76d085734697ccc17c4b21f59c15e078e0aa (diff)
downloaddotty-3a68e50073e9c4cef06c44e1dec7e3e492eb3274.tar.gz
dotty-3a68e50073e9c4cef06c44e1dec7e3e492eb3274.tar.bz2
dotty-3a68e50073e9c4cef06c44e1dec7e3e492eb3274.zip
Merge pull request #270 from dotty-staging/change/type-aliases
Change/type aliases
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/core/Constraint.scala6
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala4
-rw-r--r--src/dotty/tools/dotc/core/Substituters.scala40
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala6
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala4
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala13
-rw-r--r--src/dotty/tools/dotc/core/Types.scala149
-rw-r--r--src/dotty/tools/dotc/core/Uniques.scala25
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala38
-rw-r--r--src/dotty/tools/dotc/typer/ProtoTypes.scala4
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala2
11 files changed, 144 insertions, 147 deletions
diff --git a/src/dotty/tools/dotc/core/Constraint.scala b/src/dotty/tools/dotc/core/Constraint.scala
index 339dbb64a..e241794d0 100644
--- a/src/dotty/tools/dotc/core/Constraint.scala
+++ b/src/dotty/tools/dotc/core/Constraint.scala
@@ -24,7 +24,9 @@ object Constraint {
private val addDep: DepDelta = (_ + _)
private val removeDep: DepDelta = (_ - _)
- private val NoTypeBounds = new TypeBounds(WildcardType, WildcardType){}
+ private val NoTypeBounds = new TypeBounds(WildcardType, WildcardType) {
+ override def computeHash = unsupported("computeHash")
+ }
/** An accumulator that changes dependencies on `param`.
* @param param The parameter to which changed dependencies refer.
@@ -70,7 +72,7 @@ import Constraint._
* @param dependents a map from PolyTypes to arrays of Sets of PolyParams.
* The i'th set in an array corresponding to polytype `pt` contains
* those dependent `PolyParam`s `dp` that have `PolyParam(pt, i)` in their bounds in
- * significant position. A position is significant if solving the
+ * significant position. A position is significant if solving the
* constraint for `(pt, i)` with a type higher than its lower bound
* would lead to a constraint for `dp` that was not looser than
* the existing constraint. Specifically, it means that all poly params
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 805b7660c..98a71dd98 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -528,13 +528,13 @@ object Contexts {
private[core] val uniqueNamedTypes = new NamedTypeUniques
/** A table for hash consing unique type bounds */
- private[core] val uniqueTypeBounds = new TypeBoundsUniques
+ private[core] val uniqueTypeAliases = new TypeAliasUniques
private def uniqueSets = Map(
"uniques" -> uniques,
"uniqueRefinedTypes" -> uniqueRefinedTypes,
"uniqueNamedTypes" -> uniqueNamedTypes,
- "uniqueTypeBounds" -> uniqueTypeBounds)
+ "uniqueTypeAliases" -> uniqueTypeAliases)
/** A map that associates label and size of all uniques sets */
def uniquesSizes: Map[String, Int] = uniqueSets.mapValues(_.size)
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/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index 874928fcc..6443c5054 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -62,7 +62,7 @@ class TypeApplications(val self: Type) extends AnyVal {
case tp: RefinedType =>
val tparams = tp.parent.typeParams
tp.refinedInfo match {
- case TypeBounds(lo, hi) if lo eq hi => tparams.filterNot(_.name == tp.refinedName)
+ case rinfo: TypeAlias => tparams.filterNot(_.name == tp.refinedName)
case _ => tparams
}
case tp: SingletonType =>
@@ -353,9 +353,9 @@ class TypeApplications(val self: Type) extends AnyVal {
* for a contravariant type-parameter becomes L.
*/
final def argInfo(tparam: Symbol, interpolate: Boolean = true)(implicit ctx: Context): Type = self match {
+ case self: TypeAlias => self.alias
case TypeBounds(lo, hi) =>
- if (lo eq hi) hi
- else if (interpolate) {
+ if (interpolate) {
val v = tparam.variance
if (v > 0 && (lo isRef defn.NothingClass)) hi
else if (v < 0 && (hi isRef defn.AnyClass)) lo
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 42af31553..09087ac6c 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -667,8 +667,8 @@ class TypeComparer(initctx: Context) extends DotClass {
{ // special case for situations like:
// foo <: C { type T = foo.T }
tp2.refinedInfo match {
- case TypeBounds(lo, hi) if lo eq hi =>
- !ctx.phase.erasedTypes && (tp1r select name) =:= lo
+ case rinfo: TypeAlias =>
+ !ctx.phase.erasedTypes && (tp1r select name) =:= rinfo.alias
case _ => false
}
})
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index 2b129ebf5..8190b8cb6 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -43,8 +43,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)
@@ -73,8 +73,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) =>
@@ -144,9 +144,10 @@ trait TypeOps { this: Context =>
def needsChecking(tp: Type, isPart: Boolean): Boolean = tp match {
case tp: TypeRef =>
tp.info match {
+ case TypeAlias(alias) =>
+ needsChecking(alias, isPart)
case TypeBounds(lo, hi) =>
- if (lo eq hi) needsChecking(hi, isPart)
- else isPart || tp.controlled(isVolatile(hi))
+ isPart || tp.controlled(isVolatile(hi))
case _ => false
}
case tp: RefinedType =>
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 3100be9a0..473b23f7b 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -104,8 +104,8 @@ object Types {
*/
def isRef(sym: Symbol)(implicit ctx: Context): Boolean = stripTypeVar match {
case this1: TypeRef =>
- this1.info match { // see comment in Namers/typeDefSig
- case TypeBounds(lo, hi) if lo eq hi => hi.isRef(sym)
+ this1.info match { // see comment in Namer#typeDefSig
+ case TypeAlias(tp) => tp.isRef(sym)
case _ => this1.symbol eq sym
}
case this1: RefinedType =>
@@ -193,10 +193,7 @@ object Types {
}
/** Is this an alias TypeBounds? */
- def isAlias: Boolean = this match {
- case TypeBounds(lo, hi) => lo eq hi
- case _ => false
- }
+ def isAlias: Boolean = this.isInstanceOf[TypeAlias]
/** Is this type a transitive refinement of the given type?
* This is true if the type consists of 0 or more refinements or other
@@ -669,7 +666,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 =>
@@ -753,7 +750,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
@@ -770,7 +767,7 @@ object Types {
case pre: RefinedType =>
if (pre.refinedName ne name) loop(pre.parent)
else this.member(name).info match {
- case TypeBounds(lo, hi) if (lo eq hi) && !dependsOnRefinedThis(hi) => hi
+ case TypeAlias(tp) if !dependsOnRefinedThis(tp) => tp
case _ => NoType
}
case RefinedThis(rt) =>
@@ -1926,7 +1923,7 @@ object Types {
case MethodParam(`thisMethodType`, _) => true
case tp @ TypeRef(MethodParam(`thisMethodType`, _), name) =>
tp.info match { // follow type arguments to avoid dependency
- case TypeBounds(lo, hi) if lo eq hi => apply(x, hi)
+ case TypeAlias(tp)=> apply(x, tp)
case _ => true
}
case _ =>
@@ -2412,42 +2409,33 @@ object Types {
override def underlying(implicit ctx: Context): Type = hi
- def derivedTypeBounds(lo: Type, hi: Type, variance: Int = this.variance)(implicit ctx: Context) =
- 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)
+ /** The non-alias type bounds type with given bounds */
+ def derivedTypeBounds(lo: Type, hi: Type)(implicit ctx: Context) =
+ if ((lo eq this.lo) && (hi eq this.hi) && (variance == 0)) this
+ else TypeBounds(lo, hi)
/** If this is an alias, a derived alias with the new variance,
* Otherwise the type itself.
*/
- def withVariance(variance: Int)(implicit ctx: Context) =
- if (lo ne hi) this
- else derivedTypeBounds(lo, hi, variance)
+ def withVariance(variance: Int)(implicit ctx: Context) = this match {
+ case tp: TypeAlias => tp.derivedTypeAlias(tp.alias, variance)
+ case _ => this
+ }
def contains(tp: Type)(implicit ctx: Context) = tp match {
case tp: TypeBounds => lo <:< tp.lo && tp.hi <:< hi
case _ => lo <:< tp && tp <:< hi
}
- 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)
- else derivedTypeBounds(this.lo | that.lo, this.hi & that.hi, v)
- }
+ def & (that: TypeBounds)(implicit ctx: Context): TypeBounds =
+ if (this.lo <:< that.lo && that.hi <:< this.hi) that
+ else if (that.lo <:< this.lo && this.hi <:< that.hi) this
+ else TypeBounds(this.lo | that.lo, this.hi & that.hi)
- 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)
- else derivedTypeBounds(this.lo & that.lo, this.hi | that.hi, v)
- }
+ def | (that: TypeBounds)(implicit ctx: Context): TypeBounds =
+ if (this.lo <:< that.lo && that.hi <:< this.hi) this
+ else if (that.lo <:< this.lo && this.hi <:< that.hi) that
+ else TypeBounds(this.lo & that.lo, this.hi | that.hi)
override def & (that: Type)(implicit ctx: Context) = that match {
case that: TypeBounds => this & that
@@ -2462,38 +2450,60 @@ object Types {
/** If this type and that type have the same variance, this variance, otherwise 0 */
final def commonVariance(that: TypeBounds): Int = (this.variance + that.variance) / 2
+ override def equals(that: Any): Boolean = that match {
+ case that: TypeBounds =>
+ (this.lo eq that.lo) && (this.hi eq that.hi) && this.variance == that.variance
+ case _ =>
+ false
+ }
+
override def toString =
if (lo eq hi) s"TypeAlias($lo)" else s"TypeBounds($lo, $hi)"
-
- override def computeHash = unsupported("computeHash")
}
- class CachedTypeBounds(lo: Type, hi: Type, hc: Int) extends TypeBounds(lo, hi) {
- myHash = hc
+ class RealTypeBounds(lo: Type, hi: Type) extends TypeBounds(lo, hi) {
+ override def computeHash = doHash(variance, lo, hi)
}
- final class CoTypeBounds(lo: Type, hi: Type, hc: Int) extends CachedTypeBounds(lo, hi, hc) {
- override def variance = 1
- override def toString = "Co" + super.toString
+ 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)
+
+ override def & (that: TypeBounds)(implicit ctx: Context): TypeBounds = {
+ val v = this commonVariance that
+ if (v > 0) derivedTypeAlias(this.hi & that.hi, v)
+ else if (v < 0) derivedTypeAlias(this.lo | that.lo, v)
+ else super.& (that)
+ }
+
+ override def | (that: TypeBounds)(implicit ctx: Context): TypeBounds = {
+ val v = this commonVariance that
+ if (v > 0) derivedTypeAlias(this.hi | that.hi, v)
+ else if (v < 0) derivedTypeAlias(this.lo & that.lo, v)
+ else super.| (that)
+ }
}
- final class ContraTypeBounds(lo: Type, hi: Type, hc: Int) extends CachedTypeBounds(lo, hi, hc) {
- override def variance = -1
- override def toString = "Contra" + super.toString
+ class CachedTypeAlias(alias: Type, variance: Int, hc: Int) extends TypeAlias(alias, variance) {
+ myHash = hc
+ override def computeHash = doHash(variance, lo, hi)
}
object TypeBounds {
- def apply(lo: Type, hi: Type, variance: Int = 0)(implicit ctx: Context): TypeBounds =
- ctx.uniqueTypeBounds.enterIfNew(lo, hi, variance)
+ def apply(lo: Type, hi: Type)(implicit ctx: Context): TypeBounds =
+ unique(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)
- def lower(lo: Type, variance: Int = 0)(implicit ctx: Context) = apply(lo, defn.AnyType, variance)
+ def upper(hi: Type)(implicit ctx: Context) = apply(defn.NothingType, hi)
+ def lower(lo: Type)(implicit ctx: Context) = apply(lo, defn.AnyType)
}
object TypeAlias {
- def apply(tp: Type, variance: Int = 0)(implicit ctx: Context) = TypeBounds(tp, tp, variance)
- def unapply(tp: Type): Option[Type] = tp match {
- case TypeBounds(lo, hi) if lo eq hi => Some(lo)
+ def apply(alias: Type, variance: Int = 0)(implicit ctx: Context) =
+ ctx.uniqueTypeAliases.enterIfNew(alias, variance)
+ def unapply(tp: TypeAlias): Option[Type] = tp match {
+ case tp: TypeAlias => Some(tp.alias)
case _ => None
}
}
@@ -2650,24 +2660,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 = {
@@ -2917,12 +2921,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/core/Uniques.scala b/src/dotty/tools/dotc/core/Uniques.scala
index 0ade58193..fcf2df30b 100644
--- a/src/dotty/tools/dotc/core/Uniques.scala
+++ b/src/dotty/tools/dotc/core/Uniques.scala
@@ -65,30 +65,27 @@ object Uniques {
}
}
- final class TypeBoundsUniques extends HashSet[TypeBounds](initialUniquesCapacity) with Hashable {
- override def hash(x: TypeBounds): Int = x.hash
+ final class TypeAliasUniques extends HashSet[TypeAlias](initialUniquesCapacity) with Hashable {
+ override def hash(x: TypeAlias): Int = x.hash
- private def findPrevious(h: Int, lo: Type, hi: Type, variance: Int): TypeBounds = {
+ private def findPrevious(h: Int, alias: Type, variance: Int): TypeAlias = {
var e = findEntryByHash(h)
while (e != null) {
- if ((e.lo eq lo) && (e.hi eq hi) && (e.variance == variance)) return e
+ if ((e.alias eq alias) && (e.variance == variance)) return e
e = nextEntryByHash(h)
}
e
}
- def enterIfNew(lo: Type, hi: Type, variance: Int): TypeBounds = {
- val h = doHash(variance, lo, hi)
- if (monitored) recordCaching(h, classOf[TypeBounds])
- def newBounds =
- if (variance == 0) new CachedTypeBounds(lo, hi, h)
- else if (variance == 1) new CoTypeBounds(lo, hi, h)
- else new ContraTypeBounds(lo, hi, h)
- if (h == NotCached) newBounds
+ def enterIfNew(alias: Type, variance: Int): TypeAlias = {
+ val h = doHash(variance, alias)
+ if (monitored) recordCaching(h, classOf[TypeAlias])
+ def newAlias = new CachedTypeAlias(alias, variance, h)
+ if (h == NotCached) newAlias
else {
- val r = findPrevious(h, lo, hi, variance)
+ val r = findPrevious(h, alias, variance)
if (r ne null) r
- else addEntryAfterScan(newBounds)
+ else addEntryAfterScan(newAlias)
}
}
}
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index 56b5100b1..1354b8926 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))
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index 9c0af8a6d..97c959a7a 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -355,7 +355,7 @@ trait TypeAssigner {
tree.withType(ExprType(result.tpe))
def assignType(tree: untpd.TypeBoundsTree, lo: Tree, hi: Tree)(implicit ctx: Context) =
- tree.withType(TypeBounds(lo.tpe, hi.tpe))
+ tree.withType(if (lo eq hi) TypeAlias(lo.tpe) else TypeBounds(lo.tpe, hi.tpe))
def assignType(tree: untpd.Bind, sym: Symbol)(implicit ctx: Context) =
tree.withType(NamedType.withFixedSym(NoPrefix, sym))