Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
14 changes: 14 additions & 0 deletions library/src/scala/Predef.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
8 changes: 6 additions & 2 deletions library/test/scala/collection/immutable/SetTest.scala
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]]
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion tests/run-staging/i5965.check
Original file line number Diff line number Diff line change
Expand Up @@ -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])
}
Expand Down
2 changes: 1 addition & 1 deletion tests/run-staging/i5965b.check
Original file line number Diff line number Diff line change
Expand Up @@ -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])
}
Expand Down
2 changes: 1 addition & 1 deletion tests/semanticdb/expect/Synthetic.expect.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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*/)

Expand Down
7 changes: 3 additions & 4 deletions tests/semanticdb/metac.expect
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down Expand Up @@ -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().
Expand Down Expand Up @@ -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](*)
Expand Down
Loading