Skip to content
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

Check all bindings exhaustively, e.g. tuples components #9147

Merged
merged 1 commit into from Aug 18, 2020
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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) {
dwijnand marked this conversation as resolved.
Show resolved Hide resolved
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