From d055a8d8097aba7778e2d67a9115280e96d47135 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 23 Jun 2022 12:03:12 +0100 Subject: [PATCH 1/2] Don't unsoundly maximise types to Any/Nothing Also fix the span of the new pattern bound symbol, which was failing pickling tests. --- .../src/dotty/tools/dotc/typer/Applications.scala | 2 +- .../src/dotty/tools/dotc/typer/Inferencing.scala | 4 ++-- tests/neg/i14983.scala | 13 +++++++++++++ tests/run/i14983.scala | 13 +++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 tests/neg/i14983.scala create mode 100644 tests/run/i14983.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 9e4a1edd6e84..c523b82f4562 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -1341,7 +1341,7 @@ trait Applications extends Compatibility { // Constraining only fails if the pattern cannot possibly match, // but useless pattern checks detect more such cases, so we simply rely on them instead. withMode(Mode.GadtConstraintInference)(TypeComparer.constrainPatternType(unapplyArgType, selType)) - val patternBound = maximizeType(unapplyArgType, tree.span) + val patternBound = maximizeType(unapplyArgType, unapplyFn.span.endPos) if (patternBound.nonEmpty) unapplyFn = addBinders(unapplyFn, patternBound) unapp.println(i"case 2 $unapplyArgType ${ctx.typerState.constraint}") unapplyArgType diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala index 20da4723d27f..3a7788bf5fd9 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala @@ -405,8 +405,8 @@ object Inferencing { val patternBindings = new mutable.ListBuffer[(Symbol, TypeParamRef)] vs foreachBinding { (tvar, v) => if !tvar.isInstantiated then - if (v == 1) tvar.instantiate(fromBelow = false) - else if (v == -1) tvar.instantiate(fromBelow = true) + if (v == 1 && tvar.hasUpperBound) tvar.instantiate(fromBelow = false) + else if (v == -1 && tvar.hasLowerBound) tvar.instantiate(fromBelow = true) else { val bounds = TypeComparer.fullBounds(tvar.origin) if bounds.hi <:< bounds.lo || bounds.hi.classSymbol.is(Final) then diff --git a/tests/neg/i14983.scala b/tests/neg/i14983.scala new file mode 100644 index 000000000000..3bb9fc107e07 --- /dev/null +++ b/tests/neg/i14983.scala @@ -0,0 +1,13 @@ +sealed trait Tree[+A] +final case class Leaf[+B](v: B) extends Tree[B] +final case class Node[+C](xs: List[C]) extends Tree[List[C]] + +object Test: + def meth[X](tree: Tree[X]): X = tree match + case Leaf(v) => v + case Node(x) => List("boom") // error + + def main(args: Array[String]): Unit = + val tree = Node(List(42)) + val res = meth(tree) + assert(res.head == 42) // was: ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer diff --git a/tests/run/i14983.scala b/tests/run/i14983.scala new file mode 100644 index 000000000000..5d1105d3412a --- /dev/null +++ b/tests/run/i14983.scala @@ -0,0 +1,13 @@ +sealed trait Tree[+A] +final case class Leaf[+B](v: B) extends Tree[B] +final case class Node[+C](xs: List[C]) extends Tree[List[C]] + +object Test: + def meth[X](tree: Tree[X]): X = tree match + case Leaf(v) => v + case Node(x) => x // ok + + def main(args: Array[String]): Unit = + val tree = Node(List(42)) + val res = meth(tree) + assert(res.head == 42) // ok From b7b26895435f1b491bc60cd3cceb21b7a264772d Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 23 Jun 2022 13:20:12 +0100 Subject: [PATCH 2/2] ci: drop dist/pack from test_non_bootstrapped --- .github/workflows/ci.yaml | 7 ++++++- compiler/test/dotty/tools/scripting/BashScriptsTests.scala | 2 ++ compiler/test/dotty/tools/scripting/ExpressionTest.scala | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6cad2057dd01..92d82aed9967 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -69,8 +69,13 @@ jobs: run: cp -vf .github/workflows/repositories /root/.sbt/ ; true - name: Test + # DON'T add dist/pack! + # Adding dist/pack bootstraps the compiler + # which undermines the point of these tests: + # to quickly run the tests without the cost of bootstrapping + # and also to run tests when the compiler doesn't bootstrap run: | - ./project/scripts/sbt ";dist/pack; compile ;test" + ./project/scripts/sbt ";compile ;test" ./project/scripts/cmdTests test: diff --git a/compiler/test/dotty/tools/scripting/BashScriptsTests.scala b/compiler/test/dotty/tools/scripting/BashScriptsTests.scala index 6fa009428bb1..8a19d0420692 100644 --- a/compiler/test/dotty/tools/scripting/BashScriptsTests.scala +++ b/compiler/test/dotty/tools/scripting/BashScriptsTests.scala @@ -7,6 +7,7 @@ import scala.language.unsafeNulls import java.nio.file.Paths import org.junit.{Test, AfterClass} import org.junit.Assert.assertEquals +import org.junit.experimental.categories.Category import vulpix.TestConfiguration @@ -156,6 +157,7 @@ class BashScriptsTests: * verify that scriptPath.sc sees a valid script.path property, * and that it's value is the path to "scriptPath.sc". */ + @Category(Array(classOf[BootstrappedOnlyTests])) @Test def verifyScriptPathProperty = val scriptFile = testFiles.find(_.getName == "scriptPath.sc").get val expected = s"${scriptFile.getName}" diff --git a/compiler/test/dotty/tools/scripting/ExpressionTest.scala b/compiler/test/dotty/tools/scripting/ExpressionTest.scala index 803baf30e6d8..a464d15a8fab 100755 --- a/compiler/test/dotty/tools/scripting/ExpressionTest.scala +++ b/compiler/test/dotty/tools/scripting/ExpressionTest.scala @@ -7,6 +7,7 @@ import scala.language.unsafeNulls import java.nio.file.Paths import org.junit.{Test, AfterClass} import org.junit.Assert.assertEquals +import org.junit.experimental.categories.Category import vulpix.TestConfiguration @@ -15,6 +16,7 @@ import ScriptTestEnv.* /** * +. test scala -e */ +@Category(Array(classOf[BootstrappedOnlyTests])) class ExpressionTest: /* * verify -e works.