From 42da707fc490b50768ad0dd60c9119a59587dbab Mon Sep 17 00:00:00 2001 From: Krzysztof Pado Date: Thu, 21 Apr 2022 14:19:39 -0700 Subject: [PATCH] Introduce a flag to enable Scala-3-style implicit resolution --- src/compiler/scala/tools/nsc/Global.scala | 1 + .../scala/tools/nsc/settings/ScalaSettings.scala | 1 + .../scala/tools/nsc/typechecker/Infer.scala | 6 +++--- test/files/neg/t2509-2.scala | 2 +- test/files/neg/t2509-3.scala | 2 +- test/files/neg/t2509-7b.scala | 2 +- test/files/pos/t2509-5.scala | 2 +- test/files/pos/t2509-6.scala | 2 +- test/files/pos/t2509-7a.scala | 2 +- test/files/run/t2509-1.scala | 2 +- test/files/run/t2509-4.scala | 2 +- test/files/run/t7768.scala | 2 +- .../tools/nsc/typechecker/InferencerTest.scala | 14 +++++++------- 13 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index dba1e63ae971..b0b8d4df40c2 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1160,6 +1160,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) // We hit these checks regularly. They shouldn't change inside the same run, so cache the comparisons here. val isScala3 = settings.isScala3 + val isScala3ImplicitResolution = settings.Yscala3ImplicitResolution // used in sbt def uncheckedWarnings: List[(Position, String)] = reporting.uncheckedWarnings diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 8e6ac5db2e04..c920eed42688 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -283,6 +283,7 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett val YpickleWrite = StringSetting("-Ypickle-write", "directory|jar", "destination for generated .sig files containing type signatures.", "", None).internalOnly() val YpickleWriteApiOnly = BooleanSetting("-Ypickle-write-api-only", "Exclude private members (other than those material to subclass compilation, such as private trait vals) from generated .sig files containing type signatures.").internalOnly() val YtrackDependencies = BooleanSetting("-Ytrack-dependencies", "Record references to in unit.depends. Deprecated feature that supports SBT 0.13 with incOptions.withNameHashing(false) only.", default = true) + val Yscala3ImplicitResolution = BooleanSetting("-Yscala3-implicit-resolution", "Use Scala-3-style downwards comparisons for implicit search and overloading resolution", default = false) sealed abstract class CachePolicy(val name: String, val help: String) object CachePolicy { diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 5ce94a93dbf4..89f0ca078460 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -903,9 +903,9 @@ trait Infer extends Checkable { isAsSpecificValueType(rtpe1, tpe2, undef1 ::: tparams1, undef2) case _ => tpe2 match { - case PolyType(tparams2, rtpe2) => isAsSpecificValueType(tpe1, rtpe2, undef1, undef2 ::: tparams2) - case _ if !currentRun.isScala3 => existentialAbstraction(undef1, tpe1) <:< existentialAbstraction(undef2, tpe2) - case _ => + case PolyType(tparams2, rtpe2) => isAsSpecificValueType(tpe1, rtpe2, undef1, undef2 ::: tparams2) + case _ if !currentRun.isScala3ImplicitResolution => existentialAbstraction(undef1, tpe1) <:< existentialAbstraction(undef2, tpe2) + case _ => // Backport of fix for https://github.com/scala/bug/issues/2509 // from Dotty https://github.com/lampepfl/dotty/commit/89540268e6c49fb92b9ca61249e46bb59981bf5a // diff --git a/test/files/neg/t2509-2.scala b/test/files/neg/t2509-2.scala index 032e6083acca..6023d1c85640 100644 --- a/test/files/neg/t2509-2.scala +++ b/test/files/neg/t2509-2.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3.0 +// scalac: -Yscala3-implicit-resolution class A class B extends A class C extends B diff --git a/test/files/neg/t2509-3.scala b/test/files/neg/t2509-3.scala index 619be4e439b2..5ca13fc1f62e 100644 --- a/test/files/neg/t2509-3.scala +++ b/test/files/neg/t2509-3.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3.0 +// scalac: -Yscala3-implicit-resolution class A class B extends A diff --git a/test/files/neg/t2509-7b.scala b/test/files/neg/t2509-7b.scala index 120c6e649143..31ed5c6b49c6 100644 --- a/test/files/neg/t2509-7b.scala +++ b/test/files/neg/t2509-7b.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3.0 +// scalac: -Yscala3-implicit-resolution class Both[-A, +B] trait Factory[A] { diff --git a/test/files/pos/t2509-5.scala b/test/files/pos/t2509-5.scala index 00a23f60644c..edda1cd4ca38 100644 --- a/test/files/pos/t2509-5.scala +++ b/test/files/pos/t2509-5.scala @@ -1,5 +1,5 @@ // See https://github.com/lampepfl/dotty/issues/2974 -// scalac: -Xsource:3.0 +// scalac: -Yscala3-implicit-resolution trait Foo[-T] diff --git a/test/files/pos/t2509-6.scala b/test/files/pos/t2509-6.scala index da5e69187714..d604b32750dc 100644 --- a/test/files/pos/t2509-6.scala +++ b/test/files/pos/t2509-6.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3.0 +// scalac: -Yscala3-implicit-resolution class A class B extends A diff --git a/test/files/pos/t2509-7a.scala b/test/files/pos/t2509-7a.scala index 5e3f8b781300..b2ab27c90de2 100644 --- a/test/files/pos/t2509-7a.scala +++ b/test/files/pos/t2509-7a.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3.0 +// scalac: -Yscala3-implicit-resolution class Both[-A, +B] diff --git a/test/files/run/t2509-1.scala b/test/files/run/t2509-1.scala index bb86e84c8ea8..7f834462c49e 100644 --- a/test/files/run/t2509-1.scala +++ b/test/files/run/t2509-1.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3.0 +// scalac: -Yscala3-implicit-resolution import scala.language.implicitConversions class A diff --git a/test/files/run/t2509-4.scala b/test/files/run/t2509-4.scala index 107ad1430350..474fb22e11be 100644 --- a/test/files/run/t2509-4.scala +++ b/test/files/run/t2509-4.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3.0 +// scalac: -Yscala3-implicit-resolution import scala.language.implicitConversions class A diff --git a/test/files/run/t7768.scala b/test/files/run/t7768.scala index ea3c8f7c352b..05f07332f69d 100644 --- a/test/files/run/t7768.scala +++ b/test/files/run/t7768.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3.0 +// scalac: -Yscala3-implicit-resolution class A class B extends A class C extends B diff --git a/test/junit/scala/tools/nsc/typechecker/InferencerTest.scala b/test/junit/scala/tools/nsc/typechecker/InferencerTest.scala index de48597af134..898755263a66 100644 --- a/test/junit/scala/tools/nsc/typechecker/InferencerTest.scala +++ b/test/junit/scala/tools/nsc/typechecker/InferencerTest.scala @@ -6,7 +6,6 @@ import org.junit.{After, Before, Test} import org.junit.runner.RunWith import org.junit.runners.JUnit4 -import scala.tools.nsc.settings.ScalaVersion import scala.tools.testkit.BytecodeTesting class A @@ -26,18 +25,19 @@ trait ZwC[-T] extends Z[T] with C class InferencerTests extends BytecodeTesting { import compiler.global._, analyzer._ - var storedXsource: ScalaVersion = null + var storedYscala3ImplicitResolution: Boolean = false @Before - def storeXsource(): Unit = { - storedXsource = settings.source.value + def storeYscala3ImplicitResolution(): Unit = { + storedYscala3ImplicitResolution = settings.Yscala3ImplicitResolution.value } @After - def restoreXsource(): Unit = { - settings.source.value = storedXsource + def restoreYscala3ImplicitResolution(): Unit = { + settings.Yscala3ImplicitResolution.value = storedYscala3ImplicitResolution } @Test def isAsSpecificScala2(): Unit = { + settings.Yscala3ImplicitResolution.value = false val run = new global.Run enteringPhase(run.typerPhase) { @@ -103,7 +103,7 @@ class InferencerTests extends BytecodeTesting { @Test def isAsSpecificScala3(): Unit = { - settings.source.value = ScalaVersion("3.0") + settings.Yscala3ImplicitResolution.value = true val run = new global.Run