-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Regression in eta-expansion while overloading as of 3.3.4 #21727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thank you for the bug report! Bisect on main points to 0337efd I'm preparing a self-contained minimization |
Self contained minimization with the same error: //> using options -Ykind-projector:underscores
import java.util.UUID
object MyId:
def fromUUID[F[_]: Functor: UUIDGen]: F[String] =
toFunctorOps(UUIDGen[F].randomUUID).map(fromUUID) // error
private def fromUUID(id: UUID): String = ???
object UUIDGen:
def apply[F[_]](implicit ev: UUIDGen[F]): UUIDGen[F] = ev
trait UUIDGen[F[_]]:
def randomUUID: F[UUID]
trait FlatMap[F[_]] extends Functor[F]
trait Functor[F[_]] extends Invariant[F]
trait Invariant[F[_]]
object Invariant:
implicit def catsFlatMapForMap[K]: FlatMap[Map[K, _]] = ???
implicit def catsFlatMapForSortedMap[K]: FlatMap[scala.collection.SortedMap[K, _]] = ???
implicit def toFunctorOps[F[_], A](target: F[A])(implicit tc: Functor[F]): Ops[F, A] { type TypeClassType = Functor[F]} =
new Ops[F, A] { type TypeClassType = Functor[F] }
trait Ops[F[_], A] {
type TypeClassType <: Functor[F]
def map[B](f: A => B): F[B] = ???
} The clue of the issue seems to be fact that Functor context bound parameter is being ignored, thus the issue can be further minimized to type UUID = String
object MyId:
def fromUUID[F[_]: Functor: UUIDGen]: F[String] =
toFunctorOps(UUIDGen[F].randomUUID).map(fromUUID) // error
private def fromUUID(id: UUID): String = ???
object UUIDGen:
def apply[F[_]](implicit ev: UUIDGen[F]): UUIDGen[F] = ev
trait UUIDGen[F[_]]:
def randomUUID: F[UUID]
trait Functor[F[_]]
implicit def toFunctorOps[F[_], A](target: F[A])(implicit tc: Functor[F]): Ops[F, A] { type TypeClassType = Functor[F]} =
new Ops[F, A] { type TypeClassType = Functor[F] }
trait Ops[F[_], A] {
type TypeClassType <: Functor[F]
def map[B](f: A => B): F[B] = ???
} Failing with [error] ./test_selfcontained.scala:4:53
[error] No given instance of type Functor[F] was found for a context parameter of method fromUUID in object MyId
[error]
[error] where: F is a type variable with constraint <: [R] =>> String => R
[error] toFunctorOps(UUIDGen[F].randomUUID).map(fromUUID)
[error] ^ |
@WojciechMazur note: //> using options -Xkind-projector:underscores |
also, cc @odersky |
Yes, I think we hit the limits of SAM expansion here. I would recommend one of the workarounds that were already listed. |
I dug some more why this happens. The critical code that was deleted in 0337efd was this: val compat0 = pt.dealias match
case defn.FunctionNOf(args, resType, _) =>
narrowByTypes(alts, args, resType)
case _ =>
Nil
if compat0.isEmpty then ...
else compat0 In other words, if the expected type was a function type, we do a private def fromUUID(id: UUID): String = ??? looks more like the expected function type than the alternative. But a full comparison would pick the alternative and then fail with a subsequent implicit search. The dubious clause had to be deleted because it causes other failures and has no logic justification. So in the interest of sanity it will stay deleted. |
It looks like we won't be fixing this. Closing it. |
Compiler version
The attached code compiled well up to
3.3.3
and stopped compiling with3.3.4
. Compilation also fails on latest3.5.1
.Minimized code
Also available as a gist https://gist.github.com/majk-p/b510b46cb38ecbb9bc7dd29c30a1055f
Notice how this only affects the short syntax without explicit parentheses. Adding
(_)
solves the issue. Changing the second method name to anything non-ambiguous also fixes the example, this means following example also works:Output
Expectation
Compiles with no issues
Additional research
I found the great bisect tool in compiler sources and run it against my example code. Here's the output:
This is how I configured the bisect tool:
It looks like #20862 is the PR that introduced the regression. CC: @WojciechMazur @bishabosha
The text was updated successfully, but these errors were encountered: