@@ -2497,9 +2497,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
24972497 def provablyDisjoint (tp1 : Type , tp2 : Type )(using Context ): Boolean = trace(i " provable disjoint $tp1, $tp2" , matchTypes) {
24982498 // println(s"provablyDisjoint(${tp1.show}, ${tp2.show})")
24992499
2500- def isEnumValueOrModule (ref : TermRef ): Boolean =
2500+ def isEnumValue (ref : TermRef ): Boolean =
25012501 val sym = ref.termSymbol
2502- sym.isAllOf(EnumCase , butNot= JavaDefined ) || sym.is(Module )
2502+ sym.isAllOf(EnumCase , butNot= JavaDefined )
2503+
2504+ def isEnumValueOrModule (ref : TermRef ): Boolean =
2505+ isEnumValue(ref) || ref.termSymbol.is(Module ) || (ref.info match {
2506+ case tp : TermRef => isEnumValueOrModule(tp)
2507+ case _ => false
2508+ })
25032509
25042510 /** Can we enumerate all instantiations of this type? */
25052511 def isClosedSum (tp : Symbol ): Boolean =
@@ -2512,8 +2518,21 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25122518 def decompose (sym : Symbol , tp : Type ): List [Type ] =
25132519 sym.children.map(x => refineUsingParent(tp, x)).filter(_.exists)
25142520
2521+ def fullyInstantiated (tp : Type ): Boolean = new TypeAccumulator [Boolean ] {
2522+ override def apply (x : Boolean , t : Type ) =
2523+ x && {
2524+ t match {
2525+ case tp : TypeRef if tp.symbol.isAbstractOrParamType => false
2526+ case _ : SkolemType | _ : TypeVar => false
2527+ case _ => foldOver(x, t)
2528+ }
2529+ }
2530+ }.apply(true , tp)
2531+
25152532 (tp1.dealias, tp2.dealias) match {
2516- case (tp1 : TypeRef , tp2 : TypeRef ) if tp1.symbol == defn.SingletonClass || tp2.symbol == defn.SingletonClass =>
2533+ case (tp1 : TypeRef , _) if tp1.symbol == defn.SingletonClass =>
2534+ false
2535+ case (_, tp2 : TypeRef ) if tp2.symbol == defn.SingletonClass =>
25172536 false
25182537 case (tp1 : ConstantType , tp2 : ConstantType ) =>
25192538 tp1 != tp2
@@ -2557,21 +2576,10 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25572576 // doesn't have type tags, meaning that users cannot write patterns
25582577 // that do type tests on higher kinded types.
25592578 def invariantDisjoint (tp1 : Type , tp2 : Type , tparam : TypeParamInfo ): Boolean =
2560- covariantDisjoint(tp1, tp2, tparam) || ! isSameType(tp1, tp2) && {
2561- // We can only trust a "no" from `isSameType` when both
2562- // `tp1` and `tp2` are fully instantiated.
2563- def fullyInstantiated (tp : Type ): Boolean = new TypeAccumulator [Boolean ] {
2564- override def apply (x : Boolean , t : Type ) =
2565- x && {
2566- t match {
2567- case tp : TypeRef if tp.symbol.isAbstractOrParamType => false
2568- case _ : SkolemType | _ : TypeVar => false
2569- case _ => foldOver(x, t)
2570- }
2571- }
2572- }.apply(true , tp)
2573- fullyInstantiated(tp1) && fullyInstantiated(tp2)
2574- }
2579+ covariantDisjoint(tp1, tp2, tparam) ||
2580+ ! isSameType(tp1, tp2) &&
2581+ fullyInstantiated(tp1) && // We can only trust a "no" from `isSameType` when
2582+ fullyInstantiated(tp2) // both `tp1` and `tp2` are fully instantiated.
25752583
25762584 args1.lazyZip(args2).lazyZip(tycon1.typeParams).exists {
25772585 (arg1, arg2, tparam) =>
@@ -2608,11 +2616,10 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
26082616 provablyDisjoint(tp1, gadtBounds(tp2.symbol).hi) || provablyDisjoint(tp1, tp2.superType)
26092617 case (tp1 : TermRef , tp2 : TermRef ) if isEnumValueOrModule(tp1) && isEnumValueOrModule(tp2) =>
26102618 tp1.termSymbol != tp2.termSymbol
2611- case (tp1 : TermRef , tp2 : TypeRef ) if isEnumValueOrModule(tp1) && ! tp1.classSymbols.exists(_.derivesFrom(tp2.classSymbol)) =>
2612- // Note: enum values may have multiple parents
2613- true
2614- case (tp1 : TypeRef , tp2 : TermRef ) if isEnumValueOrModule(tp2) && ! tp2.classSymbols.exists(_.derivesFrom(tp1.classSymbol)) =>
2615- true
2619+ case (tp1 : TermRef , tp2 : TypeRef ) if isEnumValue(tp1) =>
2620+ fullyInstantiated(tp2) && ! tp1.classSymbols.exists(_.derivesFrom(tp2.symbol))
2621+ case (tp1 : TypeRef , tp2 : TermRef ) if isEnumValue(tp2) =>
2622+ fullyInstantiated(tp1) && ! tp2.classSymbols.exists(_.derivesFrom(tp1.symbol))
26162623 case (tp1 : Type , tp2 : Type ) if defn.isTupleType(tp1) =>
26172624 provablyDisjoint(tp1.toNestedPairs, tp2)
26182625 case (tp1 : Type , tp2 : Type ) if defn.isTupleType(tp2) =>
0 commit comments