milessabin/shapeless

Inconsistency in Generic derivation for non-case classes?

alexarchambault opened this issue · 1 comments

I'm getting the following when deriving (or trying to) Generic instances for non-case classes:

import shapeless.Generic

object Test {
  final class Foo(val n: Int)
  final class FooWithVal(val n: Int) {
    val isEven = n % 2 == 0
  }

  val fooGen = Generic[Foo] // works
  val fooWithValGen = Generic[FooWithVal] // fails, see error below
}

fails with

Test.scala:13:30: could not find implicit value for parameter gen: shapeless.Generic[Test.FooWithVal]
  val fooWithValGen = Generic[FooWithVal]
                             ^

So adding a val field in the body of a non-case class that Generic accepts, makes Generic reject it.

Is that intended somehow?

Just checking if that's expected or not, I can submit a fix for that.

It's falling foul of the logic which attempts to handle by-name constructor arguments. Ideally we'd like to be able to support,

class Foo(i0: => Int) {
  lazy val i: Int = i0
}

In this case we want the lazy val i in the body to be treated as the product element. There's a relevant test here. A fix would be lovely, so long as it doesn't break that one.