Skip to content

Commit

Permalink
Dealias val aliases to modules so they're =:=
Browse files Browse the repository at this point in the history
This changes the definitely of =:= in the smallest possible way:
if you have a singleton type that widens to a module,
then widen to that module.
  • Loading branch information
dwijnand committed Nov 16, 2020
1 parent 8507cf0 commit 2eeada6
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 5 deletions.
6 changes: 3 additions & 3 deletions src/reflect/scala/reflect/internal/Types.scala
Expand Up @@ -4558,9 +4558,9 @@ trait Types
if (isRawType(tp)) rawToExistential(tp)
else tp.normalize match {
// Unify the representations of module classes
case st@SingleType(_, sym) if sym.isModule => st.underlying.normalize
case st@ThisType(sym) if sym.isModuleClass => normalizePlus(st.underlying)
case _ => tp.normalize
case st @ SingleType(_, sym) if st.dealiasWiden.typeSymbol.isModuleOrModuleClass => st.dealiasWiden.normalize
case st @ ThisType(sym) if sym.isModuleClass => normalizePlus(st.underlying)
case tpNorm => tpNorm
}
}

Expand Down
29 changes: 29 additions & 0 deletions test/files/pos/t12186.scala
@@ -0,0 +1,29 @@
// scalac: -Werror

// this is remodeling of the scala package object and scala.collection.immutable.{ List, ::, Nil }
// in order to:
// * avoid the scala package, which is auto-imported
// * avoid List, which is rewritten/fudged in the pattern matcher
package skala.collect {
sealed trait Xs[+A]
final case class Cons[+A](head: A, tail: Xs[A]) extends Xs[A]
final case object Done extends Xs[Nothing]
object Xs
}
package object skala {
type Cons[+A] = skala.collect.Cons[A]
type Xs[+A] = skala.collect.Xs[A]
val Cons = skala.collect.Cons
val Done: skala.collect.Done.type = skala.collect.Done
val Xs = skala.collect.Xs
}

import skala._

class Test {
def test(xs: Xs[Int]): Boolean = xs match {
case Cons(_, _) => true
case _: Done.type => false
//case _: skala.collect.Done.type => false // done this way it already works
}
}
23 changes: 21 additions & 2 deletions test/junit/scala/reflect/internal/TypesTest.scala
Expand Up @@ -46,9 +46,14 @@ class TypesTest {
val tp1 = TypeRef(ThisType(EmptyPackageClass), moduleClass, Nil)
val tp2 = SingleType(ThisType(EmptyPackageClass), module)
val tp3 = ThisType(moduleClass)
val tps = List(tp1, tp2, tp3)

val (otherModule, otherModuleClass) = EmptyPackageClass.newModuleAndClassSymbol(TermName("Other"), NoPosition, 0L)
val aliasSym = otherModuleClass.newTermSymbol(TermName("alias")).setInfo(tp2)
val tp4 = singleType(TypeRef(ThisType(EmptyPackageClass), otherModuleClass, Nil), aliasSym)

val tps = List(tp1, tp2, tp3, tp4)
val results = mutable.Buffer[String]()
tps.permutations.foreach {
tps.combinations(3).flatMap(_.permutations).foreach {
case ts @ List(a, b, c) =>
def tsShownRaw = ts.map(t => showRaw(t)).mkString(", ")
if (a <:< b && b <:< c && !(a <:< c)) results += s"<:< intransitive: $tsShownRaw"
Expand All @@ -61,6 +66,20 @@ class TypesTest {
}
}

@Test
def testNilModuleUnification(): Unit = {
import rootMirror.RootClass
val nil1 = singleType(ThisType(RootClass), typeOf[scala.`package`.type].member(TermName("Nil")))
val nil2 = typeOf[scala.collection.immutable.Nil.type]
val tps = List(nil1, nil2)
val results = mutable.Buffer[String]()
tps.permutations.foreach { case List(a, b) =>
if (!(a =:= b))
results += s"expected a =:= b; where a=${showRaw(a)} b=${showRaw(b)}"
}
assertTrue(s"Mismatches:\n${results.mkString("\n")}", results.isEmpty)
}

@Test
def testRefinementContains(): Unit = {
val refinement = typeOf[{def foo: Int}]
Expand Down

0 comments on commit 2eeada6

Please sign in to comment.