@@ -2482,24 +2482,24 @@ object Types {
2482
2482
}
2483
2483
2484
2484
/** A common supertrait of PolyType and TypeLambda */
2485
- trait GenericType extends BindingType with TermType {
2486
-
2487
- /** The names of the type parameters */
2488
- val paramNames : List [TypeName ]
2485
+ abstract class GenericType (val paramNames : List [TypeName ])
2486
+ (paramBoundsExp : GenericType => List [TypeBounds ],
2487
+ resultTypeExp : GenericType => Type )
2488
+ extends CachedProxyType with BindingType with TermType {
2489
+ type This <: GenericType
2490
+ protected [this ] def companion : GenericCompanion [This ]
2489
2491
2490
2492
/** The bounds of the type parameters */
2491
- val paramBounds : List [TypeBounds ]
2493
+ val paramBounds : List [TypeBounds ] = paramBoundsExp( this )
2492
2494
2493
2495
/** The result type of a PolyType / body of a type lambda */
2494
- val resType : Type
2496
+ val resType : Type = resultTypeExp( this )
2495
2497
2496
2498
/** If this is a type lambda, the variances of its parameters, otherwise Nil.*/
2497
- def variances : List [Int ]
2499
+ def variances : List [Int ] = Nil
2498
2500
2499
2501
override def resultType (implicit ctx : Context ) = resType
2500
-
2501
- /** Unconditionally create a new generic type like this one with given elements */
2502
- def duplicate (paramNames : List [TypeName ] = this .paramNames, paramBounds : List [TypeBounds ] = this .paramBounds, resType : Type )(implicit ctx : Context ): GenericType
2502
+ override def underlying (implicit ctx : Context ) = resType
2503
2503
2504
2504
/** Instantiate result type by substituting parameters with given arguments */
2505
2505
final def instantiate (argTypes : List [Type ])(implicit ctx : Context ): Type =
@@ -2509,9 +2509,17 @@ object Types {
2509
2509
def instantiateBounds (argTypes : List [Type ])(implicit ctx : Context ): List [TypeBounds ] =
2510
2510
paramBounds.mapConserve(_.substParams(this , argTypes).bounds)
2511
2511
2512
- def derivedGenericType (paramNames : List [TypeName ], paramBounds : List [TypeBounds ], resType : Type )(implicit ctx : Context ) =
2512
+ /** Unconditionally create a new generic type like this one with given elements */
2513
+ def newLikeThis (paramNames : List [TypeName ] = this .paramNames, paramBounds : List [TypeBounds ] = this .paramBounds, resType : Type )(implicit ctx : Context ): This =
2514
+ companion.apply(paramNames, variances)(
2515
+ x => paramBounds mapConserve (_.subst(this , x).bounds),
2516
+ x => resType.subst(this , x))
2517
+
2518
+ def derivedGenericType (paramNames : List [TypeName ] = this .paramNames,
2519
+ paramBounds : List [TypeBounds ] = this .paramBounds,
2520
+ resType : Type = this .resType)(implicit ctx : Context ) =
2513
2521
if ((paramNames eq this .paramNames) && (paramBounds eq this .paramBounds) && (resType eq this .resType)) this
2514
- else duplicate (paramNames, paramBounds, resType)
2522
+ else newLikeThis (paramNames, paramBounds, resType)
2515
2523
2516
2524
/** PolyParam references to all type parameters of this type */
2517
2525
lazy val paramRefs : List [PolyParam ] = paramNames.indices.toList.map(PolyParam (this , _))
@@ -2533,14 +2541,28 @@ object Types {
2533
2541
other.variances == this .variances
2534
2542
case _ => false
2535
2543
}
2544
+
2545
+ override def computeHash = doHash(variances ::: paramNames, resType, paramBounds)
2546
+ }
2547
+
2548
+ abstract class GenericCompanion [GT <: GenericType ] {
2549
+ def apply (paramNames : List [TypeName ], variances : List [Int ])(
2550
+ paramBoundsExp : GenericType => List [TypeBounds ],
2551
+ resultTypeExp : GenericType => Type )(implicit ctx : Context ): GT
2552
+
2553
+ def fromSymbols (tparams : List [Symbol ], resultType : Type )(implicit ctx : Context ): Type =
2554
+ if (tparams.isEmpty) resultType
2555
+ else apply(tparams map (_.name.asTypeName), tparams.map(_.variance))(
2556
+ pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds),
2557
+ pt => pt.lifted(tparams, resultType))
2536
2558
}
2537
2559
2538
2560
/** A type for polymorphic methods */
2539
- class PolyType (val paramNames : List [TypeName ])(paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )
2540
- extends CachedGroundType with GenericType with MethodOrPoly {
2541
- val paramBounds : List [ TypeBounds ] = paramBoundsExp( this )
2542
- val resType : Type = resultTypeExp( this )
2543
- def variances = Nil
2561
+ class PolyType (paramNames : List [TypeName ])(paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )
2562
+ extends GenericType (paramNames)(paramBoundsExp, resultTypeExp) with MethodOrPoly {
2563
+
2564
+ type This = PolyType
2565
+ def companion = PolyType
2544
2566
2545
2567
protected def computeSignature (implicit ctx : Context ) = resultSignature
2546
2568
@@ -2549,70 +2571,59 @@ object Types {
2549
2571
case _ => false
2550
2572
}
2551
2573
2552
- def derivedPolyType (paramNames : List [TypeName ], paramBounds : List [TypeBounds ], resType : Type )(implicit ctx : Context ): PolyType =
2553
- derivedGenericType(paramNames, paramBounds, resType).asInstanceOf [PolyType ]
2554
-
2555
- def duplicate (paramNames : List [TypeName ] = this .paramNames, paramBounds : List [TypeBounds ] = this .paramBounds, resType : Type )(implicit ctx : Context ): PolyType =
2556
- PolyType (paramNames)(
2557
- x => paramBounds mapConserve (_.subst(this , x).bounds),
2558
- x => resType.subst(this , x))
2559
-
2560
2574
override def toString = s " PolyType( $paramNames, $paramBounds, $resType) "
2561
-
2562
- override def computeHash = doHash(paramNames, resType, paramBounds)
2563
2575
}
2564
2576
2565
- object PolyType {
2566
- def apply (paramNames : List [TypeName ])(paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )(implicit ctx : Context ): PolyType = {
2577
+ object PolyType extends GenericCompanion [ PolyType ] {
2578
+ def apply (paramNames : List [TypeName ], variances : List [ Int ] = Nil )(paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )(implicit ctx : Context ): PolyType = {
2567
2579
unique(new PolyType (paramNames)(paramBoundsExp, resultTypeExp))
2568
2580
}
2569
-
2570
- def fromSymbols (tparams : List [Symbol ], resultType : Type )(implicit ctx : Context ) =
2571
- if (tparams.isEmpty) resultType
2572
- else apply(tparams map (_.name.asTypeName))(
2573
- pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds),
2574
- pt => pt.lifted(tparams, resultType))
2575
2581
}
2576
2582
2577
2583
// ----- HK types: TypeLambda, LambdaParam, HKApply ---------------------
2578
2584
2579
2585
/** A type lambda of the form `[v_0 X_0, ..., v_n X_n] => T` */
2580
- class TypeLambda (val paramNames : List [TypeName ], val variances : List [Int ])(paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )
2581
- extends CachedProxyType with GenericType with ValueType {
2582
- val paramBounds = paramBoundsExp(this )
2583
- val resType = resultTypeExp(this )
2586
+ class TypeLambda (paramNames : List [TypeName ], override val variances : List [Int ])(
2587
+ paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )
2588
+ extends GenericType (paramNames)(paramBoundsExp, resultTypeExp) {
2584
2589
2585
2590
assert(resType.isInstanceOf [TermType ], this )
2586
2591
assert(paramNames.nonEmpty)
2587
2592
2588
- override def underlying (implicit ctx : Context ) = resType
2593
+ type This = TypeLambda
2594
+ def companion = TypeLambda
2589
2595
2590
2596
lazy val typeParams : List [LambdaParam ] =
2591
2597
paramNames.indices.toList.map(new LambdaParam (this , _))
2592
2598
2593
2599
def derivedLambdaAbstraction (paramNames : List [TypeName ], paramBounds : List [TypeBounds ], resType : Type )(implicit ctx : Context ): Type =
2594
2600
resType match {
2595
2601
case resType @ TypeAlias (alias) =>
2596
- resType.derivedTypeAlias(duplicate (paramNames, paramBounds, alias))
2602
+ resType.derivedTypeAlias(newLikeThis (paramNames, paramBounds, alias))
2597
2603
case resType @ TypeBounds (lo, hi) =>
2598
2604
resType.derivedTypeBounds(
2599
- if (lo.isRef(defn.NothingClass )) lo else duplicate (paramNames, paramBounds, lo),
2600
- duplicate (paramNames, paramBounds, hi))
2605
+ if (lo.isRef(defn.NothingClass )) lo else newLikeThis (paramNames, paramBounds, lo),
2606
+ newLikeThis (paramNames, paramBounds, hi))
2601
2607
case _ =>
2602
- derivedTypeLambda (paramNames, paramBounds, resType)
2608
+ derivedGenericType (paramNames, paramBounds, resType)
2603
2609
}
2604
2610
2605
- def derivedTypeLambda ( paramNames : List [ TypeName ] = paramNames, paramBounds : List [ TypeBounds ] = paramBounds, resType : Type )( implicit ctx : Context ) : TypeLambda =
2606
- derivedGenericType(paramNames, paramBounds, resType). asInstanceOf [ TypeLambda ]
2611
+ override def toString = s " TypeLambda( $variances , $ paramNames, $ paramBounds, $ resType) "
2612
+ }
2607
2613
2608
- def duplicate (paramNames : List [TypeName ] = this .paramNames, paramBounds : List [TypeBounds ] = this .paramBounds, resType : Type )(implicit ctx : Context ): TypeLambda =
2609
- TypeLambda (paramNames, variances)(
2610
- x => paramBounds mapConserve (_.subst(this , x).bounds),
2611
- x => resType.subst(this , x))
2614
+ object TypeLambda extends GenericCompanion [TypeLambda ] {
2615
+ def apply (paramNames : List [TypeName ], variances : List [Int ])(
2616
+ paramBoundsExp : GenericType => List [TypeBounds ],
2617
+ resultTypeExp : GenericType => Type )(implicit ctx : Context ): TypeLambda = {
2618
+ unique(new TypeLambda (paramNames, variances)(paramBoundsExp, resultTypeExp))
2619
+ }
2612
2620
2613
- override def toString = s " TypeLambda( $variances, $paramNames, $paramBounds, $resType) "
2621
+ def unapply (tl : TypeLambda ): Some [(List [LambdaParam ], Type )] =
2622
+ Some ((tl.typeParams, tl.resType))
2614
2623
2615
- override def computeHash = doHash(variances ::: paramNames, resType, paramBounds)
2624
+ def any (n : Int )(implicit ctx : Context ) =
2625
+ apply(tpnme.syntheticLambdaParamNames(n), List .fill(n)(0 ))(
2626
+ pt => List .fill(n)(TypeBounds .empty), pt => defn.AnyType )
2616
2627
}
2617
2628
2618
2629
/** The parameter of a type lambda */
@@ -2627,24 +2638,6 @@ object Types {
2627
2638
def paramRef (implicit ctx : Context ): Type = PolyParam (tl, n)
2628
2639
}
2629
2640
2630
- object TypeLambda {
2631
- def apply (paramNames : List [TypeName ], variances : List [Int ])(paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )(implicit ctx : Context ): TypeLambda = {
2632
- unique(new TypeLambda (paramNames, variances)(paramBoundsExp, resultTypeExp))
2633
- }
2634
-
2635
- def fromSymbols (tparams : List [Symbol ], resultType : Type )(implicit ctx : Context ) =
2636
- if (tparams.isEmpty) resultType
2637
- else apply(tparams map (_.name.asTypeName), tparams.map(_.variance))(
2638
- pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds),
2639
- pt => pt.lifted(tparams, resultType))
2640
- def unapply (tl : TypeLambda ): Some [(List [LambdaParam ], Type )] =
2641
- Some ((tl.typeParams, tl.resType))
2642
-
2643
- def any (n : Int )(implicit ctx : Context ) =
2644
- apply(tpnme.syntheticLambdaParamNames(n), List .fill(n)(0 ))(
2645
- pt => List .fill(n)(TypeBounds .empty), pt => defn.AnyType )
2646
- }
2647
-
2648
2641
/** A higher kinded type application `C[T_1, ..., T_n]` */
2649
2642
abstract case class HKApply (tycon : Type , args : List [Type ])
2650
2643
extends CachedProxyType with ValueType {
0 commit comments