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

Exhaustiveness checking uses excessive resources (regression) #10057

Closed
scabug opened this issue Nov 14, 2016 · 3 comments
Closed

Exhaustiveness checking uses excessive resources (regression) #10057

scabug opened this issue Nov 14, 2016 · 3 comments

Comments

@scabug
Copy link

scabug commented Nov 14, 2016

When compiling code that contains non-exhaustive matches on case classes with multiple parameters like the test case below, the compiler uses excessive system resources. For the test case below, on my system scalac peaks to using over 2 GB of memory (when run with -J-Xmx4G) and does not finish compiling after running for 10 minutes. Adding a default case to make the match exhaustive or compiling with -Xno-patmat-analysis allows compilation to finish in reasonable time with compiler version 2.12.0, but was not necessary with version 2.11.8.

Test case:

case class C(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int)
object C {
	def bug(c: C): Int = c match {
		case C(0, 0, 0, 0, 0, 0) => 0
		case C(1, 1, 1, 1, 1, 1) => 1
		case C(2, 2, 2, 2, 2, 2) => 2
		case C(3, 3, 3, 3, 3, 3) => 3
		case C(4, 4, 4, 4, 4, 4) => 4
		case C(5, 5, 5, 5, 5, 5) => 5
		case C(6, 6, 6, 6, 6, 6) => 6
		case C(7, 7, 7, 7, 7, 7) => 7
		case C(8, 8, 8, 8, 8, 8) => 8
		case C(9, 9, 9, 9, 9, 9) => 9
	}
}
@scabug
Copy link
Author

scabug commented Nov 14, 2016

Imported From: https://issues.scala-lang.org/browse/SI-10057?orig=1
Reporter: Aaron Willey (awilley1)
Affected Versions: 2.12.0

@scabug
Copy link
Author

scabug commented Nov 22, 2016

@retronym said:
The difference between 2.11.8 and 2.12.0 is that we have started to treat case classes as one-case-ADTs for the purposes of the analysis. If we introduce a sealed parent type, I get a OOME in 2.11.8:

sealed trait T
case class C(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) extends T

object Test {
  def bug(c: T): Int = c match {
      case C(0, 0, 0, 0, 0, 0) => 0
      case C(1, 1, 1, 1, 1, 1) => 1
      case C(2, 2, 2, 2, 2, 2) => 2
      case C(3, 3, 3, 3, 3, 3) => 3
      case C(4, 4, 4, 4, 4, 4) => 4
      case C(5, 5, 5, 5, 5, 5) => 5
      case C(6, 6, 6, 6, 6, 6) => 6
      case C(7, 7, 7, 7, 7, 7) => 7
      case C(8, 8, 8, 8, 8, 8) => 8
      case C(9, 9, 9, 9, 9, 9) => 9
  }
}

The bottleneck seems to be:

scala/scala@578c3b1#diff-2f2813e98b667286e1c6c57d432af657R697

In which the compiler doggedly attempts to produce an exhaustive list of counter examples. Were it possible to create these We can tell in advance that this is impractically large, the question is what to do instead in degrade to a useful counter example message.

@adriaanm
Copy link
Contributor

I don't think we'll get to this one for 2.12.3, but @retronym, could you take a look after?

@retronym retronym modified the milestones: 2.12.3, 2.12.4 Jul 8, 2017
@adriaanm adriaanm modified the milestones: 2.12.4, 2.12.5 Oct 10, 2017
@SethTisue SethTisue modified the milestones: 2.12.5, Backlog Mar 1, 2018
@SethTisue SethTisue modified the milestones: Backlog, 2.13.6 Oct 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants