scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

StackOverflow in the compiler, involving... well, quite a lot of different things #12461

Open noresttherein opened 3 years ago

noresttherein commented 3 years ago

using Scala 2.13.6


    trait Root { type A; type B }
    type Nasty[X, Y] = Root { type A = X; type B = Y }
    type ProjectB[Y] = Root { type B = Y }

    class Marker[A, T[X] <: ProjectB[X]]

    class Problem[T[A] <: Nasty[S, A], S, O]
                 (val underlying :Problem[T, S, O],
                  val seq :Seq[ProjectB[O]] = Seq.empty[Nasty[_, O]])
    {
        lazy val issue :Nasty[S, O] = ???
        def mark[Y](m :Marker[Y, T]) :Problem[T, S, Y] = ???

        def copy[E](position :Marker[E, T]) :Problem[T, S, E] =
            new Problem(mark(position)) {
                override lazy val issue = Problem.this.issue.asInstanceOf[Nasty[S, E]]
            }
    }
java.lang.StackOverflowError
    at scala.reflect.internal.Symbols$TypeSymbol.tpe_$times(Symbols.scala:3215)
    at scala.reflect.internal.Symbols$Symbol.typeOfThis(Symbols.scala:2115)
    at scala.reflect.internal.Types$ThisType.underlying(Types.scala:1411)
    at scala.reflect.internal.Types$SimpleTypeProxy.widen(Types.scala:159)
    at scala.reflect.internal.Types$SimpleTypeProxy.widen$(Types.scala:159)
    at scala.reflect.internal.Types$SingletonType.widen(Types.scala:1111)
    at scala.reflect.internal.tpe.TypeMaps$AsSeenFromMap.scala$reflect$internal$tpe$TypeMaps$AsSeenFromMap$$matchesPrefixAndClass(TypeMaps.scala:589)
    at scala.reflect.internal.tpe.TypeMaps$AsSeenFromMap.loop$4(TypeMaps.scala:644)
    at scala.reflect.internal.tpe.TypeMaps$AsSeenFromMap.thisTypeAsSeen(TypeMaps.scala:651)
    at scala.reflect.internal.tpe.TypeMaps$AsSeenFromMap.apply(TypeMaps.scala:443)
    at scala.reflect.internal.Types$TypeRef.mapOver(Types.scala:2371)
    at scala.reflect.internal.tpe.TypeMaps$AsSeenFromMap.apply(TypeMaps.scala:446)
    at scala.reflect.internal.Types$TypeVar.mapOver(Types.scala:3803)
    at scala.reflect.internal.tpe.TypeMaps$AsSeenFromMap.apply(TypeMaps.scala:446)
    at scala.reflect.internal.Types$Type.asSeenFrom(Types.scala:705)
    at scala.reflect.internal.Types$TypeRef.relativize(Types.scala:2466)
    at scala.reflect.internal.Types$AliasTypeRef.betaReduce(Types.scala:2299)
    at scala.reflect.internal.Types$AliasTypeRef.betaReduce$(Types.scala:2299)
    at scala.reflect.internal.Types$AliasNoArgsTypeRef.betaReduce(Types.scala:2742)
    at scala.reflect.internal.Types$AliasTypeRef.dealias(Types.scala:2243)
    at scala.reflect.internal.Types$AliasTypeRef.dealias$(Types.scala:2243)
    at scala.reflect.internal.Types$AliasNoArgsTypeRef.dealias(Types.scala:2742)
    at scala.reflect.internal.Types$AliasTypeRef.dealias(Types.scala:2243)
    at scala.reflect.internal.Types$AliasTypeRef.dealias$(Types.scala:2243)
    at scala.reflect.internal.Types$AliasNoArgsTypeRef.dealias(Types.scala:2742)
    at scala.reflect.internal.Types$AliasTypeRef.dealias(Types.scala:2243)
    at scala.reflect.internal.Types$AliasTypeRef.dealias$(Types.scala:2243)
    at scala.reflect.internal.Types$AliasNoArgsTypeRef.dealias(Types.scala:2742)
    at scala.reflect.internal.Types$AliasTypeRef.dealias(Types.scala:2243)
    at scala.reflect.internal.Types$AliasTypeRef.dealias$(Types.scala:2243)
    at scala.reflect.internal.Types$AliasNoArgsTypeRef.dealias(Types.scala:2742)
    at scala.reflect.internal.Types$AliasTypeRef.dealias(Types.scala:2243)
    at scala.reflect.internal.Types$AliasTypeRef.dealias$(Types.scala:2243)
    at scala.reflect.internal.Types$AliasNoArgsTypeRef.dealias(Types.scala:2742)
    at scala.reflect.internal.Types$AliasTypeRef.dealias(Types.scala:2243)
    at scala.reflect.internal.Types$AliasTypeRef.dealias$(Types.scala:2243)
    at scala.reflect.internal.Types$AliasNoArgsTypeRef.dealias(Types.scala:2742)
    at scala.reflect.internal.Types$AliasTypeRef.dealias(Types.scala:2243)
    at scala.reflect.internal.Types$AliasTypeRef.dealias$(Types.scala:2243)

