Skip to content

Commit

Permalink
Check all bindings exhaustively, e.g. tuples components
Browse files Browse the repository at this point in the history
The change to drop the null checks (introducing
`TreeMakersToPropsIgnoreNullChecks`) over-reached and got rid of all the
Vars that those null-checks were referencing.  So, instead of that,
finish honouring the `modelNull` option in `removeVarEq`.
  • Loading branch information
dwijnand committed Aug 18, 2020
1 parent e32b224 commit 93d1a5e
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 10 deletions.
7 changes: 3 additions & 4 deletions src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
Expand Up @@ -398,10 +398,9 @@ trait Logic extends Debugging {

object gatherEqualities extends PropTraverser {
override def apply(p: Prop) = p match {
case Eq(v, c) =>
vars += v
v.registerEquality(c)
case _ => super.apply(p)
case Eq(v, NullConst) if !modelNull => vars += v // not modeling equality to null
case Eq(v, c) => vars += v; v.registerEquality(c)
case _ => super.apply(p)
}
}

Expand Down
Expand Up @@ -246,10 +246,6 @@ trait MatchApproximation extends TreeAndTypeAnalysis with ScalaLogic with MatchT
override def toString = s"T${id}C($prop)"
}

class TreeMakersToPropsIgnoreNullChecks(root: Symbol) extends TreeMakersToProps(root) {
override def uniqueNonNullProp(p: Tree): Prop = True
}

// returns (tree, tests), where `tree` will be used to refer to `root` in `tests`
class TreeMakersToProps(val root: Symbol) {
prepareNewAnalysis() // reset hash consing for Var and Const
Expand All @@ -261,7 +257,6 @@ trait MatchApproximation extends TreeAndTypeAnalysis with ScalaLogic with MatchT
def uniqueEqualityProp(testedPath: Tree, rhs: Tree): Prop =
uniqueEqualityProps getOrElseUpdate((testedPath, rhs), Eq(Var(testedPath), ValueConst(rhs)))

// overridden in TreeMakersToPropsIgnoreNullChecks
def uniqueNonNullProp (testedPath: Tree): Prop =
uniqueNonNullProps getOrElseUpdate(testedPath, Not(Eq(Var(testedPath), NullConst)))

Expand Down Expand Up @@ -537,7 +532,7 @@ trait MatchAnalysis extends MatchApproximation {
val start = if (StatisticsStatics.areSomeColdStatsEnabled) statistics.startTimer(statistics.patmatAnaExhaust) else null
var backoff = false

val approx = new TreeMakersToPropsIgnoreNullChecks(prevBinder)
val approx = new TreeMakersToProps(prevBinder)
val symbolicCases = approx.approximateMatch(cases, approx.onUnknown { tm =>
approx.fullRewrite.applyOrElse[TreeMaker, Prop](tm, {
case BodyTreeMaker(_, _) => True // irrelevant -- will be discarded by symbolCase later
Expand Down
11 changes: 11 additions & 0 deletions test/files/neg/t10019.check
@@ -0,0 +1,11 @@
t10019.scala:4: warning: match may not be exhaustive.
It would fail on the following input: Foo(None)
def single(t: Foo): Nothing = t match {
^
t10019.scala:8: warning: match may not be exhaustive.
It would fail on the following input: (Foo(None), _)
def tuple(s: Foo, t: Foo): Nothing = (s, t) match {
^
error: No warnings can be incurred under -Xfatal-warnings.
two warnings found
one error found
1 change: 1 addition & 0 deletions test/files/neg/t10019.flags
@@ -0,0 +1 @@
-Xfatal-warnings
11 changes: 11 additions & 0 deletions test/files/neg/t10019.scala
@@ -0,0 +1,11 @@
object Bug {
sealed case class Foo(e: Option[Int])

def single(t: Foo): Nothing = t match {
case Foo(Some(_)) => ???
}

def tuple(s: Foo, t: Foo): Nothing = (s, t) match {
case (Foo(Some(_)), _) => ???
}
}
2 changes: 2 additions & 0 deletions test/scaladoc/run/t10673.scala
Expand Up @@ -32,6 +32,8 @@ object Test extends ScaladocModelTest {
import access._
def showParents(e: MemberTemplateEntity): Unit = {
e.parentTypes.foreach(_._2.refEntity.foreach {
case (_, (LinkToMember(mbr, tpl), _)) => println(s"found link for member $mbr to $tpl")
case (_, (LinkToTpl(tpl), _)) => println(s"found link $tpl")
case (_, (LinkToExternalTpl(name, _, tpl), _)) => println(s"'$name' links to $tpl")
case (_, (Tooltip(name), _)) => println(s"'$name' no link!")
})
Expand Down

0 comments on commit 93d1a5e

Please sign in to comment.