Skip to content

Commit 1125646

Browse files
committed
Merge pull request #984 from dotty-staging/optimize-subtyping
Fix inefficieny in the presence of aliasing.
2 parents 0a96cbe + 9e7e40b commit 1125646

File tree

6 files changed

+43
-64
lines changed

6 files changed

+43
-64
lines changed

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

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ class TypeApplications(val self: Type) extends AnyVal {
286286
*/
287287
final def baseArgInfos(base: Symbol)(implicit ctx: Context): List[Type] =
288288
if (self derivesFrom base)
289-
base.typeParams map (param => self.member(param.name).info.argInfo(param))
289+
base.typeParams map (param => self.member(param.name).info.argInfo)
290290
else
291291
Nil
292292

@@ -311,7 +311,7 @@ class TypeApplications(val self: Type) extends AnyVal {
311311
/** The first type argument of the base type instance wrt `base` of this type */
312312
final def firstBaseArgInfo(base: Symbol)(implicit ctx: Context): Type = base.typeParams match {
313313
case param :: _ if self derivesFrom base =>
314-
self.member(param.name).info.argInfo(param)
314+
self.member(param.name).info.argInfo
315315
case _ =>
316316
NoType
317317
}
@@ -369,9 +369,8 @@ class TypeApplications(val self: Type) extends AnyVal {
369369
/** If this is an encoding of a (partially) applied type, return its arguments,
370370
* otherwise return Nil.
371371
* Existential types in arguments are returned as TypeBounds instances.
372-
* @param interpolate See argInfo
373372
*/
374-
final def argInfos(interpolate: Boolean)(implicit ctx: Context): List[Type] = {
373+
final def argInfos(implicit ctx: Context): List[Type] = {
375374
var tparams: List[TypeSymbol] = null
376375
def recur(tp: Type, refineCount: Int): mutable.ListBuffer[Type] = tp.stripTypeVar match {
377376
case tp @ RefinedType(tycon, name) =>
@@ -381,7 +380,7 @@ class TypeApplications(val self: Type) extends AnyVal {
381380
if (tparams == null) tparams = tycon.typeParams
382381
if (buf.size < tparams.length) {
383382
val tparam = tparams(buf.size)
384-
if (name == tparam.name) buf += tp.refinedInfo.argInfo(tparam, interpolate)
383+
if (name == tparam.name) buf += tp.refinedInfo.argInfo
385384
else null
386385
} else null
387386
}
@@ -393,8 +392,6 @@ class TypeApplications(val self: Type) extends AnyVal {
393392
if (buf == null) Nil else buf.toList
394393
}
395394

396-
final def argInfos(implicit ctx: Context): List[Type] = argInfos(interpolate = true)
397-
398395
/** Argument types where existential types in arguments are disallowed */
399396
def argTypes(implicit ctx: Context) = argInfos mapConserve noBounds
400397

@@ -415,31 +412,13 @@ class TypeApplications(val self: Type) extends AnyVal {
415412
self
416413
}
417414

418-
/** If this is the image of a type argument to type parameter `tparam`,
419-
* recover the type argument, otherwise NoType.
420-
* @param interpolate If true, replace type bounds as arguments corresponding to
421-
* variant type parameters by their dominating element. I.e. an argument
422-
*
423-
* T <: U
424-
*
425-
* for a covariant type-parameter becomes U, and an argument
426-
*
427-
* T >: L
428-
*
429-
* for a contravariant type-parameter becomes L.
415+
/** If this is the image of a type argument; recover the type argument,
416+
* otherwise NoType.
430417
*/
431-
final def argInfo(tparam: Symbol, interpolate: Boolean = true)(implicit ctx: Context): Type = self match {
418+
final def argInfo(implicit ctx: Context): Type = self match {
432419
case self: TypeAlias => self.alias
433-
case TypeBounds(lo, hi) =>
434-
if (interpolate) {
435-
val v = tparam.variance
436-
if (v > 0 && (lo isRef defn.NothingClass)) hi
437-
else if (v < 0 && (hi isRef defn.AnyClass)) lo
438-
else self
439-
}
440-
else self
441-
case _ =>
442-
NoType
420+
case self: TypeBounds => self
421+
case _ => NoType
443422
}
444423

445424
/** The element type of a sequence or array */

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

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -140,38 +140,38 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
140140

141141
private def firstTry(tp1: Type, tp2: Type): Boolean = tp2 match {
142142
case tp2: NamedType =>
143-
def compareAlias(info1: Type) = tp2.info match {
144-
case info2: TypeAlias => isSubType(tp1, info2.alias)
145-
case _ => info1 match {
146-
case info1: TypeAlias => isSubType(info1.alias, tp2)
147-
case _ => false
148-
}
149-
}
150-
def compareNamed = {
151-
implicit val ctx: Context = this.ctx // Dotty deviation: implicits need explicit type
152-
tp1 match {
153-
case tp1: NamedType =>
154-
val sym1 = tp1.symbol
155-
compareAlias(tp1.info) ||
156-
(if ((sym1 ne NoSymbol) && (sym1 eq tp2.symbol))
157-
ctx.erasedTypes || sym1.isStaticOwner || isSubType(tp1.prefix, tp2.prefix)
158-
else
159-
(tp1.name eq tp2.name) &&
160-
isSubType(tp1.prefix, tp2.prefix) &&
161-
(tp1.signature == tp2.signature) &&
162-
!tp1.isInstanceOf[WithFixedSym] &&
163-
!tp2.isInstanceOf[WithFixedSym]
164-
) ||
165-
compareHK(tp1, tp2, inOrder = true) ||
166-
compareHK(tp2, tp1, inOrder = false) ||
167-
thirdTryNamed(tp1, tp2)
168-
case _ =>
169-
compareHK(tp2, tp1, inOrder = false) ||
170-
compareAlias(NoType) ||
171-
secondTry(tp1, tp2)
143+
def compareNamed(tp1: Type, tp2: NamedType): Boolean = {
144+
implicit val ctx: Context = this.ctx
145+
tp2.info match {
146+
case info2: TypeAlias => firstTry(tp1, info2.alias)
147+
case _ => tp1 match {
148+
case tp1: NamedType =>
149+
tp1.info match {
150+
case info1: TypeAlias => compareNamed(info1.alias, tp2)
151+
case _ =>
152+
val sym1 = tp1.symbol
153+
(if ((sym1 ne NoSymbol) && (sym1 eq tp2.symbol))
154+
ctx.erasedTypes ||
155+
sym1.isStaticOwner ||
156+
isSubType(tp1.prefix, tp2.prefix) ||
157+
thirdTryNamed(tp1, tp2)
158+
else
159+
(tp1.name eq tp2.name) &&
160+
isSubType(tp1.prefix, tp2.prefix) &&
161+
(tp1.signature == tp2.signature) &&
162+
!tp1.isInstanceOf[WithFixedSym] &&
163+
!tp2.isInstanceOf[WithFixedSym] ||
164+
compareHK(tp1, tp2, inOrder = true) ||
165+
compareHK(tp2, tp1, inOrder = false) ||
166+
thirdTryNamed(tp1, tp2))
167+
}
168+
case _ =>
169+
compareHK(tp2, tp1, inOrder = false) ||
170+
secondTry(tp1, tp2)
171+
}
172172
}
173173
}
174-
compareNamed
174+
compareNamed(tp1, tp2)
175175
case tp2: ProtoType =>
176176
isMatchedByProto(tp2, tp1)
177177
case tp2: BoundType =>

src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ class TreePickler(pickler: TastyPickler) {
211211
case tpe: SkolemType =>
212212
pickleType(tpe.info)
213213
case tpe: RefinedType =>
214-
val args = tpe.argInfos(interpolate = false)
214+
val args = tpe.argInfos
215215
if (args.isEmpty) {
216216
writeByte(REFINEDtype)
217217
withLength {

src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
109109
}
110110
homogenize(tp) match {
111111
case tp: RefinedType =>
112-
val args = tp.argInfos(interpolate = false)
112+
val args = tp.argInfos
113113
if (args.nonEmpty) {
114114
val tycon = tp.unrefine
115115
val cls = tycon.typeSymbol

src/dotty/tools/dotc/reporting/Reporter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ trait Reporting { this: Context =>
155155
else {
156156
// Avoid evaluating question multiple time, since each evaluation
157157
// may cause some extra logging output.
158-
val q: String = question
158+
lazy val q: String = question
159159
traceIndented[T](s"==> $q?", (res: Any) => s"<== $q = ${resStr(res)}")(op)
160160
}
161161
}

src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ class Namer { typer: Typer =>
848848
def apply(tp: Type): Type = {
849849
tp match {
850850
case tp: RefinedType =>
851-
val args = tp.argInfos(interpolate = false).mapconserve(this)
851+
val args = tp.argInfos.mapconserve(this)
852852
if (args.nonEmpty) {
853853
val tycon = tp.withoutArgs(args)
854854
val tparams = tycon.typeParams

0 commit comments

Comments
 (0)