@@ -324,6 +324,15 @@ object ProtoTypes {
324
324
def typedArgs : List [Tree ] = typedArgs(force = true )
325
325
def unforcedTypedArgs : List [Tree ] = typedArgs(force = false )
326
326
327
+ /** The types of all arguments that are already known at this point.
328
+ * WildcardType for the others.
329
+ */
330
+ def unforcedArgTypes (implicit ctx : Context ): List [Type ] =
331
+ for (arg <- args) yield {
332
+ val targ = state.typedArg(arg)
333
+ if (targ != null ) targ.tpe else WildcardType
334
+ }
335
+
327
336
/** Type single argument and remember the unadapted result in `myTypedArg`.
328
337
* used to avoid repeated typings of trees when backtracking.
329
338
*/
@@ -393,6 +402,32 @@ object ProtoTypes {
393
402
override def withContext (ctx : Context ): FunProtoTyped = this
394
403
}
395
404
405
+ /** A wildcard approximation of FunProtos used in implicit search */
406
+ abstract class WildFunProto (argTypes : List [Type ], resType : Type )
407
+ extends CachedGroundType with ProtoType {
408
+
409
+ def isMatchedBy (tp : Type , keepConstraint : Boolean = false )(implicit ctx : Context ): Boolean = true
410
+
411
+ def fold [T ](x : T , ta : TypeAccumulator [T ])(implicit ctx : Context ): T =
412
+ ta(ta.foldOver(x, argTypes), resType)
413
+
414
+ def map (tm : TypeMap )(implicit ctx : Context ): ProtoType =
415
+ derivedWildFunProto(argTypes.mapconserve(tm), tm(resType))
416
+
417
+ def derivedWildFunProto (argTypes : List [Type ], resType : Type )(implicit ctx : Context ) =
418
+ if ((argTypes `eq` this .argTypes) && (resType `eq` this .resType)) this
419
+ else WildFunProto (argTypes, resType)
420
+ }
421
+
422
+ class CachedWildFunProto (argTypes : List [Type ], resultType : Type ) extends WildFunProto (argTypes, resultType) {
423
+ override def computeHash (bs : Hashable .Binders ): Int = doHash(bs, argTypes, resultType)
424
+ }
425
+
426
+ object WildFunProto {
427
+ def apply (argTypes : List [Type ], resType : Type )(implicit ctx : Context ) =
428
+ unique(new CachedWildFunProto (argTypes, resType))
429
+ }
430
+
396
431
/** A prototype for implicitly inferred views:
397
432
*
398
433
* []: argType => resultType
@@ -661,7 +696,9 @@ object ProtoTypes {
661
696
wildApprox(tp.argType, theMap, seen),
662
697
wildApprox(tp.resultType, theMap, seen))
663
698
case tp : FunProto =>
664
- WildcardType
699
+ WildFunProto (
700
+ tp.unforcedArgTypes.mapConserve(wildApprox(_, theMap, seen)),
701
+ wildApprox(tp.resType, theMap, seen))
665
702
case _ : ThisType | _ : BoundType => // default case, inlined for speed
666
703
tp
667
704
case _ =>
0 commit comments