@@ -1014,6 +1014,12 @@ object Types {
10141014 case _ => this
10151015 }
10161016
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+
10171023 /** The type constructor of an applied type, otherwise the type itself */
10181024 final def typeConstructor (implicit ctx : Context ): Type = this match {
10191025 case AppliedType (tycon, _) => tycon
@@ -1312,15 +1318,18 @@ object Types {
13121318// ----- misc -----------------------------------------------------------
13131319
13141320 /** 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 .
13161322 * @param dropLast The number of trailing parameters that should be dropped
13171323 * when forming the function type.
13181324 */
13191325 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 =>
13211327 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
13241333 }
13251334
13261335 /** The signature of this type. This is by default NotAMethod,
@@ -2581,7 +2590,7 @@ object Types {
25812590 def integrate (tparams : List [ParamInfo ], tp : Type )(implicit ctx : Context ): Type =
25822591 tparams match {
25832592 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)
25852594 }
25862595
25872596 final def derivedLambdaType (paramNames : List [ThisName ] = this .paramNames,
@@ -2688,7 +2697,7 @@ object Types {
26882697 * def f(x: C)(y: x.S) // dependencyStatus = TrueDeps
26892698 * def f(x: C)(y: x.T) // dependencyStatus = FalseDeps, i.e.
26902699 * // dependency can be eliminated by dealiasing.
2691- */
2700+ */
26922701 private def dependencyStatus (implicit ctx : Context ): DependencyStatus = {
26932702 if (myDependencyStatus != Unknown ) myDependencyStatus
26942703 else {
@@ -2723,6 +2732,20 @@ object Types {
27232732 def isParamDependent (implicit ctx : Context ): Boolean = paramDependencyStatus == TrueDeps
27242733
27252734 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
27262749 }
27272750
27282751 abstract case class MethodType (paramNames : List [TermName ])(
@@ -3197,8 +3220,10 @@ object Types {
31973220 case _ => false
31983221 }
31993222
3223+ protected def kindString : String
3224+
32003225 override def toString =
3201- try s " ParamRef( $paramName) "
3226+ try s " ${kindString} ParamRef( $paramName) "
32023227 catch {
32033228 case ex : IndexOutOfBoundsException => s " ParamRef(<bad index: $paramNum>) "
32043229 }
@@ -3207,8 +3232,9 @@ object Types {
32073232 /** Only created in `binder.paramRefs`. Use `binder.paramRefs(paramNum)` to
32083233 * refer to `TermParamRef(binder, paramNum)`.
32093234 */
3210- abstract case class TermParamRef (binder : TermLambda , paramNum : Int ) extends ParamRef {
3235+ abstract case class TermParamRef (binder : TermLambda , paramNum : Int ) extends ParamRef with SingletonType {
32113236 type BT = TermLambda
3237+ def kindString = " Term"
32123238 def copyBoundType (bt : BT ) = bt.paramRefs(paramNum)
32133239 }
32143240
@@ -3217,6 +3243,7 @@ object Types {
32173243 */
32183244 abstract case class TypeParamRef (binder : TypeLambda , paramNum : Int ) extends ParamRef {
32193245 type BT = TypeLambda
3246+ def kindString = " Type"
32203247 def copyBoundType (bt : BT ) = bt.paramRefs(paramNum)
32213248
32223249 /** Looking only at the structure of `bound`, is one of the following true?
@@ -3731,7 +3758,7 @@ object Types {
37313758 // println(s"absMems: ${absMems map (_.show) mkString ", "}")
37323759 if (absMems.size == 1 )
37333760 absMems.head.info match {
3734- case mt : MethodType if ! mt.isDependent => Some (absMems.head)
3761+ case mt : MethodType if ! mt.isParamDependent => Some (absMems.head)
37353762 case _ => None
37363763 }
37373764 else if (tp isRef defn.PartialFunctionClass )
0 commit comments