diff --git a/compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala b/compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala index 0c2929283ee3..354f09382d82 100644 --- a/compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala +++ b/compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala @@ -178,7 +178,20 @@ class VarianceChecker(using Context) { i"\n${hl("enum case")} ${towner.name} requires explicit declaration of $tvar to resolve this issue.\n$example" else "" - em"${varianceLabel(tvar.flags)} $tvar occurs in ${varianceLabel(required)} position in type ${sym.info} of $sym$enumAddendum" + val privateParamAddendum = + if sym.flags.is(ParamAccessor) && sym.flags.is(Private) then + val varOrVal = if sym.is(Mutable) then "var" else "val" + val varFieldInstead = if sym.is(Mutable) then " and add\na field inside the class instead" else "" + s""" + | + |Implementation limitation: ${hl(f"private $varOrVal")} parameters cannot be inferred to be local + |and therefore are always variance-checked. + | + |Potential fix: remove the ${hl(f"private $varOrVal")} modifiers on the parameter ${sym.name}$varFieldInstead. + """.stripMargin + else + "" + em"${varianceLabel(tvar.flags)} $tvar occurs in ${varianceLabel(required)} position in type ${sym.info} of $sym$enumAddendum$privateParamAddendum" if (migrateTo3 && (sym.owner.isConstructor || sym.ownersIterator.exists(_.isAllOf(ProtectedLocal)))) report.migrationWarning( diff --git a/tests/neg/i22620.check b/tests/neg/i22620.check new file mode 100644 index 000000000000..51a79d7cabce --- /dev/null +++ b/tests/neg/i22620.check @@ -0,0 +1,21 @@ +-- Error: tests/neg/i22620.scala:4:34 ---------------------------------------------------------------------------------- +4 |class PrivateTest[-M](private val v: ArrayBuffer[M]) // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | contravariant type M occurs in invariant position in type scala.collection.mutable.ArrayBuffer[M] of value v + | + | Implementation limitation: private val parameters cannot be inferred to be local + | and therefore are always variance-checked. + | + | Potential fix: remove the private val modifiers on the parameter v. + | +-- Error: tests/neg/i22620.scala:6:37 ---------------------------------------------------------------------------------- +6 |class PrivateTestMut[-M](private var v: ArrayBuffer[M]) // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | contravariant type M occurs in invariant position in type scala.collection.mutable.ArrayBuffer[M] of variable v + | + | Implementation limitation: private var parameters cannot be inferred to be local + | and therefore are always variance-checked. + | + | Potential fix: remove the private var modifiers on the parameter v and add + | a field inside the class instead. + | diff --git a/tests/neg/i22620.scala b/tests/neg/i22620.scala index 97d1d55e3302..0f06d97f73e0 100644 --- a/tests/neg/i22620.scala +++ b/tests/neg/i22620.scala @@ -2,3 +2,7 @@ import scala.collection.mutable.ArrayBuffer class PrivateTest[-M](private val v: ArrayBuffer[M]) // error + +class PrivateTestMut[-M](private var v: ArrayBuffer[M]) // error + +class PrivateTestParamOnly[-M](v: ArrayBuffer[M]) // no error