summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2010-09-27 13:27:35 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2010-09-27 13:27:35 +0000
commitb40f4ba3221f1091f4821423f18c157907e9a3c7 (patch)
tree3cc32dc30da1f640bfc7df01a78f2e679803087d /src
parent9522f08f413305c949008e161984fd3900094e3f (diff)
downloadscala-b40f4ba3221f1091f4821423f18c157907e9a3c7.tar.gz
scala-b40f4ba3221f1091f4821423f18c157907e9a3c7.tar.bz2
scala-b40f4ba3221f1091f4821423f18c157907e9a3c7.zip
closes #3873.
review by maier as no good deed goes unpunished
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala89
1 files changed, 15 insertions, 74 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 07d63d62d2..c853efb725 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -3494,85 +3494,26 @@ A type's typeSymbol should never be inspected directly.
else mapOver(tp)
}
-/*
- /** Most of the implementation for MethodType.resultType. The
- * caller also needs to existentially quantify over the
- * variables in existentialsNeeded.
- */
- class InstantiateDeBruijnMap(actuals: List[Type]) extends TypeMap {
- def apply(tp: Type): Type = tp match {
- case DeBruijnIndex(level, pid) =>
- if (level == 1)
- if (pid < actuals.length) actuals(pid) else tp
- else DeBruijnIndex(level - 1, pid)
- case _ =>
- mapOver(tp)
- }
-
+ class InstantiateDependentMap(params: List[Symbol], actuals: List[Type]) extends TypeMap {
override val dropNonConstraintAnnotations = true
- private var existSyms = immutable.Map.empty[Int, Symbol]
- def existentialsNeeded: List[Symbol] = existSyms.values.toList
-
- /* Return the type symbol for referencing a parameter index
- * inside the existential quantifier. */
- def existSymFor(actualIdx: Int, oldSym: Symbol) =
- if (existSyms.isDefinedAt(actualIdx))
- existSyms(actualIdx)
- else {
- val symowner = oldSym.owner // what should be used??
- val bound = singletonBounds(actuals(actualIdx))
-
- val sym = symowner.newExistential(oldSym.pos, oldSym.name+".type")
- sym.setInfo(bound)
- sym.setFlag(oldSym.flags)
-
- existSyms = existSyms + (actualIdx -> sym)
- sym
- }
-
- override def mapOver(arg: Tree, giveup: ()=>Nothing): Tree = {
- object treeTrans extends TypeMapTransformer {
- override def transform(tree: Tree): Tree =
- tree match {
- case Ident(name) =>
- tree.tpe.withoutAnnotations match {
- case DeBruijnIndex(level, pid) =>
- if (level == 1) {
- if (actuals(pid).isStable)
- mkAttributedQualifier(actuals(pid), tree.symbol)
- else {
- val sym = existSymFor(pid, tree.symbol)
- (Ident(tree.symbol.name)
- copyAttrs tree
- setType typeRef(NoPrefix, sym, Nil))
- }
- } else
- Ident(name)
- .setPos(tree.pos)
- .setSymbol(tree.symbol)
- .setType(DeBruijnIndex(level-1, pid))
- case _ =>
- super.transform(tree)
-
- }
- case _ => super.transform(tree)
- }
+ object ParamWithActual {
+ def unapply(sym: Symbol): Option[Type] = {
+ val pid = params indexOf sym
+ if(pid != -1) Some(actuals(pid)) else None
}
-
- treeTrans.transform(arg)
}
- }
-*/
- class InstantiateDependentMap(params: List[Symbol], actuals: List[Type]) extends SubstTypeMap(params, actuals) {
- override protected def renameBoundSyms(tp: Type): Type = tp match {
- case MethodType(ps, restp) => tp // the whole point of this substitution is to instantiate these args
- case _ => super.renameBoundSyms(tp)
- }
- // TODO: should we optimise this? only need to consider singletontypes
-
- override val dropNonConstraintAnnotations = true
+ def apply(tp: Type): Type =
+ mapOver(tp) match {
+ case SingleType(NoPrefix, ParamWithActual(arg)) if arg isStable => arg // unsound to replace args by unstable actual #3873
+ // (soundly) expand type alias selections on implicit arguments, see depmet_implicit_oopsla* test cases -- typically, `param.isImplicit`
+ case tp1@TypeRef(SingleType(NoPrefix, param@ParamWithActual(arg)), sym, targs) =>
+ val res = typeRef(arg, sym, targs)
+ if(res.typeSymbolDirect isAliasType) res.dealias
+ else tp1
+ case tp1 => tp1 // don't return the original `tp`, which may be different from `tp1`, due to `dropNonConstraintAnnotations`
+ }
def existentialsNeeded: List[Symbol] = existSyms.filter(_ ne null).toList