Skip to content

Commit 2fb757a

Browse files
Merge pull request #3986 from dotty-staging/cleanup-megamorphic-calls
Remove AndOrType
2 parents 412fe37 + 5c81269 commit 2fb757a

15 files changed

+202
-133
lines changed

Diff for: compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,9 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
679679
rname == tree.name || hasRefinement(parent)
680680
case tp: TypeProxy =>
681681
hasRefinement(tp.underlying)
682-
case tp: AndOrType =>
682+
case tp: AndType =>
683+
hasRefinement(tp.tp1) || hasRefinement(tp.tp2)
684+
case tp: OrType =>
683685
hasRefinement(tp.tp1) || hasRefinement(tp.tp2)
684686
case _ =>
685687
false
@@ -731,4 +733,4 @@ object TreeInfo {
731733
val Pure = new PurityLevel(2)
732734
val Idempotent = new PurityLevel(1)
733735
val Impure = new PurityLevel(0)
734-
}
736+
}

Diff for: compiler/src/dotty/tools/dotc/core/CheckRealizable.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ class CheckRealizable(implicit ctx: Context) {
8888
def isConcrete(tp: Type): Boolean = tp.dealias match {
8989
case tp: TypeRef => tp.symbol.isClass
9090
case tp: TypeProxy => isConcrete(tp.underlying)
91-
case tp: AndOrType => isConcrete(tp.tp1) && isConcrete(tp.tp2)
91+
case tp: AndType => isConcrete(tp.tp1) && isConcrete(tp.tp2)
92+
case tp: OrType => isConcrete(tp.tp1) && isConcrete(tp.tp2)
9293
case _ => false
9394
}
9495
if (!isConcrete(tp)) NotConcrete

Diff for: compiler/src/dotty/tools/dotc/core/Constants.scala

+45-19
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,10 @@ object Constants {
2323
final val EnumTag = 13
2424
final val ScalaSymbolTag = 14
2525

26-
case class Constant(value: Any) extends printing.Showable {
26+
class Constant(val value: Any, val tag: Int) extends printing.Showable with Product1[Any] {
2727
import java.lang.Double.doubleToRawLongBits
2828
import java.lang.Float.floatToRawIntBits
2929

30-
val tag: Int = value match {
31-
case null => NullTag
32-
case x: Unit => UnitTag
33-
case x: Boolean => BooleanTag
34-
case x: Byte => ByteTag
35-
case x: Short => ShortTag
36-
case x: Int => IntTag
37-
case x: Long => LongTag
38-
case x: Float => FloatTag
39-
case x: Double => DoubleTag
40-
case x: String => StringTag
41-
case x: Char => CharTag
42-
case x: Type => ClazzTag
43-
case x: Symbol => EnumTag
44-
case x: scala.Symbol => ScalaSymbolTag
45-
case _ => throw new Error("bad constant value: " + value + " of class " + value.getClass)
46-
}
47-
4830
def isByteRange: Boolean = isIntRange && Byte.MinValue <= intValue && intValue <= Byte.MaxValue
4931
def isShortRange: Boolean = isIntRange && Short.MinValue <= intValue && intValue <= Short.MaxValue
5032
def isCharRange: Boolean = isIntRange && Char.MinValue <= intValue && intValue <= Char.MaxValue
@@ -235,5 +217,49 @@ object Constants {
235217
h = mix(h, equalHashValue.##)
236218
finalizeHash(h, length = 2)
237219
}
220+
221+
override def toString = s"Constant($value)"
222+
def canEqual(x: Any) = true
223+
def get = value
224+
def isEmpty = false
225+
def _1 = value
226+
}
227+
228+
object Constant {
229+
def apply(x: Null) = new Constant(x, NullTag)
230+
def apply(x: Unit) = new Constant(x, UnitTag)
231+
def apply(x: Boolean) = new Constant(x, BooleanTag)
232+
def apply(x: Byte) = new Constant(x, ByteTag)
233+
def apply(x: Short) = new Constant(x, ShortTag)
234+
def apply(x: Int) = new Constant(x, IntTag)
235+
def apply(x: Long) = new Constant(x, LongTag)
236+
def apply(x: Float) = new Constant(x, FloatTag)
237+
def apply(x: Double) = new Constant(x, DoubleTag)
238+
def apply(x: String) = new Constant(x, StringTag)
239+
def apply(x: Char) = new Constant(x, CharTag)
240+
def apply(x: Type) = new Constant(x, ClazzTag)
241+
def apply(x: Symbol) = new Constant(x, EnumTag)
242+
def apply(x: scala.Symbol) = new Constant(x, ScalaSymbolTag)
243+
def apply(value: Any) =
244+
new Constant(value,
245+
value match {
246+
case null => NullTag
247+
case x: Unit => UnitTag
248+
case x: Boolean => BooleanTag
249+
case x: Byte => ByteTag
250+
case x: Short => ShortTag
251+
case x: Int => IntTag
252+
case x: Long => LongTag
253+
case x: Float => FloatTag
254+
case x: Double => DoubleTag
255+
case x: String => StringTag
256+
case x: Char => CharTag
257+
case x: Type => ClazzTag
258+
case x: Symbol => EnumTag
259+
case x: scala.Symbol => ScalaSymbolTag
260+
}
261+
)
262+
263+
def unapply(c: Constant) = c
238264
}
239265
}

Diff for: compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala

+11-4
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ trait ConstraintHandling {
5353
val b = bound.dealias
5454
(b eq param) || {
5555
b match {
56-
case b: AndOrType => occursIn(b.tp1) || occursIn(b.tp2)
56+
case b: AndType => occursIn(b.tp1) || occursIn(b.tp2)
57+
case b: OrType => occursIn(b.tp1) || occursIn(b.tp2)
5758
case b: TypeVar => occursIn(b.origin)
5859
case b: TermRef => occursIn(b.underlying)
5960
case _ => false
@@ -256,7 +257,8 @@ trait ConstraintHandling {
256257
def isFullyDefined(tp: Type): Boolean = tp match {
257258
case tp: TypeVar => tp.isInstantiated && isFullyDefined(tp.instanceOpt)
258259
case tp: TypeProxy => isFullyDefined(tp.underlying)
259-
case tp: AndOrType => isFullyDefined(tp.tp1) && isFullyDefined(tp.tp2)
260+
case tp: AndType => isFullyDefined(tp.tp1) && isFullyDefined(tp.tp2)
261+
case tp: OrType => isFullyDefined(tp.tp1) && isFullyDefined(tp.tp2)
260262
case _ => true
261263
}
262264
def isOrType(tp: Type): Boolean = tp.stripTypeVar.dealias match {
@@ -430,10 +432,15 @@ trait ConstraintHandling {
430432
* @return The pruned type if all `addLess` calls succeed, `NoType` otherwise.
431433
*/
432434
def prune(bound: Type): Type = bound match {
433-
case bound: AndOrType =>
435+
case bound: AndType =>
434436
val p1 = prune(bound.tp1)
435437
val p2 = prune(bound.tp2)
436-
if (p1.exists && p2.exists) bound.derivedAndOrType(p1, p2)
438+
if (p1.exists && p2.exists) bound.derivedAndType(p1, p2)
439+
else NoType
440+
case bound: OrType =>
441+
val p1 = prune(bound.tp1)
442+
val p2 = prune(bound.tp2)
443+
if (p1.exists && p2.exists) bound.derivedOrType(p1, p2)
437444
else NoType
438445
case bound: TypeVar if constraint contains bound.origin =>
439446
prune(bound.underlying)

Diff for: compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala

+26-13
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,8 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
222222
def dependentParams(tp: Type, isUpper: Boolean): List[TypeParamRef] = tp match {
223223
case param: TypeParamRef if contains(param) =>
224224
param :: (if (isUpper) upper(param) else lower(param))
225-
case tp: AndOrType =>
226-
val ps1 = dependentParams(tp.tp1, isUpper)
227-
val ps2 = dependentParams(tp.tp2, isUpper)
228-
if (isUpper == tp.isAnd) ps1.union(ps2) else ps1.intersect(ps2)
225+
case tp: AndType => dependentParams(tp.tp1, isUpper).union (dependentParams(tp.tp2, isUpper))
226+
case tp: OrType => dependentParams(tp.tp1, isUpper).intersect(dependentParams(tp.tp2, isUpper))
229227
case _ =>
230228
Nil
231229
}
@@ -260,11 +258,18 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
260258
case param: TypeParamRef if contains(param) =>
261259
if (!paramBuf.contains(param)) paramBuf += param
262260
NoType
263-
case tp: AndOrType if isUpper == tp.isAnd =>
261+
case tp: AndType if isUpper =>
264262
val tp1 = stripParams(tp.tp1, paramBuf, isUpper)
265263
val tp2 = stripParams(tp.tp2, paramBuf, isUpper)
266264
if (tp1.exists)
267-
if (tp2.exists) tp.derivedAndOrType(tp1, tp2)
265+
if (tp2.exists) tp.derivedAndType(tp1, tp2)
266+
else tp1
267+
else tp2
268+
case tp: OrType if !isUpper =>
269+
val tp1 = stripParams(tp.tp1, paramBuf, isUpper)
270+
val tp2 = stripParams(tp.tp2, paramBuf, isUpper)
271+
if (tp1.exists)
272+
if (tp2.exists) tp.derivedOrType(tp1, tp2)
268273
else tp1
269274
else tp2
270275
case _ =>
@@ -395,24 +400,32 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
395400
def replaceParam(tp: Type, atPoly: TypeLambda, atIdx: Int): Type = tp match {
396401
case bounds @ TypeBounds(lo, hi) =>
397402

398-
def recombine(andor: AndOrType, op: (Type, Boolean) => Type, isUpper: Boolean): Type = {
399-
val tp1 = op(andor.tp1, isUpper)
400-
val tp2 = op(andor.tp2, isUpper)
401-
if ((tp1 eq andor.tp1) && (tp2 eq andor.tp2)) andor
402-
else if (andor.isAnd) tp1 & tp2
403+
def recombineAnd(and: AndType, op: (Type, Boolean) => Type, isUpper: Boolean): Type = {
404+
val tp1 = op(and.tp1, isUpper)
405+
val tp2 = op(and.tp2, isUpper)
406+
if (tp1.eq(and.tp1) && tp2.eq(and.tp2)) and
407+
else tp1 & tp2
408+
}
409+
410+
def recombineOr(or: OrType, op: (Type, Boolean) => Type, isUpper: Boolean): Type = {
411+
val tp1 = op(or.tp1, isUpper)
412+
val tp2 = op(or.tp2, isUpper)
413+
if (tp1.eq(or.tp1) && tp2.eq(or.tp2)) or
403414
else tp1 | tp2
404415
}
405416

406417
def normalize(tp: Type, isUpper: Boolean): Type = tp match {
407418
case p: TypeParamRef if p.binder == atPoly && p.paramNum == atIdx =>
408419
if (isUpper) defn.AnyType else defn.NothingType
409-
case tp: AndOrType if isUpper == tp.isAnd => recombine(tp, normalize, isUpper)
420+
case tp: AndType if isUpper => recombineAnd(tp, normalize, isUpper)
421+
case tp: OrType if !isUpper => recombineOr (tp, normalize, isUpper)
410422
case _ => tp
411423
}
412424

413425
def replaceIn(tp: Type, isUpper: Boolean): Type = tp match {
414426
case `param` => normalize(replacement, isUpper)
415-
case tp: AndOrType if isUpper == tp.isAnd => recombine(tp, replaceIn, isUpper)
427+
case tp: AndType if isUpper => recombineAnd(tp, replaceIn, isUpper)
428+
case tp: OrType if !isUpper => recombineOr (tp, replaceIn, isUpper)
416429
case _ => tp.substParam(param, replacement)
417430
}
418431

Diff for: compiler/src/dotty/tools/dotc/core/SymDenotations.scala

+4-3
Original file line numberDiff line numberDiff line change
@@ -1202,7 +1202,8 @@ object SymDenotations {
12021202
case tp: ExprType => hasSkolems(tp.resType)
12031203
case tp: AppliedType => hasSkolems(tp.tycon) || tp.args.exists(hasSkolems)
12041204
case tp: LambdaType => tp.paramInfos.exists(hasSkolems) || hasSkolems(tp.resType)
1205-
case tp: AndOrType => hasSkolems(tp.tp1) || hasSkolems(tp.tp2)
1205+
case tp: AndType => hasSkolems(tp.tp1) || hasSkolems(tp.tp2)
1206+
case tp: OrType => hasSkolems(tp.tp1) || hasSkolems(tp.tp2)
12061207
case tp: AnnotatedType => hasSkolems(tp.tpe)
12071208
case _ => false
12081209
}
@@ -1641,9 +1642,9 @@ object SymDenotations {
16411642
case tp: TypeRef if tp.symbol.isClass => true
16421643
case tp: TypeVar => tp.inst.exists && inCache(tp.inst)
16431644
//case tp: TypeProxy => inCache(tp.underlying) // disabled, can re-enable insyead of last two lines for performance testing
1644-
//case tp: AndOrType => inCache(tp.tp1) && inCache(tp.tp2)
16451645
case tp: TypeProxy => isCachable(tp.underlying, btrCache)
1646-
case tp: AndOrType => isCachable(tp.tp1, btrCache) && isCachable(tp.tp2, btrCache)
1646+
case tp: AndType => isCachable(tp.tp1, btrCache) && isCachable(tp.tp2, btrCache)
1647+
case tp: OrType => isCachable(tp.tp1, btrCache) && isCachable(tp.tp2, btrCache)
16471648
case _ => true
16481649
}
16491650
}

Diff for: compiler/src/dotty/tools/dotc/core/TypeApplications.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,10 @@ class TypeApplications(val self: Type) extends AnyVal {
374374
tryReduce
375375
case dealiased: PolyType =>
376376
dealiased.instantiate(args)
377-
case dealiased: AndOrType =>
378-
dealiased.derivedAndOrType(dealiased.tp1.appliedTo(args), dealiased.tp2.appliedTo(args))
377+
case dealiased: AndType =>
378+
dealiased.derivedAndType(dealiased.tp1.appliedTo(args), dealiased.tp2.appliedTo(args))
379+
case dealiased: OrType =>
380+
dealiased.derivedOrType(dealiased.tp1.appliedTo(args), dealiased.tp2.appliedTo(args))
379381
case dealiased: TypeAlias =>
380382
dealiased.derivedTypeAlias(dealiased.alias.appliedTo(args))
381383
case dealiased: TypeBounds =>

Diff for: compiler/src/dotty/tools/dotc/core/TypeComparer.scala

+7-5
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
925925
case tp @ RefinedType(parent, rname, rinfo) => tp.derivedRefinedType(fix(parent), rname, rinfo)
926926
case tp: TypeParamRef => fixOrElse(bounds(tp).hi, tp)
927927
case tp: TypeProxy => fixOrElse(tp.underlying, tp)
928-
case tp: AndOrType => tp.derivedAndOrType(fix(tp.tp1), fix(tp.tp2))
928+
case tp: AndType => tp.derivedAndType(fix(tp.tp1), fix(tp.tp2))
929+
case tp: OrType => tp.derivedOrType (fix(tp.tp1), fix(tp.tp2))
929930
case tp => tp
930931
}
931932
def fixOrElse(tp: Type, fallback: Type) = {
@@ -1075,7 +1076,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
10751076
case tp: AppliedType => isCovered(tp.tycon)
10761077
case tp: RefinedOrRecType => isCovered(tp.parent)
10771078
case tp: AnnotatedType => isCovered(tp.underlying)
1078-
case tp: AndOrType => isCovered(tp.tp1) && isCovered(tp.tp2)
1079+
case tp: AndType => isCovered(tp.tp1) && isCovered(tp.tp2)
1080+
case tp: OrType => isCovered(tp.tp1) && isCovered(tp.tp2)
10791081
case _ => false
10801082
}
10811083

@@ -1323,18 +1325,18 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
13231325
Nil
13241326
}
13251327

1326-
private def recombineAndOr(tp: AndOrType, tp1: Type, tp2: Type) =
1328+
private def recombineAnd(tp: AndType, tp1: Type, tp2: Type) =
13271329
if (!tp1.exists) tp2
13281330
else if (!tp2.exists) tp1
1329-
else tp.derivedAndOrType(tp1, tp2)
1331+
else tp.derivedAndType(tp1, tp2)
13301332

13311333
/** If some (&-operand of) this type is a supertype of `sub` replace it with `NoType`.
13321334
*/
13331335
private def dropIfSuper(tp: Type, sub: Type): Type =
13341336
if (isSubTypeWhenFrozen(sub, tp)) NoType
13351337
else tp match {
13361338
case tp @ AndType(tp1, tp2) =>
1337-
recombineAndOr(tp, dropIfSuper(tp1, sub), dropIfSuper(tp2, sub))
1339+
recombineAnd(tp, dropIfSuper(tp1, sub), dropIfSuper(tp2, sub))
13381340
case _ =>
13391341
tp
13401342
}

Diff for: compiler/src/dotty/tools/dotc/core/TypeErasure.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,8 @@ object TypeErasure {
322322
case tp: TypeParamRef => false
323323
case tp: TypeBounds => false
324324
case tp: TypeProxy => hasStableErasure(tp.superType)
325-
case tp: AndOrType => hasStableErasure(tp.tp1) && hasStableErasure(tp.tp2)
325+
case tp: AndType => hasStableErasure(tp.tp1) && hasStableErasure(tp.tp2)
326+
case tp: OrType => hasStableErasure(tp.tp1) && hasStableErasure(tp.tp2)
326327
case _ => false
327328
}
328329
}

0 commit comments

Comments
 (0)