Skip to content

Commit

Permalink
Merge pull request #2228 from armanbilge/thunk-ce2
Browse files Browse the repository at this point in the history
Backport thunk
  • Loading branch information
djspiewak authored Aug 14, 2021
2 parents 0cd5da5 + d92e81e commit 82e6bf8
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
4 changes: 2 additions & 2 deletions core/shared/src/main/scala/cats/effect/IO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1152,7 +1152,7 @@ object IO extends IOInstances {
* `IO`.
*/
def defer[A](thunk: => IO[A]): IO[A] = {
val nextIo = Suspend(() => thunk)
val nextIo = Suspend(Thunk.asFunction0(thunk))
if (isFullStackTracing) {
IOTracing.decorated(nextIo)
} else {
Expand All @@ -1167,7 +1167,7 @@ object IO extends IOInstances {
* into the `IO`.
*/
def delay[A](body: => A): IO[A] = {
val nextIo = Delay(() => body)
val nextIo = Delay(Thunk.asFunction0(body))
if (isFullStackTracing) {
IOTracing.decorated(nextIo)
} else {
Expand Down
29 changes: 29 additions & 0 deletions core/shared/src/main/scala/cats/effect/Thunk.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2017-2021 The Typelevel Cats-effect Project Developers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package cats.effect

/**
* A utility to convert a by-name `thunk: => A` to a `Function0[A]` (its binary representation).
* Scala 2 performs this optimization automatically but on Scala 3 the thunk is wrapped inside of a new `Function0`.
* See https://github.com/typelevel/cats-effect/pull/2226
*/
private object Thunk {
private[this] val impl =
((x: Any) => x).asInstanceOf[(=> Any) => Function0[Any]]

def asFunction0[A](thunk: => A): Function0[A] = impl(thunk).asInstanceOf[Function0[A]]
}
27 changes: 27 additions & 0 deletions core/shared/src/test/scala/cats/effect/ThunkSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2020-2021 Typelevel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package cats.effect

class ThunkSpec extends CatsEffectSuite {

test("Thunk.asFunction0") {
var i = 0
val f = () => i += 1
assertEquals(Thunk.asFunction0(f()), f)
}

}

0 comments on commit 82e6bf8

Please sign in to comment.