diff --git a/core/src/main/scala/cats/implicits.scala b/core/src/main/scala/cats/implicits.scala index 1267851ae6..6094afa1b9 100644 --- a/core/src/main/scala/cats/implicits.scala +++ b/core/src/main/scala/cats/implicits.scala @@ -11,3 +11,4 @@ object implicits with instances.AllInstancesBinCompat0 with instances.AllInstancesBinCompat1 with instances.AllInstancesBinCompat2 + with instances.AllInstancesBinCompat3 diff --git a/core/src/main/scala/cats/instances/all.scala b/core/src/main/scala/cats/instances/all.scala index 3cc7339d9d..b46054f9d2 100644 --- a/core/src/main/scala/cats/instances/all.scala +++ b/core/src/main/scala/cats/instances/all.scala @@ -44,3 +44,5 @@ trait AllInstancesBinCompat1 with SortedMapInstancesBinCompat0 trait AllInstancesBinCompat2 extends DurationInstances with FiniteDurationInstances + +trait AllInstancesBinCompat3 extends AllCoreDurationInstances diff --git a/core/src/main/scala/cats/instances/duration.scala b/core/src/main/scala/cats/instances/duration.scala index 2cc6f1b940..8e0385390f 100644 --- a/core/src/main/scala/cats/instances/duration.scala +++ b/core/src/main/scala/cats/instances/duration.scala @@ -1,9 +1,26 @@ package cats package instances -import scala.concurrent.duration.Duration +import scala.concurrent.duration.{Duration, FiniteDuration} trait DurationInstances extends cats.kernel.instances.DurationInstances { - implicit val catsStdShowForDuration: Show[Duration] = + + @deprecated("Left to keep binary compatibility. Use CoreDurationInstances.catsStdShowForDurationUnambiguous instead.", + "1.5.0") + val catsStdShowForDuration: Show[Duration] = + AllCoreDurationInstances.catsStdShowForDurationUnambiguous +} + +private[instances] trait AllCoreDurationInstances extends CoreFiniteDurationInstances + +private[instances] trait CoreFiniteDurationInstances extends CoreDurationInstances { + implicit final val catsStdShowForFiniteDurationUnambiguous: Show[FiniteDuration] = + Show.fromToString[FiniteDuration] +} + +private[instances] trait CoreDurationInstances { + implicit final val catsStdShowForDurationUnambiguous: Show[Duration] = Show.fromToString[Duration] } + +private[instances] object AllCoreDurationInstances extends AllCoreDurationInstances diff --git a/core/src/main/scala/cats/instances/finiteDuration.scala b/core/src/main/scala/cats/instances/finiteDuration.scala index 182b7d9905..22077abaeb 100644 --- a/core/src/main/scala/cats/instances/finiteDuration.scala +++ b/core/src/main/scala/cats/instances/finiteDuration.scala @@ -4,6 +4,11 @@ package instances import scala.concurrent.duration.FiniteDuration trait FiniteDurationInstances extends cats.kernel.instances.FiniteDurationInstances { - implicit val catsStdShowForFiniteDuration: Show[FiniteDuration] = - Show.fromToString[FiniteDuration] + + @deprecated( + "Left to keep binary compatibility. Use CoreFiniteDurationInstances.catsStdShowForFiniteDurationUnambiguous instead.", + "1.5.0" + ) + val catsStdShowForFiniteDuration: Show[FiniteDuration] = + AllCoreDurationInstances.catsStdShowForFiniteDurationUnambiguous } diff --git a/core/src/main/scala/cats/instances/package.scala b/core/src/main/scala/cats/instances/package.scala index e32d519d53..60801f5e34 100644 --- a/core/src/main/scala/cats/instances/package.scala +++ b/core/src/main/scala/cats/instances/package.scala @@ -9,12 +9,12 @@ package object instances { object byte extends ByteInstances object char extends CharInstances object double extends DoubleInstances - object duration extends DurationInstances + object duration extends CoreDurationInstances with DurationInstances object either extends EitherInstances object eq extends EqInstances object equiv extends EquivInstances object float extends FloatInstances - object finiteDuration extends FiniteDurationInstances + object finiteDuration extends CoreFiniteDurationInstances with FiniteDurationInstances object function extends FunctionInstances with FunctionInstancesBinCompat0 object future extends FutureInstances object int extends IntInstances diff --git a/testkit/src/main/scala/cats/tests/CatsSuite.scala b/testkit/src/main/scala/cats/tests/CatsSuite.scala index 6f881244a1..e4da414b36 100644 --- a/testkit/src/main/scala/cats/tests/CatsSuite.scala +++ b/testkit/src/main/scala/cats/tests/CatsSuite.scala @@ -3,7 +3,13 @@ package tests import catalysts.Platform -import cats.instances.{AllInstances, AllInstancesBinCompat0, AllInstancesBinCompat1, AllInstancesBinCompat2} +import cats.instances.{ + AllInstances, + AllInstancesBinCompat0, + AllInstancesBinCompat1, + AllInstancesBinCompat2, + AllInstancesBinCompat3 +} import cats.syntax.{ AllSyntax, AllSyntaxBinCompat0, @@ -47,6 +53,7 @@ trait CatsSuite with AllInstancesBinCompat0 with AllInstancesBinCompat1 with AllInstancesBinCompat2 + with AllInstancesBinCompat3 with AllSyntax with AllSyntaxBinCompat0 with AllSyntaxBinCompat1 diff --git a/tests/src/test/scala/cats/tests/ShowSuite.scala b/tests/src/test/scala/cats/tests/ShowSuite.scala index 99d1997ba0..0f70850121 100644 --- a/tests/src/test/scala/cats/tests/ShowSuite.scala +++ b/tests/src/test/scala/cats/tests/ShowSuite.scala @@ -1,10 +1,15 @@ package cats package tests -import cats.Contravariant +import java.util.concurrent.TimeUnit + +import cats.Show.ContravariantShow import cats.laws.discipline.arbitrary._ import cats.laws.discipline.{ContravariantTests, SerializableTests} import cats.laws.discipline.eq._ +import org.scalatest.FunSuite + +import scala.concurrent.duration.{Duration, FiniteDuration} class ShowSuite extends CatsSuite { checkAll("Contravariant[Show]", ContravariantTests[Show].contravariant[Int, Int, Int]) @@ -34,4 +39,41 @@ class ShowSuite extends CatsSuite { assertResult("Good morning")(show"Good $tod") } + + test("contravariant show is not ambiguous when both FiniteDuration's and Duration's instances are in scope") { + implicitly[ContravariantShow[FiniteDuration]] + implicitly[ContravariantShow[Duration]] + } + + test("show interpolation works when both FiniteDuration's and Duration's instances are in scope") { + show"instance resolution is not ambiguous for ${FiniteDuration(3L, TimeUnit.SECONDS)}" + show"instance resolution is not ambiguous for ${Duration(3L, TimeUnit.SECONDS)}" + } +} + +final class ShowSuite2 extends FunSuite { + + test( + "contravariant show for FiniteDuration can be inferred when importing both duration's and finiteDuration's instances" + ) { + + import cats.instances.duration._ + import cats.instances.finiteDuration._ + + implicitly[Order[Duration]] + implicitly[Order[FiniteDuration]] + + implicitly[ContravariantShow[FiniteDuration]] + } + + test("all the Duration's and FiniteDuration's instances can be correctly inferred when importing implicits") { + + import cats.implicits._ + + implicitly[Order[Duration]] + implicitly[Order[FiniteDuration]] + + implicitly[ContravariantShow[Duration]] + implicitly[ContravariantShow[FiniteDuration]] + } }