@@ -2508,24 +2508,24 @@ object Types {
2508
2508
}
2509
2509
2510
2510
/** A common supertrait of PolyType and TypeLambda */
2511
- trait GenericType extends BindingType with TermType {
2512
-
2513
- /** The names of the type parameters */
2514
- val paramNames : List [TypeName ]
2511
+ abstract class GenericType (val paramNames : List [TypeName ])
2512
+ (paramBoundsExp : GenericType => List [TypeBounds ],
2513
+ resultTypeExp : GenericType => Type )
2514
+ extends CachedProxyType with BindingType with TermType {
2515
+ type This <: GenericType
2516
+ protected [this ] def companion : GenericCompanion [This ]
2515
2517
2516
2518
/** The bounds of the type parameters */
2517
- val paramBounds : List [TypeBounds ]
2519
+ val paramBounds : List [TypeBounds ] = paramBoundsExp( this )
2518
2520
2519
2521
/** The result type of a PolyType / body of a type lambda */
2520
- val resType : Type
2522
+ val resType : Type = resultTypeExp( this )
2521
2523
2522
2524
/** If this is a type lambda, the variances of its parameters, otherwise Nil.*/
2523
- def variances : List [Int ]
2525
+ def variances : List [Int ] = Nil
2524
2526
2525
2527
override def resultType (implicit ctx : Context ) = resType
2526
-
2527
- /** Unconditionally create a new generic type like this one with given elements */
2528
- def duplicate (paramNames : List [TypeName ] = this .paramNames, paramBounds : List [TypeBounds ] = this .paramBounds, resType : Type )(implicit ctx : Context ): GenericType
2528
+ override def underlying (implicit ctx : Context ) = resType
2529
2529
2530
2530
/** Instantiate result type by substituting parameters with given arguments */
2531
2531
final def instantiate (argTypes : List [Type ])(implicit ctx : Context ): Type =
@@ -2535,9 +2535,17 @@ object Types {
2535
2535
def instantiateBounds (argTypes : List [Type ])(implicit ctx : Context ): List [TypeBounds ] =
2536
2536
paramBounds.mapConserve(_.substParams(this , argTypes).bounds)
2537
2537
2538
- def derivedGenericType (paramNames : List [TypeName ], paramBounds : List [TypeBounds ], resType : Type )(implicit ctx : Context ) =
2538
+ /** Unconditionally create a new generic type like this one with given elements */
2539
+ def newLikeThis (paramNames : List [TypeName ] = this .paramNames, paramBounds : List [TypeBounds ] = this .paramBounds, resType : Type )(implicit ctx : Context ): This =
2540
+ companion.apply(paramNames, variances)(
2541
+ x => paramBounds mapConserve (_.subst(this , x).bounds),
2542
+ x => resType.subst(this , x))
2543
+
2544
+ def derivedGenericType (paramNames : List [TypeName ] = this .paramNames,
2545
+ paramBounds : List [TypeBounds ] = this .paramBounds,
2546
+ resType : Type = this .resType)(implicit ctx : Context ) =
2539
2547
if ((paramNames eq this .paramNames) && (paramBounds eq this .paramBounds) && (resType eq this .resType)) this
2540
- else duplicate (paramNames, paramBounds, resType)
2548
+ else newLikeThis (paramNames, paramBounds, resType)
2541
2549
2542
2550
/** PolyParam references to all type parameters of this type */
2543
2551
lazy val paramRefs : List [PolyParam ] = paramNames.indices.toList.map(PolyParam (this , _))
@@ -2559,14 +2567,28 @@ object Types {
2559
2567
other.variances == this .variances
2560
2568
case _ => false
2561
2569
}
2570
+
2571
+ override def computeHash = doHash(variances ::: paramNames, resType, paramBounds)
2572
+ }
2573
+
2574
+ abstract class GenericCompanion [GT <: GenericType ] {
2575
+ def apply (paramNames : List [TypeName ], variances : List [Int ])(
2576
+ paramBoundsExp : GenericType => List [TypeBounds ],
2577
+ resultTypeExp : GenericType => Type )(implicit ctx : Context ): GT
2578
+
2579
+ def fromSymbols (tparams : List [Symbol ], resultType : Type )(implicit ctx : Context ): Type =
2580
+ if (tparams.isEmpty) resultType
2581
+ else apply(tparams map (_.name.asTypeName), tparams.map(_.variance))(
2582
+ pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds),
2583
+ pt => pt.lifted(tparams, resultType))
2562
2584
}
2563
2585
2564
2586
/** A type for polymorphic methods */
2565
- class PolyType (val paramNames : List [TypeName ])(paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )
2566
- extends CachedGroundType with GenericType with MethodOrPoly {
2567
- val paramBounds : List [ TypeBounds ] = paramBoundsExp( this )
2568
- val resType : Type = resultTypeExp( this )
2569
- def variances = Nil
2587
+ class PolyType (paramNames : List [TypeName ])(paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )
2588
+ extends GenericType (paramNames)(paramBoundsExp, resultTypeExp) with MethodOrPoly {
2589
+
2590
+ type This = PolyType
2591
+ def companion = PolyType
2570
2592
2571
2593
protected def computeSignature (implicit ctx : Context ) = resultSignature
2572
2594
@@ -2575,14 +2597,6 @@ object Types {
2575
2597
case _ => false
2576
2598
}
2577
2599
2578
- def derivedPolyType (paramNames : List [TypeName ], paramBounds : List [TypeBounds ], resType : Type )(implicit ctx : Context ): PolyType =
2579
- derivedGenericType(paramNames, paramBounds, resType).asInstanceOf [PolyType ]
2580
-
2581
- def duplicate (paramNames : List [TypeName ] = this .paramNames, paramBounds : List [TypeBounds ] = this .paramBounds, resType : Type )(implicit ctx : Context ): PolyType =
2582
- PolyType (paramNames)(
2583
- x => paramBounds mapConserve (_.subst(this , x).bounds),
2584
- x => resType.subst(this , x))
2585
-
2586
2600
/** Merge nested polytypes into one polytype. nested polytypes are normally not supported
2587
2601
* but can arise as temporary data structures.
2588
2602
*/
@@ -2602,61 +2616,58 @@ object Types {
2602
2616
}
2603
2617
2604
2618
override def toString = s " PolyType( $paramNames, $paramBounds, $resType) "
2605
-
2606
- override def computeHash = doHash(paramNames, resType, paramBounds)
2607
2619
}
2608
2620
2609
- object PolyType {
2610
- def apply (paramNames : List [TypeName ])(paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )(implicit ctx : Context ): PolyType = {
2621
+ object PolyType extends GenericCompanion [ PolyType ] {
2622
+ def apply (paramNames : List [TypeName ], variances : List [ Int ] = Nil )(paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )(implicit ctx : Context ): PolyType = {
2611
2623
unique(new PolyType (paramNames)(paramBoundsExp, resultTypeExp))
2612
2624
}
2613
-
2614
- def fromSymbols (tparams : List [Symbol ], resultType : Type )(implicit ctx : Context ) =
2615
- if (tparams.isEmpty) resultType
2616
- else apply(tparams map (_.name.asTypeName))(
2617
- pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds),
2618
- pt => pt.lifted(tparams, resultType))
2619
2625
}
2620
2626
2621
2627
// ----- HK types: TypeLambda, LambdaParam, HKApply ---------------------
2622
2628
2623
2629
/** A type lambda of the form `[v_0 X_0, ..., v_n X_n] => T` */
2624
- class TypeLambda (val paramNames : List [TypeName ], val variances : List [Int ])(paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )
2625
- extends CachedProxyType with GenericType with ValueType {
2626
- val paramBounds = paramBoundsExp(this )
2627
- val resType = resultTypeExp(this )
2630
+ class TypeLambda (paramNames : List [TypeName ], override val variances : List [Int ])(
2631
+ paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )
2632
+ extends GenericType (paramNames)(paramBoundsExp, resultTypeExp) {
2628
2633
2629
2634
assert(resType.isInstanceOf [TermType ], this )
2630
2635
assert(paramNames.nonEmpty)
2631
2636
2632
- override def underlying (implicit ctx : Context ) = resType
2637
+ type This = TypeLambda
2638
+ def companion = TypeLambda
2633
2639
2634
2640
lazy val typeParams : List [LambdaParam ] =
2635
2641
paramNames.indices.toList.map(new LambdaParam (this , _))
2636
2642
2637
2643
def derivedLambdaAbstraction (paramNames : List [TypeName ], paramBounds : List [TypeBounds ], resType : Type )(implicit ctx : Context ): Type =
2638
2644
resType match {
2639
2645
case resType @ TypeAlias (alias) =>
2640
- resType.derivedTypeAlias(duplicate (paramNames, paramBounds, alias))
2646
+ resType.derivedTypeAlias(newLikeThis (paramNames, paramBounds, alias))
2641
2647
case resType @ TypeBounds (lo, hi) =>
2642
2648
resType.derivedTypeBounds(
2643
- if (lo.isRef(defn.NothingClass )) lo else duplicate (paramNames, paramBounds, lo),
2644
- duplicate (paramNames, paramBounds, hi))
2649
+ if (lo.isRef(defn.NothingClass )) lo else newLikeThis (paramNames, paramBounds, lo),
2650
+ newLikeThis (paramNames, paramBounds, hi))
2645
2651
case _ =>
2646
- derivedTypeLambda (paramNames, paramBounds, resType)
2652
+ derivedGenericType (paramNames, paramBounds, resType)
2647
2653
}
2648
2654
2649
- def derivedTypeLambda ( paramNames : List [ TypeName ] = paramNames, paramBounds : List [ TypeBounds ] = paramBounds, resType : Type )( implicit ctx : Context ) : TypeLambda =
2650
- derivedGenericType(paramNames, paramBounds, resType). asInstanceOf [ TypeLambda ]
2655
+ override def toString = s " TypeLambda( $variances , $ paramNames, $ paramBounds, $ resType) "
2656
+ }
2651
2657
2652
- def duplicate (paramNames : List [TypeName ] = this .paramNames, paramBounds : List [TypeBounds ] = this .paramBounds, resType : Type )(implicit ctx : Context ): TypeLambda =
2653
- TypeLambda (paramNames, variances)(
2654
- x => paramBounds mapConserve (_.subst(this , x).bounds),
2655
- x => resType.subst(this , x))
2658
+ object TypeLambda extends GenericCompanion [TypeLambda ] {
2659
+ def apply (paramNames : List [TypeName ], variances : List [Int ])(
2660
+ paramBoundsExp : GenericType => List [TypeBounds ],
2661
+ resultTypeExp : GenericType => Type )(implicit ctx : Context ): TypeLambda = {
2662
+ unique(new TypeLambda (paramNames, variances)(paramBoundsExp, resultTypeExp))
2663
+ }
2656
2664
2657
- override def toString = s " TypeLambda( $variances, $paramNames, $paramBounds, $resType) "
2665
+ def unapply (tl : TypeLambda ): Some [(List [LambdaParam ], Type )] =
2666
+ Some ((tl.typeParams, tl.resType))
2658
2667
2659
- override def computeHash = doHash(variances ::: paramNames, resType, paramBounds)
2668
+ def any (n : Int )(implicit ctx : Context ) =
2669
+ apply(tpnme.syntheticLambdaParamNames(n), List .fill(n)(0 ))(
2670
+ pt => List .fill(n)(TypeBounds .empty), pt => defn.AnyType )
2660
2671
}
2661
2672
2662
2673
/** The parameter of a type lambda */
@@ -2671,24 +2682,6 @@ object Types {
2671
2682
def paramRef (implicit ctx : Context ): Type = PolyParam (tl, n)
2672
2683
}
2673
2684
2674
- object TypeLambda {
2675
- def apply (paramNames : List [TypeName ], variances : List [Int ])(paramBoundsExp : GenericType => List [TypeBounds ], resultTypeExp : GenericType => Type )(implicit ctx : Context ): TypeLambda = {
2676
- unique(new TypeLambda (paramNames, variances)(paramBoundsExp, resultTypeExp))
2677
- }
2678
-
2679
- def fromSymbols (tparams : List [Symbol ], resultType : Type )(implicit ctx : Context ) =
2680
- if (tparams.isEmpty) resultType
2681
- else apply(tparams map (_.name.asTypeName), tparams.map(_.variance))(
2682
- pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds),
2683
- pt => pt.lifted(tparams, resultType))
2684
- def unapply (tl : TypeLambda ): Some [(List [LambdaParam ], Type )] =
2685
- Some ((tl.typeParams, tl.resType))
2686
-
2687
- def any (n : Int )(implicit ctx : Context ) =
2688
- apply(tpnme.syntheticLambdaParamNames(n), List .fill(n)(0 ))(
2689
- pt => List .fill(n)(TypeBounds .empty), pt => defn.AnyType )
2690
- }
2691
-
2692
2685
/** A higher kinded type application `C[T_1, ..., T_n]` */
2693
2686
abstract case class HKApply (tycon : Type , args : List [Type ])
2694
2687
extends CachedProxyType with ValueType {
0 commit comments