Skip to content

Instantly share code, notes, and snippets.

@retronym
Created October 18, 2022 07:10
Show Gist options
  • Save retronym/68e4d5c1a4300983939bfa8fd25b76ec to your computer and use it in GitHub Desktop.
Save retronym/68e4d5c1a4300983939bfa8fd25b76ec to your computer and use it in GitHub Desktop.
class covariant extends scala.annotation.StaticAnnotation with scala.annotation.TypeConstraint
object SetFactory {
def empty[K]: Set[K @covariant] = Set.empty[K @covariant]
}
class Client {
val x = if (true) Set("") else SetFactory.empty
}
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index d1c46db78d..7cdce5159f 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -5117,7 +5117,9 @@ trait Types
else if (tparam.variance == variance.flip) glb(asKinded, depth.decr)
else {
val l = lub(asKinded, depth.decr)
- val g = glb(asKinded, depth.decr)
+ def isCovariantNothing(tp: Type) =
+ tp =:= NothingTpe && tp.annotations.exists(_.symbol.name.string_==("covariant"))
+ val g = glb(asKinded.filterNot(isCovariantNothing), depth.decr)
if (l <:< g) l
else {
// @M this has issues with f-bounds, see #2251
scalac -Xprint:typer ~/code/scratch/test.scala
[[syntax trees at end of typer]] // test.scala
package <empty> {
class covariant extends scala.annotation.Annotation with scala.annotation.StaticAnnotation with scala.annotation.TypeConstraint {
def <init>(): covariant = {
covariant.super.<init>();
()
}
};
object SetFactory extends scala.AnyRef {
def <init>(): SetFactory.type = {
SetFactory.super.<init>();
()
};
def empty[K]: Set[K @covariant] = scala.Predef.Set.empty[K @covariant]
};
class Client extends scala.AnyRef {
def <init>(): Client = {
Client.super.<init>();
()
};
private[this] val x: scala.collection.immutable.Set[_ >: Nothing @covariant <: String] = if (true)
scala.Predef.Set.apply[String]("")
else
SetFactory.empty[Nothing];
<stable> <accessor> def x: scala.collection.immutable.Set[_ >: Nothing @covariant <: String] = Client.this.x
}
}
./build/quick/bin/scalac -Xprint:typer ~/code/scratch/test.scala
[[syntax trees at end of typer]] // test.scala
package <empty> {
class covariant extends scala.annotation.Annotation with scala.annotation.StaticAnnotation with scala.annotation.TypeConstraint {
def <init>(): covariant = {
covariant.super.<init>();
()
}
};
object SetFactory extends scala.AnyRef {
def <init>(): SetFactory.type = {
SetFactory.super.<init>();
()
};
def empty[K]: Set[K @covariant] = scala.Predef.Set.empty[K @covariant]
};
class Client extends scala.AnyRef {
def <init>(): Client = {
Client.super.<init>();
()
};
private[this] val x: scala.collection.immutable.Set[String] = if (true)
scala.Predef.Set.apply[String]("")
else
SetFactory.empty[Nothing];
<stable> <accessor> def x: scala.collection.immutable.Set[String] = Client.this.x
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment