Skip to content

Tighten condition when to check enum constructors #11098

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

Merged
merged 3 commits into from
Jan 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions compiler/src/dotty/tools/dotc/typer/Checking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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))
Expand All @@ -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 @
Expand All @@ -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 _ =>
}
}
Expand Down
6 changes: 6 additions & 0 deletions tests/neg/i11081.scala
Original file line number Diff line number Diff line change
@@ -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()
6 changes: 6 additions & 0 deletions tests/pos/i11081.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
enum Outer:
case Foo
object Outer:
trait Bar
case class Baz(bar: Bar)
case class Bam(bar: Bar = new Bar() {})