Closed mpilquist closed 2 years ago
There's a lot going on in this code snippet, could you simplify it to a truly minimal example?
This may be a minimization:
//> using scala "3.1.1"
enum Pull[+F[_], +R]:
case Uncons(value: Pull[F, R]) extends Pull[F, Pull[F, R]]
def step[F[_], R](p: Pull[F, R]): F[Pull[F, R]] =
p match
case Pull.Uncons(v) => step(v)
[error] ./foo.scala:7:33: Found: (v : Pull[F, Any])
[error] Required: Pull[F, R]
[error]
[error] where: F is a type in method step with bounds <: [_] =>> Any
[error] R is a type in method step with bounds >: Pull[F, Any]
[error] case Pull.Uncons(v) => step(v)
[error]
./foo.scala:7:33: Found: (v : Pull[F, Any])
What would you expect to see instead of Any here? It doesn't seem like R would fit, since if v has type Pull[F, R] that would imply that p has type Pull[F, Pull[F, R]] whereas it has type Pull[F, R].
Hm, Pull[F, R]
along with R =:= Pull[F, R]
? Is that nonsensical?
I realized the original version infers v: Pull[F, Any, Any]
in both the method and the extension method examples. The extension method version types v.stepViaExtension.map(Left(_))
as F[Left[Either[Any, (Any, Pull[F, Any, Any])], Nothing]]
and it accepts that as a subtype of F[Either[R, (O, Pull[F, O, R])]]
.
R =:= Pull[F, R]
This would be a weird recursive type definition which I'm fairly sure we can't support (the best we can do is f-bounded types where a type appears in its own upper-bound, but not in its own lower-bound). I also don't think that would be sound but it's hard to say as-is since there's no way to create a value of type Pull.
Closing since there doesn't seem to be an agreed-upon bug here, but feel free to reopen with a different example or more precise description of what should happen.
Compiler version
3.1.1
Minimized code
Output
step
fails to compile with this error:Expectation
Any
is inferred for each of the type params ofv
. The equivalent match written as an extension method without bounded super types infers correctly.