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

Regression: cannot pattern match on type T[_] when T's type parameter has bounds

    Details

      Description

      Upon entering this code into the REPL:

      trait TA[X <: CharSequence]
      val ta: TA[_] = new TA[String] {}
      
      ta match {
      case _ => "hi"
      }
      

      I get this error:

      error: type arguments [_$1] do not conform to trait TA's type parameter bounds [X <: CharSequence]
                    ta match {
                    ^
      

      The code compiles on Scala 2.9.2, but fails on at least 2.10.0 and 2.10.2. Thus it appears to be a regression.

        Issue Links

          Activity

          Hide
          Paul Phillips added a comment -

          Some workarounds:

          • compile with -Xoldpatmat
          • val ta: TA[_ <: CharSequence] = new TA[String] {}
          • val ta = new TA[String] {}

          In some similar scenarios this already works again in 2.11, e.g.

          def f(ta: TA[_]) = ta match

          { case _ => "hi" }

          But the val example isn't compiling even now.

          Show
          Paul Phillips added a comment - Some workarounds: compile with -Xoldpatmat val ta: TA [_ <: CharSequence] = new TA [String] {} val ta = new TA [String] {} In some similar scenarios this already works again in 2.11, e.g. def f(ta: TA [_] ) = ta match { case _ => "hi" } But the val example isn't compiling even now.
          Hide
          Alex Hvostov added a comment -

          Sorry about the overstated priority, by the way. JIRA wasn't letting me adjust it from "blocker" for some reason.

          Show
          Alex Hvostov added a comment - Sorry about the overstated priority, by the way. JIRA wasn't letting me adjust it from "blocker" for some reason.
          Hide
          Jason Zaugg added a comment -

          Another example from the mailing list:

          scala> val e: java.lang.Enum[_] = java.util.concurrent.TimeUnit.SECONDS
          
          scala> e match { case _ => 0 }
          <console>:9: error: type arguments [_$1] do not conform to class Enum's type parameter bounds [E <: Enum[E]]
                        e match { case _ => 0 }
                        ^
          [[syntax trees at end of                 refchecks]] // <console>
          package $line4 {
            object $read extends scala.AnyRef {
              def <init>(): $line4.$read.type = {
                $read.super.<init>();
                ()
              };
              object $iw extends scala.AnyRef {
                def <init>(): type = {
                  $iw.super.<init>();
                  ()
                };
                object $iw extends scala.AnyRef {
                  def <init>(): type = {
                    $iw.super.<init>();
                    ()
                  };
                  private[this] val res0: Int = {
                    case <synthetic> val x1: Enum[_$1] = $line3.$read.$iw.$iw.e;
                    case4(){
                      matchEnd3(0)
                    };
                    matchEnd3(x: Int){
                      x
                    }
                  };
                  <stable> <accessor> def res0: Int = $iw.this.res0
                }
              }
            }
          }
          

          This is somewhat related to SI-7694; the pattern matcher translation now happens before refchecks, and the TypeTree in the tpt of the synthetic temporary `x1` is subject to bounds checking.

          Show
          Jason Zaugg added a comment - Another example from the mailing list: scala> val e: java.lang.Enum[_] = java.util.concurrent.TimeUnit.SECONDS scala> e match { case _ => 0 } <console>:9: error: type arguments [_$1] do not conform to class Enum's type parameter bounds [E <: Enum[E]] e match { case _ => 0 } ^ [[syntax trees at end of refchecks]] // <console> package $line4 { object $read extends scala.AnyRef { def <init>(): $line4.$read.type = { $read.super.<init>(); () }; object $iw extends scala.AnyRef { def <init>(): type = { $iw.super.<init>(); () }; object $iw extends scala.AnyRef { def <init>(): type = { $iw.super.<init>(); () }; private[this] val res0: Int = { case <synthetic> val x1: Enum[_$1] = $line3.$read.$iw.$iw.e; case4(){ matchEnd3(0) }; matchEnd3(x: Int){ x } }; <stable> <accessor> def res0: Int = $iw.this.res0 } } } } This is somewhat related to SI-7694 ; the pattern matcher translation now happens before refchecks, and the TypeTree in the tpt of the synthetic temporary `x1` is subject to bounds checking.
          Show
          Jason Zaugg added a comment - https://github.com/scala/scala/pull/2838

            People

            • Assignee:
              Jason Zaugg
              Reporter:
              Alex Hvostov
            • Votes:
              1 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development