Skip to content

Commit a8d07c6

Browse files
committed
fix scala#9260: copy variance in derived type parameters
1 parent e1f89fb commit a8d07c6

File tree

2 files changed

+11
-4
lines changed

2 files changed

+11
-4
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,9 @@ object desugar {
136136
)
137137

138138
/** A derived type definition watching `sym` */
139-
def derivedTypeParam(sym: TypeSymbol)(using Context): TypeDef =
140-
TypeDef(sym.name, DerivedFromParamTree().watching(sym)).withFlags(TypeParam)
139+
def derivedTypeParamWithVariance(sym: TypeSymbol)(using Context): TypeDef =
140+
val variance = (Covariant | Contravariant) & sym.flags
141+
TypeDef(sym.name, DerivedFromParamTree().watching(sym)).withFlags(TypeParam | variance)
141142

142143
/** A value definition copied from `vdef` with a tpt typetree derived from it */
143144
def derivedTermParam(vdef: ValDef)(using Context): ValDef =
@@ -406,7 +407,7 @@ object desugar {
406407

407408
val originalTparams = constr1.tparams
408409
val originalVparamss = constr1.vparamss
409-
lazy val derivedEnumParams = enumClass.typeParams.map(derivedTypeParam)
410+
lazy val derivedEnumParams = enumClass.typeParams.map(derivedTypeParamWithVariance)
410411
val impliedTparams =
411412
if (isEnumCase) {
412413
val tparamReferenced = typeParamIsReferenced(

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,13 @@ class VarianceChecker(using Context) {
166166
private object Traverser extends TreeTraverser {
167167
def checkVariance(sym: Symbol, pos: SrcPos) = Validator.validateDefinition(sym) match {
168168
case Some(VarianceError(tvar, required)) =>
169-
def msg = i"${varianceLabel(tvar.flags)} $tvar occurs in ${varianceLabel(required)} position in type ${sym.info} of $sym"
169+
def msg =
170+
val enumAddendum =
171+
if sym.owner.isAllOf(EnumCase) && sym.owner.isClass then
172+
i"\nenum case ${sym.owner} may require explicit type parameters to resolve this issue"
173+
else
174+
""
175+
i"${varianceLabel(tvar.flags)} $tvar occurs in ${varianceLabel(required)} position in type ${sym.info} of $sym$enumAddendum"
170176
if (migrateTo3 &&
171177
(sym.owner.isConstructor || sym.ownersIterator.exists(_.isAllOf(ProtectedLocal))))
172178
report.migrationWarning(

0 commit comments

Comments
 (0)