Skip to content

Commit

Permalink
Apply @threadUnsafe3 to lazy vals
Browse files Browse the repository at this point in the history
  • Loading branch information
armanbilge committed Nov 13, 2023
1 parent c2b8c1e commit e3ad690
Show file tree
Hide file tree
Showing 15 changed files with 50 additions and 12 deletions.
2 changes: 2 additions & 0 deletions core/src/main/scala/cats/Eval.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
package cats

import org.typelevel.scalaccompat.annotation.uncheckedVariance2
import org.typelevel.scalaccompat.annotation.threadUnsafe3

import scala.annotation.tailrec

Expand Down Expand Up @@ -479,6 +480,7 @@ trait EvalSemigroup[A] extends Semigroup[Eval[A]] {

trait EvalMonoid[A] extends Monoid[Eval[A]] with EvalSemigroup[A] {
implicit def algebra: Monoid[A]
@threadUnsafe3
lazy val empty: Eval[A] = Eval.later(algebra.empty)
}

Expand Down
2 changes: 2 additions & 0 deletions core/src/main/scala/cats/data/Ior.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ package data

import cats.arrow.FunctionK
import cats.data.Validated.{Invalid, Valid}
import org.typelevel.scalaccompat.annotation.threadUnsafe3

import scala.annotation.tailrec

Expand Down Expand Up @@ -946,6 +947,7 @@ sealed abstract private[data] class IorInstances extends IorInstances0 {
}
}

@threadUnsafe3
lazy val monad: Monad[Ior[E, *]] = Monad[Ior[E, *]]
}

Expand Down
4 changes: 4 additions & 0 deletions core/src/main/scala/cats/data/IorT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package cats
package data

import cats.arrow.FunctionK
import org.typelevel.scalaccompat.annotation.threadUnsafe3

