Skip to content

Commit 7ad47dd

Browse files
committed
Use a pattern-bound type variable instead of Any
`Bind` has an extra type parameter `S` which does not exist in `Resource`, so when pattern matching on `Bind`, that type parameter is replaced by a skolem (that is, a fresh abstract type whose bounds are those of `S` in `Bind`), we can get a reference to this skolem by using a pattern-bound type variable (here called `s`), this allows us to type the lambda parameter `r` correctly. Before this commit, `Any` was used instead of a type variable, this is unsound since `S` appears contravariantly in `fs` but didn't lead to any issue since it only appeared in the expression `fs(s)` (but if someone had accidentally written `fs(0)`, the compiler wouldn't have detected the error). This issue was identified by Dotty (though it somewhat confusingly reported that `Bind(_, _)` was missing from the match instead of reporting the use of an unchecked type test, I've minimized that and opened scala/scala3#9682), the remaining Dotty warnings are all unchecked type tests and they all seem like legitimate warnings to me. It's also worth noting that if we didn't have to cross-compile with Scala 2, we could just omit the type of the lambda parameter and Dotty would figure it out, so no explicit pattern-bound type variable would be needed at all :). I haven't tried it but this change should be backportable as-is to `series/2.x`.
1 parent c037893 commit 7ad47dd

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

core/shared/src/main/scala/cats/effect/Resource.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -665,11 +665,11 @@ abstract private[effect] class ResourceMonadError[F[_], E]
665665
case Left(error) => (Left(error), (_: ExitCase) => F.unit)
666666
case Right((a, release)) => (Right(a), release)
667667
})
668-
case Bind(source: Resource[F, Any], fs: (Any => Resource[F, A])) =>
668+
case Bind(source: Resource[F, s], fs) =>
669669
Suspend(F.pure(source).map[Resource[F, Either[E, A]]] { source =>
670670
Bind(
671671
attempt(source),
672-
(r: Either[E, Any]) =>
672+
(r: Either[E, s]) =>
673673
r match {
674674
case Left(error) => Resource.pure[F, Either[E, A]](Left(error))
675675
case Right(s) => attempt(fs(s))

0 commit comments

Comments
 (0)