Closed
Description
Compiler version
Scala 3.2.2
Minimized code and Ouptut
class local(predicate: Int) extends annotation.StaticAnnotation
def failing1(x: Int, z: Int @local(x + x)) = ??? //error: undefined: x.+ # -1: TermRef(TermParamRef(x),+) at typer
Scastie which also contains the examples below:
https://scastie.scala-lang.org/jfNlEM8sR26DI2priR6mWQ
Expectation
Assuming following definitions in scope
class local(num: Int) extends annotation.StaticAnnotation
class local2(predicate: Boolean) extends annotation.StaticAnnotation
The above should compile since the reference to x is totally valid here, for example the following compiles:
def working2(x: Int, z: Int @local(x)) = ???
def working3(x: Int, z: Int & x.type ) = ???
You can see in particular that it is the selection that causes the problem, and not the reference to x
In dependent types, the selection doesn't cause the same problem:
def expectedlyFailing2(x: String, z: x.length.type) = ??? //error: Int is not a valid singleton type, since it is not an immutable path
Notice that the error mentions Int
explicitly, so it has to know x.length
is both a valid selection, and of type Int
I do not advocate for changing the following however:
def expectedlyFailing1(x: Int @local(x == x)) = ??? //error: Cyclic reference involving val x
Finally, here is another failing example, even though the selection in question is ==
which is defined on (pretty much?) every Scala type:
def failing2(x: Int, z: Int @local2(x == x)) = ??? //error: undefined: x.== # -1: TermRef(TermParamRef(x),==) at typer