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