The issue is the copy method, combining type inference, higher types and default parameters. It is pretty close to minimal:

  1. Specifying the type parameters for the anonymous Problem explicitly fixes the issue;
  2. Replacing Nasty[_, O] with ProjectB[O] fixes the issue;
  3. Specifying the default argument explicitly fixes the issue;
  4. Not using an anonymous class with overriden lazy val fixes the issue
som-snytt commented 3 years ago

TIL -XX:MaxJavaStackTraceDepth=1073741823

to show higher up the stack.

        at scala.reflect.internal.Types$AliasTypeRef.dealias$(Types.scala:2243)
        at scala.reflect.internal.Types$AliasNoArgsTypeRef.dealias(Types.scala:2742)
        at scala.reflect.internal.Types$TypeRef.customToString(Types.scala:2711)
        at scala.reflect.internal.Types$TypeRef.safeToString(Types.scala:2716)
        at scala.reflect.internal.tpe.TypeToStrings.typeToString(TypeToStrings.scala:55)
        at scala.reflect.internal.tpe.TypeToStrings.typeToString$(TypeToStrings.scala:34)
        at scala.reflect.internal.SymbolTable.typeToString(SymbolTable.scala:28)
        at scala.reflect.internal.Types$Type.toString(Types.scala:950)
        at java.base/java.lang.String.valueOf(String.java:4215)
        at java.base/java.lang.StringBuilder.append(StringBuilder.java:169)
        at scala.collection.IterableOnceOps.addString(IterableOnce.scala:1187)
        at scala.collection.IterableOnceOps.addString$(IterableOnce.scala:1179)
        at scala.collection.AbstractIterable.addString(Iterable.scala:919)
        at scala.collection.IterableOnceOps.mkString(IterableOnce.scala:1129)
        at scala.collection.IterableOnceOps.mkString$(IterableOnce.scala:1127)
        at scala.tools.nsc.typechecker.ContextErrors$InferencerContextErrors$InferErrorGen$.NotWithinBoundsErrorMessage(ContextErrors.scala:1233)        at scala.tools.nsc.typechecker.ContextErrors$InferencerContextErrors$InferErrorGen$.NotWithinBounds(ContextErrors.scala:1241)
        at scala.tools.nsc.typechecker.Infer$Inferencer.issueBoundsError$1(Infer.scala:981)
        at scala.tools.nsc.typechecker.Infer$Inferencer.check$1(Infer.scala:987)
        at scala.tools.nsc.typechecker.Infer$Inferencer.checkBounds(Infer.scala:991)
        at scala.tools.nsc.typechecker.Infer$Inferencer.inferMethodInstance(Infer.scala:1089)
        at scala.tools.nsc.typechecker.Typers$Typer.handlePolymorphicCall$1(Typers.scala:3841)
        at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:3846)
        at scala.tools.nsc.typechecker.Typers$Typer.tryNamesDefaults$1(Typers.scala:3728)
        at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:3742)
        at scala.tools.nsc.typechecker.Typers$Typer.normalTypedApply$1(Typers.scala:5095)

Stubbing the failure with !!!

t12461.scala:18: error: inferred type arguments [[A]T[A],S,!!!] do not conform to class Problem's type parameter bounds [T[A] <: X.Nasty[S,A],S,O]
Error occurred in an application involving default arguments.
                        new Problem(mark(position)) {
                            ^
t12461.scala:18: error: type mismatch;
 found   : X.Problem[T(in class Problem),S(in class Problem),E]
 required: X.Problem[(some other)T(in class Problem),(some other)S(in class Problem),O]
Error occurred in an application involving default arguments.
                        new Problem(mark(position)) {
                                        ^
t12461.scala:19: error: type mismatch;
 found   : X.Root{type A = S; type B = E}
 required: X.Nasty[Nothing,Nothing]
    (which expands to)  X.Root{type A = Nothing; type B = Nothing}
                                override lazy val issue = Problem.this.issue.asInstanceOf[Nasty[S, E]]
                                                                                         ^
t12461.scala:18: error: type mismatch;
 found   : X.Problem[Nothing,Nothing,Nothing]
 required: X.Problem[T,S,E]
Note: Nothing <: T, but class Problem is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
Note: Nothing <: S, but class Problem is invariant in type S.
You may wish to define S as +S instead. (SLS 4.5)
Note: Nothing <: E, but class Problem is invariant in type O.
You may wish to define O as +O instead. (SLS 4.5)
                        new Problem(mark(position)) {
                        ^