@@ -301,8 +301,11 @@ object Types {
301301 }
302302
303303 /** Does this type occur as a part of type `that`? */
304- final def occursIn (that : Type )(implicit ctx : Context ): Boolean =
305- that existsPart (this == _)
304+ def occursIn (that : Type )(implicit ctx : Context ): Boolean =
305+ that.existsPart(this == _)
306+
307+ /** Does this type not refer to TypeParamRefs or uninstantiated TypeVars? */
308+ final def isGround (implicit ctx : Context ): Boolean = true
306309
307310 /** Is this a type of a repeated parameter? */
308311 def isRepeatedParam (implicit ctx : Context ): Boolean =
@@ -3271,6 +3274,17 @@ object Types {
32713274 private [this ] var cachedSuper : Type = _
32723275 private [this ] var myStableHash : Byte = 0
32733276
3277+ private [this ] var isGroundKnown : Boolean = false
3278+ private [this ] var isGroundCache : Boolean = _
3279+
3280+ def isGround (acc : TypeAccumulator [Boolean ])(implicit ctx : Context ): Boolean = {
3281+ if (! isGroundKnown) {
3282+ isGroundCache = acc.foldOver(false , this )
3283+ isGroundKnown = true
3284+ }
3285+ isGroundCache
3286+ }
3287+
32743288 override def underlying (implicit ctx : Context ): Type = tycon
32753289
32763290 override def superType (implicit ctx : Context ): Type = {
@@ -3414,6 +3428,11 @@ object Types {
34143428 def kindString = " Type"
34153429 def copyBoundType (bt : BT ) = bt.paramRefs(paramNum)
34163430
3431+ /** Optimized version of occursIn, avoid quadratic blowup when solving
3432+ * constraints over large ground types.
3433+ */
3434+ override def occursIn (that : Type )(implicit ctx : Context ) = ! that.isGround && super .occursIn(that)
3435+
34173436 /** Looking only at the structure of `bound`, is one of the following true?
34183437 * - fromBelow and param <:< bound
34193438 * - !fromBelow and param >:> bound
@@ -4777,6 +4796,17 @@ object Types {
47774796 }
47784797 }
47794798
4799+ class isGroundAccumulator (implicit ctx : Context ) extends TypeAccumulator [Boolean ] {
4800+ def apply (x : Boolean , tp : Type ) = x || {
4801+ tp match {
4802+ case _ : TypeParamRef => false
4803+ case tp : TypeVar => apply(x, tp.underlying)
4804+ case tp : AppliedType => tp.isGround(this )
4805+ case _ => foldOver(x, tp)
4806+ }
4807+ }
4808+ }
4809+
47804810 // ----- Name Filters --------------------------------------------------
47814811
47824812 /** A name filter selects or discards a member name of a type `pre`.
0 commit comments