final case class IorT[F[_], A, B](value: F[Ior[A, B]]) {

Expand Down Expand Up @@ -533,6 +534,7 @@ abstract private[data] class IorTInstances extends IorTInstances1 {
IorT(FA.map2(ff.value, fa.value)((f, a) => IorA.ap(f)(a)))
}

@threadUnsafe3
lazy val monad: Monad[IorT[M, E, *]] = {
implicit def underlyingMonadM: Monad[M] = P.monad
Monad[IorT[M, E, *]]
Expand Down Expand Up @@ -566,6 +568,7 @@ abstract private[data] class IorTInstances extends IorTInstances1 {
IorT(FA.map2(ff.value, fa.value)((f, a) => IorA.ap(f)(a)))
}

@threadUnsafe3
lazy val monad: Monad[IorT[M, E, *]] = {
implicit def underlyingMonadM: Monad[M] = P.monad
Monad[IorT[M, E, *]]
Expand Down Expand Up @@ -611,6 +614,7 @@ abstract private[data] class IorTInstances1 extends IorTInstances2 {
IorT(F.map2(ff.value, fa.value)((f, a) => underlyingParallel.applicative.ap[A, B](f)(a)))
}

@threadUnsafe3
lazy val monad: Monad[IorT[F0, E, *]] = Monad[IorT[F0, E, *]]
}

Expand Down
3 changes: 2 additions & 1 deletion core/src/main/scala/cats/data/Kleisli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ package data
import cats.{Contravariant, Id}
import cats.arrow._
import cats.evidence.As
import org.typelevel.scalaccompat.annotation.threadUnsafe3

/**
* Represents a function `A => F[B]`.
Expand Down Expand Up @@ -372,7 +373,7 @@ sealed abstract private[data] class KleisliInstances extends KleisliInstances0 {
implicit def catsDataDeferForKleisli[F[_], A](implicit F: Defer[F]): Defer[Kleisli[F, A, *]] =
new Defer[Kleisli[F, A, *]] {
def defer[B](fa: => Kleisli[F, A, B]): Kleisli[F, A, B] = {
lazy val cacheFa = fa
@threadUnsafe3 lazy val cacheFa = fa
Kleisli[F, A, B] { a =>
F.defer(cacheFa.run(a))
}
Expand Down
3 changes: 3 additions & 0 deletions core/src/main/scala/cats/data/RepresentableStore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
package cats.data

import cats.{Comonad, Functor, Representable}
import org.typelevel.scalaccompat.annotation.threadUnsafe3

/**
* A generalization of `StoreT`, where the underlying functor `F` has a `Representable` instance.
Expand Down Expand Up @@ -53,12 +54,14 @@ final case class RepresentableStore[F[_], S, A](fa: F[A], index: S)(implicit R:
/**
* Extract the value at the current index.
*/
@threadUnsafe3
lazy val extract: A = peek(index)

/**
* `coflatten` is the dual of `flatten` on `FlatMap`. Whereas flatten removes
* a layer of `F`, coflatten adds a layer of `F`
*/
@threadUnsafe3
lazy val coflatten: RepresentableStore[F, S, RepresentableStore[F, S, A]] =
RepresentableStore(R.tabulate(idx => RepresentableStore(fa, idx)), index)

Expand Down
3 changes: 2 additions & 1 deletion core/src/main/scala/cats/data/Tuple2K.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package cats
package data

import cats.arrow.FunctionK
import org.typelevel.scalaccompat.annotation.threadUnsafe3

/**
* [[Tuple2K]] is a product to two independent functor values.
Expand Down Expand Up @@ -89,7 +90,7 @@ sealed abstract private[data] class Tuple2KInstances extends Tuple2KInstances0 {
new Defer[Tuple2K[F, G, *]] {
def defer[A](fa: => Tuple2K[F, G, A]): Tuple2K[F, G, A] = {
// Make sure we only evaluate once on both the first and second
lazy val cacheFa = fa
@threadUnsafe3 lazy val cacheFa = fa

Tuple2K(F.defer(cacheFa.first), G.defer(cacheFa.second))
}
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/scala/cats/instances/eq.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
package cats
package instances

import org.typelevel.scalaccompat.annotation.threadUnsafe3

import scala.annotation.tailrec

trait EqInstances extends kernel.instances.EqInstances {
Expand Down Expand Up @@ -52,6 +54,7 @@ object EqInstances {
private val catsDeferForEqCache: Defer[Eq] =
new Defer[Eq] {
case class Deferred[A](fa: () => Eq[A]) extends Eq[A] {
@threadUnsafe3
private lazy val resolved: Eq[A] = {
@tailrec
def loop(f: () => Eq[A]): Eq[A] =
Expand All @@ -66,7 +69,7 @@ object EqInstances {
}

override def defer[A](fa: => Eq[A]): Eq[A] = {
lazy val cachedFa = fa
@threadUnsafe3 lazy val cachedFa = fa
Deferred(() => cachedFa)
}
}
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/scala/cats/instances/equiv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
package cats
package instances

import org.typelevel.scalaccompat.annotation.threadUnsafe3

import scala.annotation.tailrec

trait EquivInstances {
Expand Down Expand Up @@ -61,6 +63,7 @@ object EquivInstances {
private val catsDeferForEquivCache: Defer[Equiv] =
new Defer[Equiv] {
case class Deferred[A](fa: () => Equiv[A]) extends Equiv[A] {
@threadUnsafe3
private lazy val resolved: Equiv[A] = {
@tailrec
def loop(f: () => Equiv[A]): Equiv[A] =
Expand All @@ -75,7 +78,7 @@ object EquivInstances {
}

override def defer[A](fa: => Equiv[A]): Equiv[A] = {
lazy val cachedFa = fa
@threadUnsafe3 lazy val cachedFa = fa
Deferred(() => cachedFa)
}
}
Expand Down
7 changes: 5 additions & 2 deletions core/src/main/scala/cats/instances/function.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ package instances
import cats.Contravariant
import cats.arrow.{ArrowChoice, Category, CommutativeArrow}
import cats.data.AndThen
import org.typelevel.scalaccompat.annotation.threadUnsafe3

import annotation.tailrec

Expand All @@ -46,6 +47,7 @@ private[instances] trait FunctionInstancesBinCompat0 {
implicit val catsSddDeferForFunction0: Defer[Function0] =
new Defer[Function0] {
case class Deferred[A](fa: () => Function0[A]) extends Function0[A] {
@threadUnsafe3
private lazy val resolved: Function0[A] = {
@annotation.tailrec
def loop(f: () => Function0[A]): Function0[A] =
Expand All @@ -59,14 +61,15 @@ private[instances] trait FunctionInstancesBinCompat0 {
def apply(): A = resolved()
}
def defer[A](fa: => Function0[A]): Function0[A] = {
lazy val cachedFa = fa
@threadUnsafe3 lazy val cachedFa = fa
Deferred(() => cachedFa)
}
}

implicit def catsStdDeferForFunction1[A]: Defer[A => *] =
new Defer[A => *] {
case class Deferred[B](fa: () => A => B) extends (A => B) {
@threadUnsafe3
private lazy val resolved: A => B = {
@annotation.tailrec
def loop(f: () => A => B): A => B =
Expand All @@ -80,7 +83,7 @@ private[instances] trait FunctionInstancesBinCompat0 {
def apply(a: A): B = resolved(a)
}
def defer[B](fa: => A => B): A => B = {
lazy val cachedFa = fa
@threadUnsafe3 lazy val cachedFa = fa
Deferred(() => cachedFa)
}
}
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/scala/cats/instances/hash.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
package cats
package instances

import org.typelevel.scalaccompat.annotation.threadUnsafe3

import scala.annotation.tailrec

trait HashInstances extends kernel.instances.HashInstances {
Expand All @@ -42,6 +44,7 @@ object HashInstances {
private val catsDeferForHashCache: Defer[Hash] =
new Defer[Hash] {
case class Deferred[A](fa: () => Hash[A]) extends Hash[A] {
@threadUnsafe3
private lazy val resolve: Hash[A] = {
@tailrec
def loop(f: () => Hash[A]): Hash[A] =
Expand All @@ -62,7 +65,7 @@ object HashInstances {
}

override def defer[A](fa: => Hash[A]): Hash[A] = {
lazy val cachedFa = fa
@threadUnsafe3 lazy val cachedFa = fa
Deferred(() => cachedFa)
}
}
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/scala/cats/instances/order.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package cats
package instances

import cats.kernel.instances.unit._
import org.typelevel.scalaccompat.annotation.threadUnsafe3

import scala.annotation.tailrec

Expand Down Expand Up @@ -56,6 +57,7 @@ object OrderInstances {
private val catsDeferForOrderCache: Defer[Order] =
new Defer[Order] {
case class Deferred[A](fa: () => Order[A]) extends Order[A] {
@threadUnsafe3
private lazy val resolved: Order[A] = {
@tailrec
def loop(f: () => Order[A]): Order[A] =
Expand All @@ -70,7 +72,7 @@ object OrderInstances {
}

override def defer[A](fa: => Order[A]): Order[A] = {
lazy val cachedFa = fa
@threadUnsafe3 lazy val cachedFa = fa
Deferred(() => cachedFa)
}
}
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/scala/cats/instances/ordering.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package cats
package instances

import cats.kernel.instances.unit._
import org.typelevel.scalaccompat.annotation.threadUnsafe3

import scala.annotation.tailrec

Expand Down Expand Up @@ -52,6 +53,7 @@ object OrderingInstances {
private val catsStdDeferForOrderingCache: Defer[Ordering] =
new Defer[Ordering] {
case class Deferred[A](fa: () => Ordering[A]) extends Ordering[A] {
@threadUnsafe3
private lazy val resolved: Ordering[A] = {
@tailrec
def loop(f: () => Ordering[A]): Ordering[A] =
Expand All @@ -66,7 +68,7 @@ object OrderingInstances {
}

override def defer[A](fa: => Ordering[A]): Ordering[A] = {
lazy val cachedFa = fa
@threadUnsafe3 lazy val cachedFa = fa
Deferred(() => cachedFa)
}
}
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/scala/cats/instances/partialOrder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ package cats
package instances
import cats.kernel.instances.unit._

import org.typelevel.scalaccompat.annotation.threadUnsafe3

import scala.annotation.tailrec

trait PartialOrderInstances extends kernel.instances.PartialOrderInstances {
Expand Down Expand Up @@ -50,6 +52,7 @@ object PartialOrderInstances {
private val catsDeferForPartialOrderCache: Defer[PartialOrder] =
new Defer[PartialOrder] {
case class Deferred[A](fa: () => PartialOrder[A]) extends PartialOrder[A] {
@threadUnsafe3
private lazy val resolved: PartialOrder[A] = {
@tailrec
def loop(f: () => PartialOrder[A]): PartialOrder[A] =
Expand All @@ -64,7 +67,7 @@ object PartialOrderInstances {
}

override def defer[A](fa: => PartialOrder[A]): PartialOrder[A] = {
lazy val cachedFa = fa
@threadUnsafe3 lazy val cachedFa = fa
Deferred(() => cachedFa)
}
}
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/scala/cats/instances/partialOrdering.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
package cats
package instances

import org.typelevel.scalaccompat.annotation.threadUnsafe3

import scala.annotation.tailrec

trait PartialOrderingInstances {
Expand Down Expand Up @@ -60,6 +62,7 @@ object PartialOrderingInstances {
private val catsStdDeferForPartialOrderingCache: Defer[PartialOrdering] =
new Defer[PartialOrdering] {
case class Deferred[A](fa: () => PartialOrdering[A]) extends PartialOrdering[A] {
@threadUnsafe3
private lazy val resolve: PartialOrdering[A] = {
@tailrec
def loop(f: () => PartialOrdering[A]): PartialOrdering[A] =
Expand All @@ -77,7 +80,7 @@ object PartialOrderingInstances {
}

override def defer[A](fa: => PartialOrdering[A]): PartialOrdering[A] = {
lazy val cachedFa = fa
@threadUnsafe3 lazy val cachedFa = fa
Deferred(() => cachedFa)
}
}
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/scala/cats/instances/show.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
package cats
package instances

import org.typelevel.scalaccompat.annotation.threadUnsafe3

import scala.annotation.tailrec

trait ShowInstances {
Expand All @@ -31,6 +33,7 @@ object ShowInstances {
private val catsDeferForShowCache: Defer[Show] =
new Defer[Show] {
case class Deferred[A](fa: () => Show[A]) extends Show[A] {
@threadUnsafe3
private lazy val resolved: Show[A] = {
@tailrec
def loop(f: () => Show[A]): Show[A] =
Expand All @@ -45,7 +48,7 @@ object ShowInstances {
}

override def defer[A](fa: => Show[A]): Show[A] = {
lazy val cachedFa = fa
@threadUnsafe3 lazy val cachedFa = fa
Deferred(() => cachedFa)
}
}
Expand Down

0 comments on commit e3ad690

Please sign in to comment.