Skip to content

StackOverflowError in typer when an existential type is passed to unapply #12602

Open
@noresttherein

Description

@noresttherein

Reproduction steps

Ok, this little pos is a bit complex:

trait POS[O] { type Value }
trait BigPOS[V, O] extends POS[O] { type Value = V }
trait BadJoke[V, +T[_]]
trait Root[V] extends BadJoke[V, Root]
trait Bugger[M[O] <: POS[O]] extends Root[M[Unit]#Value]
trait Fokker[M[O] <: BigPOS[V, O], V] extends Bugger[M]

object Root {
	def unapply[X](e :Root[X]) :Option[Unit] = None
}
object Bugger {
	def unapply[X](e :Root[X]) :Option[Fokker[M, V]] forSome { type M[O] <: BigPOS[V, O]; type V } = ???

	def error[X](e :Root[X]) = e match {
		case Bugger(Root(_)) => ()
	}
}

Problem

Crucial factors:

  1. M[Unit]#Value used as the type argument to Root
  2. unapply, or at least using an Option or otherwise wrapping the result of Bugger.unapply, as dropping the Option[_] wrapper from the unapply results and composing the calls normally works.
  3. What's most amusing here, is that BadJoke which seems to do nothing here, is actually crucial: removing it makes the whole clusterf$$$ compile.
java.lang.StackOverflowError
	at scala.reflect.internal.Types$TypeVar.registerTypeEquality(Types.scala:3701)
	at scala.reflect.internal.tpe.TypeComparers.mutateNonTypeConstructs$1(TypeComparers.scala:217)
	at scala.reflect.internal.tpe.TypeComparers.isSameType2(TypeComparers.scala:261)
	at scala.reflect.internal.tpe.TypeComparers.isSameType2$(TypeComparers.scala:198)
	at scala.reflect.internal.SymbolTable.isSameType2(SymbolTable.scala:28)
	at scala.reflect.internal.tpe.TypeComparers.isSameType1(TypeComparers.scala:142)
	at scala.reflect.internal.tpe.TypeComparers.isSameType(TypeComparers.scala:117)
	at scala.reflect.internal.tpe.TypeComparers.isSameType$(TypeComparers.scala:105)
	at scala.reflect.internal.SymbolTable.isSameType(SymbolTable.scala:28)
	at scala.reflect.internal.Types$Type.$eq$colon$eq(Types.scala:864)
	at scala.reflect.internal.Types$TypeVar.checkIsSameType$1(Types.scala:3697)
	at scala.reflect.internal.Types$TypeVar.registerTypeEquality(Types.scala:3702)
	at scala.reflect.internal.tpe.TypeComparers.mutateNonTypeConstructs$1(TypeComparers.scala:217)
	at scala.reflect.internal.tpe.TypeComparers.isSameType2(TypeComparers.scala:261)
	at scala.reflect.internal.tpe.TypeComparers.isSameType2$(TypeComparers.scala:198)
	at scala.reflect.internal.SymbolTable.isSameType2(SymbolTable.scala:28)
	at scala.reflect.internal.tpe.TypeComparers.isSameType1(TypeComparers.scala:142)
	at scala.reflect.internal.tpe.TypeComparers.isSameType(TypeComparers.scala:117)
	at scala.reflect.internal.tpe.TypeComparers.isSameType$(TypeComparers.scala:105)
	at scala.reflect.internal.SymbolTable.isSameType(SymbolTable.scala:28)
	at scala.reflect.internal.Types$Type.$eq$colon$eq(Types.scala:864)
	at scala.reflect.internal.Types$TypeVar.checkIsSameType$1(Types.scala:3697)
	at scala.reflect.internal.Types$TypeVar.registerTypeEquality(Types.scala:3702)
	at scala.reflect.internal.tpe.TypeComparers.mutateNonTypeConstructs$1(TypeComparers.scala:217)

I lost a loving week on isolating it, and looking at how it involves both existentials and abstract type projection, I know it's unlikely to ever get fixed :,,(

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions