@@ -476,9 +476,14 @@ trait ClassLikeSupport:
476476 val memberInfo = unwrapMemberInfo(c, methodSymbol)
477477
478478 val basicKind : Kind .Def = Kind .Def (
479- genericTypes.map(mkTypeArgument(_, memberInfo.genericTypes)),
480- paramLists.zipWithIndex.map { (pList, index) =>
481- ParametersList (pList.params.map(mkParameter(_, paramPrefix, memberInfo = memberInfo.paramLists(index))), paramListModifier(pList.params))
479+ genericTypes.map(mkTypeArgument(_, memberInfo.genericTypes, memberInfo.contextBounds)),
480+ paramLists.zipWithIndex.flatMap { (pList, index) =>
481+ memberInfo.paramLists(index) match
482+ case EvidenceOnlyParameterList => Nil
483+ case info : RegularParameterList =>
484+ Seq (ParametersList (pList.params.map(
485+ mkParameter(_, paramPrefix, memberInfo = info)), paramListModifier(pList.params)
486+ ))
482487 }
483488 )
484489
@@ -523,20 +528,30 @@ trait ClassLikeSupport:
523528 isGrouped
524529 )
525530
526- def mkTypeArgument (argument : TypeDef , memberInfo : Map [String , TypeBounds ] = Map .empty): TypeParameter =
531+ def mkTypeArgument (
532+ argument : TypeDef ,
533+ memberInfo : Map [String , TypeBounds ] = Map .empty,
534+ contextBounds : Map [String , DSignature ] = Map .empty
535+ ): TypeParameter =
527536 val variancePrefix : " +" | " -" | " " =
528537 if argument.symbol.flags.is(Flags .Covariant ) then " +"
529538 else if argument.symbol.flags.is(Flags .Contravariant ) then " -"
530539 else " "
531540
532541 val name = argument.symbol.normalizedName
533542 val normalizedName = if name.matches(" _\\ $\\ d*" ) then " _" else name
543+ val boundsSignature = memberInfo.get(name).fold(argument.rhs.asSignature)(_.asSignature)
544+ val signature = contextBounds.get(name) match
545+ case None => boundsSignature
546+ case Some (contextBoundsSignature) =>
547+ boundsSignature ++ DSignature (" : " ) ++ contextBoundsSignature
548+
534549 TypeParameter (
535550 argument.symbol.getAnnotations(),
536551 variancePrefix,
537552 normalizedName,
538553 argument.symbol.dri,
539- memberInfo.get(name).fold(argument.rhs.asSignature)(_.asSignature)
554+ signature
540555 )
541556
542557 def parseTypeDef (typeDef : TypeDef ): Member =
@@ -586,7 +601,18 @@ trait ClassLikeSupport:
586601 deprecated = deprecated
587602 )
588603
589- case class MemberInfo (genericTypes : Map [String , TypeBounds ], paramLists : List [Map [String , TypeRepr ]], res : TypeRepr )
604+ object EvidenceOnlyParameterList
605+ type RegularParameterList = Map [String , TypeRepr ]
606+ type ParameterList = RegularParameterList | EvidenceOnlyParameterList .type
607+
608+ case class MemberInfo (
609+ genericTypes : Map [String , TypeBounds ],
610+ paramLists : List [ParameterList ],
611+ res : TypeRepr ,
612+ contextBounds : Map [String , DSignature ] = Map .empty,
613+ )
614+
615+ def isSyntheticEvidence (name : String ) = name.startsWith(" evidence$" )
590616
591617 def unwrapMemberInfo (c : ClassDef , symbol : Symbol ): MemberInfo =
592618 val baseTypeRepr = memberInfo(c, symbol)
@@ -595,7 +621,35 @@ trait ClassLikeSupport:
595621 MemberInfo (polyType.paramNames.zip(polyType.paramBounds).toMap, List .empty, polyType.resType)
596622
597623 def handleMethodType (memberInfo : MemberInfo , methodType : MethodType ): MemberInfo =
598- MemberInfo (memberInfo.genericTypes, memberInfo.paramLists ++ List (methodType.paramNames.zip(methodType.paramTypes).toMap), methodType.resType)
624+ val rawParams = methodType.paramNames.zip(methodType.paramTypes).toMap
625+ val (evidences, newParams) = rawParams.partition(e => isSyntheticEvidence(e._1))
626+ val newLists : List [ParameterList ] = if newParams.isEmpty && evidences.nonEmpty
627+ then memberInfo.paramLists ++ Seq (EvidenceOnlyParameterList )
628+ else memberInfo.paramLists ++ Seq (newParams)
629+
630+ def findParamRefs (t : TypeRepr ): Seq [ParamRef ] = t match
631+ case paramRef : ParamRef => Seq (paramRef)
632+ case AppliedType (_, args) => args.flatMap(findParamRefs)
633+ case MatchType (bound, scrutinee, cases) =>
634+ findParamRefs(bound) ++ findParamRefs(scrutinee)
635+ case _ => Nil
636+
637+ def nameForRef (ref : ParamRef ): String =
638+ val PolyType (names, _, _) = ref.binder
639+ names(ref.paramNum)
640+
641+ val contextBounds =
642+ evidences.collect {
643+ case (_, AppliedType (tpe, List (typeParam : ParamRef ))) =>
644+ nameForRef(typeParam) -> tpe.asSignature
645+ case (_, original) =>
646+ val typeParam = findParamRefs(original).head // TODO throw nicer error!
647+ val name = nameForRef(typeParam)
648+ val signature = Seq (s " ([ $name] =>> " ) ++ original.asSignature ++ Seq (" )" )
649+ name -> signature
650+ }
651+
652+ MemberInfo (memberInfo.genericTypes, newLists , methodType.resType, contextBounds.toMap)
599653
600654 def handleByNameType (memberInfo : MemberInfo , byNameType : ByNameType ): MemberInfo =
601655 MemberInfo (memberInfo.genericTypes, memberInfo.paramLists, byNameType.underlying)
0 commit comments