diff options
Diffstat (limited to 'src/dotty/tools')
-rw-r--r-- | src/dotty/tools/dotc/core/Constraint.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/ConstraintHandling.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Signature.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 13 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 25 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeParamInfo.scala | 14 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/sbt/ExtractAPI.scala | 3 |
11 files changed, 55 insertions, 49 deletions
diff --git a/src/dotty/tools/dotc/core/Constraint.scala b/src/dotty/tools/dotc/core/Constraint.scala index e480d1bfe..e10523753 100644 --- a/src/dotty/tools/dotc/core/Constraint.scala +++ b/src/dotty/tools/dotc/core/Constraint.scala @@ -119,7 +119,7 @@ abstract class Constraint extends Showable { /** Is entry associated with `pt` removable? This is the case if * all type parameters of the entry are associated with type variables - * which have its `inst` fields set. + * which have their `inst` fields set. */ def isRemovable(pt: GenericType): Boolean diff --git a/src/dotty/tools/dotc/core/ConstraintHandling.scala b/src/dotty/tools/dotc/core/ConstraintHandling.scala index 1c3bd7384..c5e3bad40 100644 --- a/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -385,13 +385,7 @@ trait ConstraintHandling { case bound: PolyParam if constraint contains bound => addParamBound(bound) case _ => - var pbound = prune(bound) - if (pbound.isHK && !param.isHK) { - param match { - case EtaExpansion(tycon) if tycon.symbol.isClass => pbound = tycon - case _ => - } - } + val pbound = prune(bound) pbound.exists && ( if (fromBelow) addLowerBound(param, pbound) else addUpperBound(param, pbound)) } diff --git a/src/dotty/tools/dotc/core/Signature.scala b/src/dotty/tools/dotc/core/Signature.scala index c0647ad1d..b2e627cbe 100644 --- a/src/dotty/tools/dotc/core/Signature.scala +++ b/src/dotty/tools/dotc/core/Signature.scala @@ -50,7 +50,7 @@ case class Signature(paramsSig: List[TypeName], resSig: TypeName) { /** The degree to which this signature matches `that`. * If parameter names are consistent and result types names match (i.e. they are the same * or one is a wildcard), the result is `FullMatch`. - * If only the parameter names are constistent, the result is `ParamMatch` before erasure and + * If only the parameter names are consistent, the result is `ParamMatch` before erasure and * `NoMatch` otherwise. * If the parameters are inconsistent, the result is always `NoMatch`. */ @@ -71,7 +71,7 @@ case class Signature(paramsSig: List[TypeName], resSig: TypeName) { Signature((params.map(sigName(_, isJava))) ++ paramsSig, resSig) /** A signature is under-defined if its paramsSig part contains at least one - * `tpnme.Uninstantited`. Under-defined signatures arise when taking a signature + * `tpnme.Uninstantiated`. Under-defined signatures arise when taking a signature * of a type that still contains uninstantiated type variables. They are eliminated * by `fixSignature` in `PostTyper`. */ diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 1417347bf..16c77ac30 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1209,7 +1209,7 @@ object SymDenotations { private[this] var myNamedTypeParams: Set[TypeSymbol] = _ /** The type parameters in this class, in the order they appear in the current - * scope `decls`. This is might be temporarily the incorrect order when + * scope `decls`. This might be temporarily the incorrect order when * reading Scala2 pickled info. The problem is fixed by `updateTypeParams` * which is called once an unpickled symbol has been completed. */ @@ -1543,18 +1543,19 @@ object SymDenotations { } /** Make sure the type parameters of this class appear in the order given - * by `tparams` in the scope of the class. Reorder definitions in scope if necessary. - * @pre All type parameters in `tparams` are entered in class scope `info.decls`. + * by `typeParams` in the scope of the class. Reorder definitions in scope if necessary. */ - def updateTypeParams(tparams: List[Symbol])(implicit ctx: Context): Unit = - if (!ctx.erasedTypes && !typeParamsFromDecls.corresponds(typeParams)(_.name == _.name)) { + def ensureTypeParamsInCorrectOrder()(implicit ctx: Context): Unit = { + val tparams = typeParams + if (!ctx.erasedTypes && !typeParamsFromDecls.corresponds(tparams)(_.name == _.name)) { val decls = info.decls val decls1 = newScope - for (tparam <- tparams) decls1.enter(decls.lookup(tparam.name)) + for (tparam <- typeParams) decls1.enter(decls.lookup(tparam.name)) for (sym <- decls) if (!tparams.contains(sym)) decls1.enter(sym) info = classInfo.derivedClassInfo(decls = decls1) myTypeParams = null } + } /** All members of this class that have the given name. * The elements of the returned pre-denotation all diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index ae88753d0..229df4576 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -494,6 +494,7 @@ object Symbols { def paramName(implicit ctx: Context): Name = name def paramBounds(implicit ctx: Context) = denot.info.bounds def paramBoundsAsSeenFrom(pre: Type)(implicit ctx: Context) = pre.memberInfo(this).bounds + def paramBoundsOrCompleter(implicit ctx: Context): Type = denot.infoOrCompleter def paramVariance(implicit ctx: Context) = denot.variance def paramRef(implicit ctx: Context) = denot.typeRef diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index 6e0bf7786..09f006a11 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -41,7 +41,7 @@ object TypeApplications { /** Does variance `v1` conform to variance `v2`? * This is the case if the variances are the same or `sym` is nonvariant. */ - def varianceConforms(v1: Int, v2: Int)(implicit ctx: Context): Boolean = + def varianceConforms(v1: Int, v2: Int): Boolean = v1 == v2 || v2 == 0 /** Does the variance of type parameter `tparam1` conform to the variance of type parameter `tparam2`? @@ -49,7 +49,7 @@ object TypeApplications { def varianceConforms(tparam1: TypeParamInfo, tparam2: TypeParamInfo)(implicit ctx: Context): Boolean = varianceConforms(tparam1.paramVariance, tparam2.paramVariance) - /** Doe the variances of type parameters `tparams1` conform to the variances + /** Do the variances of type parameters `tparams1` conform to the variances * of corresponding type parameters `tparams2`? * This is only the case of `tparams1` and `tparams2` have the same length. */ @@ -116,17 +116,11 @@ object TypeApplications { /** Adapt all arguments to possible higher-kinded type parameters using etaExpandIfHK */ - def etaExpandIfHK(tparams: List[TypeParamInfo], args: List[Type])(implicit ctx: Context): List[Type] = + def EtaExpandIfHK(tparams: List[TypeParamInfo], args: List[Type])(implicit ctx: Context): List[Type] = if (tparams.isEmpty) args - else { - def bounds(tparam: TypeParamInfo) = tparam match { - case tparam: Symbol => tparam.infoOrCompleter - case tparam: LambdaParam => tparam.paramBounds - } - args.zipWithConserve(tparams)((arg, tparam) => arg.etaExpandIfHK(bounds(tparam))) - } + else args.zipWithConserve(tparams)((arg, tparam) => arg.EtaExpandIfHK(tparam.paramBoundsOrCompleter)) - /** A type map that tries to reduce a (part of) the result type of the type lambda `tycon` + /** A type map that tries to reduce (part of) the result type of the type lambda `tycon` * with the given `args`(some of which are wildcard arguments represented by type bounds). * Non-wildcard arguments are substituted everywhere as usual. A wildcard argument * `>: L <: H` is substituted for a type lambda parameter `X` only under certain conditions. @@ -166,7 +160,7 @@ object TypeApplications { * produce a higher-kinded application with a type lambda as type constructor. */ class Reducer(tycon: TypeLambda, args: List[Type])(implicit ctx: Context) extends TypeMap { - private var available = Set((0 until args.length): _*) + private var available = (0 until args.length).toSet var allReplaced = true def hasWildcardArg(p: PolyParam) = p.binder == tycon && args(p.paramNum).isInstanceOf[TypeBounds] @@ -320,7 +314,10 @@ class TypeApplications(val self: Type) extends AnyVal { case self: TypeLambda => true case self: HKApply => false case self: SingletonType => false - case self: TypeVar => self.origin.isHK // discrepancy with typeParams, why? + case self: TypeVar => + // Using `origin` instead of `underlying`, as is done for typeParams, + // avoids having to set ephemeral in some cases. + self.origin.isHK case self: WildcardType => self.optBounds.isHK case self: TypeProxy => self.underlying.isHK case _ => false @@ -378,7 +375,7 @@ class TypeApplications(val self: Type) extends AnyVal { if (isHK) self else EtaExpansion(self) /** Eta expand if `self` is a (non-lambda) class reference and `bound` is a higher-kinded type */ - def etaExpandIfHK(bound: Type)(implicit ctx: Context): Type = { + def EtaExpandIfHK(bound: Type)(implicit ctx: Context): Type = { val hkParams = bound.hkTypeParams if (hkParams.isEmpty) self else self match { diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 3a0311977..faa4e1b16 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -531,7 +531,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { isNewSubType(tp1.parent, tp2) case tp1: RecType => isNewSubType(tp1.parent, tp2) - case HKApply(tycon1, args1) => + case tp1 @ HKApply(tycon1, args1) => compareHkApply1(tp1, tycon1, args1, tp2) case EtaExpansion(tycon1) => isSubType(tycon1, tp2) @@ -567,10 +567,13 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { /** Subtype test for the hk application `tp2 = tycon2[args2]`. */ - def compareHkApply2(tp1: Type, tp2: Type, tycon2: Type, args2: List[Type]): Boolean = { + def compareHkApply2(tp1: Type, tp2: HKApply, tycon2: Type, args2: List[Type]): Boolean = { val tparams = tycon2.typeParams assert(tparams.nonEmpty) + /** True if `tp1` and `tp2` have compatible type constructors and their + * corresponding arguments are subtypes relative to their variance (see `isSubArgs`). + */ def isMatchingApply(tp1: Type): Boolean = tp1 match { case HKApply(tycon1, args1) => tycon1.dealias match { @@ -602,7 +605,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { * and the resulting type application is a supertype of `tp1`, * or fallback to fourthTry. */ - def canInstantiate(param2: PolyParam): Boolean = { + def canInstantiate(tycon2: PolyParam): Boolean = { /** Let * @@ -611,7 +614,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { * `args1_1, ..., args1_n-1` be the type arguments of the lhs * `d = n - k` * - * Returns `true` iff `d >= 0` and `param2` can be instantiated to + * Returns `true` iff `d >= 0` and `tycon2` can be instantiated to * * [tparams1_d, ... tparams1_n-1] -> tycon1a[args_1, ..., args_d-1, tparams_d, ... tparams_n-1] * @@ -629,7 +632,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { .appliedTo(args1.take(lengthDiff) ++ tparams1.map(_.paramRef)) .LambdaAbstract(tparams1) (ctx.mode.is(Mode.TypevarsMissContext) || - tryInstantiate(param2, tycon1b.ensureHK)) && + tryInstantiate(tycon2, tycon1b.ensureHK)) && isSubType(tp1, tycon1b.appliedTo(args2)) } } @@ -690,7 +693,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { /** Subtype test for the hk application `tp1 = tycon1[args1]`. */ - def compareHkApply1(tp1: Type, tycon1: Type, args1: List[Type], tp2: Type): Boolean = + def compareHkApply1(tp1: HKApply, tycon1: Type, args1: List[Type], tp2: Type): Boolean = tycon1 match { case param1: PolyParam => def canInstantiate = tp2 match { @@ -716,7 +719,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { val v = tparams.head.paramVariance (v > 0 || isSubType(args2.head, args1.head)) && (v < 0 || isSubType(args1.head, args2.head)) - } + } && isSubArgs(args1.tail, args2.tail, tparams) /** Test whether `tp1` has a base type of the form `B[T1, ..., Tn]` where * - `B` derives from one of the class symbols of `tp2`, @@ -1522,7 +1525,7 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) { override def copyIn(ctx: Context) = new ExplainingTypeComparer(ctx) - override def compareHkApply2(tp1: Type, tp2: Type, tycon2: Type, args2: List[Type]): Boolean = { + override def compareHkApply2(tp1: Type, tp2: HKApply, tycon2: Type, args2: List[Type]): Boolean = { def addendum = "" traceIndented(i"compareHkApply $tp1, $tp2$addendum") { super.compareHkApply2(tp1, tp2, tycon2, args2) diff --git a/src/dotty/tools/dotc/core/TypeParamInfo.scala b/src/dotty/tools/dotc/core/TypeParamInfo.scala index 6bec2e0e0..1d79e4204 100644 --- a/src/dotty/tools/dotc/core/TypeParamInfo.scala +++ b/src/dotty/tools/dotc/core/TypeParamInfo.scala @@ -9,7 +9,9 @@ import Types.{Type, TypeBounds} */ trait TypeParamInfo { - /** Is this the info of a type parameter? Might be wrong for symbols */ + /** Is this the info of a type parameter? Will return `false` for symbols + * that are not type parameters. + */ def isTypeParam(implicit ctx: Context): Boolean /** The name of the type parameter */ @@ -19,10 +21,16 @@ trait TypeParamInfo { def paramBounds(implicit ctx: Context): TypeBounds /** The info of the type parameter as seen from a prefix type. - * This can be different from `memberInfo` if the binding - * is a type symbol of a class. + * For type parameter symbols, this is the `memberInfo` as seen from `prefix`. + * For type lambda parameters, it's the same as `paramBounds` as + * `asSeenFrom` has already been applied to the whole type lambda. */ def paramBoundsAsSeenFrom(pre: Type)(implicit ctx: Context): TypeBounds + + /** The parameter bounds, or the completer if the type parameter + * is an as-yet uncompleted symbol. + */ + def paramBoundsOrCompleter(implicit ctx: Context): Type /** The variance of the type parameter */ def paramVariance(implicit ctx: Context): Int diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 728f7fc21..63f39637b 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -452,7 +452,7 @@ object Types { // We have to be careful because we might open the same (wrt eq) recursive type // twice during findMember which risks picking the wrong prefix in the `substRecThis(rt, pre)` // call below. To avoid this problem we do a defensive copy of the recursive - // type first. But if we do this always we risk being inefficient and we run into + // type first. But if we do this always we risk being inefficient and we ran into // stackoverflows when compiling pos/hk.scala under the refinement encoding // of hk-types. So we only do a copy if the type // is visited again in a recursive call to `findMember`, as tracked by `tp.opened`. @@ -470,7 +470,7 @@ object Types { // // fails (in fact it thinks the underlying type of the LHS is `Tree[Untyped]`.) // - // Without the without the `openedTwice` trick, Typer.scala fails to Ycheck + // Without the `openedTwice` trick, Typer.scala fails to Ycheck // at phase resolveSuper. val rt = if (tp.opened) { // defensive copy @@ -2510,7 +2510,7 @@ object Types { else duplicate(paramNames, paramBounds, resType) /** PolyParam references to all type parameters of this type */ - def paramRefs: List[PolyParam] = paramNames.indices.toList.map(PolyParam(this, _)) + lazy val paramRefs: List[PolyParam] = paramNames.indices.toList.map(PolyParam(this, _)) /** The type `[tparams := paramRefs] tp`, where `tparams` can be * either a list of type parameter symbols or a list of lambda parameters @@ -2518,7 +2518,7 @@ object Types { def lifted(tparams: List[TypeParamInfo], tp: Type)(implicit ctx: Context): Type = tparams match { case LambdaParam(poly, _) :: _ => tp.subst(poly, this) - case tparams: List[Symbol] => tp.subst(tparams, paramRefs) + case tparams: List[Symbol @unchecked] => tp.subst(tparams, paramRefs) } override def equals(other: Any) = other match { @@ -2612,6 +2612,7 @@ object Types { def paramName(implicit ctx: Context): TypeName = tl.paramNames(n) def paramBounds(implicit ctx: Context): TypeBounds = tl.paramBounds(n) def paramBoundsAsSeenFrom(pre: Type)(implicit ctx: Context): TypeBounds = paramBounds + def paramBoundsOrCompleter(implicit ctx: Context): Type = paramBounds def paramVariance(implicit ctx: Context): Int = tl.variances(n) def toArg: Type = PolyParam(tl, n) def paramRef(implicit ctx: Context): Type = PolyParam(tl, n) @@ -2643,7 +2644,7 @@ object Types { override def superType(implicit ctx: Context): Type = tycon match { case tp: TypeLambda => defn.AnyType - case tp: TypeProxy => tp.superType.appliedTo(args) + case tp: TypeProxy => tp.superType.applyIfParameterized(args) case _ => defn.AnyType } /* diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index e8f3d63a9..3dbeb4040 100644 --- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -134,7 +134,7 @@ object Scala2Unpickler { denot.info = ClassInfo( // final info, except possibly for typeparams ordering denot.owner.thisType, denot.classSymbol, parentRefs, decls, ost) - denot.updateTypeParams(tparams) + denot.ensureTypeParamsInCorrectOrder() } } @@ -733,7 +733,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas else TypeRef(pre, sym.name.asTypeName) val args = until(end, readTypeRef) if (sym == defn.ByNameParamClass2x) ExprType(args.head) - else if (args.nonEmpty) tycon.safeAppliedTo(etaExpandIfHK(sym.typeParams, args)) + else if (args.nonEmpty) tycon.safeAppliedTo(EtaExpandIfHK(sym.typeParams, args)) else if (sym.typeParams.nonEmpty) tycon.EtaExpand(sym.typeParams) else tycon case TYPEBOUNDStpe => diff --git a/src/dotty/tools/dotc/sbt/ExtractAPI.scala b/src/dotty/tools/dotc/sbt/ExtractAPI.scala index d4b38c66e..26611ef43 100644 --- a/src/dotty/tools/dotc/sbt/ExtractAPI.scala +++ b/src/dotty/tools/dotc/sbt/ExtractAPI.scala @@ -404,13 +404,14 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder case tp: ThisType => apiThis(tp.cls) case RecThis(binder) => - apiThis(binder.typeSymbol) // !!! this is almost certainly wrong !!! + apiThis(binder.typeSymbol) // !!! this is almost certainly wrong: binder does not always have a typeSymbol !!! case tp: ParamType => new api.ParameterRef(tp.paramName.toString) case tp: LazyRef => apiType(tp.ref) case tp: TypeVar => apiType(tp.underlying) + // !!! missing cases: TypeLambda, HKApply case _ => { ctx.warning(i"sbt-api: Unhandled type ${tp.getClass} : $tp") Constants.emptyType |