Skip to content
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

Lazy does not instantiate type parameters #828

Open
Katrix opened this issue May 1, 2018 · 6 comments · Fixed by #991
Open

Lazy does not instantiate type parameters #828

Katrix opened this issue May 1, 2018 · 6 comments · Fixed by #991
Assignees
Labels

Comments

@Katrix
Copy link

Katrix commented May 1, 2018

From my testing, Lazy does not work if more than a single type parameter is involved. I have only tested two myself.

import shapeless._

object LazyTest {

  new FindSimpleFooer[Int].find
  new FindLazySimpleFooer[Int].find
  new FindFooer[Int].find
  new FindLazyFooer[Int].find
}

class FindSimpleFooer[Tpe] {
  def find(implicit fooer: SimpleFooer[Tpe]) = fooer
}

class FindLazySimpleFooer[Tpe] {
  def find(implicit fooer: Lazy[SimpleFooer[Tpe]]) = fooer
}

class FindFooer[Tpe] {
  def find[F <: Foo](implicit fooer: Fooer[Tpe, F]) = fooer
}

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

trait Foo
case class BarFoo(i: Int) extends Foo

trait SimpleFooer[Tpe] {
  def makeFoo(obj: Tpe): Foo
}
object SimpleFooer {
  implicit val barFooer: SimpleFooer[Int] = (obj: Int) => BarFoo(obj)
}

trait Fooer[Tpe, FooTpe <: Foo] {
  def makeFoo(obj: Tpe): FooTpe
}
object Fooer {
  implicit val barFooer: Fooer[Int, BarFoo] = (obj: Int) => BarFoo(obj)
}
@joroKr21
Copy link
Collaborator

joroKr21 commented May 1, 2018

Lazy can't know what is F - it's probably Nothing

@Katrix
Copy link
Author

Katrix commented May 1, 2018

It works fine when Lazy is not present though. Only the last one of the four above fails.

@joroKr21 joroKr21 changed the title Lazy does not work for types with two type paramters Lazy does not instantiate type parameters Mar 24, 2020
@joroKr21 joroKr21 added the Bug label Mar 24, 2020
@joroKr21 joroKr21 self-assigned this Mar 24, 2020
@joroKr21 joroKr21 added this to the shapeless-2.4.0 milestone Mar 24, 2020
@joroKr21
Copy link
Collaborator

I meant that the problem is F <: Foo and not that there are two type parameters.

@Katrix
Copy link
Author

Katrix commented Mar 24, 2020

That bound is clearly needed as that's the bound of Fooer. Even if you remove that bound though, it still fails.

@joroKr21
Copy link
Collaborator

joroKr21 commented Mar 24, 2020

Yeah the reason is that Lazy is using a macro and inside we programatically ask the compiler to infer an implicit with that type, but that doesn't correspond exactly to what the compiler is doing. So we ask to infer Fooer[Tpe, F] where F is the type parameter and instead we should try to substitute it with a wildcard and ask for Fooer[Tpe, ? <: Foo]. I have a WIP for a fix, let's see if we can make it work.

@joroKr21
Copy link
Collaborator

joroKr21 commented May 4, 2021

We had to revert the fix, because it breaks kittens

@joroKr21 joroKr21 reopened this May 4, 2021
@joroKr21 joroKr21 removed this from the shapeless-2.4.0 milestone May 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants