Skip to content

Instantly share code, notes, and snippets.

@retronym
Last active September 14, 2021 01:50
Show Gist options
  • Save retronym/ee7a0311c9ce8850de17081d0ecc99c7 to your computer and use it in GitHub Desktop.
Save retronym/ee7a0311c9ce8850de17081d0ecc99c7 to your computer and use it in GitHub Desktop.
Rich Map woes
class M {
type AnyIterableOps[+A, Repr] = collection.IterableOps[A, Any, Repr]
def richMap[K, V, CC <: collection.MapOps[K, V, AnyIterableOps, CC]] = ()
def foo(m: scala.collection.immutable.Map[String, String]): AnyIterableOps[(String, String), scala.collection.immutable.Map[String, String]] = m
richMap[Int, String, scala.collection.immutable.Map[Int, String]]
}
./build/quick/bin/scalac -d /tmp /tmp/map.scala -explaintypes
Nothing <: Int?
true
Nothing <: String?
Nothing <: String?
true
true
Nothing <: scala.collection.immutable.Map[Int,String]?
true
Int <: Any?
true
String <: Any?
true
scala.collection.immutable.Map[Int,String] <: scala.collection.MapOps[Int,String,M.this.AnyIterableOps,scala.collection.immutable.Map[Int,String]]?
scala.collection.MapOps[Int,String,[_, _]scala.collection.immutable.Map[_,_],scala.collection.immutable.Map[Int,String]] <: scala.collection.MapOps[Int,String,M.this.AnyIterableOps,scala.collection.immutable.Map[Int,String]]?
[_, _]scala.collection.immutable.Map[_,_] <: M.this.AnyIterableOps?
scala.collection.immutable.Map[_,_] <: M.this.AnyIterableOps[_,_]?
scala.collection.immutable.Map[_,_] <: scala.collection.IterableOps[_,Any,_]?
scala.collection.IterableOps[(_, _),[_]scala.collection.immutable.Iterable[_],scala.collection.immutable.Map[_,_]] <: scala.collection.IterableOps[_,Any,_]?
(_, _) <: _?
(_, _) <: Nothing?
false
false
false
false
false
false
false
false
/tmp/map.scala:9: error: type arguments [Int,String,scala.collection.immutable.Map[Int,String]] do not conform to method richMap's type parameter bounds [K,V,CC <: scala.collection.MapOps[K,V,M.this.AnyIterableOps,CC]]
richMap[Int, String, scala.collection.immutable.Map[Int, String]]
^
1 error
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 1cefcf355d..4ae40687c2 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -98,6 +98,7 @@ trait Types
import statistics._
private[this] var explainSwitch = false
+ final def explainSwitchEnabled = explainSwitch
@unused private final val emptySymbolSet = immutable.Set.empty[Symbol]
@unused private final val breakCycles = settings.breakCycles.value
@@ -817,8 +818,7 @@ trait Types
if (settings.areStatisticsEnabled) stat_<:<(that)
else {
(this eq that) ||
- (if (explainSwitch) explain("<:", isSubType(_: Type, _: Type), this, that)
- else isSubType(this, that))
+ (isSubType(this, that))
}
}
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
index 92357d0e0e..9cc8e91999 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
@@ -265,6 +265,10 @@ trait TypeComparers {
}
def isSubType(tp1: Type, tp2: Type, depth: Depth = Depth.AnyDepth): Boolean = try {
+ if (explainSwitchEnabled) explain("<:", isSubTypeUnexplained(_: Type, _: Type, depth), tp1, tp2)
+ else isSubTypeUnexplained(tp1, tp2, depth)
+ }
+ def isSubTypeUnexplained(tp1: Type, tp2: Type, depth: Depth = Depth.AnyDepth): Boolean = try {
subsametypeRecursions += 1
//OPT cutdown on Function0 allocation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment