diff --git a/core/src/main/scala/simulacrum/typeclass.scala b/core/src/main/scala/simulacrum/typeclass.scala index 0060710..a23be7b 100644 --- a/core/src/main/scala/simulacrum/typeclass.scala +++ b/core/src/main/scala/simulacrum/typeclass.scala @@ -199,7 +199,7 @@ class TypeClassMacros(val c: Context) { if (arg equalsStructure Ident(simpleArg)) { (withRewrittenFirst, true) } else { - val typeEqualityType = tq"_root_.scala.Predef.=:=[${liftedTypeArg.name}, $arg]" + val typeEqualityType = tq"_root_.scala.Predef.<:<[${liftedTypeArg.name}, $arg]" val equalityEvidence = ValDef(Modifiers(Flag.IMPLICIT), TermName(c.freshName("ev")), typeEqualityType, EmptyTree) val updatedParamss = { if (withRewrittenFirst.nonEmpty && withRewrittenFirst.last.head.mods.hasFlag(Flag.IMPLICIT)) diff --git a/core/src/test/scala/simulacrum/typeclass.scala b/core/src/test/scala/simulacrum/typeclass.scala index 4c7fc35..daf1503 100644 --- a/core/src/test/scala/simulacrum/typeclass.scala +++ b/core/src/test/scala/simulacrum/typeclass.scala @@ -303,6 +303,22 @@ class TypeClassTest extends WordSpec with Matchers { import Foo.ops._ Option(Option(1)).bar } + + "supports type inference for syntax for operations where the instance type is constrained" in { + @typeclass trait Ap[F[_]] { + def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] + } + + object Ap { + implicit val apOption: Ap[Option] = new Ap[Option] { + def ap[A, B](ff: Option[A => B])(fa: Option[A]): Option[B] = ff.flatMap(fa.map) + } + } + + import Ap.ops._ + val ff: Option[Int => String] = Some(_.toString) + ff.ap(Some(0)) shouldBe Some("0") + } } "support annotated companions" in {