Skip to content

Commit 24463aa

Browse files
committed
less eager dealiasing of type aliases
1 parent 732ad27 commit 24463aa

32 files changed

+212
-62
lines changed

compiler/src/dotty/tools/dotc/config/Config.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,10 @@ object Config {
174174

175175
/** If this flag is on, always rewrite an application `S[Ts]` where `S` is an alias for
176176
* `[Xs] -> U` to `[Xs := Ts]U`.
177-
* Turning this flag on was observed to give a ~6% speedup on the JUnit test suite.
177+
* Turning this flag on was observed to give a ~6% speedup on the JUnit test suite
178+
* but over-eagerly dealiases type aliases.
178179
*/
179-
inline val simplifyApplications = true
180+
inline val simplifyApplications = false
180181

181182
/** Assume -indent by default */
182183
inline val defaultIndent = true

compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
443443
* of the parameter elsewhere in the constraint by type `tp`.
444444
*/
445445
def replace(param: TypeParamRef, tp: Type)(using Context): OrderingConstraint =
446-
val replacement = tp.dealiasKeepAnnots.stripTypeVar
446+
val replacement = tp.stripTypeVar
447447
if param == replacement then this.checkNonCyclic()
448448
else
449449
assert(replacement.isValueTypeOrLambda)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ class TypeApplications(val self: Type) extends AnyVal {
329329
case dealiased: HKTypeLambda =>
330330
def tryReduce =
331331
if (!args.exists(isBounds)) {
332-
val followAlias = Config.simplifyApplications && {
332+
val followAlias = (Config.simplifyApplications || self.typeSymbol.isPrivate) && {
333333
dealiased.resType match {
334334
case AppliedType(tyconBody, dealiasedArgs) =>
335335
// Reduction should not affect type inference when it's

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,25 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
407407
case tp1: NamedType =>
408408
tp1.info match {
409409
case info1: TypeAlias =>
410-
if (recur(info1.alias, tp2)) return true
410+
def realiasConstraint() = tp2 match {
411+
case tp2: TypeParamRef =>
412+
constraint.entry(tp2) match {
413+
case TypeBounds(lo, hi) =>
414+
val aliasLo = tp1 != lo && info1.alias == lo
415+
val aliasHi = tp1 != hi && info1.alias == hi
416+
if aliasLo || aliasHi then
417+
constraint = constraint.updateEntry(tp2, TypeBounds(
418+
if aliasLo then tp1 else lo,
419+
if aliasHi then tp1 else hi))
420+
case tp =>
421+
if tp1 != tp && info1.alias == tp then
422+
constraint = constraint.updateEntry(tp2, tp1)
423+
}
424+
case _ =>
425+
}
426+
val res = recur(info1.alias, tp2)
427+
if (tp1.symbol.isStatic) realiasConstraint()
428+
if (res) return true
411429
if (tp1.prefix.isStable) return tryLiftedToThis1
412430
case _ =>
413431
if (tp1 eq NothingType) || isBottom(tp1) then return true

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ object TypeOps:
423423
override def apply(tp: Type): Type = tp match
424424
case tp: TermRef
425425
if toAvoid(tp) =>
426-
tp.info.widenExpr.dealias match {
426+
tp.info.widenExpr match {
427427
case info: SingletonType => apply(info)
428428
case info => range(defn.NothingType, apply(info))
429429
}

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

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,11 +1304,11 @@ object Types {
13041304
case tp =>
13051305
tp
13061306

1307-
/** Widen all top-level singletons reachable by dealiasing
1308-
* and going to the operands of & and |.
1307+
/** Widen all top-level singletons reachable
1308+
* by going to the operands of & and |.
13091309
* Overridden and cached in OrType.
13101310
*/
1311-
def widenSingletons(using Context): Type = dealias match {
1311+
def widenSingletons(using Context): Type = this match {
13121312
case tp: SingletonType =>
13131313
tp.widen
13141314
case tp: OrType =>
@@ -1856,11 +1856,11 @@ object Types {
18561856
case _ => this
18571857
}
18581858

1859-
/** The set of distinct symbols referred to by this type, after all aliases are expanded */
1859+
/** The set of distinct symbols referred to by this type */
18601860
def coveringSet(using Context): Set[Symbol] =
18611861
(new CoveringSetAccumulator).apply(Set.empty[Symbol], this)
18621862

1863-
/** The number of applications and refinements in this type, after all aliases are expanded */
1863+
/** The number of applications and refinements in this type */
18641864
def typeSize(using Context): Int =
18651865
(new TypeSizeAccumulator).apply(0, this)
18661866

@@ -6178,11 +6178,12 @@ object Types {
61786178

61796179
class TypeSizeAccumulator(using Context) extends TypeAccumulator[Int] {
61806180
var seen = util.HashSet[Type](initialCapacity = 8)
6181-
def apply(n: Int, tp: Type): Int =
6182-
if seen.contains(tp) then n
6181+
def apply(n: Int, tp1: Type): Int =
6182+
val tp0 = tp1.dealias
6183+
if seen.contains(tp0) then n
61836184
else {
6184-
seen += tp
6185-
tp match {
6185+
seen += tp0
6186+
tp0 match {
61866187
case tp: AppliedType =>
61876188
foldOver(n + 1, tp)
61886189
case tp: RefinedType =>
@@ -6192,23 +6193,24 @@ object Types {
61926193
case tp: TypeParamRef =>
61936194
apply(n, TypeComparer.bounds(tp))
61946195
case _ =>
6195-
foldOver(n, tp)
6196+
foldOver(n, tp0)
61966197
}
61976198
}
61986199
}
61996200

62006201
class CoveringSetAccumulator(using Context) extends TypeAccumulator[Set[Symbol]] {
62016202
var seen = util.HashSet[Type](initialCapacity = 8)
6202-
def apply(cs: Set[Symbol], tp: Type): Set[Symbol] =
6203-
if seen.contains(tp) then cs
6203+
def apply(cs: Set[Symbol], tp1: Type): Set[Symbol] =
6204+
val tp0 = tp1.dealias
6205+
if seen.contains(tp0) then cs
62046206
else {
6205-
seen += tp
6206-
tp match {
6207+
seen += tp0
6208+
tp0 match {
62076209
case tp if tp.isExactlyAny || tp.isExactlyNothing =>
62086210
cs
6209-
case tp: AppliedType =>
6211+
case tp: AppliedType if !tp.typeSymbol.isAliasType =>
62106212
foldOver(cs + tp.typeSymbol, tp)
6211-
case tp: RefinedType =>
6213+
case tp: RefinedType if !tp.typeSymbol.isAliasType =>
62126214
foldOver(cs + tp.typeSymbol, tp)
62136215
case tp: TypeRef if tp.info.isTypeAlias =>
62146216
apply(cs, tp.superType)
@@ -6220,7 +6222,7 @@ object Types {
62206222
case tp: TypeParamRef =>
62216223
apply(cs, TypeComparer.bounds(tp))
62226224
case other =>
6223-
foldOver(cs, tp)
6225+
foldOver(cs, tp0)
62246226
}
62256227
}
62266228
}

compiler/src/dotty/tools/dotc/util/Signatures.scala

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,18 +105,20 @@ object Signatures {
105105
ctx.definitions.isTupleClass(tree.symbol.owner.companionClass)
106106

107107
private def extractParamTypess(resultType: Type)(using Context): List[List[Type]] =
108-
resultType match {
108+
resultType.dealias match {
109109
// Reference to a type which is not a type class
110110
case ref: TypeRef if !ref.symbol.isPrimitiveValueClass =>
111111
getExtractorMembers(ref)
112112
// Option or Some applied type. There is special syntax for multiple returned arguments:
113113
// Option[TupleN] and Option[Seq],
114-
// We are not intrested in them, instead we extract proper type parameters from the Option type parameter.
115-
case AppliedType(TypeRef(_, cls), (appliedType @ AppliedType(tycon, args)) :: Nil)
116-
if (cls == ctx.definitions.OptionClass || cls == ctx.definitions.SomeClass) =>
117-
tycon match
118-
case TypeRef(_, cls) if cls == ctx.definitions.SeqClass => List(List(appliedType))
119-
case _ => List(args)
114+
// We are not interested in them, instead we extract proper type parameters from the Option type parameter.
115+
case AppliedType(TypeRef(_, cls), (appliedType @ AppliedType(_, args)) :: Nil)
116+
if cls == ctx.definitions.OptionClass || cls == ctx.definitions.SomeClass =>
117+
appliedType.dealias match
118+
case appliedType @ AppliedType(TypeRef(_, cls), args) =>
119+
if cls == ctx.definitions.SeqClass then List(List(appliedType)) else List(args)
120+
case _ =>
121+
List(args)
120122
// Applied type extractor. We must extract from applied type to retain type parameters
121123
case appliedType: AppliedType => getExtractorMembers(appliedType)
122124
// This is necessary to extract proper result type as unapply can return other methods eg. apply

compiler/test-resources/repl/i5177

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
scala> class A[T]
2+
// defined class A
3+
scala> type B[T] = A[T]
4+
// defined alias type B[T] = A[T]
5+
scala> def b: B[String] = ???
6+
def b: B[String]
7+
scala> class C
8+
// defined class C
9+
scala> type D = C
10+
// defined alias type D = C
11+
scala> def d: D = ???
12+
def d: D

scaladoc/test/dotty/tools/scaladoc/ExternalLocationProviderIntegrationTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class Scaladoc3ExternalLocationProviderIntegrationTest extends ExternalLocationP
4747
".*externalStubs.*::scaladoc3::https://external.stubs/api/"
4848
),
4949
List(
50-
"https://dotty.epfl.ch/api/scala/collection/immutable/Map.html",
50+
"https://dotty.epfl.ch/api/scala/Predef$.html#Map-0",
5151
"https://dotty.epfl.ch/api/scala/Predef$.html#String-0",
5252
"https://dotty.epfl.ch/api/scala/util/matching/Regex$$Match.html",
5353
"https://external.stubs/api/tests/externalStubs/$div$bslash$.html",
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
trait Iterable[T]
2+
3+
@deprecated type Traversable[T] = Iterable[T]
4+
5+
def test: Traversable[Int] = ??? // error

0 commit comments

Comments
 (0)