Skip to content

Commit e6c474d

Browse files
committed
Add addendum to private val parameter variance error message
1 parent 48bc891 commit e6c474d

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,20 @@ class VarianceChecker(using Context) {
178178
i"\n${hl("enum case")} ${towner.name} requires explicit declaration of $tvar to resolve this issue.\n$example"
179179
else
180180
""
181-
em"${varianceLabel(tvar.flags)} $tvar occurs in ${varianceLabel(required)} position in type ${sym.info} of $sym$enumAddendum"
181+
val privateParamAddendum =
182+
if sym.flags.is(ParamAccessor) && sym.flags.is(Private) then
183+
val varOrVal = if sym.is(Mutable) then "var" else "val"
184+
val varFieldInstead = if sym.is(Mutable) then " and add\na field inside the class instead" else ""
185+
s"""
186+
|
187+
|Implementation limitation: ${hl(f"private $varOrVal")} parameters cannot be inferred to be local
188+
|and therefore are always variance-checked.
189+
|
190+
|Potential fix: remove the ${hl(f"private $varOrVal")} modifiers on the parameter ${sym.name}$varFieldInstead.
191+
""".stripMargin
192+
else
193+
""
194+
em"${varianceLabel(tvar.flags)} $tvar occurs in ${varianceLabel(required)} position in type ${sym.info} of $sym$enumAddendum$privateParamAddendum"
182195
if (migrateTo3 &&
183196
(sym.owner.isConstructor || sym.ownersIterator.exists(_.isAllOf(ProtectedLocal))))
184197
report.migrationWarning(

tests/neg/i22620.check

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-- Error: tests/neg/i22620.scala:4:34 ----------------------------------------------------------------------------------
2+
4 |class PrivateTest[-M](private val v: ArrayBuffer[M]) // error
3+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
| contravariant type M occurs in invariant position in type scala.collection.mutable.ArrayBuffer[M] of value v
5+
|
6+
| Implementation limitation: private val parameters cannot be inferred to be local
7+
| and therefore are always variance-checked.
8+
|
9+
| Potential fix: remove the private val modifiers on the parameter v.
10+
|
11+
-- Error: tests/neg/i22620.scala:6:37 ----------------------------------------------------------------------------------
12+
6 |class PrivateTestMut[-M](private var v: ArrayBuffer[M]) // error
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
| contravariant type M occurs in invariant position in type scala.collection.mutable.ArrayBuffer[M] of variable v
15+
|
16+
| Implementation limitation: private var parameters cannot be inferred to be local
17+
| and therefore are always variance-checked.
18+
|
19+
| Potential fix: remove the private var modifiers on the parameter v and add
20+
| a field inside the class instead.
21+
|

tests/neg/i22620.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@
22
import scala.collection.mutable.ArrayBuffer
33

44
class PrivateTest[-M](private val v: ArrayBuffer[M]) // error
5+
6+
class PrivateTestMut[-M](private var v: ArrayBuffer[M]) // error
7+
8+
class PrivateTestParamOnly[-M](v: ArrayBuffer[M]) // no error

0 commit comments

Comments
 (0)