diff --git a/language-server/test/dotty/tools/languageserver/CompletionTest.scala b/language-server/test/dotty/tools/languageserver/CompletionTest.scala index e06e6c78f5bb..0f356cd27bf6 100644 --- a/language-server/test/dotty/tools/languageserver/CompletionTest.scala +++ b/language-server/test/dotty/tools/languageserver/CompletionTest.scala @@ -1044,7 +1044,7 @@ class CompletionTest { ("!=", Method, "(x$0: Any): Boolean"), ("fromOrdinal", Method, "(ordinal: Int): Foo.Bar"), ("asInstanceOf", Method, "[X0]: X0"), - ("->", Method, "[B](y: B): (Foo.Bar.type, B)"), + ("->", Method, "[B](that: B): (Foo.Bar.type, B)"), ("wait", Method, "(x$0: Long, x$1: Int): Unit"), ("`back-tick`", Field, "Foo.Bar"), ("notify", Method, "(): Unit"), diff --git a/library/src/scala/Predef.scala b/library/src/scala/Predef.scala index 85f4908faa04..306f4eb55af1 100644 --- a/library/src/scala/Predef.scala +++ b/library/src/scala/Predef.scala @@ -403,7 +403,9 @@ object Predef extends LowPriorityImplicits { * @tparam A the type of the left-hand side of the arrow association * @param self the value to use as the first element of the resulting tuple */ + @deprecated("Use `->` extension method instead.", since = "3.10.0") implicit final class ArrowAssoc[A](private val self: A) extends AnyVal { + @deprecated("Use `->` extension method instead.", since = "3.10.0") @inline def -> [B](y: B): (A, B) = (self, y) @deprecated("Use `->` instead. If you still wish to display it as one character, consider using a font with programming ligatures such as Fira Code.", "2.13.0") def →[B](y: B): (A, B) = ->(y) @@ -727,6 +729,18 @@ object Predef extends LowPriorityImplicits { */ inline def runtimeChecked: x.type @RuntimeChecked = x: @RuntimeChecked + // extension method sugar --------------------------------------------- + + extension [A](inline self: A) + /** + * @tparam A the type of the left-hand side of the arrow association + * @tparam B the type of the left-hand side of the arrow association + * @param self the value to use as the first element of the resulting tuple + * @param that the value to use as the second element of the resulting tuple + */ + inline def -> [B](inline that: B): (A, B) = (self, that) + + } /** The `LowPriorityImplicits` class provides implicit values that diff --git a/library/test/scala/collection/immutable/SetTest.scala b/library/test/scala/collection/immutable/SetTest.scala index c02854949bda..6fce504293b5 100644 --- a/library/test/scala/collection/immutable/SetTest.scala +++ b/library/test/scala/collection/immutable/SetTest.scala @@ -1,7 +1,10 @@ package scala.collection.immutable // "Disabled string conversions so as not to get confused!" -import scala.Predef.{any2stringadd => _, *} +// import scala.Predef.{any2stringadd => _, *} +// ^^^^^^^^^^^^^^^^^^^^^^^ +// FIXME: editing Predef imports makes the name resolver prefer `ArrowAssoc` over the new `->` extension method, +// which is not what we want. however if you try to unimport `ArrowAssoc` then you can no longer resolve `->` ?. import org.junit.Assert.{assertEquals, assertNotSame, assertSame, assertTrue} import org.junit.Test @@ -12,7 +15,8 @@ class SetTest { def any[A](set: Set[A]): Set[Any] = { val anyset = set.toSet[Any] - assertTrue((anyset + "fish") contains "fish") + val fish = new Object() + assertTrue((anyset + fish) contains fish) anyset } diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala index 3b4dfef7cdab..38e683e369ba 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala @@ -450,6 +450,7 @@ class CompletionExtensionSuite extends BaseCompletionSuite: """|baz(): Unit |copy(): Bar |qux: Unit + |->[B](inline that: B): (Bar, B) |asInstanceOf[X0]: X0 |canEqual(that: Any): Boolean |equals(x$0: Any): Boolean @@ -464,7 +465,6 @@ class CompletionExtensionSuite extends BaseCompletionSuite: |productPrefix: String |synchronized[X0](x$0: X0): X0 |toString(): String - |->[B](y: B): (Bar, B) |ensuring(cond: Boolean): Bar |ensuring(cond: Bar => Boolean): Bar |ensuring(cond: Boolean, msg: => Any): Bar diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala index 30062f485989..54d73c6c64de 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala @@ -119,6 +119,7 @@ class CompletionSuite extends BaseCompletionSuite: |tabulate[A](n: Int)(f: Int => A): List[A] |unapplySeq[A](x: List[A] @uncheckedVariance): UnapplySeqWrapper[A] |unfold[A, S](init: S)(f: S => Option[(A, S)]): List[A] + |->[B](inline that: B): (List.type, B) |fromSpecific(from: Any)(it: IterableOnce[Nothing]): List[Nothing] |fromSpecific(it: IterableOnce[Nothing]): List[Nothing] |toFactory(from: Any): Factory[Nothing, List[Nothing]] @@ -130,7 +131,6 @@ class CompletionSuite extends BaseCompletionSuite: |isInstanceOf[X0]: Boolean |synchronized[X0](x$0: X0): X0 |toString(): String - |->[B](y: B): (List.type, B) |ensuring(cond: Boolean): List.type |ensuring(cond: List.type => Boolean): List.type |ensuring(cond: Boolean, msg: => Any): List.type diff --git a/tests/run-staging/i5965.check b/tests/run-staging/i5965.check index 2e991af71892..7711f2db455c 100644 --- a/tests/run-staging/i5965.check +++ b/tests/run-staging/i5965.check @@ -11,7 +11,7 @@ List(1, 2, 3) } Some(4) { - val y: [V >: scala.Nothing <: scala.Any] =>> scala.collection.immutable.Map[scala.Int, V][scala.Int] = scala.Predef.Map.apply[scala.Int, scala.Int](scala.Predef.ArrowAssoc[scala.Int](4).->[scala.Int](1)) + val y: [V >: scala.Nothing <: scala.Any] =>> scala.collection.immutable.Map[scala.Int, V][scala.Int] = scala.Predef.Map.apply[scala.Int, scala.Int](scala.Predef.->[scala.Int](4)[scala.Int](1)) (y: scala.collection.immutable.Map[scala.Int, scala.Int]) } diff --git a/tests/run-staging/i5965b.check b/tests/run-staging/i5965b.check index f88ef8f53869..475a87e5a05f 100644 --- a/tests/run-staging/i5965b.check +++ b/tests/run-staging/i5965b.check @@ -11,7 +11,7 @@ List(1, 2, 3) } Some(4) { - val y: scala.collection.immutable.Map[scala.Int, scala.Int] = scala.Predef.Map.apply[scala.Int, scala.Int](scala.Predef.ArrowAssoc[scala.Int](4).->[scala.Int](1)) + val y: scala.collection.immutable.Map[scala.Int, scala.Int] = scala.Predef.Map.apply[scala.Int, scala.Int](scala.Predef.->[scala.Int](4)[scala.Int](1)) (y: scala.collection.immutable.Map[scala.Int, scala.Int]) } diff --git a/tests/semanticdb/expect/Synthetic.expect.scala b/tests/semanticdb/expect/Synthetic.expect.scala index 5286745100a7..e040733eaffd 100644 --- a/tests/semanticdb/expect/Synthetic.expect.scala +++ b/tests/semanticdb/expect/Synthetic.expect.scala @@ -17,7 +17,7 @@ class Synthetic/*<-example::Synthetic#*/ { val lst/*<-example::Synthetic#lst.*/ = 1 #:: 2 #:: LazyList/*->scala::package.LazyList.*/.empty/*->scala::collection::immutable::LazyList.empty().*/ - for (x/*<-local0*/ <- 1 to/*->scala::runtime::RichInt#to().*/ 10; y/*<-local1*/ <- 0 until/*->scala::runtime::RichInt#until().*/ 10) println/*->scala::Predef.println(+1).*/(x/*->local0*/ ->/*->scala::Predef.ArrowAssoc#`->`().*/ x/*->local0*/) + for (x/*<-local0*/ <- 1 to/*->scala::runtime::RichInt#to().*/ 10; y/*<-local1*/ <- 0 until/*->scala::runtime::RichInt#until().*/ 10) println/*->scala::Predef.println(+1).*/(x/*->local0*/ ->/*->scala::Predef.`->`().*/ x/*->local0*/) for (i/*<-local2*/ <- 1 to/*->scala::runtime::RichInt#to().*/ 10; j/*<-local3*/ <- 0 until/*->scala::runtime::RichInt#until().*/ 10) yield (i/*->local2*/, j/*->local3*/) for (i/*<-local4*/ <- 1 to/*->scala::runtime::RichInt#to().*/ 10; j/*<-local5*/ <- 0 until/*->scala::runtime::RichInt#until().*/ 10 if i/*->local4*/ %/*->scala::Int#`%`(+3).*/ 2 ==/*->scala::Int#`==`(+3).*/ 0) yield (i/*->local4*/, j/*->local5*/) diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index 2c97be5ed2b7..0f6fa08e857d 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -3910,7 +3910,7 @@ Language => Scala Symbols => 62 entries Occurrences => 165 entries Diagnostics => 4 entries -Synthetics => 48 entries +Synthetics => 47 entries Symbols: example/Synthetic# => class Synthetic extends Object { self: Synthetic => +23 decls } @@ -4016,7 +4016,7 @@ Occurrences: [19:28..19:33): until -> scala/runtime/RichInt#until(). [19:38..19:45): println -> scala/Predef.println(+1). [19:46..19:47): x -> local0 -[19:48..19:50): -> -> scala/Predef.ArrowAssoc#`->`(). +[19:48..19:50): -> -> scala/Predef.`->`(). [19:51..19:52): x -> local0 [20:7..20:8): i <- local2 [20:14..20:16): to -> scala/runtime/RichInt#to(). @@ -4176,8 +4176,7 @@ Synthetics: [17:24..17:38):LazyList.empty => *[Nothing] [19:12..19:13):1 => intWrapper(*) [19:26..19:27):0 => intWrapper(*) -[19:46..19:50):x -> => *[Int] -[19:46..19:47):x => ArrowAssoc[Int](*) +[19:48..19:50):-> => *[Int] [20:12..20:13):1 => intWrapper(*) [20:26..20:27):0 => intWrapper(*) [20:44..20:50):(i, j) => Tuple2.apply[Int, Int](*)