Open catap opened 2 years ago
This looks like "leading infix" syntax, where the leading operator is in backticks.
Putting myop
in backticks is special in Scala 3 because members are deemed "eligible for infix" syntax.
The syntax is supported in Scala 2.13 with -Xsource:3
but the behavior may diverge a bit.
The advice in the message is to make it not look like infix. (Add ;
or remove a space, etc.)
I wonder if it could emit a better message when the operator name also designates a definition in scope, as in this example. Alternatively, change the feature so that it is actually ambiguous if there is both a member myop
and a definition in scope; or, less likely, actually pick the intended meaning and use the definition in a new statement, but then leading infix is not just syntax.
@som-snytt anyway, I do not understand why is using one such variable works fine.
I was going to make a clever example, but I was done in by unary ops:
scala> {
| val + = 42
| 1 + 2
| + + 1
| }
val +: Int = 42
val res0: Int = 4
where I intended
scala> {
| val + = 42
| 1 + 2
| +.+(1)
| }
val +: Int = 42
val res6: Int = 3
val res7: Int = 43
I tried it out with the scalatest dependency -- I still have to create an sbt project instead of using ammonite or other quickie tools -- and I wanted to register that I was also confused by the first error, about postfix.
I tried it out with scala 2 -Xsource;3
with similar results.
Parser says
[info] "can\'t compile" in
[info] {
[info] val n1 = 42
[info] val n2 = 44
[info] `n1` shouldBe `n1` `n2` shouldBe `n2`
[info] }
so infix line continuation says only "join the lines".
Sorry I didn't have a quick answer.
can't compile
inspired the notion can't complain
where the compiler is really a complainer, so thanks for that inspiration.
@som-snytt anyway, workaround is simple: just rename variable to something without ` :)
or for improved funkiness
`n2`shouldBe `n2`
-Xsource:3
says value n2 is not a member of org.scalatest.Assertion
, not found: value shouldBe
, postfix operator n2 needs to be enabled
, meaning the second n2
is postfix.
@som-snytt In order to do some quick test, you may want to use scala-cli Having it in version 0.0.9, you just create file:
// using scala "3.1.2-RC1-bin-20220106-0b4c6e7-NIGHTLY"
// using lib "org.scalatest::scalatest:3.2.10"
import org.scalatest._
import org.scalatest.matchers._
class BugTest extends wordspec.AnyWordSpec with should.Matchers {
"can't compile" in {
val `n1` = 42
val `n2` = 44
`n1` shouldBe `n1`
`n2` shouldBe `n2`
}
"can compile 1" in {
val `n1` = 42
`n1` shouldBe `n1`
}
"can compile 2" in {
val n1 = 42
val n2 = 44
n1 shouldBe n1
n2 shouldBe n2
}
}
and run scala-cli test <filename>
@pikinier20 thanks! Sorry to bump the thread just for "thanks!", but that is an especially good feature. I've meant to try scala-cli
since I learned about it.
The message is slightly less provoking in 3.4.2 or at least more direct:
[error] 11 | `n2` shouldBe `n2`
[error] | ^^
[error] | end of statement expected but identifier found
My previous comment did not go far enough. I propose the progressive elimination of all space in favor of backticks, a style I call spaceticks
:
`n1` shouldBe `n1`
`n2` shouldBe `n2`
`n1`shouldBe`n1`
`n2`shouldBe`n2`
n1`shouldBe`n1
n2`shouldBe`n2
Compiler version
This test reproduces with
scalatest-3.2.10
.Compilers and results:
2.11.12
2.12.15
2.13.7
3.0.0
3.0.1
3.0.2
3.1.0
3.1.1-RC2
Minimized code
Output
Suggested by compiler approach with adding
postfixOps
leads to this:Expectation
Should work on all tested compilers.