@@ -12,6 +12,8 @@ import scala.reflect.ClassTag
1212object Magnolia {
1313 import CompileTimeState ._
1414
15+ /** A "typeclass" that is a subtype of any typeclass.
16+ */
1517 private [Magnolia ] type ConstNothing [a] = Nothing
1618
1719 /** derives a generic typeclass instance for the type `T`
@@ -569,6 +571,9 @@ object Magnolia {
569571
570572 val paramsValDef = {
571573 val method = TermName (if (isReadOnly) " readOnlyParams" else " params" )
574+
575+ // When building `paramsVal`, we simultaneously let the typer calculate the narrowest subtype of the original `Typeclass`
576+ // we can fit over the params. We can then use it instead of the original `Typeclass`.
572577 q " $PartsObj. $method[ $typeConstructor, $genericType](.. $paramsItems) "
573578 }
574579
@@ -1000,6 +1005,7 @@ final class Parts[F[+_[_]], Tc[_]]private[Parts] (val array: Array[F[Tc]]) exten
10001005/** Helpers to guide `Param`/`Subtype` array types and to provide access to the resulting typeclass.
10011006 */
10021007object Parts {
1008+ // This is the magic that lets the typer choose a narrower typeclass, while still being constrained by the original `Typeclass` (`TcWide` here).
10031009 def params [TcWide [_], T ]: PartiallyApplied [Param [* [_], T ], TcWide ] = new PartiallyApplied [Param [* [_], T ], TcWide ]()
10041010 def readOnlyParams [TcWide [_], T ]: PartiallyApplied [ReadOnlyParam [* [_], T ], TcWide ] = new PartiallyApplied [ReadOnlyParam [* [_], T ], TcWide ]()
10051011 def subtypes [TcWide [_], T ]: PartiallyApplied [Subtype [* [_], T ], TcWide ] = new PartiallyApplied [Subtype [* [_], T ], TcWide ]()
0 commit comments