@@ -25,9 +25,48 @@ object Applications {
25
25
26
26
private val isNamedArg = (arg : Any ) => arg.isInstanceOf [Trees .NamedArg [_]]
27
27
def hasNamedArg (args : List [Any ]) = args exists isNamedArg
28
+
29
+ /** A trait defining an `isCompatible` method. */
30
+ trait Compatibility {
31
+
32
+ /** Is there an implicit conversion from `tp` to `pt`? */
33
+ def viewExists (tp : Type , pt : Type )(implicit ctx : Context ): Boolean
34
+
35
+ /** A type `tp` is compatible with a type `pt` if one of the following holds:
36
+ * 1. `tp` is a subtype of `pt`
37
+ * 2. `pt` is by name parameter type, and `tp` is compatible with its underlying type
38
+ * 3. there is an implicit conversion from `tp` to `pt`.
39
+ */
40
+ def isCompatible (tp : Type , pt : Type )(implicit ctx : Context ): Boolean = (
41
+ tp <:< pt
42
+ || pt.typeSymbol == defn.ByNameParamClass && tp <:< pt.typeArgs.head
43
+ || viewExists(tp, pt)
44
+ )
45
+ }
46
+
47
+ /** A trait defining a `normalize` method. */
48
+ trait Normalizing {
49
+
50
+ /** The normalized form of a type
51
+ * - unwraps polymorphic types, tracking their parameters in the current constraint
52
+ * - skips implicit parameters
53
+ * - converts non-dependent method types to the corresponding function types
54
+ * - dereferences parameterless method types
55
+ */
56
+ def normalize (tp : Type )(implicit ctx : Context ): Type = tp.widen match {
57
+ case pt : PolyType => normalize(ctx.track(pt).resultType)
58
+ case mt : MethodType if ! mt.isDependent =>
59
+ if (mt.isImplicit) mt.resultType
60
+ else defn.FunctionType (mt.paramTypes, mt.resultType)
61
+ case et : ExprType => et.resultType
62
+ case _ => tp
63
+ }
64
+ }
28
65
}
29
66
30
- trait Applications { self : Typer =>
67
+ import Applications ._
68
+
69
+ trait Applications extends Compatibility with Normalizing { self : Typer =>
31
70
32
71
import Applications ._
33
72
import Trees ._
@@ -66,21 +105,6 @@ trait Applications { self: Typer =>
66
105
tree
67
106
}
68
107
69
- def normalize (tp : Type )(implicit ctx : Context ) = tp.widen match {
70
- case pt : PolyType => ctx.track(pt).resultType
71
- case mt : MethodType if ! mt.isDependent =>
72
- if (mt.isImplicit) mt.resultType
73
- else defn.FunctionType (mt.paramTypes, mt.resultType)
74
- case et : ExprType => et.resultType
75
- case _ => tp
76
- }
77
-
78
- def isCompatible (tp : Type , pt : Type )(implicit ctx : Context ): Boolean = (
79
- tp <:< pt
80
- || pt.typeSymbol == defn.ByNameParamClass && tp <:< pt.typeArgs.head
81
- || viewExists(tp, pt)
82
- )
83
-
84
108
/**
85
109
* @param Arg the type of arguments, could be tpd.Tree, untpd.Tree, or Type
86
110
* @param methRef the reference to the method of the application
@@ -492,6 +516,12 @@ trait Applications { self: Typer =>
492
516
def treeToArg (arg : tpd.Tree ): tpd.Tree = arg
493
517
}
494
518
519
+ def typedApply (app : untpd.Apply , fun : tpd.Tree , methRef : TermRef , args : List [tpd.Tree ], resultType : Type )(implicit ctx : Context ): tpd.Tree =
520
+ new ApplyToTyped (app, fun, methRef, args, resultType).result
521
+
522
+ def typedApply (fun : tpd.Tree , methRef : TermRef , args : List [tpd.Tree ], resultType : Type )(implicit ctx : Context ): tpd.Tree =
523
+ typedApply(Apply (untpd.TypedSplice (fun), Nil ), fun, methRef, args, resultType)
524
+
495
525
/** Is given method reference applicable to argument types `args`?
496
526
* @param resultType The expected result type of the application
497
527
*/
@@ -580,6 +610,9 @@ trait Applications { self: Typer =>
580
610
best :: asGood(alts1)
581
611
}
582
612
613
+ private val dummyTree = Literal (Constant (null ))
614
+ def dummyTreeOfType (tp : Type ): tpd.Tree = dummyTree withType tp
615
+
583
616
/** Resolve overloaded alternative `alts`, given expected type `pt`. */
584
617
def resolveOverloaded (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] = {
585
618
@@ -601,7 +634,7 @@ trait Applications { self: Typer =>
601
634
val argShape = treeShape(arg)
602
635
tree.withType(argShape.tpe).derivedNamedArg(name, argShape)
603
636
case _ =>
604
- Literal ( Constant ( null )) withType typeShape(tree)
637
+ dummyTreeOfType( typeShape(tree) )
605
638
}
606
639
607
640
def narrowByTypes (alts : List [TermRef ], argTypes : List [Type ], resultType : Type ): List [TermRef ] =
0 commit comments