summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-12-26 14:26:05 -0800
committerPaul Phillips <paulp@improving.org>2011-12-30 11:19:05 -0800
commitd323f2f8d631404f10887d73e075e56a3fffc755 (patch)
treec2edc3e3d67b355ee717d88a189fb7ba023f0516 /src/compiler
parentb2b59a124a2a8adf8e88c1e692c96263e0955b16 (diff)
downloadscala-d323f2f8d631404f10887d73e075e56a3fffc755.tar.gz
scala-d323f2f8d631404f10887d73e075e56a3fffc755.tar.bz2
scala-d323f2f8d631404f10887d73e075e56a3fffc755.zip
Creator for existentials which flattens.
Currently it is possible to end up with nested existentials, because existentialAbstraction only looks one level deeper. This works harder to flatten them.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala23
-rw-r--r--src/compiler/scala/reflect/internal/pickling/UnPickler.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala4
7 files changed, 22 insertions, 19 deletions
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala
index 60b353a7c4..a4af4bf8f3 100644
--- a/src/compiler/scala/reflect/internal/Importers.scala
+++ b/src/compiler/scala/reflect/internal/Importers.scala
@@ -161,7 +161,7 @@ trait Importers { self: SymbolTable =>
case from.RefinedType(parents, decls) =>
RefinedType(parents map importType, importScope(decls), importSymbol(tpe.typeSymbol))
case from.ExistentialType(tparams, restpe) =>
- ExistentialType(tparams map importSymbol, importType(restpe))
+ newExistentialType(tparams map importSymbol, importType(restpe))
case from.OverloadedType(pre, alts) =>
OverloadedType(importType(pre), alts map importSymbol)
case from.AntiPolyType(pre, targs) =>
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index f37509af39..046689ae9f 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -2236,6 +2236,15 @@ A type's typeSymbol should never be inspected directly.
}
object PolyType extends PolyTypeExtractor
+
+ /** A creator for existential types which flattens nested existentials.
+ */
+ def newExistentialType(quantified: List[Symbol], underlying: Type): Type =
+ if (quantified.isEmpty) underlying
+ else underlying match {
+ case ExistentialType(qs, restpe) => newExistentialType(quantified ::: qs, restpe)
+ case _ => ExistentialType(quantified, underlying)
+ }
case class ExistentialType(quantified: List[Symbol],
override val underlying: Type) extends RewrappingTypeProxy
@@ -2300,7 +2309,7 @@ A type's typeSymbol should never be inspected directly.
}
override def cloneInfo(owner: Symbol) =
- createFromClonedSymbolsAtOwner(quantified, owner, underlying)(ExistentialType(_, _))
+ createFromClonedSymbolsAtOwner(quantified, owner, underlying)(newExistentialType)
override def atOwner(owner: Symbol) =
if (quantified exists (_.owner != owner)) cloneInfo(owner) else this
@@ -2999,7 +3008,7 @@ A type's typeSymbol should never be inspected directly.
case TypeRef(pre, sym @ (NothingClass|AnyClass), _) => copyTypeRef(tycon, pre, sym, Nil) //@M drop type args to Any/Nothing
case TypeRef(pre, sym, _) => copyTypeRef(tycon, pre, sym, args)
case PolyType(tparams, restpe) => restpe.instantiateTypeParams(tparams, args)
- case ExistentialType(tparams, restpe) => ExistentialType(tparams, appliedType(restpe, args))
+ case ExistentialType(tparams, restpe) => newExistentialType(tparams, appliedType(restpe, args))
case st: SingletonType => appliedType(st.widen, args) // @M TODO: what to do? see bug1
case RefinedType(parents, decls) => RefinedType(parents map (appliedType(_, args)), decls) // MO to AM: please check
case TypeBounds(lo, hi) => TypeBounds(appliedType(lo, args), appliedType(hi, args))
@@ -3112,11 +3121,7 @@ A type's typeSymbol should never be inspected directly.
tparams1 exists { p1 => p1 == p || (p1.info contains p) }
}
}
- if (tparams1.isEmpty) tpe1
- else tpe1 match {
- case ExistentialType(tparams2, tpe2) => ExistentialType(tparams1 ::: tparams2, tpe2)
- case _ => ExistentialType(tparams1, tpe1)
- }
+ newExistentialType(tparams1, tpe1)
}
/** Remove any occurrences of type aliases from this type */
@@ -3432,7 +3437,7 @@ A type's typeSymbol should never be inspected directly.
val tparams1 = mapOver(tparams)
var result1 = this(result)
if ((tparams1 eq tparams) && (result1 eq result)) tp
- else ExistentialType(tparams1, result1.substSym(tparams, tparams1))
+ else newExistentialType(tparams1, result1.substSym(tparams, tparams1))
case OverloadedType(pre, alts) =>
val pre1 = if (pre.isInstanceOf[ClassInfoType]) pre else this(pre)
if (pre1 eq pre) tp
@@ -3801,7 +3806,7 @@ A type's typeSymbol should never be inspected directly.
case PolyType(bs, restp) =>
createFromClonedSymbols(bs, restp)((ps1, tp1) => PolyType(ps1, renameBoundSyms(tp1)))
case ExistentialType(bs, restp) =>
- createFromClonedSymbols(bs, restp)(ExistentialType(_, _))
+ createFromClonedSymbols(bs, restp)(newExistentialType)
case _ =>
tp
}
diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
index 1a8540c158..9927560c8c 100644
--- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
@@ -378,7 +378,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
// that it isn't right here. See #4757 for the immediate
// motivation to fix it.
val tparams = until(end, readSymbolRef) map (_ setFlag EXISTENTIAL)
- ExistentialType(tparams, restpe)
+ newExistentialType(tparams, restpe)
case ANNOTATEDtpe =>
var typeRef = readNat()
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index e67ce90cfa..b73eaff524 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -682,8 +682,6 @@ abstract class ClassfileParser {
while (!isDelimiter(sig(index))) { index += 1 }
sig.subName(start, index)
}
- def existentialType(tparams: List[Symbol], tp: Type): Type =
- if (tparams.isEmpty) tp else ExistentialType(tparams, tp)
def sig2type(tparams: immutable.Map[Name,Symbol], skiptvs: Boolean): Type = {
val tag = sig(index); index += 1
tag match {
@@ -729,14 +727,14 @@ abstract class ClassfileParser {
}
accept('>')
assert(xs.length > 0)
- existentialType(existentials.toList, typeRef(pre, classSym, xs.toList))
+ newExistentialType(existentials.toList, typeRef(pre, classSym, xs.toList))
} else if (classSym.isMonomorphicType) {
tp
} else {
// raw type - existentially quantify all type parameters
val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams)
val t = typeRef(pre, classSym, eparams.map(_.tpe))
- val res = existentialType(eparams, t)
+ val res = newExistentialType(eparams, t)
if (settings.debug.value && settings.verbose.value)
println("raw type " + classSym + " -> " + res)
res
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 5b38ddd092..67fa67b0f3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -180,7 +180,7 @@ trait Infer {
case NullaryMethodType(restpe) =>
normalize(restpe)
case ExistentialType(tparams, qtpe) =>
- ExistentialType(tparams, normalize(qtpe))
+ newExistentialType(tparams, normalize(qtpe))
case tp1 =>
tp1 // @MAT aliases already handled by subtyping
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index cf8c0c596c..3d4f5e8724 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -50,7 +50,7 @@ trait SyntheticMethods extends ast.TreeDSL {
/** To avoid unchecked warnings on polymorphic classes.
*/
def clazzTypeToTest(clazz: Symbol) = clazz.tpe.normalize match {
- case TypeRef(_, sym, args) if args.nonEmpty => ExistentialType(sym.typeParams, clazz.tpe)
+ case TypeRef(_, sym, args) if args.nonEmpty => newExistentialType(sym.typeParams, clazz.tpe)
case tp => tp
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index f6f783516c..a4c00e9f89 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2965,7 +2965,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
error(vd.pos, "illegal abstraction from value with volatile type "+vd.symbol.tpe)
val tpt1 = typedType(tree.tpt, mode)
existentialTransform(tree.whereClauses map (_.symbol), tpt1.tpe)((tparams, tp) =>
- TypeTree(ExistentialType(tparams, tp)) setOriginal tree
+ TypeTree(newExistentialType(tparams, tp)) setOriginal tree
)
}
@@ -4134,7 +4134,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (isValueClass(pt.typeSymbol) || !isFullyDefined(pt)) arrayType(pt)
else {
val tparam = context.owner freshExistential "" setInfo TypeBounds.upper(pt)
- ExistentialType(List(tparam), arrayType(tparam.tpe))
+ newExistentialType(List(tparam), arrayType(tparam.tpe))
}
val (expr1, baseClass) = expr0.tpe.typeSymbol match {
case ArrayClass => (adapt(expr0, onlyStickyModes(mode), subArrayType(pt)), ArrayClass)