Skip to content

Commit 4295d3c

Browse files
committed
Support variance annotations in -Ykind-projector mode
This change expands the supported subset of `kind-projector` syntax, specifically: * `+*` and `-*` variance annotated variants of `*` placeholder * Variance annotated named parameters in `λ` - `λ[(`-R`, `+E`, `+A`) => F[R, E, A]]`
1 parent 83acd4b commit 4295d3c

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,9 @@ object StdNames {
660660
final val STAR : N = "*"
661661
final val TILDE: N = "~"
662662

663+
final val MINUS_STAR: N = "-*"
664+
final val PLUS_STAR : N = "+*"
665+
663666
final val isUnary: Set[Name] = Set(MINUS, PLUS, TILDE, BANG)
664667
}
665668

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,8 +1447,11 @@ object Parsers {
14471447
}
14481448
}
14491449

1450-
private def makeKindProjectorTypeDef(name: TypeName): TypeDef =
1451-
TypeDef(name, WildcardTypeBoundsTree()).withFlags(Param)
1450+
private def makeKindProjectorTypeDef(name: TypeName): TypeDef = {
1451+
val isVarianceAnnotated = name.lastPart.startsWith("+") || name.lastPart.startsWith("-")
1452+
val unannotatedName = if (isVarianceAnnotated) name.mapLast(_.drop(1)) else name
1453+
TypeDef(unannotatedName, WildcardTypeBoundsTree()).withFlags(Param)
1454+
}
14521455

14531456
/** Replaces kind-projector's `*` in a list of types arguments with synthetic names,
14541457
* returning the new argument list and the synthetic type definitions.
@@ -1457,7 +1460,7 @@ object Parsers {
14571460
val tparams = new ListBuffer[TypeDef]
14581461

14591462
val newParams = params.mapConserve {
1460-
case param @ Ident(tpnme.raw.STAR) =>
1463+
case param @ Ident(tpnme.raw.STAR | tpnme.raw.MINUS_STAR | tpnme.raw.PLUS_STAR) =>
14611464
val name = WildcardParamName.fresh().toTypeName
14621465
tparams += makeKindProjectorTypeDef(name)
14631466
Ident(name)

tests/pos-special/kind-projector.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ trait Foo[F[_]]
44
trait Qux[F[_, _]]
55
trait Baz[F[_], A, B]
66

7+
trait FooPlus[+F[+_]]
8+
trait QuxPlus[+F[+_, +_]]
9+
trait BazPlus[+F[+_], +A, +B]
10+
11+
trait FooMinus[-F[-_]]
12+
trait QuxMinus[-F[-_, -_]]
13+
trait BazMinus[-F[-_], -A, -B]
14+
715
class Bar1 extends Foo[Either[Int, *]]
816
class Bar2 extends Foo[Either[*, Int]]
917
class Bar3 extends Foo[* => Int]
@@ -13,3 +21,23 @@ class Bar6 extends Foo[λ[x => Either[Int, x]]]
1321
class Bar7 extends Qux[λ[(x, y) => Either[y, x]]]
1422
class Bar8 extends Foo[Baz[Int => *, *, Int]]
1523
class Bar9 extends Foo[λ[x => Baz[x => *, Int, x]]]
24+
25+
class BarPlus1 extends FooPlus[Either[Int, +*]]
26+
class BarPlus2 extends FooPlus[Either[+*, Int]]
27+
class BarPlus3 extends FooPlus[Int => +*]
28+
class BarPlus4 extends FooPlus[(Int, +*, Int)]
29+
class BarPlus5 extends FooPlus[λ[`+x` => Either[Int, x]]]
30+
class BarPlus6 extends QuxPlus[λ[(`+x`, `+y`) => Either[y, x]]]
31+
class BarPlus7 extends FooPlus[BazPlus[Int => +*, +*, Int]]
32+
33+
class BarMinus1 extends FooMinus[-* => Int]
34+
35+
class VarianceAnnotationIsActuallyIgnored1 extends FooPlus[Either[Int, -*]]
36+
class VarianceAnnotationIsActuallyIgnored2 extends FooPlus[Either[-*, Int]]
37+
class VarianceAnnotationIsActuallyIgnored3 extends FooMinus[+* => Int]
38+
class VarianceAnnotationIsActuallyIgnored4 extends FooPlus[Int => -*]
39+
class VarianceAnnotationIsActuallyIgnored5 extends FooPlus[(Int, -*, Int)]
40+
class VarianceAnnotationIsActuallyIgnored6 extends FooPlus[λ[`-x` => Either[Int, x]]]
41+
class VarianceAnnotationIsActuallyIgnored7 extends QuxPlus[λ[(`-x`, `-y`) => Either[y, x]]]
42+
class VarianceAnnotationIsActuallyIgnored8 extends FooPlus[BazPlus[Int => -*, -*, Int]]
43+
class VarianceAnnotationIsActuallyIgnored9 extends Foo[λ[`-x` => BazPlus[x => -*, Int, x]]]

0 commit comments

Comments
 (0)