File tree Expand file tree Collapse file tree 5 files changed +13
-13
lines changed
compiler/src/dotty/tools/dotc
docs/docs/reference/enums
tests/neg-custom-args/fatal-warnings Expand file tree Collapse file tree 5 files changed +13
-13
lines changed Original file line number Diff line number Diff line change @@ -137,8 +137,8 @@ object desugar {
137137
138138 /** A derived type definition watching `sym` */
139139 def derivedTypeParamWithVariance (sym : TypeSymbol )(using Context ): TypeDef =
140- val variance = ( Covariant | Contravariant ) & sym.flags
141- TypeDef (sym.name, DerivedFromParamTree ().watching(sym)).withFlags(TypeParam | variance)
140+ val variance = VarianceFlags & sym.flags
141+ TypeDef (sym.name, DerivedFromParamTree ().watching(sym)).withFlags(TypeParam | Synthetic | variance)
142142
143143 /** A value definition copied from `vdef` with a tpt typetree derived from it */
144144 def derivedTermParam (vdef : ValDef )(using Context ): ValDef =
Original file line number Diff line number Diff line change @@ -12,6 +12,7 @@ import util.SrcPos
1212import config .Printers .variances
1313import config .Feature .migrateTo3
1414import reporting .trace
15+ import printing .Formatting .hl
1516
1617/** Provides `check` method to check that all top-level definitions
1718 * in tree are variance correct. Does not recurse inside methods.
@@ -169,13 +170,10 @@ class VarianceChecker(using Context) {
169170 def msg =
170171 val enumAddendum =
171172 val towner = tvar.owner
172- if towner.isAllOf(EnumCase ) && towner.isClass
173- && tvar.span.exists && towner.span.exists
174- && tvar.span.start < towner.span.start // implies that `tvar` was not user declared
175- then
173+ if towner.isAllOf(EnumCase ) && towner.isClass && tvar.is(Synthetic ) then
176174 val example =
177175 " See an example at http://dotty.epfl.ch/docs/reference/enums/adts.html#parameter-variance-of-enums"
178- i " \n enum case ${towner} requires explicit declaration of $tvar to resolve this issue. \n $example"
176+ i " \n ${hl( " enum case" )} ${towner.name } requires explicit declaration of $tvar to resolve this issue. \n $example"
179177 else
180178 " "
181179 i " ${varianceLabel(tvar.flags)} $tvar occurs in ${varianceLabel(required)} position in type ${sym.info} of $sym$enumAddendum"
Original file line number Diff line number Diff line change @@ -97,7 +97,7 @@ function type, leading to the following error:
97972 | case Refl (f : T => T )
9898 | ^^^^^^^^^
9999 | contravariant type T occurs in covariant position in type T => T of value f
100- | enum case class Refl requires explicit declaration of type T to resolve this issue.
100+ | enum case Refl requires explicit declaration of type T to resolve this issue.
101101```
102102Because ` Refl ` does not declare explicit parameters, it looks to the compiler like the following:
103103``` scala
@@ -106,14 +106,16 @@ enum View[-T]:
106106```
107107
108108The compiler has inferred for ` Refl ` the contravariant type parameter ` T1 ` , following ` T ` in ` View ` .
109- We can now clearly see that ` Refl ` needs to declare its own type parameters to satisfy the variance condition ,
109+ We can now clearly see that ` Refl ` needs to declare its own non-variant type parameter to correctly type ` f ` ,
110110and can remedy the error by the following change to ` Refl ` :
111111
112112``` diff
113113enum View[-T]:
114114- case Refl(f: T => T)
115- + case Refl[T ](f: T => T ) extends View[T ]
115+ + case Refl[U ](f: U => U ) extends View[U ]
116116```
117+ Above, type ` U ` is chosen as the parameter for ` Refl ` to highlight that it has a different meaning to
118+ type ` T ` in ` View ` , but any name will do.
117119
118120Enumerations and ADTs have been presented as two different
119121concepts. But since they share the same syntactic construct, they can
Original file line number Diff line number Diff line change 11-- Error: tests/neg-custom-args/fatal-warnings/enum-variance.scala:2:12 ------------------------------------------------
2- 2 | case Refl(f: T => T) // error: enum case class Refl requires explicit declaration of type T
2+ 2 | case Refl(f: T => T) // error: enum case Refl requires explicit declaration of type T
33 | ^^^^^^^^^
44 | contravariant type T occurs in covariant position in type T => T of value f
5- | enum case class Refl requires explicit declaration of type T to resolve this issue.
5+ | enum case Refl requires explicit declaration of type T to resolve this issue.
66 | See an example at http://dotty.epfl.ch/docs/reference/enums/adts.html#parameter-variance-of-enums
77-- Error: tests/neg-custom-args/fatal-warnings/enum-variance.scala:5:16 ------------------------------------------------
885 | case Refl[-T](f: T => T) extends ExplicitView[T] // error: contravariant type T occurs in covariant position
Original file line number Diff line number Diff line change 11enum View [- T ]:
2- case Refl (f : T => T ) // error: enum case class Refl requires explicit declaration of type T
2+ case Refl (f : T => T ) // error: enum case Refl requires explicit declaration of type T
33
44enum ExplicitView [- T ]: // desugared version of View
55 case Refl [- T ](f : T => T ) extends ExplicitView [T ] // error: contravariant type T occurs in covariant position
You can’t perform that action at this time.
0 commit comments