Skip to content

More robust comparison of type constructors in provablyDisjoint #11435

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/config/Printers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ object Printers {
val init = noPrinter
val inlining = noPrinter
val interactiv = noPrinter
val matchTypes = noPrinter
val nullables = noPrinter
val overload = noPrinter
val patmatch = noPrinter
Expand Down
9 changes: 5 additions & 4 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import collection.mutable
import util.Stats
import config.Config
import config.Feature.migrateTo3
import config.Printers.{constr, subtyping, gadts, noPrinter}
import config.Printers.{constr, subtyping, gadts, matchTypes, noPrinter}
import TypeErasure.{erasedLub, erasedGlb}
import TypeApplications._
import Variances.{Variance, variancesConform}
Expand Down Expand Up @@ -2408,7 +2408,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
* property that in all possible contexts, the same match type expression
* is either stuck or reduces to the same case.
*/
def provablyDisjoint(tp1: Type, tp2: Type)(using Context): Boolean = {
def provablyDisjoint(tp1: Type, tp2: Type)(using Context): Boolean = trace(i"provable disjoint $tp1, $tp2", matchTypes) {
// println(s"provablyDisjoint(${tp1.show}, ${tp2.show})")

def isEnumValueOrModule(ref: TermRef): Boolean =
Expand Down Expand Up @@ -2452,7 +2452,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
decompose(cls2, tp2).forall(x => provablyDisjoint(x, tp1))
else
false
case (AppliedType(tycon1, args1), AppliedType(tycon2, args2)) if tycon1 == tycon2 =>
case (AppliedType(tycon1, args1), AppliedType(tycon2, args2))
if tycon1.typeSymbol == tycon2.typeSymbol && tycon1 =:= tycon2 =>
// It is possible to conclude that two types applies are disjoint by
// looking at covariant type parameters if the said type parameters
// are disjoin and correspond to fields.
Expand Down Expand Up @@ -2768,7 +2769,7 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
* None if the match fails and we should consider the following cases
* because scrutinee and pattern do not overlap
*/
def matchCase(cas: Type): Option[Type] = {
def matchCase(cas: Type): Option[Type] = trace(i"match case $cas vs $scrut", matchTypes) {
val cas1 = cas match {
case cas: HKTypeLambda =>
caseLambda = constrained(cas)
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import config.Config
import annotation.{tailrec, constructorOnly}
import language.implicitConversions
import scala.util.hashing.{ MurmurHash3 => hashing }
import config.Printers.{core, typr}
import config.Printers.{core, typr, matchTypes}
import reporting.{trace, Message}
import java.lang.ref.WeakReference

Expand Down Expand Up @@ -4489,7 +4489,7 @@ object Types {
record("MatchType.reduce computed")
if (myReduced != null) record("MatchType.reduce cache miss")
myReduced =
trace(i"reduce match type $this $hashCode", typr, show = true) {
trace(i"reduce match type $this $hashCode", matchTypes, show = true) {
def matchCases(cmp: TrackingTypeComparer): Type =
try cmp.matchCases(scrutinee.normalized, cases)
catch case ex: Throwable =>
Expand Down
7 changes: 7 additions & 0 deletions tests/pos/i11393/Format_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
object Formatt:
type ToFormat[X <: Tuple] = X match
case EmptyTuple => String
case '%' *: 's' *: ts => (String => ToFormat[ts])
case Char *: ts => ToFormat[ts]


5 changes: 5 additions & 0 deletions tests/pos/i11393/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@main def hello: Unit = {
val x: Formatt.ToFormat['a' *: EmptyTuple] = ""


}