Skip to content

Commit

Permalink
Merge pull request #991 from joroKr21/lazy-type-params
Browse files Browse the repository at this point in the history
Fix Lazy implicit resolution with type parameters
  • Loading branch information
joroKr21 authored Mar 24, 2020
2 parents 88a803f + 65243a0 commit 17e3c6f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
16 changes: 10 additions & 6 deletions core/src/main/scala/shapeless/lazy.scala
Original file line number Diff line number Diff line change
Expand Up @@ -295,17 +295,21 @@ class LazyMacros(val c: whitebox.Context) extends CaseClassMacros with OpenImpli

private var current = Option.empty[State]

private def typeParamsToWildcards(tpe: Type): Type = tpe.map { t =>
val sym = t.typeSymbol
if (sym.isParameter) boundedWildcardType(sym.info.asInstanceOf[TypeBounds]) else t
}

def resolveInstance(state: State)(tpe: Type): Option[(State, Tree)] = {
val former = State.current
State.current = Some(state)
val (state0, tree) =
try {
val tree = c.inferImplicitValue(tpe, silent = true)
if(tree.isEmpty) {
tpe.typeSymbol.annotations.
find(_.tree.tpe =:= typeOf[_root_.scala.annotation.implicitNotFound]).foreach { _ =>
setAnnotation(implicitNotFoundMessage(c)(tpe))
}
val tree = c.inferImplicitValue(tpe, silent = true) orElse c.inferImplicitValue(typeParamsToWildcards(tpe), silent = true)
if (tree.isEmpty) {
tpe.typeSymbol.annotations
.find(_.tree.tpe =:= typeOf[_root_.scala.annotation.implicitNotFound])
.foreach(_ => setAnnotation(implicitNotFoundMessage(c)(tpe)))
}
(State.current.get, tree)
} finally {
Expand Down
24 changes: 24 additions & 0 deletions core/src/test/scala/shapeless/lazy.scala
Original file line number Diff line number Diff line change
Expand Up @@ -334,3 +334,27 @@ class LazyStrictTests {
implicitly[Strict[Readable[Id]]]
}
}

object TestLazyWithTypeParametersAndBounds {
trait Foo
case class BarFoo(i: Int) extends Foo

trait Fooer[Tpe, FooTpe] {
def makeFoo(obj: Tpe): FooTpe
}

object Fooer {
implicit val barFooer: Fooer[Int, BarFoo] = null
}

class Finder[Tpe] {
def find[F <: Foo](implicit fooer: Fooer[Tpe, F]) = fooer
def findLazy[F <: Foo](implicit fooer: Lazy[Fooer[Tpe, F]]) = fooer
def findNoBounds[F](implicit fooer: Lazy[Fooer[Tpe, F]]) = fooer
}

val intFinder = new Finder[Int]
intFinder.find
intFinder.findLazy
intFinder.findNoBounds
}

0 comments on commit 17e3c6f

Please sign in to comment.