Skip to content

Commit

Permalink
Discover inner classes for sealed hierarchy
Browse files Browse the repository at this point in the history
  • Loading branch information
som-snytt committed Apr 25, 2023
1 parent 62c5acf commit 9c3e87d
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 16 deletions.
36 changes: 23 additions & 13 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Expand Up @@ -15,12 +15,11 @@ package tools.nsc
package typechecker

import scala.annotation.{tailrec, unused}
import scala.collection.mutable
import scala.collection.mutable, mutable.ListBuffer
import scala.reflect.internal.{Chars, TypesStats}
import scala.reflect.internal.util.{FreshNameCreator, ListOfNil, Statistics, StringContextStripMarginOps}
import scala.tools.nsc.Reporting.{MessageFilter, Suppression, WConf, WarningCategory}
import scala.util.chaining._
import mutable.ListBuffer
import symtab.Flags._
import Mode._

Expand Down Expand Up @@ -2653,18 +2652,29 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val selectorTp = packCaptured(selector1.tpe.widen).skolemizeExistential(context.owner, selector)
val casesTyped = typedCases(cases, selectorTp, pt)

def initChildren(sym: Symbol): Unit = if (sym.isJava && sym.isSealed) {
sym.attachments.get[PermittedSubclassSymbols].foreach(_.permits.foreach { child =>
child.initialize
initChildren(child)
})
patmat.javaClassesByUnit.get(sym.pos.source).foreach(_.foreach { c =>
if (c.parentSymbols.contains(sym)) {
c.initialize
initChildren(c)
def initChildren(sym: Symbol): Unit =
if (sym.isJava && sym.isSealed)
sym.attachments.get[PermittedSubclassSymbols] match {
case Some(PermittedSubclassSymbols(permits)) =>
for (child <- permits if child.isJava)
initChildren(child.initialize)
case _ =>
val seen = mutable.HashSet.empty[Symbol]
def populate(): Unit =
patmat.javaClassesByUnit.get(sym.pos.source) match {
case Some(classes) =>
classes.find(!seen(_)) match {
case Some(unseen) =>
seen += unseen
unseen.initialize.companionSymbol.moduleClass.initialize
if (unseen.hasAttachment[PermittedSubclassSymbols]) initChildren(unseen)
populate()
case _ =>
}
case _ =>
}
populate()
}
})
}
initChildren(selectorTp.typeSymbol)

def finish(cases: List[CaseDef], matchType: Type) =
Expand Down
7 changes: 7 additions & 0 deletions test/files/neg/t12159g.check
@@ -0,0 +1,7 @@
t.scala:4: warning: match may not be exhaustive.
It would fail on the following inputs: Oz(), Z()
def n(a: X) = a match { case _: Y => 42 }
^
error: No warnings can be incurred under -Werror.
1 warning
1 error
5 changes: 4 additions & 1 deletion test/files/neg/t12159g/X.java
@@ -1,9 +1,12 @@

package p;
public sealed interface X {
public default int x() { return 1; }
public default int x() { return 27; }
}
final class Y implements X { }
final class O {
final static class Z implements X { }
final static class Inner {
final static class Oz implements X { }
}
}
4 changes: 2 additions & 2 deletions test/files/neg/t12159g/t.scala
@@ -1,5 +1,5 @@

// scalac: -Werror -Xlint
package p
class T {
def n(a: X) = a match { case _: Y => 0 }
def n(a: X) = a match { case _: Y => 42 }
}

0 comments on commit 9c3e87d

Please sign in to comment.