aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-07-11 17:02:16 +0200
committerMartin Odersky <odersky@gmail.com>2016-07-11 17:47:23 +0200
commit6d7bc4996d6ad2095442ebc43f59307448226fd7 (patch)
tree7cee580a3dce11cb59d232c435e90660f3dee6ea
parenta200695677237922fdf6f995c690cb0108ec2fc4 (diff)
downloaddotty-6d7bc4996d6ad2095442ebc43f59307448226fd7.tar.gz
dotty-6d7bc4996d6ad2095442ebc43f59307448226fd7.tar.bz2
dotty-6d7bc4996d6ad2095442ebc43f59307448226fd7.zip
Address reviewers comments
-rw-r--r--src/dotty/tools/dotc/core/Constraint.scala2
-rw-r--r--src/dotty/tools/dotc/core/ConstraintHandling.scala8
-rw-r--r--src/dotty/tools/dotc/core/Signature.scala4
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala13
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala1
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala25
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala19
-rw-r--r--src/dotty/tools/dotc/core/TypeParamInfo.scala14
-rw-r--r--src/dotty/tools/dotc/core/Types.scala11
-rw-r--r--src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala4
-rw-r--r--src/dotty/tools/dotc/sbt/ExtractAPI.scala3
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