Search code examples
scalamigrationscala-3

After migrating to Scala 3, I get this warning: A pure expression does nothing in statement position


I have this piece of code that used to compile ok in Scala 2:

object TareaRima {
  private def guardaEnHistorico(det: JobDetail, exito: Boolean, texto: String, mime: String, tmp: Long): Unit = {
    // escribir histórico en la traza
    try {
      val txt =
        if (texto == null || texto.isEmpty) "_"
        else if (texto.length > 3000) texto.substring(0, 3000)
      val mimeVal =
        if (mime == null || mime.isEmpty) "?"
        else mime
      val isExito = if (exito) "S" else "N"
      val tmpVal = tmp.toString
      val formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss")
      val msj = det.getGroup + " -- " + det.getName + " -- " + formatter.format(
        new Date,
      ) + " -- " + isExito + " " + tmpVal + " -- " + txt + " -- " + mimeVal
      traza info msj
    } catch {
      case NonFatal(ex) =>
        traza.warn("Error al guardar a historico", ex)
    }
  }
  ...
}

When compiling for Scala 3, I get this warning:

A pure expression does nothing in statement position; you may be omitting necessary parentheses
        if (texto == null || texto.isEmpty) "_"

I've rechecked the code and I see it ok. I think it must'nt be a bug in Scala 3, as it is quite mature now. I've tried to use parentheses, but no luck:

      val txt = (
        if (texto == null || texto.isEmpty) "_"
        else if (texto.length > 3000) texto.substring(0, 3000)
      )

I've also tried to reindent everything around the warning.


Solution

  •       val txt = (
            if (texto == null || texto.isEmpty) "_"
            else if (texto.length > 3000) texto.substring(0, 3000)
          )
    

    There is no else texto, so if (texto.length > 3000) texto.substring(0, 3000) resolves to Unit. (Then txt becomes String | Unit and probably is upcasted to Any).

    Since, it's resolved to Unit, it is kinda like

    // this whole block is Unit
    if (cond) {
      statements
    }
    

    and in such case Scala checks that you actually don't have unused non-Unit values in that if which you might have accidentally ignored. IMHO you have.