summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAntonio Cunei <antonio.cunei@epfl.ch>2010-09-28 12:31:56 +0000
committerAntonio Cunei <antonio.cunei@epfl.ch>2010-09-28 12:31:56 +0000
commit16dd1e6bfd7e55930becedf03f54261a0faa814e (patch)
treeaaaec04a0167db3939f97ec0ad9465a4de3277c4 /src
parent394bc2928b6ad24306038a4c4a73611b2ec13ae3 (diff)
downloadscala-16dd1e6bfd7e55930becedf03f54261a0faa814e.tar.gz
scala-16dd1e6bfd7e55930becedf03f54261a0faa814e.tar.bz2
scala-16dd1e6bfd7e55930becedf03f54261a0faa814e.zip
Merged revisions 23111 via svnmerge from
https://lampsvn.epfl.ch/svn-repos/scala/scala/trunk ........ r23111 | moors | 2010-09-27 15:27:35 +0200 (Mon, 27 Sep 2010) | 3 lines closes #3873. fixed unsoundness in dependent method types reported by Ingo. 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 deffa1d852..a7f8db28b2 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -3493,85 +3493,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