Skip to content

Commit 939d9da

Browse files
committed
Add a second betaReduce
The new one only reduces straight applications of type lambdas with definite arguments. It is called very early on appliedTo, and derivedRefinedType. The old one, now renamed to normalizeHkApply also handles wildcard arguments and can garbage collect general unneeded hk-refinements. It is called later, at various places. TODO: See what functionality of normalizeHkApply should go into betaReduce instead. Maybe we can even drop normalizeHkApply? However: need to be careful to maintain aliases for hk type inference.
1 parent ae1f248 commit 939d9da

File tree

6 files changed

+50
-15
lines changed

6 files changed

+50
-15
lines changed

src/dotty/tools/dotc/core/ConstraintHandling.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ trait ConstraintHandling {
286286
else if (fromBelow) defn.NothingType
287287
else defn.AnyType
288288
case bound: RefinedType =>
289-
bound.BetaReduce
289+
bound.normalizeHkApply
290290
case _ =>
291291
bound
292292
}

src/dotty/tools/dotc/core/TypeApplications.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -565,12 +565,12 @@ class TypeApplications(val self: Type) extends AnyVal {
565565
assert(!isHK, self)
566566
self match {
567567
case self: TypeAlias =>
568-
self.derivedTypeAlias(expand(self.alias.BetaReduce))
568+
self.derivedTypeAlias(expand(self.alias.normalizeHkApply))
569569
case self @ TypeBounds(lo, hi) =>
570570
if (Config.newHK)
571-
self.derivedTypeBounds(lo, expand(hi.BetaReduce))
571+
self.derivedTypeBounds(lo, expand(hi.normalizeHkApply))
572572
else
573-
self.derivedTypeBounds(lo, expand(TypeBounds.upper(hi.BetaReduce)))
573+
self.derivedTypeBounds(lo, expand(TypeBounds.upper(hi.normalizeHkApply)))
574574
case _ => expand(self)
575575
}
576576
}
@@ -603,7 +603,7 @@ class TypeApplications(val self: Type) extends AnyVal {
603603
* - dropping refinements and rec-types
604604
* - going from a wildcard type to its upper bound
605605
*/
606-
def BetaReduce(implicit ctx: Context): Type = self.strictDealias match {
606+
def normalizeHkApply(implicit ctx: Context): Type = self.strictDealias match {
607607
case self1 @ RefinedType(_, rname, _) if Config.newHK && rname.isHkArgName && self1.typeParams.isEmpty =>
608608
val inst = new InstMap(self)
609609

@@ -840,8 +840,9 @@ class TypeApplications(val self: Type) extends AnyVal {
840840
}
841841
assert(args.nonEmpty)
842842
matchParams(self, typParams, args) match {
843-
case refined @ RefinedType(_, pname, _) if pname.isHkArgName && !Config.newHK =>
844-
TypeRef(refined, tpnme.hkApplyOBS)
843+
case refined @ RefinedType(_, pname, _) if pname.isHkArgName =>
844+
if (Config.newHK) refined.betaReduce
845+
else TypeRef(refined, tpnme.hkApplyOBS)
845846
case refined =>
846847
refined
847848
}

src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
661661
}
662662
}
663663
Config.newHK && app.isHKApply && !other.isHKApply && {
664-
val reduced = app.BetaReduce
664+
val reduced = app.normalizeHkApply
665665
if (reduced ne app)
666666
if (inOrder) isSubType(reduced, other) else isSubType(other, reduced)
667667
else tryInfer(app.typeConstructor.dealias)
@@ -675,7 +675,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
675675
val applied = other.appliedTo(argRefs(rt, args.length))
676676
if (inOrder) isSubType(body, applied)
677677
else body match {
678-
case body: TypeBounds => body.contains(applied)
678+
case body: TypeBounds => body.contains(applied) // Can be dropped?
679679
case _ => isSubType(applied, body)
680680
}
681681
}
@@ -1503,7 +1503,7 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
15031503

15041504
override def compareHkApply(app: RefinedType, other: Type, inOrder: Boolean) =
15051505
if (app.isHKApply)
1506-
traceIndented(i"compareHkApply $app, $other, $inOrder, ${app.BetaReduce}") {
1506+
traceIndented(i"compareHkApply $app, $other, $inOrder, ${app.normalizeHkApply}") {
15071507
super.compareHkApply(app, other, inOrder)
15081508
}
15091509
else super.compareHkApply(app, other, inOrder)

src/dotty/tools/dotc/core/TypeOps.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
158158
tp
159159
case tp: RefinedType =>
160160
tp.derivedRefinedType(simplify(tp.parent, theMap), tp.refinedName, simplify(tp.refinedInfo, theMap))
161-
.BetaReduce
161+
.normalizeHkApply
162162
case tp: TypeAlias =>
163163
tp.derivedTypeAlias(simplify(tp.alias, theMap))
164164
case AndType(l, r) =>
@@ -384,7 +384,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
384384
var formals: SimpleMap[TypeName, Symbol] = SimpleMap.Empty // A map of all formal parent parameter
385385

386386
// Strip all refinements from parent type, populating `refinements` and `formals` maps.
387-
def normalizeToRef(tp: Type): TypeRef = tp.dealias.BetaReduce match {
387+
def normalizeToRef(tp: Type): TypeRef = tp.dealias.normalizeHkApply match {
388388
case tp: TypeRef =>
389389
tp
390390
case tp @ RefinedType(tp1, name: TypeName, rinfo) =>

src/dotty/tools/dotc/core/Types.scala

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,9 +2131,43 @@ object Types {
21312131
this
21322132
}
21332133

2134-
def derivedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type)(implicit ctx: Context): RefinedType =
2134+
def betaReduce(implicit ctx: Context): Type = refinedInfo match {
2135+
case TypeAlias(alias) =>
2136+
def instantiate(rt: RecType) = new TypeMap {
2137+
def apply(t: Type) = t match {
2138+
case TypeRef(RecThis(`rt`), `refinedName`) => alias
2139+
case tp: TypeRef =>
2140+
val pre1 = apply(tp.prefix)
2141+
if (pre1 ne tp.prefix) tp.newLikeThis(pre1) else tp
2142+
case _ => mapOver(t)
2143+
}
2144+
}
2145+
def substAlias(tp: Type): Type = tp.safeDealias match {
2146+
case tp @ RefinedType(p, rname, rinfo) if tp.isTypeParam =>
2147+
if (rname == refinedName) p // check bounds?
2148+
else tp.derivedRefinedType(substAlias(p), rname, rinfo)
2149+
case tp: RecType =>
2150+
val p1 = substAlias(tp.parent)
2151+
if (p1 ne tp.parent) tp.rebind(instantiate(tp)(p1))
2152+
else tp
2153+
case _ =>
2154+
tp
2155+
}
2156+
val reduced = substAlias(parent)
2157+
if (reduced ne parent) {
2158+
hk.println(i"REDUCE $this ----> ${reduced}")
2159+
reduced
2160+
}
2161+
else this
2162+
case _ =>
2163+
this
2164+
}
2165+
2166+
def derivedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type)(implicit ctx: Context): Type =
21352167
if ((parent eq this.parent) && (refinedName eq this.refinedName) && (refinedInfo eq this.refinedInfo)) this
2136-
else RefinedType(parent, refinedName, rt => refinedInfo.substRefinedThis(this, RefinedThis(rt)))
2168+
else
2169+
RefinedType(parent, refinedName, rt => refinedInfo.substRefinedThis(this, RefinedThis(rt)))
2170+
.betaReduce
21372171

21382172
/** Add this refinement to `parent`, provided If `refinedName` is a member of `parent`. */
21392173
def wrapIfMember(parent: Type)(implicit ctx: Context): Type =

tests/neg/hklower.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
class Test { // error conflicting bounds
1+
class Test {
22

33
type T[X] // OK
44
type U[X] = T[X] // OK

0 commit comments

Comments
 (0)