diff --git a/library/src/dotty/DottyPredef.scala b/library/src/dotty/DottyPredef.scala index 0a1276e1958e..19e9e87f63ad 100644 --- a/library/src/dotty/DottyPredef.scala +++ b/library/src/dotty/DottyPredef.scala @@ -1,6 +1,7 @@ package dotty import scala.forceInline +import scala.collection.generic.IsTraversableLike object DottyPredef { @@ -55,4 +56,14 @@ object DottyPredef { * @group utilities */ @forceInline def valueOf[T](implicit vt: ValueOf[T]): T = vt.value + + /** + * Add an `empty` operation to all collection instances, returning an empty collection + * of the same type. + */ + implicit class EmptyOperation[C](c: C)(implicit isTraversable: IsTraversableLike[C]) { + // Ideally we would use `withFilter`, but it is not defined on `GenTraversableLike`. + def empty: C = isTraversable.conversion(c).filter(_ => false) + } + } diff --git a/tests/pos/collectionsEmpty.scala b/tests/pos/collectionsEmpty.scala new file mode 100644 index 000000000000..577a1cf81cfa --- /dev/null +++ b/tests/pos/collectionsEmpty.scala @@ -0,0 +1,40 @@ +object collectionsEmpty { + + locally { + val xs1 = List(1, 2, 3) + val xs2 = xs1.empty + val xs3: List[Int] = xs2 + } + + locally { + val xs1 = Array(1, 2, 3) + val xs2 = xs1.empty + val xs3: Array[Int] = xs2 + } + + locally { + val xs1 = Set(1, 2, 3) + val xs2 = xs1.empty + val xs3: Set[Int] = xs2 + } + + locally { + val xs1 = "foo" + val xs2 = xs1.empty + val xs3: String = xs2 + } + + // Commented because there is no IsTraversableLike[Range] instance + // locally { + // val xs1 = 1 to 3 + // val xs2 = xs1.empty + // val xs3: IndexedSeq[Int] = xs2 + // } + + locally { + val xs1 = Iterable(1, 2, 3) + val xs2 = xs1.empty + val xs3: Iterable[Int] = xs2 + } + +} \ No newline at end of file