aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/core
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-03-04 17:27:10 +0100
committerMartin Odersky <odersky@gmail.com>2017-03-04 18:28:21 +0100
commit353a4d9f17b91d09dea3c9090c7a21e267372abe (patch)
tree08e1541da2f277c17da167ee6b9758a3f08e5f90 /compiler/src/dotty/tools/dotc/core
parent06d3f7aefa620ce006008955203d7f8f8dc7b605 (diff)
downloaddotty-353a4d9f17b91d09dea3c9090c7a21e267372abe.tar.gz
dotty-353a4d9f17b91d09dea3c9090c7a21e267372abe.tar.bz2
dotty-353a4d9f17b91d09dea3c9090c7a21e267372abe.zip
Drop named type parameters in classes
Drop the [type T] syntax, and what's associated to make it work. Motivation: It's an alternative way of doing things for which there seems to be little need. The implementation was provisional and bitrotted during the various iterations to introduce higher-kinded types. So in the end the complxity-cost for language and compiler was not worth the added benefit that [type T] parameters provide. Noe that we still accept _named arguments_ [A = T] in expressions; these are useful for specifying some parameters and letting others be inferred.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/core')
-rw-r--r--compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/Flags.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/SymDenotations.scala17
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeApplications.scala61
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeComparer.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeOps.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/core/Types.scala8
7 files changed, 7 insertions, 113 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
index 3aa20f15b..b3c50fb71 100644
--- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
+++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
@@ -253,9 +253,6 @@ trait ConstraintHandling {
if (fromBelow && isOrType(inst) && isFullyDefined(inst) && !isOrType(upperBound))
inst = ctx.harmonizeUnion(inst)
- // 3. If instance is from below, and upper bound has open named parameters
- // make sure the instance has all named parameters of the bound.
- if (fromBelow) inst = inst.widenToNamedTypeParams(param.namedTypeParams)
inst
}
diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala
index 63fbc98dc..d2a1c58f5 100644
--- a/compiler/src/dotty/tools/dotc/core/Flags.scala
+++ b/compiler/src/dotty/tools/dotc/core/Flags.scala
@@ -613,9 +613,6 @@ object Flags {
/** A private parameter accessor */
final val PrivateParamAccessor = allOf(Private, ParamAccessor)
- /** A type parameter introduced with [type ... ] */
- final val NamedTypeParam = allOf(TypeParam, ParamAccessor)
-
/** A local parameter */
final val ParamAndLocal = allOf(Param, Local)
diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
index a3475e14c..9b9caf8e7 100644
--- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -1086,9 +1086,6 @@ object SymDenotations {
/** The type parameters of a class symbol, Nil for all other symbols */
def typeParams(implicit ctx: Context): List[TypeSymbol] = Nil
- /** The named type parameters declared or inherited by this symbol */
- def namedTypeParams(implicit ctx: Context): Set[TypeSymbol] = Set()
-
/** The type This(cls), where cls is this class, NoPrefix for all other symbols */
def thisType(implicit ctx: Context): Type = NoPrefix
@@ -1226,11 +1223,9 @@ object SymDenotations {
/** TODO: Document why caches are supposedly safe to use */
private[this] var myTypeParams: List[TypeSymbol] = _
- private[this] var myNamedTypeParams: Set[TypeSymbol] = _
-
/** The type parameters in this class, in the order they appear in the current
* scope `decls`. This might be temporarily the incorrect order when
- * reading Scala2 pickled info. The problem is fixed by `updateTypeParams`
+ * reading Scala2 pickled info. The problem is fixed by `ensureTypeParamsInCorrectOrder`,
* which is called once an unpickled symbol has been completed.
*/
private def typeParamsFromDecls(implicit ctx: Context) =
@@ -1253,16 +1248,6 @@ object SymDenotations {
myTypeParams
}
- /** The named type parameters declared or inherited by this class */
- override final def namedTypeParams(implicit ctx: Context): Set[TypeSymbol] = {
- def computeNamedTypeParams: Set[TypeSymbol] =
- if (ctx.erasedTypes || is(Module)) Set() // fast return for modules to avoid scanning package decls
- else memberNames(abstractTypeNameFilter).map(name =>
- info.member(name).symbol.asType).filter(_.is(TypeParam, butNot = ExpandedName)).toSet
- if (myNamedTypeParams == null) myNamedTypeParams = computeNamedTypeParams
- myNamedTypeParams
- }
-
override protected[dotc] final def info_=(tp: Type) = {
super.info_=(tp)
myTypeParams = null // changing the info might change decls, and with it typeParams
diff --git a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala
index 70819e590..c713cd542 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -246,67 +246,6 @@ class TypeApplications(val self: Type) extends AnyVal {
case _ => Nil
}
- /** The named type parameters declared or inherited by this type.
- * These are all uninstantiated named type parameters of this type or one
- * of its base types.
- */
- final def namedTypeParams(implicit ctx: Context): Set[TypeSymbol] = self match {
- case self: ClassInfo =>
- self.cls.namedTypeParams
- case self: RefinedType =>
- self.parent.namedTypeParams.filterNot(_.name == self.refinedName)
- case self: SingletonType =>
- Set()
- case self: TypeProxy =>
- self.underlying.namedTypeParams
- case _ =>
- Set()
- }
-
- /** The smallest supertype of this type that instantiated none of the named type parameters
- * in `params`. That is, for each named type parameter `p` in `params`, either there is
- * no type field named `p` in this type, or `p` is a named type parameter of this type.
- * The first case is important for the recursive case of AndTypes, because some of their operands might
- * be missing the named parameter altogether, but the AndType as a whole can still
- * contain it.
- */
- final def widenToNamedTypeParams(params: Set[TypeSymbol])(implicit ctx: Context): Type = {
-
- /** Is widening not needed for `tp`? */
- def isOK(tp: Type) = {
- val ownParams = tp.namedTypeParams
- def isMissingOrOpen(param: TypeSymbol) = {
- val ownParam = tp.nonPrivateMember(param.name).symbol
- !ownParam.exists || ownParams.contains(ownParam.asType)
- }
- params.forall(isMissingOrOpen)
- }
-
- /** Widen type by forming the intersection of its widened parents */
- def widenToParents(tp: Type) = {
- val parents = tp.parents.map(p =>
- tp.baseTypeWithArgs(p.symbol).widenToNamedTypeParams(params))
- parents.reduceLeft(ctx.typeComparer.andType(_, _))
- }
-
- if (isOK(self)) self
- else self match {
- case self @ AppliedType(tycon, args) if !isOK(tycon) =>
- widenToParents(self)
- case self: TypeRef if self.symbol.isClass =>
- widenToParents(self)
- case self: RefinedType =>
- val parent1 = self.parent.widenToNamedTypeParams(params)
- if (params.exists(_.name == self.refinedName)) parent1
- else self.derivedRefinedType(parent1, self.refinedName, self.refinedInfo)
- case self: TypeProxy =>
- self.superType.widenToNamedTypeParams(params)
- case self: AndOrType =>
- self.derivedAndOrType(
- self.tp1.widenToNamedTypeParams(params), self.tp2.widenToNamedTypeParams(params))
- }
- }
-
/** Is self type higher-kinded (i.e. of kind != "*")? */
def isHK(implicit ctx: Context): Boolean = self.dealias match {
case self: TypeRef => self.info.isHK
diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
index fca111702..b97dfe684 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -1264,22 +1264,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
}
}
- /** `op(tp1, tp2)` unless `tp1` and `tp2` are type-constructors with at least
- * some unnamed type parameters.
+ /** `op(tp1, tp2)` unless `tp1` and `tp2` are type-constructors.
* In the latter case, combine `tp1` and `tp2` under a type lambda like this:
*
* [X1, ..., Xn] -> op(tp1[X1, ..., Xn], tp2[X1, ..., Xn])
- *
- * Note: There is a tension between named and positional parameters here, which
- * is impossible to resolve completely. Say you have
- *
- * C[type T], D[type U]
- *
- * Then do you expand `C & D` to `[T] -> C[T] & D[T]` or not? Under the named
- * type parameter interpretation, this would be wrong whereas under the traditional
- * higher-kinded interpretation this would be required. The problem arises from
- * allowing both interpretations. A possible remedy is to be somehow stricter
- * in where we allow which interpretation.
*/
private def liftIfHK(tp1: Type, tp2: Type, op: (Type, Type) => Type, original: (Type, Type) => Type) = {
val tparams1 = tp1.typeParams
diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala
index 308e6e306..6c40794e3 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala
@@ -428,16 +428,10 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
case tp: TypeRef =>
tp
case tp @ RefinedType(tp1, name: TypeName, rinfo) =>
- rinfo match {
- case TypeAlias(TypeRef(pre, name1)) if name1 == name && (pre =:= cls.thisType) =>
- // Don't record refinements of the form X = this.X (These can arise using named parameters).
- typr.println(s"dropping refinement $tp")
- case _ =>
- val prevInfo = refinements(name)
- refinements = refinements.updated(name,
- if (prevInfo == null) tp.refinedInfo else prevInfo & tp.refinedInfo)
- formals = formals.updated(name, tp1.typeParamNamed(name))
- }
+ val prevInfo = refinements(name)
+ refinements = refinements.updated(name,
+ if (prevInfo == null) tp.refinedInfo else prevInfo & tp.refinedInfo)
+ formals = formals.updated(name, tp1.typeParamNamed(name))
normalizeToRef(tp1)
case _: ErrorType =>
defn.AnyType
diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala
index f56c6a286..9dd767a8e 100644
--- a/compiler/src/dotty/tools/dotc/core/Types.scala
+++ b/compiler/src/dotty/tools/dotc/core/Types.scala
@@ -549,13 +549,7 @@ object Types {
def goThis(tp: ThisType) = {
val d = go(tp.underlying)
- if (d.exists)
- if ((pre eq tp) && d.symbol.is(NamedTypeParam) && (d.symbol.owner eq tp.cls))
- // If we look for a named type parameter `P` in `C.this.P`, looking up
- // the fully applied self type of `C` will give as an info the alias type
- // `P = this.P`. We need to return a denotation with the underlying bounds instead.
- d.symbol.denot
- else d
+ if (d.exists) d
else
// There is a special case to handle:
// trait Super { this: Sub => private class Inner {} println(this.Inner) }