propensive / wisteria

Easy, fast, transparent generic derivation of typeclass instances in Scala
https://soundness.dev/wisteria/
Apache License 2.0
19 stars 1 forks source link

Check default values are available from within sum derivations #8

Closed propensive closed 1 month ago

propensive commented 5 months ago

It seems like a default value can be accessed when deriving a product type, but not if that product type is being derived as part of a sum type.

NPCRUS commented 1 month ago

What I found is following(within Wisteria.default() macro), when trying to run some derivation for sum:

TypeRepr.of[ProductType] == wisteria.DefaultTest.First & wisteria.DefaultTest

it seems like the original DefaultTest.First type is being enchanced somewhere through wisteria derivation process with it's parent DefaultTest in this case somehow there's no access to usual product methods you would expect, but if you refine it to First by:

val productSymbol = TypeRepr.of[ProductType].classSymbol.get

now all default values are accessible as for case classes

propensive commented 1 month ago

If I understand correctly, First is a subtype of DefaultTest, so we should have that First & DefaultTest =:= First by subsumption of types. But if that's not happening automatically, and we end up getting the symbol for DefaultTest rather than First (because of the ordering of the types in the intersection, maybe?) then we would be looking at the parent type's companion object rather than the variant's companion when we look for the default values.

I've joined up some dots in this, but does it sound like I've misunderstood anywhere?

NPCRUS commented 1 month ago

@propensive You've joined it correctly. I'm not sure how the type subsumption should work exactly, but I think compiler doesn't understand that there's a subsumption because of this (SumDerivationMethods.scala, line 106):

type VariantType = variantType & DerivationType

where you manually intersect the current's variant variantType with DerivationType to make compiler happy on returning. I wasn't able to mitigate this intersection, it seems like we need it, but I adjusted code in macro, so that we can kinda access the class Symbol, which works for both case classes and sum variants: https://github.com/propensive/wisteria/pull/16