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 {
137
137
138
138
/** A derived type definition watching `sym` */
139
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)
140
+ val variance = VarianceFlags & sym.flags
141
+ TypeDef (sym.name, DerivedFromParamTree ().watching(sym)).withFlags(TypeParam | Synthetic | variance)
142
142
143
143
/** A value definition copied from `vdef` with a tpt typetree derived from it */
144
144
def derivedTermParam (vdef : ValDef )(using Context ): ValDef =
Original file line number Diff line number Diff line change @@ -12,6 +12,7 @@ import util.SrcPos
12
12
import config .Printers .variances
13
13
import config .Feature .migrateTo3
14
14
import reporting .trace
15
+ import printing .Formatting .hl
15
16
16
17
/** Provides `check` method to check that all top-level definitions
17
18
* in tree are variance correct. Does not recurse inside methods.
@@ -169,13 +170,10 @@ class VarianceChecker(using Context) {
169
170
def msg =
170
171
val enumAddendum =
171
172
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
176
174
val example =
177
175
" 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"
179
177
else
180
178
" "
181
179
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:
97
97
2 | case Refl (f : T => T )
98
98
| ^^^^^^^^^
99
99
| 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.
101
101
```
102
102
Because ` Refl ` does not declare explicit parameters, it looks to the compiler like the following:
103
103
``` scala
@@ -106,14 +106,16 @@ enum View[-T]:
106
106
```
107
107
108
108
The 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 ` ,
110
110
and can remedy the error by the following change to ` Refl ` :
111
111
112
112
``` diff
113
113
enum View[-T]:
114
114
- 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 ]
116
116
```
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.
117
119
118
120
Enumerations and ADTs have been presented as two different
119
121
concepts. But since they share the same syntactic construct, they can
Original file line number Diff line number Diff line change 1
1
-- 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
3
3
| ^^^^^^^^^
4
4
| 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.
6
6
| See an example at http://dotty.epfl.ch/docs/reference/enums/adts.html#parameter-variance-of-enums
7
7
-- Error: tests/neg-custom-args/fatal-warnings/enum-variance.scala:5:16 ------------------------------------------------
8
8
5 | 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 1
1
enum 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
3
3
4
4
enum ExplicitView [- T ]: // desugared version of View
5
5
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