Skip to content

Commit c0dcf97

Browse files
committed
less eager dealiasing of type aliases
1 parent d53cf4b commit c0dcf97

31 files changed

+203
-55
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
@@ -436,7 +436,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
436436
* of the parameter elsewhere in the constraint by type `tp`.
437437
*/
438438
def replace(param: TypeParamRef, tp: Type)(using Context): OrderingConstraint =
439-
val replacement = tp.dealiasKeepAnnots.stripTypeVar
439+
val replacement = tp.stripTypeVar
440440
if param == replacement then this.checkNonCyclic()
441441
else
442442
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
@@ -325,7 +325,7 @@ class TypeApplications(val self: Type) extends AnyVal {
325325
case dealiased: HKTypeLambda =>
326326
def tryReduce =
327327
if (!args.exists(isBounds)) {
328-
val followAlias = Config.simplifyApplications && {
328+
val followAlias = (Config.simplifyApplications || self.typeSymbol.isPrivate) && {
329329
dealiased.resType match {
330330
case AppliedType(tyconBody, dealiasedArgs) =>
331331
// 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
@@ -403,7 +403,25 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
403403
case tp1: NamedType =>
404404
tp1.info match {
405405
case info1: TypeAlias =>
406-
if (recur(info1.alias, tp2)) return true
406+
def realiasConstraint() = tp2 match {
407+
case tp2: TypeParamRef =>
408+
constraint.entry(tp2) match {
409+
case TypeBounds(lo, hi) =>
410+
val aliasLo = tp1 != lo && info1.alias == lo
411+
val aliasHi = tp1 != hi && info1.alias == hi
412+
if aliasLo || aliasHi then
413+
constraint = constraint.updateEntry(tp2, TypeBounds(
414+
if aliasLo then tp1 else lo,
415+
if aliasHi then tp1 else hi))
416+
case tp =>
417+
if tp1 != tp && info1.alias == tp then
418+
constraint = constraint.updateEntry(tp2, tp1)
419+
}
420+
case _ =>
421+
}
422+
val res = recur(info1.alias, tp2)
423+
if (tp1.symbol.isStatic) realiasConstraint()
424+
if (res) return true
407425
if (tp1.prefix.isStable) return tryLiftedToThis1
408426
case _ =>
409427
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
@@ -1300,11 +1300,11 @@ object Types {
13001300
case tp =>
13011301
tp
13021302

1303-
/** Widen all top-level singletons reachable by dealiasing
1304-
* and going to the operands of & and |.
1303+
/** Widen all top-level singletons reachable
1304+
* by going to the operands of & and |.
13051305
* Overridden and cached in OrType.
13061306
*/
1307-
def widenSingletons(using Context): Type = dealias match {
1307+
def widenSingletons(using Context): Type = this match {
13081308
case tp: SingletonType =>
13091309
tp.widen
13101310
case tp: OrType =>
@@ -1846,11 +1846,11 @@ object Types {
18461846
case _ => this
18471847
}
18481848

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

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

@@ -6137,11 +6137,12 @@ object Types {
61376137

61386138
class TypeSizeAccumulator(using Context) extends TypeAccumulator[Int] {
61396139
var seen = util.HashSet[Type](initialCapacity = 8)
6140-
def apply(n: Int, tp: Type): Int =
6141-
if seen.contains(tp) then n
6140+
def apply(n: Int, tp1: Type): Int =
6141+
val tp0 = tp1.dealias
6142+
if seen.contains(tp0) then n
61426143
else {
6143-
seen += tp
6144-
tp match {
6144+
seen += tp0
6145+
tp0 match {
61456146
case tp: AppliedType =>
61466147
foldOver(n + 1, tp)
61476148
case tp: RefinedType =>
@@ -6151,23 +6152,24 @@ object Types {
61516152
case tp: TypeParamRef =>
61526153
apply(n, TypeComparer.bounds(tp))
61536154
case _ =>
6154-
foldOver(n, tp)
6155+
foldOver(n, tp0)
61556156
}
61566157
}
61576158
}
61586159

61596160
class CoveringSetAccumulator(using Context) extends TypeAccumulator[Set[Symbol]] {
61606161
var seen = util.HashSet[Type](initialCapacity = 8)
6161-
def apply(cs: Set[Symbol], tp: Type): Set[Symbol] =
6162-
if seen.contains(tp) then cs
6162+
def apply(cs: Set[Symbol], tp1: Type): Set[Symbol] =
6163+
val tp0 = tp1.dealias
6164+
if seen.contains(tp0) then cs
61636165
else {
6164-
seen += tp
6165-
tp match {
6166+
seen += tp0
6167+
tp0 match {
61666168
case tp if tp.isExactlyAny || tp.isExactlyNothing =>
61676169
cs
6168-
case tp: AppliedType =>
6170+
case tp: AppliedType if !tp.typeSymbol.isAliasType =>
61696171
foldOver(cs + tp.typeSymbol, tp)
6170-
case tp: RefinedType =>
6172+
case tp: RefinedType if !tp.typeSymbol.isAliasType =>
61716173
foldOver(cs + tp.typeSymbol, tp)
61726174
case tp: TypeRef if tp.info.isTypeAlias =>
61736175
apply(cs, tp.superType)
@@ -6179,7 +6181,7 @@ object Types {
61796181
case tp: TypeParamRef =>
61806182
apply(cs, TypeComparer.bounds(tp))
61816183
case other =>
6182-
foldOver(cs, tp)
6184+
foldOver(cs, tp0)
61836185
}
61846186
}
61856187
}

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

tests/neg-macros/i6997.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ import scala.quoted.*
33
class Foo {
44
def mcrImpl(body: Expr[Any])(using t: Type[_ <: Any])(using ctx: Quotes): Expr[Any] = '{
55
val tmp = ???.asInstanceOf[t.Underlying] // error // error
6-
tmp
6+
tmp // error
77
}
88
}

tests/neg/12974.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ object RecMap {
2525

2626
val foo: Any = Rec.empty.fetch("foo") // error
2727
// ^
28-
// Match type reduction failed since selector EmptyTuple.type
28+
// Match type reduction failed since selector EmptyTuple
2929
// matches none of the cases
3030
//
3131
// case (("foo" : String), t) *: _ => t

tests/neg/i12049.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
-- Error: tests/neg/i12049.scala:14:23 ---------------------------------------------------------------------------------
1919
14 |val y3: String = ??? : Last[Int *: Int *: Boolean *: String *: EmptyTuple] // error
2020
| ^
21-
| Match type reduction failed since selector EmptyTuple.type
21+
| Match type reduction failed since selector EmptyTuple
2222
| matches none of the cases
2323
|
2424
| case _ *: _ *: t => Last[t]
@@ -48,7 +48,7 @@
4848
-- Error: tests/neg/i12049.scala:25:26 ---------------------------------------------------------------------------------
4949
25 |val _ = summon[String =:= Last[Int *: Int *: Boolean *: String *: EmptyTuple]] // error
5050
| ^
51-
| Match type reduction failed since selector EmptyTuple.type
51+
| Match type reduction failed since selector EmptyTuple
5252
| matches none of the cases
5353
|
5454
| case _ *: _ *: t => Last[t]

tests/neg/i4565.check

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
-- [E007] Type Mismatch Error: tests/neg/i4565.scala:17:13 -------------------------------------------------------------
2+
17 |def b: Int = a // error
3+
| ^
4+
| Found: Test1[F[Int, String]]
5+
| Required: Int
6+
|
7+
| longer explanation available when compiling with `-explain`
8+
-- [E007] Type Mismatch Error: tests/neg/i4565.scala:20:13 -------------------------------------------------------------
9+
20 |def d: Int = c // error
10+
| ^
11+
| Found: F[Int, String]
12+
| Required: Int
13+
|
14+
| longer explanation available when compiling with `-explain`
15+
-- [E007] Type Mismatch Error: tests/neg/i4565.scala:23:13 -------------------------------------------------------------
16+
23 |def f: Int = e // error
17+
| ^
18+
| Found: F[Int, String]
19+
| Required: Int
20+
|
21+
| longer explanation available when compiling with `-explain`
22+
-- [E007] Type Mismatch Error: tests/neg/i4565.scala:26:13 -------------------------------------------------------------
23+
26 |def h: Int = g // error
24+
| ^
25+
| Found: Test1[B]
26+
| Required: Int
27+
|
28+
| longer explanation available when compiling with `-explain`
29+
-- [E007] Type Mismatch Error: tests/neg/i4565.scala:29:13 -------------------------------------------------------------
30+
29 |def j: Int = i // error
31+
| ^
32+
| Found: Test2[B]
33+
| Required: Int
34+
|
35+
| longer explanation available when compiling with `-explain`
36+
-- [E007] Type Mismatch Error: tests/neg/i4565.scala:32:13 -------------------------------------------------------------
37+
32 |def l: Int = k // error
38+
| ^
39+
| Found: Test3[B]
40+
| Required: Int
41+
|
42+
| longer explanation available when compiling with `-explain`
43+
-- [E007] Type Mismatch Error: tests/neg/i4565.scala:35:13 -------------------------------------------------------------
44+
35 |def n: Int = m // error
45+
| ^
46+
| Found: MyAlias
47+
| Required: Int
48+
|
49+
| longer explanation available when compiling with `-explain`

tests/neg/i4565.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
type F[A, B] = A => B
2+
3+
type LongComplictedType
4+
type B = LongComplictedType
5+
6+
case class Test1[T](v: T)
7+
case class Test2[T <: B](v: T)
8+
case class Test3[T <: LongComplictedType](v: T)
9+
10+
class MyClass
11+
type MyAlias = MyClass
12+
13+
14+
// these tests check that the inferred types are not dealiased
15+
16+
def a = Test1(??? : F[Int, String])
17+
def b: Int = a // error
18+
19+
def c: F[Int, String] = ???
20+
def d: Int = c // error
21+
22+
def e = { val v = ??? : F[Int, String]; v }
23+
def f: Int = e // error
24+
25+
def g = Test1(??? : B)
26+
def h: Int = g // error
27+
28+
def i = Test2(??? : B)
29+
def j: Int = i // error
30+
31+
def k = Test3(??? : B)
32+
def l: Int = k // error
33+
34+
def m: MyAlias = new MyClass
35+
def n: Int = m // error

tests/pos/i14171.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
object Test1:
2+
trait MyTypeclass[F[_]]
3+
def f[F[_]: MyTypeclass, U](t: F[U]) = ???
4+
5+
type MyType[T] = String
6+
given MyTypeclass[MyType] = ???
7+
8+
val stream: Option[MyType[Int]] = ???
9+
for
10+
keyStream <- stream
11+
x = 17
12+
yield f(keyStream)
13+
14+
15+
object Test2:
16+
trait MyTypeclass[F[_]]
17+
def f[F[_]: MyTypeclass, U](t: F[U]) = ???
18+
19+
type MyType[T] = Nil.type
20+
given MyTypeclass[MyType] = ???
21+
22+
val stream: Option[MyType[Int]] = ???
23+
for
24+
keyStream <- stream
25+
x = 17
26+
yield f(keyStream)

tests/printing/i13306.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ package example {
88
final module class Exports() extends Object() { this: example.Exports.type =>
99
val instance: example.MembersContainer = new example.MembersContainer()
1010
export example.Exports.instance.*
11-
final type MyType[T <: example.MyClass] = Comparable[T]
11+
final type MyType[T <: example.MyClass] = example.Exports.instance.MyType[T]
1212
}
1313
}
1414

tests/run-macros/i10863.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[A >: scala.Nothing <: scala.Any] => scala.collection.immutable.List[A]
1+
scala.List

tests/run-macros/quote-matching-optimize-3.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ Optimized: ls.foreach[scala.Any](((x: scala.Int) => if (((`x₂`: scala.Int) =>
1717
Result: ()
1818

1919
Original: ls.map[scala.Long](((a: scala.Int) => a.toLong)).map[java.lang.String](((b: scala.Long) => b.toString()))
20-
Optimized: ls.map[java.lang.String](((x: scala.Int) => ((b: scala.Long) => b.toString()).apply(((a: scala.Int) => a.toLong).apply(x))))
20+
Optimized: ls.map[scala.Predef.String](((x: scala.Int) => ((b: scala.Long) => b.toString()).apply(((a: scala.Int) => a.toLong).apply(x))))
2121
Result: List(1, 2, 3)
2222

2323
Original: ls.map[scala.Char](((a: scala.Int) => a.toChar)).map[java.lang.String](((b: scala.Char) => b.toString()))
24-
Optimized: ls.map[java.lang.String](((x: scala.Int) => ((b: scala.Char) => b.toString()).apply(((a: scala.Int) => a.toChar).apply(x))))
24+
Optimized: ls.map[scala.Predef.String](((x: scala.Int) => ((b: scala.Char) => b.toString()).apply(((a: scala.Int) => a.toChar).apply(x))))
2525
Result: List(, , )
2626

tests/run-macros/quote-type-matcher.check

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ Scrutinee: scala.Int
1010
Pattern: 2
1111
Result: None
1212

13-
Scrutinee: scala.collection.immutable.List[scala.Int]
14-
Pattern: scala.collection.immutable.List[scala.Int]
13+
Scrutinee: scala.List[scala.Int]
14+
Pattern: scala.List[scala.Int]
1515
Result: Some(List())
1616

17-
Scrutinee: scala.collection.immutable.List[scala.Int]
18-
Pattern: scala.collection.immutable.List[scala.Double]
17+
Scrutinee: scala.List[scala.Int]
18+
Pattern: scala.List[scala.Double]
1919
Result: None
2020

tests/run-macros/tasty-definitions-1.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Double")
165165
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Boolean")
166166
TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "<root>")), "scala"), "Any")
167167
TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "<root>")), "scala"), "AnyVal")
168-
TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "java")), "lang"), "Object")
168+
TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "<root>")), "scala"), "AnyRef")
169169
TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "java")), "lang"), "Object")
170170
TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "<root>")), "scala"), "Nothing")
171171
TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "<root>")), "scala"), "Null")
172-
TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "java")), "lang"), "String")
172+
TypeRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix(), "<root>")), "scala"), "Predef"), "String")

tests/run-macros/tasty-extractors-2.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Inlined(None, Nil, Typed(Literal(IntConstant(1)), TypeIdent("Int")))
1414
TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "<root>")), "scala"), "Int")
1515

1616
Inlined(None, Nil, Typed(Ident("Nil"), Applied(TypeIdent("List"), List(TypeIdent("Int")))))
17-
AppliedType(TypeRef(ThisType(TypeRef(NoPrefix(), "immutable")), "List"), List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "<root>")), "scala"), "Int")))
17+
AppliedType(TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "scala")), "package"), "List"), List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "<root>")), "scala"), "Int")))
1818

1919
Inlined(None, Nil, Typed(Apply(Select(New(TypeIdent("Baz")), "<init>"), Nil), Applied(TypeIdent("&"), List(TypeIdent("Foo"), TypeIdent("Bar")))))
2020
AndType(TypeRef(ThisType(TypeRef(NoPrefix(), "<empty>")), "Foo"), TypeRef(ThisType(TypeRef(NoPrefix(), "<empty>")), "Bar"))

0 commit comments

Comments
 (0)