scala / bug

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

Stack overflow when type checking long lists #2355

Closed scabug closed 13 years ago

scabug commented 15 years ago

Attempting to compile the following code gives a type checker stack overflow crash with 2.7.6.final and 2.8.0.r18678-b20090910020815

The crash also occurs if each "(Mnn: M) ::" is simply "Mnn ::", but the difficulty in type checking is more obvious in that case.

Note the developer can easily avoid the crash by splitting "data" into separate lists.

abstract class M {}

object M00 extends M {}
object M01 extends M {}
object M02 extends M {}
object M03 extends M {}
object M04 extends M {}
object M05 extends M {}
object M06 extends M {}
object M07 extends M {}
object M08 extends M {}
object M09 extends M {}
object M10 extends M {}
object M11 extends M {}
object M12 extends M {}
object M13 extends M {}
object M14 extends M {}
object M15 extends M {}
object M16 extends M {}
object M17 extends M {}
object M18 extends M {}
object M19 extends M {}
object M20 extends M {}
object M21 extends M {}
object M22 extends M {}
object M23 extends M {}
object M24 extends M {}
object M25 extends M {}
object M26 extends M {}
object M27 extends M {}
object M28 extends M {}
object M29 extends M {}
object M30 extends M {}
object M31 extends M {}
object M32 extends M {}
object M33 extends M {}
object M34 extends M {}
object M35 extends M {}
object M36 extends M {}
object M37 extends M {}
object M38 extends M {}
object M39 extends M {}
object M40 extends M {}
object M41 extends M {}
object M42 extends M {}
object M43 extends M {}
object M44 extends M {}
object M45 extends M {}
object M46 extends M {}
object M47 extends M {}
object M48 extends M {}
object M49 extends M {}
object M50 extends M {}
object M51 extends M {}
object M52 extends M {}
object M53 extends M {}
object M54 extends M {}
object M55 extends M {}
object M56 extends M {}
object M57 extends M {}
object M58 extends M {}
object M59 extends M {}
object M60 extends M {}
object M61 extends M {}
object M62 extends M {}
object M63 extends M {}
object M64 extends M {}
object M65 extends M {}
object M66 extends M {}
object M67 extends M {}
object M68 extends M {}
object M69 extends M {}
object M70 extends M {}
object M71 extends M {}
object M72 extends M {}
object M73 extends M {}
object M74 extends M {}
object M75 extends M {}
object M76 extends M {}
object M77 extends M {}
object M78 extends M {}
object M79 extends M {}
object M80 extends M {}
object M81 extends M {}
object M82 extends M {}
object M83 extends M {}
object M84 extends M {}
object M85 extends M {}
object M86 extends M {}
object M87 extends M {}
object M88 extends M {}
object M89 extends M {}
object M90 extends M {}
object M91 extends M {}
object M92 extends M {}
object M93 extends M {}
object M94 extends M {}
object M95 extends M {}
object M96 extends M {}
object M97 extends M {}
object M98 extends M {}
object M99 extends M {}

object Client {
  val data: List[M] =
  (M00: M) ::
  (M01: M) ::
  (M02: M) ::
  (M03: M) ::
  (M04: M) ::
  (M05: M) ::
  (M06: M) ::
  (M07: M) ::
  (M08: M) ::
  (M09: M) ::
  (M10: M) ::
  (M11: M) ::
  (M12: M) ::
  (M13: M) ::
  (M14: M) ::
  (M15: M) ::
  (M16: M) ::
  (M17: M) ::
  (M18: M) ::
  (M19: M) ::
  (M20: M) ::
  (M21: M) ::
  (M22: M) ::
  (M23: M) ::
  (M24: M) ::
  (M25: M) ::
  (M26: M) ::
  (M27: M) ::
  (M28: M) ::
  (M29: M) ::
  (M30: M) ::
  (M31: M) ::
  (M32: M) ::
  (M33: M) ::
  (M34: M) ::
  (M35: M) ::
  (M36: M) ::
  (M37: M) ::
  (M38: M) ::
  (M39: M) ::
  (M40: M) ::
  (M41: M) ::
  (M42: M) ::
  (M43: M) ::
  (M44: M) ::
  (M45: M) ::
  (M46: M) ::
  (M47: M) ::
  (M48: M) ::
  (M49: M) ::
  (M50: M) ::
  (M51: M) ::
  (M52: M) ::
  (M53: M) ::
  (M54: M) ::
  (M55: M) ::
  (M56: M) ::
  (M57: M) ::
  (M58: M) ::
  (M59: M) ::
  (M60: M) ::
  (M61: M) ::
  (M62: M) ::
  (M63: M) ::
  (M64: M) ::
  (M65: M) ::
  (M66: M) ::
  (M67: M) ::
  (M68: M) ::
  (M69: M) ::
  (M70: M) ::
  (M71: M) ::
  (M72: M) ::
  (M73: M) ::
  (M74: M) ::
  (M75: M) ::
  (M76: M) ::
  (M77: M) ::
  (M78: M) ::
  (M79: M) ::
  (M80: M) ::
  (M81: M) ::
  (M82: M) ::
  (M83: M) ::
  (M84: M) ::
  (M85: M) ::
  (M86: M) ::
  (M87: M) ::
  (M88: M) ::
  (M89: M) ::
  (M90: M) ::
  (M91: M) ::
  (M92: M) ::
  (M93: M) ::
  (M94: M) ::
  (M95: M) ::
  (M96: M) ::
  (M97: M) ::
  (M98: M) ::
  (M99: M) ::
  Nil
}
scabug commented 15 years ago

Imported From: https://issues.scala-lang.org/browse/SI-2355?orig=1 Reporter: Eric Willigers (ewilligers)

scabug commented 15 years ago

@cunei said: Seems to work for me in 2.8.0.r18703. Please reopen if appropriate.

scabug commented 15 years ago

Eric Willigers (ewilligers) said: Perhaps it is Windows specific?

C:...>c:...\2.8.0.r18762-b20090924021911\files\bin\scalac Test.scala Exception in thread "main" java.lang.StackOverflowError at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3448)

scabug commented 15 years ago

@paulp said: It's not windows specific, it's all-your-local-factors specific, and if you're using java 6 all the memory limitations hit faster. It crashes on snow leopard's jvm6 with default scalac from trunk:

$$ JAVA_OPTS="" scalac28 a.scala 
Exception in thread "main" java.lang.StackOverflowError
    at scala.tools.nsc.ast.Trees$$Transformer.transform(Trees.scala:1411)
    at scala.tools.nsc.typechecker.RefChecks$$RefCheckTransformer.transform(RefChecks.scala:998)

I'm not sure it's a bug though (as opposed to an "implementation limitation") as that's how the typechecker works, you get a pile of stack for each element when it's doing this kind of typing. This is a duplicate of at least one other ticket. Workaround is to use more stack. I'm not closing this as I don't know what the official position is.

scabug commented 15 years ago

@cunei said: This issue is essentially a duplicate of #1667. A simple workaround is splitting the long expression into smaller ones; even for automatically generated source code that can be easily accomplished. Alternatively, just increase your stack size: the example provided compiles if you add "-Xss1M" to JAVA_OPTS.

Either way, this ticket can be seen more like a request for improvement rather than a bug: the concrete usability of the compiler is not impacted significantly by the fact that a single expression with 100 subexpressions requires a slightly larger stack to typecheck.

Closing it as a duplicate of #1667.