From 61875a655d0967df31063300b05eb874804d2c2f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 3 Nov 2023 16:09:25 +0100 Subject: [PATCH] Deprecation warning for `with` type operator in 3.4 --- .../scala/dotty/communitybuild/projects.scala | 4 ++-- .../dotty/tools/dotc/parsing/Parsers.scala | 9 ++++---- compiler/test-resources/repl/i6643 | 9 ++++++-- compiler/test-resources/type-printer/infix | 21 +++++++++++++++++++ tests/neg-scalajs/js-native-members.check | 7 +++++++ ...constructorof-error-in-prepjsinterop.check | 14 +++++++++++++ ...onstructortag-error-in-prepjsinterop.check | 14 +++++++++++++ tests/neg/i2887b.scala | 2 +- tests/neg/i8736.scala | 6 +++--- .../with-type-operator-future-migration.check | 2 +- tests/pos-deep-subtype/3324h.scala | 4 +++- tests/pos/with-type-operator-3.3.scala | 5 +++++ ...=> with-type-operator-3.4-migration.scala} | 2 +- .../with-type-operator-future-migration.scala | 3 --- tests/semanticdb/metac.expect | 11 +++++++++- 15 files changed, 94 insertions(+), 19 deletions(-) create mode 100644 tests/pos/with-type-operator-3.3.scala rename tests/pos/{with-type-operator.scala => with-type-operator-3.4-migration.scala} (51%) delete mode 100644 tests/pos/with-type-operator-future-migration.scala diff --git a/community-build/src/scala/dotty/communitybuild/projects.scala b/community-build/src/scala/dotty/communitybuild/projects.scala index 94ee5ad44a8c..0e13522b9622 100644 --- a/community-build/src/scala/dotty/communitybuild/projects.scala +++ b/community-build/src/scala/dotty/communitybuild/projects.scala @@ -362,7 +362,7 @@ object projects: project = "shapeless-3", sbtTestCommand = "testJVM; testJS", sbtDocCommand = forceDoc("typeable", "deriving"), - scalacOptions = SbtCommunityProject.scalacOptions.filter(_ != "-Ysafe-init"), // due to -Xfatal-warnings + scalacOptions = "-source" :: "`3.3`" :: SbtCommunityProject.scalacOptions.filter(_ != "-Ysafe-init"), // due to -Xfatal-warnings ) lazy val xmlInterpolator = SbtCommunityProject( @@ -404,7 +404,7 @@ object projects: project = "zio", sbtTestCommand = "testJVMDotty", sbtDocCommand = forceDoc("coreJVM"), - scalacOptions = SbtCommunityProject.scalacOptions.filter(_ != "-Xcheck-macros"), + scalacOptions = "-source" :: "`3.3`" :: SbtCommunityProject.scalacOptions.filter(_ != "-Xcheck-macros"), dependencies =List(izumiReflect) ) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 805c25ad40e4..086c69988dcf 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1757,11 +1757,12 @@ object Parsers { t else val withSpan = Span(withOffset, withOffset + 4) - report.errorOrMigrationWarning( - DeprecatedWithOperator(rewriteNotice(`future-migration`)), + report.gradualErrorOrMigrationWarning( + DeprecatedWithOperator(rewriteNotice(`3.4-migration`)), source.atSpan(withSpan), - from = future) - if sourceVersion == `future-migration` then + warnFrom = `3.4`, + errorFrom = future) + if sourceVersion.isMigrating && sourceVersion.isAtLeast(`3.4-migration`) then patch(source, withSpan, "&") atSpan(startOffset(t)) { makeAndType(t, withType()) } else t diff --git a/compiler/test-resources/repl/i6643 b/compiler/test-resources/repl/i6643 index e139ae9f7f94..ff482d8ce5f1 100644 --- a/compiler/test-resources/repl/i6643 +++ b/compiler/test-resources/repl/i6643 @@ -1,7 +1,12 @@ scala> import scala.collection._ - scala>:type 1 Int - scala> object IterableTest { def g[CC[_] <: Iterable[_] with IterableOps[_, _, _]](from: CC[Int]): IterableFactory[CC] = ??? } +1 warning found +-- [E003] Syntax Warning: ------------------------------------------------------ +1 | object IterableTest { def g[CC[_] <: Iterable[_] with IterableOps[_, _, _]](from: CC[Int]): IterableFactory[CC] = ??? } + | ^^^^ + | with as a type operator has been deprecated; use & instead + | + | longer explanation available when compiling with `-explain` // defined object IterableTest diff --git a/compiler/test-resources/type-printer/infix b/compiler/test-resources/type-printer/infix index a7904ae9ec43..2fe2864ad9fe 100644 --- a/compiler/test-resources/type-printer/infix +++ b/compiler/test-resources/type-printer/infix @@ -48,10 +48,31 @@ def foo: Int && Boolean & String scala> def foo: Int && (Boolean & String) = ??? def foo: Int && (Boolean & String) scala> def foo: Int && (Boolean with String) = ??? +1 warning found +-- [E003] Syntax Warning: ------------------------------------------------------ +1 | def foo: Int && (Boolean with String) = ??? + | ^^^^ + | with as a type operator has been deprecated; use & instead + | + | longer explanation available when compiling with `-explain` def foo: Int && (Boolean & String) scala> def foo: (Int && Boolean) with String = ??? +1 warning found +-- [E003] Syntax Warning: ------------------------------------------------------ +1 | def foo: (Int && Boolean) with String = ??? + | ^^^^ + | with as a type operator has been deprecated; use & instead + | + | longer explanation available when compiling with `-explain` def foo: Int && Boolean & String scala> def foo: Int && Boolean with String = ??? +1 warning found +-- [E003] Syntax Warning: ------------------------------------------------------ +1 | def foo: Int && Boolean with String = ??? + | ^^^^ + | with as a type operator has been deprecated; use & instead + | + | longer explanation available when compiling with `-explain` def foo: Int && (Boolean & String) scala> def foo: Int && Boolean | String = ??? def foo: Int && Boolean | String diff --git a/tests/neg-scalajs/js-native-members.check b/tests/neg-scalajs/js-native-members.check index 466dbc9d2063..d4cf5208ce1f 100644 --- a/tests/neg-scalajs/js-native-members.check +++ b/tests/neg-scalajs/js-native-members.check @@ -1,3 +1,10 @@ +-- [E003] Syntax Warning: tests/neg-scalajs/js-native-members.scala:58:44 ---------------------------------------------- +58 | def assign[T, U](target: T, source: U): T with U = js.native // ok + | ^^^^ + | with as a type operator has been deprecated; use & instead + | This construct can be rewritten automatically under -rewrite -source 3.4-migration. + | + | longer explanation available when compiling with `-explain` -- Error: tests/neg-scalajs/js-native-members.scala:9:24 --------------------------------------------------------------- 9 | def this(z: String) = this(z.length, z) // error | ^^^^^^^^^^^^^^^^^ diff --git a/tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check b/tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check index 7687543ea75f..fe55c0caee52 100644 --- a/tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check +++ b/tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check @@ -1,3 +1,17 @@ +-- [E003] Syntax Warning: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:16:41 ------------------------- +16 | val c = js.constructorOf[NativeJSClass with NativeJSTrait] // error + | ^^^^ + | with as a type operator has been deprecated; use & instead + | This construct can be rewritten automatically under -rewrite -source 3.4-migration. + | + | longer explanation available when compiling with `-explain` +-- [E003] Syntax Warning: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:22:35 ------------------------- +22 | val g = js.constructorOf[JSClass with JSTrait] // error + | ^^^^ + | with as a type operator has been deprecated; use & instead + | This construct can be rewritten automatically under -rewrite -source 3.4-migration. + | + | longer explanation available when compiling with `-explain` -- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:13:27 ----------------------------------------- 13 | val a = js.constructorOf[NativeJSTrait] // error | ^^^^^^^^^^^^^ diff --git a/tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check b/tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check index 142de318efd3..df09d5b1953d 100644 --- a/tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check +++ b/tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check @@ -1,3 +1,17 @@ +-- [E003] Syntax Warning: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:16:42 ------------------------ +16 | val c = js.constructorTag[NativeJSClass with NativeJSTrait] // error + | ^^^^ + | with as a type operator has been deprecated; use & instead + | This construct can be rewritten automatically under -rewrite -source 3.4-migration. + | + | longer explanation available when compiling with `-explain` +-- [E003] Syntax Warning: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:22:36 ------------------------ +22 | val g = js.constructorTag[JSClass with JSTrait] // error + | ^^^^ + | with as a type operator has been deprecated; use & instead + | This construct can be rewritten automatically under -rewrite -source 3.4-migration. + | + | longer explanation available when compiling with `-explain` -- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:13:42 ---------------------------------------- 13 | val a = js.constructorTag[NativeJSTrait] // error | ^ diff --git a/tests/neg/i2887b.scala b/tests/neg/i2887b.scala index 649d869678cb..b41a392271e2 100644 --- a/tests/neg/i2887b.scala +++ b/tests/neg/i2887b.scala @@ -4,7 +4,7 @@ trait C { type M <: B } trait D { type M >: A } object Test { - def test(x: C with D): Unit = { + def test(x: C & D): Unit = { def foo(a: A, b: B)(z: a.S[b.I,a.I][b.S[a.I,a.I]]) = z def bar(a: A, y: x.M) = foo(a,y) def baz(a: A) = bar(a, a) diff --git a/tests/neg/i8736.scala b/tests/neg/i8736.scala index dc2fa1821791..9724e5f81b2a 100644 --- a/tests/neg/i8736.scala +++ b/tests/neg/i8736.scala @@ -14,13 +14,13 @@ object App extends App { def field[V](s: String)(v: V): Rec[s.type, V] = Rec0(Map(s -> v)).asInstanceOf[Rec[s.type, V]] implicit class RecOps[R <: Rec0[_]](has: R) { - def +[K1 <: String, V1](that: Rec[K1, V1]): R with Rec[K1, V1] = Rec0(has.map ++ that.map).asInstanceOf[R with Rec[K1, V1]] + def +[K1 <: String, V1](that: Rec[K1, V1]): R & Rec[K1, V1] = Rec0(has.map ++ that.map).asInstanceOf[R & Rec[K1, V1]] } def rec: Rec["k", String] - with Rec["v", Int] - with Rec["z", Boolean] + & Rec["v", Int] + & Rec["z", Boolean] = { field("k")("Str") + field("v")(0) + diff --git a/tests/neg/with-type-operator-future-migration.check b/tests/neg/with-type-operator-future-migration.check index 845601349c83..e56049880431 100644 --- a/tests/neg/with-type-operator-future-migration.check +++ b/tests/neg/with-type-operator-future-migration.check @@ -2,6 +2,6 @@ 5 |def foo: Int with String = ??? // error | ^^^^ | with as a type operator has been deprecated; use & instead - | This construct can be rewritten automatically under -rewrite -source future-migration. + | This construct can be rewritten automatically under -rewrite -source 3.4-migration. | | longer explanation available when compiling with `-explain` diff --git a/tests/pos-deep-subtype/3324h.scala b/tests/pos-deep-subtype/3324h.scala index bff25ee3c888..6bae5f6a01d9 100644 --- a/tests/pos-deep-subtype/3324h.scala +++ b/tests/pos-deep-subtype/3324h.scala @@ -1,5 +1,7 @@ //> using options -Xfatal-warnings +import scala.language.`3.3` + object Test { trait Marker def foo[T](x: T) = x match { @@ -8,7 +10,7 @@ object Test { } def foo2[T](x: T) = x match { - case _: T with Marker => // scalac emits a warning + case _: T with Marker => // scalac or 3.4 emits a warning case _ => } } diff --git a/tests/pos/with-type-operator-3.3.scala b/tests/pos/with-type-operator-3.3.scala new file mode 100644 index 000000000000..2b40939d71b0 --- /dev/null +++ b/tests/pos/with-type-operator-3.3.scala @@ -0,0 +1,5 @@ +//> using options -Werror + +import scala.language.`3.3` + +def foo: Int with String = ??? diff --git a/tests/pos/with-type-operator.scala b/tests/pos/with-type-operator-3.4-migration.scala similarity index 51% rename from tests/pos/with-type-operator.scala rename to tests/pos/with-type-operator-3.4-migration.scala index d1fa5e2c34b7..27761a5e4a7f 100644 --- a/tests/pos/with-type-operator.scala +++ b/tests/pos/with-type-operator-3.4-migration.scala @@ -1,3 +1,3 @@ -//> using options -Werror +import scala.language.`3.4-migration` def foo: Int with String = ??? // warn diff --git a/tests/pos/with-type-operator-future-migration.scala b/tests/pos/with-type-operator-future-migration.scala deleted file mode 100644 index d6fe5205fd3d..000000000000 --- a/tests/pos/with-type-operator-future-migration.scala +++ /dev/null @@ -1,3 +0,0 @@ -import scala.language.`future-migration` - -def foo: Int with String = ??? // warn diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index e05a645c0141..a7f66b2d4542 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -3377,6 +3377,7 @@ Text => empty Language => Scala Symbols => 13 entries Occurrences => 22 entries +Diagnostics => 1 entries Symbols: local0 => selfparam self: C1 @@ -3417,6 +3418,10 @@ Occurrences: [13:17..13:17): <- selfs/C6#``(). [13:27..13:28): B -> selfs/B# +Diagnostics: +[10:29..10:33): [warning] with as a type operator has been deprecated; use & instead +This construct can be rewritten automatically under -rewrite -source 3.4-migration. + expect/StructuralTypes.scala ---------------------------- @@ -5030,7 +5035,7 @@ Text => empty Language => Scala Symbols => 143 entries Occurrences => 246 entries -Diagnostics => 1 entries +Diagnostics => 3 entries Synthetics => 1 entries Symbols: @@ -5428,6 +5433,10 @@ Occurrences: Diagnostics: [5:13..5:14): [warning] unused explicit parameter +[62:25..62:29): [warning] with as a type operator has been deprecated; use & instead +This construct can be rewritten automatically under -rewrite -source 3.4-migration. +[63:25..63:29): [warning] with as a type operator has been deprecated; use & instead +This construct can be rewritten automatically under -rewrite -source 3.4-migration. Synthetics: [68:20..68:24):@ann => *[Int]