-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix cyclicity error for self-referential enum case #24138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -289,7 +289,15 @@ object DesugarEnums { | |
val (tag, scaffolding) = nextOrdinal(name, CaseKind.Object, definesLookups) | ||
val impl1 = cpy.Template(impl)(parents = impl.parents :+ scalaRuntimeDot(tpnme.EnumValue), body = Nil) | ||
.withAttachment(ExtendsSingletonMirror, ()) | ||
val vdef = ValDef(name, TypeTree(), New(impl1)).withMods(mods.withAddedFlags(EnumValue, span)) | ||
|
||
/** i11443: Attempt to provide an explicit type annotation for the enum case to allow certain cycles. | ||
* We pick the intersection of all parents, but only if they can be determined to be all types at this point. | ||
* Notably, this doesn't hold if one of the parents is a constructor call (e.g., extends Planet("Pluto")), | ||
* which might involve yet-to-be inferred generic parameters. | ||
*/ | ||
val tpt = if impl.parents.forall(_.isType) then impl.parents.reduceLeft(makeAndType(_, _)) else TypeTree() | ||
|
||
val vdef = ValDef(name, tpt, New(impl1)).withMods(mods.withAddedFlags(EnumValue, span)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we always add an explicit type without checking parent types? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No because we have a constructor, not a type when we desugar. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The best explicit annotation at this point seems to be the intersection of the parents, but only if all parent trees are known to be types. For example, all bets are off with constructor calls, because we have not yet inferred types. |
||
flatTree(vdef :: scaffolding).withSpan(span) | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,22 @@ | ||
object GADTs2 { | ||
enum Var[G, A] { | ||
case Z[A, G]() extends Expr[(A, G), A] // error | ||
case X extends AnyRef // error | ||
case X extends AnyRef // error // error | ||
} | ||
enum Expr[G, A] { | ||
case Lit[G](n: Int) extends Expr[G, Int] | ||
// case S[A, G](x: | ||
} | ||
enum Covariant[+T] { | ||
case Bottom extends AnyRef // error | ||
case Bottom extends AnyRef // error // error | ||
} | ||
enum Contravariant[-T] { | ||
case Top extends AnyRef // error | ||
case Top extends AnyRef // error // error | ||
} | ||
enum Color { | ||
case Red extends AnyRef // error | ||
case Red extends AnyRef // error // error | ||
} | ||
enum Parameterized[T](x: T) { | ||
case Foo extends AnyRef // error | ||
case Foo extends AnyRef // error // error | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
enum Opt[T] { | ||
case Nn extends Opt[Nothing] with Comparable[Nn.type] | ||
|
||
def compareTo(nn: Nn.type) = 0 | ||
} |