Skip to content

Compiler stack overflow when using Manifest with recursive existential types #6255

Open
@scabug

Description

@scabug
class C[T <: C[T]]

class UseManifest[T : Manifest]

new UseManifest[C[T] forSome{ type T <: C[T] }]

Note: I'm calling it "recursive existential type" but I'm really not sure about the terminology... maybe there's a better term.

Activity

scabug

scabug commented on Aug 18, 2012

@scabug
Author

Imported From: https://issues.scala-lang.org/browse/SI-6255?orig=1
Reporter: Bruno Bieth (mustaghattack)
See #6528

scabug

scabug commented on Jan 8, 2013

@scabug
Author

@retronym said:
It's not the same bug, but is in the same food group as #6528.

scabug

scabug commented on Aug 15, 2014

@scabug
Author

Damir Vandic (damirv) said:
Any updates on this? (or a possible/recommended workaround)

For the interested reader: I encountered this issue with trying to use 'recursive existential types' to call the following Java method (Titan Graph database v0.5.0):

public TitanGraphQuery<? extends TitanGraphQuery> query();

with TitanGraphQuery being

public interface TitanGraphQuery<Q extends TitanGraphQuery<Q>> {
    public Q has(String key, Object value);
}

Example Scala code (without explicit types):

val attrs: Map[String, Any]
val attrQ = attrs.foldLeft(g.query())({
  case (q, (name, value)) => q.has(name, value)
})

Does this bug mean I cannot use this method in Scala?

added this to the Backlog milestone on Apr 7, 2017
jvandew

jvandew commented on Sep 8, 2022

@jvandew

Related but perhaps slightly different: we hit this in our codebase during an upgrade of apache thrift due to TBase being typed in this way and scalac failing to infer a manifest for its erased type. The minimal repro in our case being:

repl_test ➤ echo "public interface Test<T extends Test<T>> {}" > Test.java
repl_test ➤ javac Test.java
repl_test ➤ scala -cp .
Welcome to Scala 2.13.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_161).
Type in expressions for evaluation. Or try :help.

scala> manifest[Test[_]]
java.lang.StackOverflowError
  at scala.reflect.internal.Symbols$Symbol.isPrimaryConstructor(Symbols.scala:955)
  at scala.tools.nsc.typechecker.Contexts$Context.withOuter$1(Contexts.scala:1123)
  at scala.tools.nsc.typechecker.Contexts$Context.implicitssImpl(Contexts.scala:1146)
  at scala.tools.nsc.typechecker.Contexts$Context.withOuter$1(Contexts.scala:1125)
...

That entry seems to have slain the compiler.  Shall I replay
your session? I can re-run each line except the last one.
[y/n]

Interestingly, the same type can be inferred without issue if declared as a scala trait instead of the java interface.

Repro'ed with both java 8 & 11 on latest versions of 2.11, 2.12, and 2.13.

deleted a comment from scabug on Sep 8, 2022
SethTisue

SethTisue commented on Sep 8, 2022

@SethTisue
Member

Consider using ClassTag if you don't need full type information, and TypeTag if you do. As the Manifest documentation states:

it is advisable to migrate any Manifest-based APIs to use Tags

jvandew

jvandew commented on Sep 9, 2022

@jvandew

We did indeed switch to using a mix of tags (ClassTag where possible, TypeTag where required) which gets around this problem. I expect we'll have to revisit this when we eventually upgrade to Scala 3 as TypeTag seems to have been removed, but it's probably a few years yet before we cross that bridge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @SethTisue@jvandew@scabug

        Issue actions

          Compiler stack overflow when using Manifest with recursive existential types · Issue #6255 · scala/bug