Closed symingz closed 4 months ago
Hey, so this is actually the intended behaviour, we do not allow to override vars.
There used to be a flag for allowing this in Scala 2 (-Yoverride-vars
), but not in Scala 3.
What we maybe could consider is adjusting the spec, since we actually don't mention it there, I think. (cc @sjrd) https://www.scala-lang.org/files/archive/spec/3.4/05-classes-and-objects.html#overriding
Either way, closing this.
I see. In this case should File 1
(without the override
modifier) be rejected by the compiler as well? Right now the compiler accepts it.
overriding is not the same thing as implementing, overriding changes signature, implementing is fine because the types stay the same
I find this confusing. For val
and def
, one can simply add the override
modifier without thinking about if it is implement
or override
. But then var
requires such fine distinction. Furthermore, I have read in multiple places (such as Programming in Scala, 5th Ed) that var
is equivalent to two methods (one getter and one setter). From this one would reasonably assume that var
can be overridden, but apparently that's not the case. These all seem unnecessary complications. I would rather the language simply ban abstract var
, and specify that all var
are implicitly final
.
you actually can not override a function to have a more precise argument, meaning you can not override a setter, so it makes no sense to override a var, which would override the setter:
scala> trait Foo:
| def setFoo(newFoo: Any): Unit
| trait Bar extends Foo:
| override def setFoo(newFoo: String): Unit
|
-- [E038] Declaration Error: ---------------------------------------------------
4 | override def setFoo(newFoo: String): Unit
| ^
| method setFoo has a different signature than the overridden declaration
|
| longer explanation available when compiling with `-explain`
1 error found
I don't think that applies to my examples, in
trait C:
var x: Int
class D extends C:
override var x: Int = 10
The type for x
is always Int
.
I am no longer convinced that this is the expected behavior. There are two open issues (#18692, #13019) raising similar questions, and in neither of them was there consensus that this is the expected behavior. If anything, the consensus is that this is an issue that needs to be fixed.
ok, comparing to scala 2 behavior it would seem attempt the override as long as the type does not change:
scala> trait Foo {
| var x: Any}
trait Foo
scala> class Bar extends Foo {
| override var x: Any = 23
| }
class Bar
scala> class Bar extends Foo {
| override var x = 23
| }
^
error: class Bar needs to be abstract.
Missing implementation for member of trait Foo:
def x_=(x$1: Any): Unit = ??? // an abstract var requires a setter in addition to the getter
override var x = 23
^
On line 2: error: variable x overrides nothing.
Note: the super classes of class Bar contain the following, non final members named x_$eq:
def x_=(x$1: Any): Unit
saying this is duplicicate of #18692 because the error message is the same
Compiler version
3.4.2
Minimized code
File1:
File2:
Output
File1
compiles,File2
fails withExpectation
Both
File1
andFile2
should compile.