Scala Programming Language
  1. Scala Programming Language
  2. SI-7100

Compiler crash with pattern match computing a result that is a specialized type parameter

    Details

      Description

      class Buffer {
        def f[@specialized(Int) T](): T = 0 match {
          case 0 => 0.asInstanceOf[T]
          case 1 => 0.asInstanceOf[T]
        }
      }
      

      causes stack overflow in 2.10.0

      uncaught exception during compilation: java.lang.StackOverflowError
      java.lang.StackOverflowError
      	at scala.collection.mutable.FlatHashTable$HashUtils$class.elemHashCode(FlatHashTable.scala:391)
      	at scala.collection.mutable.HashSet.elemHashCode(HashSet.scala:41)
      	at scala.collection.mutable.FlatHashTable$class.addEntry(FlatHashTable.scala:137)
      	at scala.collection.mutable.HashSet.addEntry(HashSet.scala:41)
      	at scala.collection.mutable.HashSet.$plus$eq(HashSet.scala:60)
      	at scala.tools.nsc.typechecker.Infer$Inferencer.checkAccessible(Infer.scala:311)
      	at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$makeAccessible(Typers.scala:598)
      	at scala.tools.nsc.typechecker.Typers$Typer.typedIdent$1(Typers.scala:5031)
      	at scala.tools.nsc.typechecker.Typers$Typer.typedIdentOrWildcard$1(Typers.scala:5048)
      	at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5379)
      	at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5458)
      	at scala.tools.nsc.typechecker.Duplicators$BodyDuplicator.typed(Duplicators.scala:386)
      	at scala.tools.nsc.typechecker.Duplicators$BodyDuplicator.typed(Duplicators.scala:352)
      	at scala.tools.nsc.typechecker.Typers$Typer.typedPos(Typers.scala:5513)
      	at scala.tools.nsc.typechecker.Duplicators$BodyDuplicator.typed(Duplicators.scala:373)
      	at scala.tools.nsc.typechecker.Typers$Typer.typedPos(Typers.scala:5513)
      	at scala.tools.nsc.typechecker.Duplicators$BodyDuplicator.typed(Duplicators.scala:373)
      	at scala.tools.nsc.typechecker.Typers$Typer.typedPos(Typers.scala:5513)
      

      Workaround:
      Replacing the pattern matching with equivalent if/else statements will allow it to compile.

        Activity

        Hide
        James Iry added a comment -

        Regression. Doesn't crash under 2.9.2 or the current 2.9.x branch (soon to be 2.9.3-RC1)

        Show
        James Iry added a comment - Regression. Doesn't crash under 2.9.2 or the current 2.9.x branch (soon to be 2.9.3-RC1)
        Hide
        Jeff Olson added a comment - - edited

        This is the original code that triggered the bug (just in case the above minimization isn't entirely equivalent):

        abstract class Buffer {
          def getByte(): Byte 
          def getShort(): Short
          def getInt(): Int  
          def getLong(): Long 
        
          def getEncoded[@specialized(Byte, Short, Int, Long) T](): T = {
            val id = getByte()
            id match {
              case 0 => getByte().asInstanceOf[T]
              case 1 => getShort().asInstanceOf[T]
              case 2 => getInt().asInstanceOf[T]
              case 3 => getLong().asInstanceOf[T]
            }
          }
        }
        
        Show
        Jeff Olson added a comment - - edited This is the original code that triggered the bug (just in case the above minimization isn't entirely equivalent): abstract class Buffer { def getByte(): Byte def getShort(): Short def getInt(): Int def getLong(): Long def getEncoded[@specialized(Byte, Short, Int, Long) T](): T = { val id = getByte() id match { case 0 => getByte().asInstanceOf[T] case 1 => getShort().asInstanceOf[T] case 2 => getInt().asInstanceOf[T] case 3 => getLong().asInstanceOf[T] } } }
        Hide
        James Iry added a comment -

        Replacing with if/else allows it to compile

        class Buffer {
          def f[@specialized(Int) T](): T = 
            if (0 == 0) 0.asInstanceOf[T] 
            else if (1 == 0) 0.asInstanceOf[T] 
            else ???
        }
        
        Show
        James Iry added a comment - Replacing with if/else allows it to compile class Buffer { def f[@specialized(Int) T](): T = if (0 == 0) 0.asInstanceOf[T] else if (1 == 0) 0.asInstanceOf[T] else ??? }
        Hide
        James Iry added a comment -

        Under -Xoldpatmat it's still broken

        Show
        James Iry added a comment - Under -Xoldpatmat it's still broken
        Hide
        James Iry added a comment -

        Not casting related per se, this also doesn't work whereas just returning x without pattern matching is fine.

        class Buffer {
          def f[@specialized(Int) T](): T = {
            var x: T = 0.asInstanceOf[T]
            0 match {
              case 0 => x
              case 1 => x
            } 
          }
        }
        
        Show
        James Iry added a comment - Not casting related per se, this also doesn't work whereas just returning x without pattern matching is fine. class Buffer { def f[@specialized(Int) T](): T = { var x: T = 0.asInstanceOf[T] 0 match { case 0 => x case 1 => x } } }
        Show
        Vlad Ureche added a comment - https://github.com/scala/scala/pull/2089

          People

          • Assignee:
            Vlad Ureche
            Reporter:
            James Iry
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development