@@ -1014,6 +1014,12 @@ object Types {
1014
1014
case _ => this
1015
1015
}
1016
1016
1017
+ /** Dealias, and if result is a dependent function type, drop the `apply` refinement. */
1018
+ final def dropDependentRefinement (implicit ctx : Context ): Type = dealias match {
1019
+ case RefinedType (parent, nme.apply, _) => parent
1020
+ case tp => tp
1021
+ }
1022
+
1017
1023
/** The type constructor of an applied type, otherwise the type itself */
1018
1024
final def typeConstructor (implicit ctx : Context ): Type = this match {
1019
1025
case AppliedType (tycon, _) => tycon
@@ -1312,15 +1318,18 @@ object Types {
1312
1318
// ----- misc -----------------------------------------------------------
1313
1319
1314
1320
/** Turn type into a function type.
1315
- * @pre this is a non-dependent method type.
1321
+ * @pre this is a method type without parameter dependencies .
1316
1322
* @param dropLast The number of trailing parameters that should be dropped
1317
1323
* when forming the function type.
1318
1324
*/
1319
1325
def toFunctionType (dropLast : Int = 0 )(implicit ctx : Context ): Type = this match {
1320
- case mt : MethodType if ! mt.isDependent || ctx.mode.is( Mode . AllowDependentFunctions ) =>
1326
+ case mt : MethodType if ! mt.isParamDependent =>
1321
1327
val formals1 = if (dropLast == 0 ) mt.paramInfos else mt.paramInfos dropRight dropLast
1322
- defn.FunctionOf (
1323
- formals1 mapConserve (_.underlyingIfRepeated(mt.isJavaMethod)), mt.resultType, mt.isImplicitMethod && ! ctx.erasedTypes)
1328
+ val funType = defn.FunctionOf (
1329
+ formals1 mapConserve (_.underlyingIfRepeated(mt.isJavaMethod)),
1330
+ mt.nonDependentResultApprox, mt.isImplicitMethod && ! ctx.erasedTypes)
1331
+ if (mt.isDependent) RefinedType (funType, nme.apply, mt)
1332
+ else funType
1324
1333
}
1325
1334
1326
1335
/** The signature of this type. This is by default NotAMethod,
@@ -2581,7 +2590,7 @@ object Types {
2581
2590
def integrate (tparams : List [ParamInfo ], tp : Type )(implicit ctx : Context ): Type =
2582
2591
tparams match {
2583
2592
case LambdaParam (lam, _) :: _ => tp.subst(lam, this )
2584
- case tparams : List [Symbol @ unchecked] => tp.subst(tparams , paramRefs)
2593
+ case params : List [Symbol @ unchecked] => tp.subst(params , paramRefs)
2585
2594
}
2586
2595
2587
2596
final def derivedLambdaType (paramNames : List [ThisName ] = this .paramNames,
@@ -2688,7 +2697,7 @@ object Types {
2688
2697
* def f(x: C)(y: x.S) // dependencyStatus = TrueDeps
2689
2698
* def f(x: C)(y: x.T) // dependencyStatus = FalseDeps, i.e.
2690
2699
* // dependency can be eliminated by dealiasing.
2691
- */
2700
+ */
2692
2701
private def dependencyStatus (implicit ctx : Context ): DependencyStatus = {
2693
2702
if (myDependencyStatus != Unknown ) myDependencyStatus
2694
2703
else {
@@ -2723,6 +2732,20 @@ object Types {
2723
2732
def isParamDependent (implicit ctx : Context ): Boolean = paramDependencyStatus == TrueDeps
2724
2733
2725
2734
def newParamRef (n : Int ) = new TermParamRef (this , n) {}
2735
+
2736
+ /** The least supertype of `resultType` that does not contain parameter dependencies */
2737
+ def nonDependentResultApprox (implicit ctx : Context ): Type =
2738
+ if (isDependent) {
2739
+ val dropDependencies = new ApproximatingTypeMap {
2740
+ def apply (tp : Type ) = tp match {
2741
+ case tp @ TermParamRef (thisLambdaType, _) =>
2742
+ range(tp.bottomType, atVariance(1 )(apply(tp.underlying)))
2743
+ case _ => mapOver(tp)
2744
+ }
2745
+ }
2746
+ dropDependencies(resultType)
2747
+ }
2748
+ else resultType
2726
2749
}
2727
2750
2728
2751
abstract case class MethodType (paramNames : List [TermName ])(
@@ -3197,8 +3220,10 @@ object Types {
3197
3220
case _ => false
3198
3221
}
3199
3222
3223
+ protected def kindString : String
3224
+
3200
3225
override def toString =
3201
- try s " ParamRef( $paramName) "
3226
+ try s " ${kindString} ParamRef( $paramName) "
3202
3227
catch {
3203
3228
case ex : IndexOutOfBoundsException => s " ParamRef(<bad index: $paramNum>) "
3204
3229
}
@@ -3207,8 +3232,9 @@ object Types {
3207
3232
/** Only created in `binder.paramRefs`. Use `binder.paramRefs(paramNum)` to
3208
3233
* refer to `TermParamRef(binder, paramNum)`.
3209
3234
*/
3210
- abstract case class TermParamRef (binder : TermLambda , paramNum : Int ) extends ParamRef {
3235
+ abstract case class TermParamRef (binder : TermLambda , paramNum : Int ) extends ParamRef with SingletonType {
3211
3236
type BT = TermLambda
3237
+ def kindString = " Term"
3212
3238
def copyBoundType (bt : BT ) = bt.paramRefs(paramNum)
3213
3239
}
3214
3240
@@ -3217,6 +3243,7 @@ object Types {
3217
3243
*/
3218
3244
abstract case class TypeParamRef (binder : TypeLambda , paramNum : Int ) extends ParamRef {
3219
3245
type BT = TypeLambda
3246
+ def kindString = " Type"
3220
3247
def copyBoundType (bt : BT ) = bt.paramRefs(paramNum)
3221
3248
3222
3249
/** Looking only at the structure of `bound`, is one of the following true?
@@ -3731,7 +3758,7 @@ object Types {
3731
3758
// println(s"absMems: ${absMems map (_.show) mkString ", "}")
3732
3759
if (absMems.size == 1 )
3733
3760
absMems.head.info match {
3734
- case mt : MethodType if ! mt.isDependent => Some (absMems.head)
3761
+ case mt : MethodType if ! mt.isParamDependent => Some (absMems.head)
3735
3762
case _ => None
3736
3763
}
3737
3764
else if (tp isRef defn.PartialFunctionClass )
0 commit comments