From 46f4f938e6e839a83e8218918b79001113adf885 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 13 Jan 2021 11:45:33 +0100 Subject: [PATCH 1/3] Tighten condition when to check enum constructors Fixes #11081 --- compiler/src/dotty/tools/dotc/typer/Checking.scala | 2 +- tests/pos/i11081.scala | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i11081.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index e2f160142e6d..dc39a21cb141 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -1193,7 +1193,7 @@ trait Checking { checkRefsLegal(tree, cdef.symbol, allowAccess, "enum case") } - if (stat.symbol.is(Case)) + if (stat.symbol.isAllOf(EnumCase)) stat match { case TypeDef(_, Template(DefDef(_, paramss, _, _), parents, _, _)) => paramss.foreach(_.foreach(check)) diff --git a/tests/pos/i11081.scala b/tests/pos/i11081.scala new file mode 100644 index 000000000000..60bd5d5fe16b --- /dev/null +++ b/tests/pos/i11081.scala @@ -0,0 +1,5 @@ +enum Outer: + case Foo +object Outer: + trait Bar + case class Baz(bar: Bar) \ No newline at end of file From 788ae4ee8a75c81d8436f8b571406736883b88d7 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 13 Jan 2021 15:56:18 +0100 Subject: [PATCH 2/3] Also strengthen checking condition for default arguments --- compiler/src/dotty/tools/dotc/typer/Checking.scala | 2 +- tests/pos/i11081.scala | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index dc39a21cb141..efad815cb2d1 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -1207,7 +1207,7 @@ trait Checking { } case _ => } - else if (stat.symbol.is(Module) && stat.symbol.linkedClass.is(Case)) + else if (stat.symbol.is(Module) && stat.symbol.linkedClass.isAllOf(EnumCase)) stat match { case TypeDef(_, impl: Template) => for ((defaultGetter @ diff --git a/tests/pos/i11081.scala b/tests/pos/i11081.scala index 60bd5d5fe16b..cd333d7e407d 100644 --- a/tests/pos/i11081.scala +++ b/tests/pos/i11081.scala @@ -2,4 +2,5 @@ enum Outer: case Foo object Outer: trait Bar - case class Baz(bar: Bar) \ No newline at end of file + case class Baz(bar: Bar) + case class Bam(bar: Bar = new Bar() {}) From 79ee0a2a7ac809a55ea7f6e64cf4a9866597c9f8 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 13 Jan 2021 18:43:39 +0100 Subject: [PATCH 3/3] Address review comment --- compiler/src/dotty/tools/dotc/typer/Checking.scala | 10 +++++----- tests/neg/i11081.scala | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 tests/neg/i11081.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index efad815cb2d1..a7a509f0f804 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -1180,7 +1180,7 @@ trait Checking { */ def checkEnumCaseRefsLegal(cdef: TypeDef, enumCtx: Context)(using Context): Unit = { - def checkCaseOrDefault(stat: Tree, caseCtx: Context) = { + def checkEnumCaseOrDefault(stat: Tree, caseCtx: Context) = { def check(tree: Tree) = { // allow access to `sym` if a typedIdent just outside the enclosing enum @@ -1219,16 +1219,16 @@ trait Checking { cdef.rhs match { case impl: Template => - def isCase(stat: Tree) = stat match { - case _: ValDef | _: TypeDef => stat.symbol.is(Case) + def isEnumCase(stat: Tree) = stat match { + case _: ValDef | _: TypeDef => stat.symbol.isAllOf(EnumCase) case _ => false } val cases = - for (stat <- impl.body if isCase(stat)) + for (stat <- impl.body if isEnumCase(stat)) yield untpd.ImportSelector(untpd.Ident(stat.symbol.name.toTermName)) val caseImport: Import = Import(ref(cdef.symbol), cases) val caseCtx = enumCtx.importContext(caseImport, caseImport.symbol) - for (stat <- impl.body) checkCaseOrDefault(stat, caseCtx) + for (stat <- impl.body) checkEnumCaseOrDefault(stat, caseCtx) case _ => } } diff --git a/tests/neg/i11081.scala b/tests/neg/i11081.scala new file mode 100644 index 000000000000..7c1e6ce6dec6 --- /dev/null +++ b/tests/neg/i11081.scala @@ -0,0 +1,6 @@ +enum Outer: + case Foo(u: Unavailable) // error + case Bar(u: DefinitelyNotAvailable) // error +object Outer: + class Unavailable(i: Int) + case class DefinitelyNotAvailable()