Search code examples
scalapattern-matchingtype-erasureparser-combinators

How to I get rid of "unchecked due to erasure" warning when pattern matching


Scala 2.8.1

I have implemented a very simple external DSL using parser/combinators for QA to write acceptance tests.

Recently I added the ability to loop over a set of expressions like so

sealed trait Expr

...
//insert other case classes extending 'Expr' here
...

case class Repetition(times: Int, expressions: List[Expr]) extends Expr

class TestFixtureParser(....) extends RegexParsers {
  val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
    case (times: Int) ~ (exprs: List[Expr]) => {
      Repetition(times, exprs)
    }
  }

  private val expressions: Parser[List[Expr]] = (repeatParser | 
    /*insert other Parser[Expr]s '|' together here */ | verifyParser ).*

}

When building, I receive the warning warning: non variable type-argument ... is unchecked since it is eliminated by erasure when pattern matching. I have tried extracting using the following as well.

  //Doesn't build with error
  /*
    error: missing parameter type for expanded function ((x0$2) => x0$2 match {
      case $tilde((times @ _), (exprs @ _)) => Repetition(times, exprs)
    })
        r: ~[Int, List[Expr]] => {
  */
  val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
    r: ~[Int, List[Expr]] => {
      case times ~ exprs =>
        Repetition(times, exprs)
    }
  }

  //Actually this does build without warning. 
  //I am unfortunately using intelliJ and it doesn't like it
  val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
    repetitions: ~[Int, List[Expr]] => {
      val ~(times, exprs) = repetitions
      Repetition(times, exprs)
    }
  }

  //Builds but same warning
  val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
    repetitions => {
      val ~(times: Int, exprs: List[Expr]) = repetitions
      Repetition(times, exprs)
    }
  }

Does anyone have any suggestions for extracting exprs in an elegant way without this warning? It does function as is. Should I just ignore it? I would hate to get into the habit of ignoring warnings.

Edit: Answer. This was actually what I tried first but then I added the types because the intelliJ scala plugin couldn't infer them.

  val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
      case times ~ exprs =>
          Repetition(times, exprs)
  }

Solution

  • I think your syntax is not right for the first "doesn't build" example (it looks like you're returning a partial function rather than applying it, which isn't what you want). Try writing:

    val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
        case times ~ exprs =>
            Repetition(times, exprs)
    }
    

    I'm afraid I can't test this because I don't have the rest of your code it depends on, but this kind of construct usually works.