Skip to content

space following unary minus produces misleading 'then expected' error message #13410

Closed
@philwalk

Description

@philwalk

Compiler version

version:=3.0.2-RC2
revision:=b8b980d1d38367fbeb153381d7c0e243db52fcc4
buildTime:=2021-08-23 22:33:43+0200

Minimized example

1 object UnaryMinus {
2   def sign(x: Int): Int = {
3     if (x > 0) 1
4     else if (x < 0) - 1
5     else 0
6   }
7 }

Output

$ scalac3 jsrc/unaryMinus.sc
-- [E040] Syntax Error: jsrc\unaryMinus.sc:5:4 ---------------------------------------------------------------------------------------------------------------------------------------------------------
5 |    else 0
  |    ^^^^
  |    'then' expected, but 'else' found
-- [E008] Not Found Error: jsrc\unaryMinus.sc:4:20 -----------------------------------------------------------------------------------------------------------------------------------------------------
4 |    else if (x < 0) - 1
  |            ^^^^^^^^^
  |            value - is not a member of Boolean, but could be made available as an extension method.
  |
  |            One of the following imports might make progress towards fixing the problem:
  |
  |              import math.Fractional.Implicits.infixFractionalOps
  |              import math.Integral.Implicits.infixIntegralOps
  |              import math.Numeric.Implicits.infixNumericOps
  |
-- [E129] Potential Issue Warning: jsrc\unaryMinus.sc:4:23 ---------------------------------------------------------------------------------------------------------------------------------------------
4 |    else if (x < 0) - 1
  |                       ^
  |                       A pure expression does nothing in statement position; you may be omitting necessary parentheses

longer explanation available when compiling with `-explain`
1 warning found
2 errors found

Expectation

The scala2 compiler compiles without error, and recognizes the expression - 1 as negative one.
The scala3 compiler seems to interpret the minus sign as Boolean operator?, resulting in an invalid boolean expression.

Perhaps the "optional braces" feature mandates that unary minus tokenization rules must be tightened relative to scala2. If so, it might be worth some effort to improve the error message here.

This particular example is based on code generated automatically by Intellij when converting a java ternary operator to scala. I'm not sure why it inserted a space after the minus sign, but it's valid scala2. There might be a fair amount of scala2 code out there that will lead to this compile error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions