aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/ConstraintHandling.scala2
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala13
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala6
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala4
-rw-r--r--src/dotty/tools/dotc/core/Types.scala38
-rw-r--r--tests/neg/hklower.scala2
6 files changed, 50 insertions, 15 deletions
diff --git a/src/dotty/tools/dotc/core/ConstraintHandling.scala b/src/dotty/tools/dotc/core/ConstraintHandling.scala
index 3b368ad5e..8072a111a 100644
--- a/src/dotty/tools/dotc/core/ConstraintHandling.scala
+++ b/src/dotty/tools/dotc/core/ConstraintHandling.scala
@@ -286,7 +286,7 @@ trait ConstraintHandling {
else if (fromBelow) defn.NothingType
else defn.AnyType
case bound: RefinedType =>
- bound.BetaReduce
+ bound.normalizeHkApply
case _ =>
bound
}
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index 7b2d2c3b2..0de951c31 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -565,12 +565,12 @@ class TypeApplications(val self: Type) extends AnyVal {
assert(!isHK, self)
self match {
case self: TypeAlias =>
- self.derivedTypeAlias(expand(self.alias.BetaReduce))
+ self.derivedTypeAlias(expand(self.alias.normalizeHkApply))
case self @ TypeBounds(lo, hi) =>
if (Config.newHK)
- self.derivedTypeBounds(lo, expand(hi.BetaReduce))
+ self.derivedTypeBounds(lo, expand(hi.normalizeHkApply))
else
- self.derivedTypeBounds(lo, expand(TypeBounds.upper(hi.BetaReduce)))
+ self.derivedTypeBounds(lo, expand(TypeBounds.upper(hi.normalizeHkApply)))
case _ => expand(self)
}
}
@@ -603,7 +603,7 @@ class TypeApplications(val self: Type) extends AnyVal {
* - dropping refinements and rec-types
* - going from a wildcard type to its upper bound
*/
- def BetaReduce(implicit ctx: Context): Type = self.strictDealias match {
+ def normalizeHkApply(implicit ctx: Context): Type = self.strictDealias match {
case self1 @ RefinedType(_, rname, _) if Config.newHK && rname.isHkArgName && self1.typeParams.isEmpty =>
val inst = new InstMap(self)
@@ -840,8 +840,9 @@ class TypeApplications(val self: Type) extends AnyVal {
}
assert(args.nonEmpty)
matchParams(self, typParams, args) match {
- case refined @ RefinedType(_, pname, _) if pname.isHkArgName && !Config.newHK =>
- TypeRef(refined, tpnme.hkApplyOBS)
+ case refined @ RefinedType(_, pname, _) if pname.isHkArgName =>
+ if (Config.newHK) refined.betaReduce
+ else TypeRef(refined, tpnme.hkApplyOBS)
case refined =>
refined
}
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index c82dc6a39..c1cbe0752 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -661,7 +661,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
}
}
Config.newHK && app.isHKApply && !other.isHKApply && {
- val reduced = app.BetaReduce
+ val reduced = app.normalizeHkApply
if (reduced ne app)
if (inOrder) isSubType(reduced, other) else isSubType(other, reduced)
else tryInfer(app.typeConstructor.dealias)
@@ -675,7 +675,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
val applied = other.appliedTo(argRefs(rt, args.length))
if (inOrder) isSubType(body, applied)
else body match {
- case body: TypeBounds => body.contains(applied)
+ case body: TypeBounds => body.contains(applied) // Can be dropped?
case _ => isSubType(applied, body)
}
}
@@ -1503,7 +1503,7 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
override def compareHkApply(app: RefinedType, other: Type, inOrder: Boolean) =
if (app.isHKApply)
- traceIndented(i"compareHkApply $app, $other, $inOrder, ${app.BetaReduce}") {
+ traceIndented(i"compareHkApply $app, $other, $inOrder, ${app.normalizeHkApply}") {
super.compareHkApply(app, other, inOrder)
}
else super.compareHkApply(app, other, inOrder)
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index c6a18f305..ca49d3d3c 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -158,7 +158,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
tp
case tp: RefinedType =>
tp.derivedRefinedType(simplify(tp.parent, theMap), tp.refinedName, simplify(tp.refinedInfo, theMap))
- .BetaReduce
+ .normalizeHkApply
case tp: TypeAlias =>
tp.derivedTypeAlias(simplify(tp.alias, theMap))
case AndType(l, r) =>
@@ -384,7 +384,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
var formals: SimpleMap[TypeName, Symbol] = SimpleMap.Empty // A map of all formal parent parameter
// Strip all refinements from parent type, populating `refinements` and `formals` maps.
- def normalizeToRef(tp: Type): TypeRef = tp.dealias.BetaReduce match {
+ def normalizeToRef(tp: Type): TypeRef = tp.dealias.normalizeHkApply match {
case tp: TypeRef =>
tp
case tp @ RefinedType(tp1, name: TypeName, rinfo) =>
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 403b49da6..2fa4f94c1 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2131,9 +2131,43 @@ object Types {
this
}
- def derivedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type)(implicit ctx: Context): RefinedType =
+ def betaReduce(implicit ctx: Context): Type = refinedInfo match {
+ case TypeAlias(alias) =>
+ def instantiate(rt: RecType) = new TypeMap {
+ def apply(t: Type) = t match {
+ case TypeRef(RecThis(`rt`), `refinedName`) => alias
+ case tp: TypeRef =>
+ val pre1 = apply(tp.prefix)
+ if (pre1 ne tp.prefix) tp.newLikeThis(pre1) else tp
+ case _ => mapOver(t)
+ }
+ }
+ def substAlias(tp: Type): Type = tp.safeDealias match {
+ case tp @ RefinedType(p, rname, rinfo) if tp.isTypeParam =>
+ if (rname == refinedName) p // check bounds?
+ else tp.derivedRefinedType(substAlias(p), rname, rinfo)
+ case tp: RecType =>
+ val p1 = substAlias(tp.parent)
+ if (p1 ne tp.parent) tp.rebind(instantiate(tp)(p1))
+ else tp
+ case _ =>
+ tp
+ }
+ val reduced = substAlias(parent)
+ if (reduced ne parent) {
+ hk.println(i"REDUCE $this ----> ${reduced}")
+ reduced
+ }
+ else this
+ case _ =>
+ this
+ }
+
+ def derivedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type)(implicit ctx: Context): Type =
if ((parent eq this.parent) && (refinedName eq this.refinedName) && (refinedInfo eq this.refinedInfo)) this
- else RefinedType(parent, refinedName, rt => refinedInfo.substRefinedThis(this, RefinedThis(rt)))
+ else
+ RefinedType(parent, refinedName, rt => refinedInfo.substRefinedThis(this, RefinedThis(rt)))
+ .betaReduce
/** Add this refinement to `parent`, provided If `refinedName` is a member of `parent`. */
def wrapIfMember(parent: Type)(implicit ctx: Context): Type =
diff --git a/tests/neg/hklower.scala b/tests/neg/hklower.scala
index 5c1ba27ba..e29a1545e 100644
--- a/tests/neg/hklower.scala
+++ b/tests/neg/hklower.scala
@@ -1,4 +1,4 @@
-class Test { // error conflicting bounds
+class Test {
type T[X] // OK
type U[X] = T[X] // OK