-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix variance loophole for private vars
In Scala 2 a setter was created at Typer for private, non-local vars. Variance checking then worked on the setter. But in Scala 3, the setter is only created later, which caused a loophole for variance checking. This PR does actually better than Scala 2 in the following sense: A private variable counts as an invariant occurrence only if it is assigned with a selector different from `this`. Or conversely, a variable containing a covariant type parameter in its type can be read from different objects, but all assignments must be via this. The motivation is that such variables effectively behave like vals for the purposes of variance checking.
- Loading branch information
Showing
5 changed files
with
71 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
-- Error: tests/neg/i18588.scala:7:14 ---------------------------------------------------------------------------------- | ||
7 | private var cached: A = value // error | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| covariant type A occurs in invariant position in type A of variable cached |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
class ROBox[+A](value: A) { | ||
private var cached: A = value | ||
def get: A = ROBox[A](value).cached | ||
} | ||
|
||
class Box[+A](value: A) { | ||
private var cached: A = value // error | ||
def get: A = cached | ||
|
||
def put[AA >: A](value: AA): Unit = { | ||
val box: Box[AA] = this | ||
box.cached = value | ||
} | ||
} | ||
|
||
trait Animal | ||
object Dog extends Animal | ||
object Cat extends Animal | ||
|
||
val dogBox: Box[Dog.type] = new Box(Dog) | ||
val _ = dogBox.put(Cat) | ||
val dog: Dog.type = dogBox.get |