diff --git a/build.sbt b/build.sbt index 698cc8f4..a9afe43e 100644 --- a/build.sbt +++ b/build.sbt @@ -15,7 +15,6 @@ ThisBuild / startYear := Some(2015) ThisBuild / crossScalaVersions := Seq(Scala3, Scala213, Scala212) ThisBuild / tlVersionIntroduced := Map("3" -> "0.9.3") -ThisBuild / tlFatalWarnings := false ThisBuild / tlCiReleaseBranches := Seq("master") ThisBuild / tlSitePublishBranch := Some("master") ThisBuild / githubWorkflowJavaVersions := Seq("8", "21").map(JavaSpec.temurin) diff --git a/core/src/main/scala/cats/collections/Dequeue.scala b/core/src/main/scala/cats/collections/Dequeue.scala index 4c720061..7beccd23 100644 --- a/core/src/main/scala/cats/collections/Dequeue.scala +++ b/core/src/main/scala/cats/collections/Dequeue.scala @@ -27,6 +27,7 @@ import cats.data.NonEmptyList import scala.annotation.tailrec import scala.collection.mutable.ListBuffer import cats.collections.compat.Factory +import org.typelevel.scalaccompat.annotation._ /** * Dequeue - A Double Ended Queue @@ -324,25 +325,28 @@ sealed trait DequeueInstances { override def combine(l: Dequeue[A], r: Dequeue[A]) = l ++ r } - implicit val dequeueInstance: Traverse[Dequeue] with MonoidK[Dequeue] with CoflatMap[Dequeue] = new Traverse[Dequeue] - with MonoidK[Dequeue] - with CoflatMap[Dequeue] { - override def empty[A]: Dequeue[A] = Dequeue.empty + @nowarn213( + "msg=Calls to parameterless method compose will be easy to mistake for calls to overloads which have a single implicit parameter list" + ) + implicit val dequeueInstance: Traverse[Dequeue] with MonoidK[Dequeue] with CoflatMap[Dequeue] = + new Traverse[Dequeue] with MonoidK[Dequeue] with CoflatMap[Dequeue] { + override def empty[A]: Dequeue[A] = Dequeue.empty - override def combineK[A](l: Dequeue[A], r: Dequeue[A]): Dequeue[A] = l ++ r + override def combineK[A](l: Dequeue[A], r: Dequeue[A]): Dequeue[A] = l ++ r - override def map[A, B](fa: Dequeue[A])(f: A => B) = fa.map(f) + override def map[A, B](fa: Dequeue[A])(f: A => B) = fa.map(f) - override def coflatMap[A, B](fa: Dequeue[A])(f: Dequeue[A] => B): Dequeue[B] = fa.coflatMap(f) + override def coflatMap[A, B](fa: Dequeue[A])(f: Dequeue[A] => B): Dequeue[B] = fa.coflatMap(f) - override def foldLeft[A, B](fa: Dequeue[A], b: B)(f: (B, A) => B): B = - fa.foldLeft(b)(f) + override def foldLeft[A, B](fa: Dequeue[A], b: B)(f: (B, A) => B): B = + fa.foldLeft(b)(f) - override def foldRight[A, B](fa: Dequeue[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = fa.foldRight(lb)(f) + override def foldRight[A, B](fa: Dequeue[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = + fa.foldRight(lb)(f) - override def traverse[G[_], A, B](fa: Dequeue[A])(f: A => G[B])(implicit G: Applicative[G]): G[Dequeue[B]] = { - val gba = G.pure(EmptyDequeue[B]()) - fa.foldLeft(gba)((bs, a) => G.map2(bs, f(a))(_ :+ _)) + override def traverse[G[_], A, B](fa: Dequeue[A])(f: A => G[B])(implicit G: Applicative[G]): G[Dequeue[B]] = { + val gba = G.pure(EmptyDequeue[B]()) + fa.foldLeft(gba)((bs, a) => G.map2(bs, f(a))(_ :+ _)) + } } - } } diff --git a/core/src/main/scala/cats/collections/HashMap.scala b/core/src/main/scala/cats/collections/HashMap.scala index f0c005ca..75500fb0 100644 --- a/core/src/main/scala/cats/collections/HashMap.scala +++ b/core/src/main/scala/cats/collections/HashMap.scala @@ -56,6 +56,8 @@ import cats.kernel.Monoid import cats.kernel.compat.scalaVersionSpecific._ import cats.syntax.eq._ +import org.typelevel.scalaccompat.annotation.unused + import java.util.Arrays import HashMap.improve @@ -216,12 +218,12 @@ final class HashMap[K, +V] private[collections] (private[collections] val rootNo /** * Typesafe equality operator. * - * This method is similar to [[scala.Any#==]] except that it only allows two [[cats.data.HashMap]] values of the same - * key-value type to be compared to each other, and uses equality provided by [[cats.kernel.Eq]] instances, rather - * than using the universal equality provided by [[java.lang.Object#equals]]. + * This method is similar to [[scala.Any#==]] except that it only allows two [[HashMap]] values of the same key-value + * type to be compared to each other, and uses equality provided by [[cats.kernel.Eq]] instances, rather than using + * the universal equality provided by [[java.lang.Object#equals]]. * * @param that - * the [[cats.data.HashMap]] to check for equality with this map. + * the [[HashMap]] to check for equality with this map. * @param eqValue * the [[cats.kernel.Eq]] instance to use for comparing values. * @return @@ -309,38 +311,38 @@ object HashMap extends HashMapInstances with compat.HashMapCompatCompanion { scala.util.hashing.byteswap32(hash) /** - * Creates a new empty [[cats.data.HashMap]] which uses `hashKey` for hashing. + * Creates a new empty [[HashMap]] which uses `hashKey` for hashing. * * @param hashKey * the [[cats.kernel.Hash]] instance used for hashing keys. * @return - * a new empty [[cats.data.HashMap]]. + * a new empty [[HashMap]]. */ final def empty[K, V](implicit hashKey: Hash[K]): HashMap[K, V] = new HashMap[K, V](Node.empty[K, V]) /** - * Creates a new [[cats.data.HashMap]] which contains all elements of `kvs`. + * Creates a new [[HashMap]] which contains all elements of `kvs`. * * @param kvs - * the key-value pairs to add to the [[cats.data.HashMap]]. + * the key-value pairs to add to the [[HashMap]]. * @param hashKey * the [[cats.kernel.Hash]] instance used for hashing keys. * @return - * a new [[cats.data.HashMap]] which contains all elements of `kvs`. + * a new [[HashMap]] which contains all elements of `kvs`. */ final def apply[K, V](kvs: (K, V)*)(implicit hashKey: Hash[K]) = fromSeq(kvs) /** - * Creates a new [[cats.data.HashMap]] which contains all elements of `seq`. + * Creates a new [[HashMap]] which contains all elements of `seq`. * * @param seq - * the sequence of elements to add to the [[cats.data.HashMap]]. + * the sequence of elements to add to the [[HashMap]]. * @param hashKey * the [[cats.kernel.Hash]] instance used for hashing values. * @return - * a new [[cats.data.HashMap]] which contains all elements of `seq`. + * a new [[HashMap]] which contains all elements of `seq`. */ final def fromSeq[K, V](seq: Seq[(K, V)])(implicit hashKey: Hash[K]): HashMap[K, V] = { val rootNode = seq.foldLeft(Node.empty[K, V]) { case (node, (k, v)) => @@ -350,14 +352,14 @@ object HashMap extends HashMapInstances with compat.HashMapCompatCompanion { } /** - * Creates a new [[cats.data.HashMap]] which contains all elements of `iterable`. + * Creates a new [[HashMap]] which contains all elements of `iterable`. * * @param iterable - * the iterable source of elements to add to the [[cats.data.HashMap]]. + * the iterable source of elements to add to the [[HashMap]]. * @param hashKey * the [[cats.kernel.Hash]] instance used for hashing values. * @return - * a new [[cats.data.HashMap]] which contains all elements of `iterable`. + * a new [[HashMap]] which contains all elements of `iterable`. */ final def fromIterableOnce[K, V](iterable: IterableOnce[(K, V)])(implicit hashKey: Hash[K]): HashMap[K, V] = { iterable match { @@ -372,16 +374,16 @@ object HashMap extends HashMapInstances with compat.HashMapCompatCompanion { } /** - * Creates a new [[cats.data.HashMap]] which contains all elements of `fkv`. + * Creates a new [[HashMap]] which contains all elements of `fkv`. * * @param fkv - * the [[cats.Foldable]] structure of elements to add to the [[cats.data.HashMap]]. + * the [[cats.Foldable]] structure of elements to add to the [[HashMap]]. * @param F * the [[cats.Foldable]] instance used for folding the structure. * @param hashKey * the [[cats.kernel.Hash]] instance used for hashing values. * @return - * a new [[cats.data.HashMap]] which contains all elements of `fkv`. + * a new [[HashMap]] which contains all elements of `fkv`. */ final def fromFoldable[F[_], K, V](fkv: F[(K, V)])(implicit F: Foldable[F], hashKey: Hash[K]): HashMap[K, V] = { val rootNode = F.foldLeft(fkv, Node.empty[K, V]) { case (node, (k, v)) => @@ -527,7 +529,7 @@ object HashMap extends HashMapInstances with compat.HashMapCompatCompanion { * rather than using the universal equality provided by [[java.lang.Object#equals]]. * * @param that - * the [[cats.data.HashMap.Node]] to check for equality with this node. + * the [[HashMap.Node]] to check for equality with this node. * @param eqValue * the [[cats.kernel.Eq]] instance to use for comparing values. * @return @@ -1427,7 +1429,9 @@ object HashMap extends HashMapInstances with compat.HashMapCompatCompanion { } sealed abstract private[collections] class HashMapInstances extends HashMapInstances1 { - implicit def catsCollectionsUnorderedTraverseForHashMap[K: Hash]: UnorderedTraverse[HashMap[K, *]] = + implicit def catsCollectionsUnorderedTraverseForHashMap[K](implicit + @unused ev: Hash[K] + ): UnorderedTraverse[HashMap[K, *]] = new UnorderedTraverse[HashMap[K, *]] { override def nonEmpty[A](fa: HashMap[K, A]): Boolean = fa.nonEmpty diff --git a/core/src/main/scala/cats/collections/HashSet.scala b/core/src/main/scala/cats/collections/HashSet.scala index 7fdc8e89..f1654020 100644 --- a/core/src/main/scala/cats/collections/HashSet.scala +++ b/core/src/main/scala/cats/collections/HashSet.scala @@ -273,12 +273,12 @@ final class HashSet[A] private (private val rootNode: HashSet.Node[A])(implicit /** * Typesafe equality operator. * - * This method is similar to [[scala.Any#==]] except that it only allows two [[cats.data.HashSet]] values of the same - * element type to be compared to each other, and uses equality provided by [[cats.kernel.Eq]] instances, rather than - * using the universal equality provided by [[java.lang.Object#equals]]. + * This method is similar to [[scala.Any#==]] except that it only allows two [[HashSet]] values of the same element + * type to be compared to each other, and uses equality provided by [[cats.kernel.Eq]] instances, rather than using + * the universal equality provided by [[java.lang.Object#equals]]. * * @param that - * the [[cats.data.HashSet]] to check for equality with this set. + * the [[HashSet]] to check for equality with this set. * @return * `true` if this set and `that` are equal, `false` otherwise. */ @@ -319,38 +319,38 @@ object HashSet extends compat.HashSetCompatCompanion { scala.util.hashing.byteswap32(hash) /** - * Creates a new empty [[cats.data.HashSet]] which uses `hash` for hashing. + * Creates a new empty [[HashSet]] which uses `hash` for hashing. * * @param hash * the [[cats.kernel.Hash]] instance used for hashing values. * @return - * a new empty [[cats.data.HashSet]]. + * a new empty [[HashSet]]. */ final def empty[A](implicit hash: Hash[A]): HashSet[A] = new HashSet(Node.empty[A]) /** - * Creates a new [[cats.data.HashSet]] which contains all elements of `as`. + * Creates a new [[HashSet]] which contains all elements of `as`. * * @param as - * the elements to add to the [[cats.data.HashSet]]. + * the elements to add to the [[HashSet]]. * @param hash * the [[cats.kernel.Hash]] instance used for hashing values. * @return - * a new [[cats.data.HashSet]] which contains all elements of `as`. + * a new [[HashSet]] which contains all elements of `as`. */ final def apply[A](as: A*)(implicit hash: Hash[A]) = fromSeq(as) /** - * Creates a new [[cats.data.HashSet]] which contains all elements of `seq`. + * Creates a new [[HashSet]] which contains all elements of `seq`. * * @param seq - * the sequence of elements to add to the [[cats.data.HashSet]]. + * the sequence of elements to add to the [[HashSet]]. * @param hash * the [[cats.kernel.Hash]] instance used for hashing values. * @return - * a new [[cats.data.HashSet]] which contains all elements of `seq`. + * a new [[HashSet]] which contains all elements of `seq`. */ final def fromSeq[A](seq: Seq[A])(implicit hash: Hash[A]): HashSet[A] = { val rootNode = seq.foldLeft(Node.empty[A]) { case (node, a) => @@ -360,14 +360,14 @@ object HashSet extends compat.HashSetCompatCompanion { } /** - * Creates a new [[cats.data.HashSet]] which contains all elements of `iterable`. + * Creates a new [[HashSet]] which contains all elements of `iterable`. * * @param seq - * the iterable source of elements to add to the [[cats.data.HashSet]]. + * the iterable source of elements to add to the [[HashSet]]. * @param hash * the [[cats.kernel.Hash]] instance used for hashing values. * @return - * a new [[cats.data.HashSet]] which contains all elements of `iterable`. + * a new [[HashSet]] which contains all elements of `iterable`. */ final def fromIterableOnce[A](iterable: IterableOnce[A])(implicit hash: Hash[A]): HashSet[A] = { iterable match { @@ -382,16 +382,16 @@ object HashSet extends compat.HashSetCompatCompanion { } /** - * Creates a new [[cats.data.HashSet]] which contains all elements of `fkv`. + * Creates a new [[HashSet]] which contains all elements of `fkv`. * * @param fa - * the [[cats.Foldable]] structure of elements to add to the [[cats.data.HashSet]]. + * the [[cats.Foldable]] structure of elements to add to the [[HashSet]]. * @param F * the [[cats.Foldable]] instance used for folding the structure. * @param hash * the [[cats.kernel.Hash]] instance used for hashing values. * @return - * a new [[cats.data.HashSet]] which contains all elements of `fa`. + * a new [[HashSet]] which contains all elements of `fa`. */ final def fromFoldable[F[_], A](fa: F[A])(implicit F: Foldable[F], hash: Hash[A]): HashSet[A] = { val rootNode = F.foldLeft(fa, Node.empty[A]) { case (node, a) => diff --git a/core/src/main/scala/cats/collections/TreeList.scala b/core/src/main/scala/cats/collections/TreeList.scala index e415619b..90172352 100644 --- a/core/src/main/scala/cats/collections/TreeList.scala +++ b/core/src/main/scala/cats/collections/TreeList.scala @@ -40,6 +40,7 @@ import cats.{ import cats.implicits._ import scala.annotation.tailrec +import org.typelevel.scalaccompat.annotation._ /** * Implementation of "Purely Functional Random Access Lists" by Chris Okasaki. This gives O(1) cons and uncons, and 2 @@ -791,6 +792,9 @@ object TreeList extends TreeListInstances0 { ts.toIterator.map(sa.show(_)).mkString("TreeList(", ", ", ")") } + @nowarn213( + "msg=Calls to parameterless method compose will be easy to mistake for calls to overloads which have a single implicit parameter list" + ) implicit val catsCollectionTreeListInstances: Traverse[TreeList] with Alternative[TreeList] with Monad[TreeList] diff --git a/tests/src/test/scala/cats/collections/DequeueSuite.scala b/tests/src/test/scala/cats/collections/DequeueSuite.scala index 656feeea..c4de39e9 100644 --- a/tests/src/test/scala/cats/collections/DequeueSuite.scala +++ b/tests/src/test/scala/cats/collections/DequeueSuite.scala @@ -130,8 +130,8 @@ class DequeueSuite extends DisciplineSuite { assertEquals(q.toList, Foldable[Dequeue].toList(q)) }) - property("toList/toStream consistency")(forAll { (q: Dequeue[Int]) => - assertEquals(q.toList, q.to[Stream, Int].toList) + property("toList/toVector consistency")(forAll { (q: Dequeue[Int]) => + assertEquals(q.toList, q.to[Vector, Int].toList) }) property("equality")(forAll { (xs: List[Int]) => diff --git a/tests/src/test/scala/cats/collections/DisjointSetsSuite.scala b/tests/src/test/scala/cats/collections/DisjointSetsSuite.scala index bd900159..9fd8c182 100644 --- a/tests/src/test/scala/cats/collections/DisjointSetsSuite.scala +++ b/tests/src/test/scala/cats/collections/DisjointSetsSuite.scala @@ -66,11 +66,11 @@ class DisjointSetsSuite extends FunSuite { dsets.union(v, v % 10)._1 } - val groupByClassification = numbers.groupBy(_ % 10).mapValues(_.toSet).toMap + val groupByClassification = numbers.groupBy(_ % 10).transform((_, v) => v.toSet).toMap val (_, disjointSetsClassification) = classifiedNumbers.toSets assertEquals( - disjointSetsClassification.toScalaMap.mapValues(_.toScalaSet).toMap, + disjointSetsClassification.toScalaMap.transform((_, v) => v.toScalaSet).toMap, groupByClassification ) }