diff options
Diffstat (limited to 'src/dotty/tools')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeErasure.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeOps.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 133 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ElimRepeated.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/SuperAccessors.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/ProtoTypes.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/TypeAssigner.scala | 2 |
11 files changed, 76 insertions, 84 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index f32a591a6..8a4b47efb 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -485,7 +485,7 @@ class TypeApplications(val self: Type) extends AnyVal { // In this case we should always dealias since we cannot handle // higher-kinded applications to wildcard arguments. dealiased - .derivedTypeLambda(resType = tycon.safeDealias.appliedTo(args1)) + .derivedGenericType(resType = tycon.safeDealias.appliedTo(args1)) .appliedTo(args) case _ => val reducer = new Reducer(dealiased, args) diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index b518bf9d9..4c962747a 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -1344,7 +1344,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { case tp1: PolyType => tp2 match { case tp2: PolyType if matchingTypeParams(tp1, tp2) => - tp1.derivedPolyType( + tp1.derivedGenericType( mergeNames(tp1.paramNames, tp2.paramNames, tpnme.syntheticTypeParamName), tp1.paramBounds, tp1.resultType & tp2.resultType.subst(tp2, tp1)) case _ => diff --git a/src/dotty/tools/dotc/core/TypeErasure.scala b/src/dotty/tools/dotc/core/TypeErasure.scala index 1a7342a12..bd1b9b1d3 100644 --- a/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/src/dotty/tools/dotc/core/TypeErasure.scala @@ -169,7 +169,7 @@ object TypeErasure { val erase = erasureFn(isJava, semiEraseVCs, sym.isConstructor, wildcardOK = false) def eraseParamBounds(tp: PolyType): Type = - tp.derivedPolyType( + tp.derivedGenericType( tp.paramNames, tp.paramNames map (Function.const(TypeBounds.upper(defn.ObjectType))), tp.resultType) if (defn.isPolymorphicAfterErasure(sym)) eraseParamBounds(sym.info.asInstanceOf[PolyType]) @@ -356,8 +356,6 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean SuperType(this(thistpe), this(supertpe)) case ExprType(rt) => defn.FunctionClass(0).typeRef - case tp: TypeProxy => - this(tp.underlying) case AndType(tp1, tp2) => erasedGlb(this(tp1), this(tp2), isJava) case OrType(tp1, tp2) => @@ -398,6 +396,8 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean tp case tp: WildcardType if wildcardOK => tp + case tp: TypeProxy => + this(tp.underlying) } private def eraseArray(tp: RefinedType)(implicit ctx: Context) = { diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index d480a792b..92e5f9d57 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -136,7 +136,6 @@ trait TypeOps { this: Context => // TODO: Make standalone object. finally seen = saved } case _ => - if (tp.isInstanceOf[MethodicType]) assert(variance != 0, tp) mapOver(tp) } } diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index ce1460980..8548a517e 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -2504,24 +2504,24 @@ object Types { } /** A common supertrait of PolyType and TypeLambda */ - trait GenericType extends BindingType with TermType { - - /** The names of the type parameters */ - val paramNames: List[TypeName] + abstract class GenericType(val paramNames: List[TypeName]) + (paramBoundsExp: GenericType => List[TypeBounds], + resultTypeExp: GenericType => Type) + extends CachedProxyType with BindingType with TermType { + type This <: GenericType + protected[this] def companion: GenericCompanion[This] /** The bounds of the type parameters */ - val paramBounds: List[TypeBounds] + val paramBounds: List[TypeBounds] = paramBoundsExp(this) /** The result type of a PolyType / body of a type lambda */ - val resType: Type + val resType: Type = resultTypeExp(this) /** If this is a type lambda, the variances of its parameters, otherwise Nil.*/ - def variances: List[Int] + def variances: List[Int] = Nil override def resultType(implicit ctx: Context) = resType - - /** Unconditionally create a new generic type like this one with given elements */ - def duplicate(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): GenericType + override def underlying(implicit ctx: Context) = resType /** Instantiate result type by substituting parameters with given arguments */ final def instantiate(argTypes: List[Type])(implicit ctx: Context): Type = @@ -2531,9 +2531,17 @@ object Types { def instantiateBounds(argTypes: List[Type])(implicit ctx: Context): List[TypeBounds] = paramBounds.mapConserve(_.substParams(this, argTypes).bounds) - def derivedGenericType(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context) = + /** Unconditionally create a new generic type like this one with given elements */ + def newLikeThis(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): This = + companion.apply(paramNames, variances)( + x => paramBounds mapConserve (_.subst(this, x).bounds), + x => resType.subst(this, x)) + + def derivedGenericType(paramNames: List[TypeName] = this.paramNames, + paramBounds: List[TypeBounds] = this.paramBounds, + resType: Type = this.resType)(implicit ctx: Context) = if ((paramNames eq this.paramNames) && (paramBounds eq this.paramBounds) && (resType eq this.resType)) this - else duplicate(paramNames, paramBounds, resType) + else newLikeThis(paramNames, paramBounds, resType) /** PolyParam references to all type parameters of this type */ lazy val paramRefs: List[PolyParam] = paramNames.indices.toList.map(PolyParam(this, _)) @@ -2555,14 +2563,28 @@ object Types { other.variances == this.variances case _ => false } + + override def computeHash = doHash(variances ::: paramNames, resType, paramBounds) + } + + abstract class GenericCompanion[GT <: GenericType] { + def apply(paramNames: List[TypeName], variances: List[Int])( + paramBoundsExp: GenericType => List[TypeBounds], + resultTypeExp: GenericType => Type)(implicit ctx: Context): GT + + def fromSymbols(tparams: List[Symbol], resultType: Type)(implicit ctx: Context): Type = + if (tparams.isEmpty) resultType + else apply(tparams map (_.name.asTypeName), tparams.map(_.variance))( + pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds), + pt => pt.lifted(tparams, resultType)) } /** A type for polymorphic methods */ - class PolyType(val paramNames: List[TypeName])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type) - extends CachedGroundType with GenericType with MethodOrPoly { - val paramBounds: List[TypeBounds] = paramBoundsExp(this) - val resType: Type = resultTypeExp(this) - def variances = Nil + class PolyType(paramNames: List[TypeName])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type) + extends GenericType(paramNames)(paramBoundsExp, resultTypeExp) with MethodOrPoly { + + type This = PolyType + def companion = PolyType protected def computeSignature(implicit ctx: Context) = resultSignature @@ -2571,14 +2593,6 @@ object Types { case _ => false } - def derivedPolyType(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context): PolyType = - derivedGenericType(paramNames, paramBounds, resType).asInstanceOf[PolyType] - - def duplicate(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): PolyType = - PolyType(paramNames)( - x => paramBounds mapConserve (_.subst(this, x).bounds), - x => resType.subst(this, x)) - /** Merge nested polytypes into one polytype. nested polytypes are normally not supported * but can arise as temporary data structures. */ @@ -2598,34 +2612,26 @@ object Types { } override def toString = s"PolyType($paramNames, $paramBounds, $resType)" - - override def computeHash = doHash(paramNames, resType, paramBounds) } - object PolyType { - def apply(paramNames: List[TypeName])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)(implicit ctx: Context): PolyType = { + object PolyType extends GenericCompanion[PolyType] { + def apply(paramNames: List[TypeName], variances: List[Int] = Nil)(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)(implicit ctx: Context): PolyType = { unique(new PolyType(paramNames)(paramBoundsExp, resultTypeExp)) } - - def fromSymbols(tparams: List[Symbol], resultType: Type)(implicit ctx: Context) = - if (tparams.isEmpty) resultType - else apply(tparams map (_.name.asTypeName))( - pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds), - pt => pt.lifted(tparams, resultType)) } // ----- HK types: TypeLambda, LambdaParam, HKApply --------------------- /** A type lambda of the form `[v_0 X_0, ..., v_n X_n] => T` */ - class TypeLambda(val paramNames: List[TypeName], val variances: List[Int])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type) - extends CachedProxyType with GenericType with ValueType { - val paramBounds = paramBoundsExp(this) - val resType = resultTypeExp(this) + class TypeLambda(paramNames: List[TypeName], override val variances: List[Int])( + paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type) + extends GenericType(paramNames)(paramBoundsExp, resultTypeExp) { assert(resType.isInstanceOf[TermType], this) assert(paramNames.nonEmpty) - override def underlying(implicit ctx: Context) = resType + type This = TypeLambda + def companion = TypeLambda lazy val typeParams: List[LambdaParam] = paramNames.indices.toList.map(new LambdaParam(this, _)) @@ -2633,26 +2639,31 @@ object Types { def derivedLambdaAbstraction(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context): Type = resType match { case resType @ TypeAlias(alias) => - resType.derivedTypeAlias(duplicate(paramNames, paramBounds, alias)) + resType.derivedTypeAlias(newLikeThis(paramNames, paramBounds, alias)) case resType @ TypeBounds(lo, hi) => resType.derivedTypeBounds( - if (lo.isRef(defn.NothingClass)) lo else duplicate(paramNames, paramBounds, lo), - duplicate(paramNames, paramBounds, hi)) + if (lo.isRef(defn.NothingClass)) lo else newLikeThis(paramNames, paramBounds, lo), + newLikeThis(paramNames, paramBounds, hi)) case _ => - derivedTypeLambda(paramNames, paramBounds, resType) + derivedGenericType(paramNames, paramBounds, resType) } - def derivedTypeLambda(paramNames: List[TypeName] = paramNames, paramBounds: List[TypeBounds] = paramBounds, resType: Type)(implicit ctx: Context): TypeLambda = - derivedGenericType(paramNames, paramBounds, resType).asInstanceOf[TypeLambda] + override def toString = s"TypeLambda($variances, $paramNames, $paramBounds, $resType)" + } - def duplicate(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): TypeLambda = - TypeLambda(paramNames, variances)( - x => paramBounds mapConserve (_.subst(this, x).bounds), - x => resType.subst(this, x)) + object TypeLambda extends GenericCompanion[TypeLambda] { + def apply(paramNames: List[TypeName], variances: List[Int])( + paramBoundsExp: GenericType => List[TypeBounds], + resultTypeExp: GenericType => Type)(implicit ctx: Context): TypeLambda = { + unique(new TypeLambda(paramNames, variances)(paramBoundsExp, resultTypeExp)) + } - override def toString = s"TypeLambda($variances, $paramNames, $paramBounds, $resType)" + def unapply(tl: TypeLambda): Some[(List[LambdaParam], Type)] = + Some((tl.typeParams, tl.resType)) - override def computeHash = doHash(variances ::: paramNames, resType, paramBounds) + def any(n: Int)(implicit ctx: Context) = + apply(tpnme.syntheticLambdaParamNames(n), List.fill(n)(0))( + pt => List.fill(n)(TypeBounds.empty), pt => defn.AnyType) } /** The parameter of a type lambda */ @@ -2667,24 +2678,6 @@ object Types { def paramRef(implicit ctx: Context): Type = PolyParam(tl, n) } - object TypeLambda { - def apply(paramNames: List[TypeName], variances: List[Int])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)(implicit ctx: Context): TypeLambda = { - unique(new TypeLambda(paramNames, variances)(paramBoundsExp, resultTypeExp)) - } - - def fromSymbols(tparams: List[Symbol], resultType: Type)(implicit ctx: Context) = - if (tparams.isEmpty) resultType - else apply(tparams map (_.name.asTypeName), tparams.map(_.variance))( - pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds), - pt => pt.lifted(tparams, resultType)) - def unapply(tl: TypeLambda): Some[(List[LambdaParam], Type)] = - Some((tl.typeParams, tl.resType)) - - def any(n: Int)(implicit ctx: Context) = - apply(tpnme.syntheticLambdaParamNames(n), List.fill(n)(0))( - pt => List.fill(n)(TypeBounds.empty), pt => defn.AnyType) - } - /** A higher kinded type application `C[T_1, ..., T_n]` */ abstract case class HKApply(tycon: Type, args: List[Type]) extends CachedProxyType with ValueType { diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index 70148b3e2..0003459e0 100644 --- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -84,7 +84,7 @@ object Scala2Unpickler { paramTypes.init :+ defn.RepeatedParamType.appliedTo(elemtp), tp.resultType) case tp: PolyType => - tp.derivedPolyType(tp.paramNames, tp.paramBounds, arrayToRepeated(tp.resultType)) + tp.derivedGenericType(tp.paramNames, tp.paramBounds, arrayToRepeated(tp.resultType)) } def ensureConstructor(cls: ClassSymbol, scope: Scope)(implicit ctx: Context) = diff --git a/src/dotty/tools/dotc/transform/ElimRepeated.scala b/src/dotty/tools/dotc/transform/ElimRepeated.scala index 258b7f234..1450ff832 100644 --- a/src/dotty/tools/dotc/transform/ElimRepeated.scala +++ b/src/dotty/tools/dotc/transform/ElimRepeated.scala @@ -44,7 +44,7 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati } else paramTypes tp.derivedMethodType(paramNames, paramTypes1, resultType1) case tp: PolyType => - tp.derivedPolyType(tp.paramNames, tp.paramBounds, elimRepeated(tp.resultType)) + tp.derivedGenericType(tp.paramNames, tp.paramBounds, elimRepeated(tp.resultType)) case tp => tp } @@ -126,7 +126,7 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati /** Convert type from Scala to Java varargs method */ private def toJavaVarArgs(tp: Type)(implicit ctx: Context): Type = tp match { case tp: PolyType => - tp.derivedPolyType(tp.paramNames, tp.paramBounds, toJavaVarArgs(tp.resultType)) + tp.derivedGenericType(tp.paramNames, tp.paramBounds, toJavaVarArgs(tp.resultType)) case tp: MethodType => val inits :+ last = tp.paramTypes val last1 = last.underlyingIfRepeated(isJava = true) diff --git a/src/dotty/tools/dotc/transform/SuperAccessors.scala b/src/dotty/tools/dotc/transform/SuperAccessors.scala index 10be6db65..79dbd9fe7 100644 --- a/src/dotty/tools/dotc/transform/SuperAccessors.scala +++ b/src/dotty/tools/dotc/transform/SuperAccessors.scala @@ -175,7 +175,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) { val accType = { def accTypeOf(tpe: Type): Type = tpe match { case tpe: PolyType => - tpe.derivedPolyType(tpe.paramNames, tpe.paramBounds, accTypeOf(tpe.resultType)) + tpe.derivedGenericType(tpe.paramNames, tpe.paramBounds, accTypeOf(tpe.resultType)) case _ => MethodType(receiverType :: Nil)(mt => tpe.substThis(sym.owner.asClass, MethodParam(mt, 0))) } @@ -227,7 +227,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) { else clazz.classInfo.selfType def accTypeOf(tpe: Type): Type = tpe match { case tpe: PolyType => - tpe.derivedPolyType(tpe.paramNames, tpe.paramBounds, accTypeOf(tpe.resultType)) + tpe.derivedGenericType(tpe.paramNames, tpe.paramBounds, accTypeOf(tpe.resultType)) case _ => MethodType(receiverType :: Nil)(mt => tpe.substThis(sym.owner.asClass, MethodParam(mt, 0))) } diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 56595a637..e2779e758 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -1019,7 +1019,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic => // todo: make sure implicit method types are not dependent? // but check test case in /tests/pos/depmet_implicit_chaining_zw.scala case pt: PolyType => - pt.derivedPolyType(pt.paramNames, pt.paramBounds, stripImplicit(pt.resultType)) + pt.derivedGenericType(pt.paramNames, pt.paramBounds, stripImplicit(pt.resultType)) case _ => tp } diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala index dd5705fbf..4fe2ea6bf 100644 --- a/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -363,7 +363,7 @@ object ProtoTypes { yield new TypeVar(PolyParam(pt, n), state, owningTree, ctx.owner) val added = - if (state.constraint contains pt) pt.duplicate(pt.paramNames, pt.paramBounds, pt.resultType) + if (state.constraint contains pt) pt.newLikeThis(pt.paramNames, pt.paramBounds, pt.resultType) else pt val tvars = if (owningTree.isEmpty) Nil else newTypeVars(added) ctx.typeComparer.addToConstraint(added, tvars) diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala index 262d3f731..aecdcbee6 100644 --- a/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -360,7 +360,7 @@ trait TypeAssigner { if (gapBuf.isEmpty) resultType1 else { val gaps = gapBuf.toList - pt.derivedPolyType( + pt.derivedGenericType( gaps.map(paramNames), gaps.map(idx => transform(pt.paramBounds(idx)).bounds), resultType1) |