diff options
author | Paul Phillips <paulp@improving.org> | 2011-07-03 20:00:25 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-07-03 20:00:25 +0000 |
commit | 552d7aa113dfda5c33c909b4a7874799a7ff1a3e (patch) | |
tree | 85872eecb1c7a83c95bcbef4b92bed1e30e8be88 | |
parent | d858fc14ad79b9c8bbe066aec70ded8fa62b0275 (diff) | |
download | scala-552d7aa113dfda5c33c909b4a7874799a7ff1a3e.tar.gz scala-552d7aa113dfda5c33c909b4a7874799a7ff1a3e.tar.bz2 scala-552d7aa113dfda5c33c909b4a7874799a7ff1a3e.zip |
Modified return type inference not to allow T* ...
Modified return type inference not to allow T* to leak from varargs
methods. Since I don't know what is supposed to be done about eta
expansion of these methods, I left the behavior as it was (except the
return type) and a boolean val in Types to change it.
def id[T](xs: T*) = xs
etaExpandKeepsStar = true // (id[Int] _) is Int* => Seq[Int]
etaExpandKeepsStar = false // (id[Int] _) is Seq[Int] => Seq[Int]
References #4176, leaving open pending resolution of eta expansion.
Review by odersky.
-rw-r--r-- | src/compiler/scala/reflect/internal/Types.scala | 21 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Namers.scala | 2 |
2 files changed, 22 insertions, 1 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 75243c6e1c..840d66c558 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -2995,6 +2995,27 @@ A type's typeSymbol should never be inspected directly. } } + // Set to true for A* => Seq[A] + // (And it will only rewrite A* in method result types.) + // This is the pre-existing behavior. + // Or false for Seq[A] => Seq[A] + // (It will rewrite A* everywhere but method parameters.) + // This is the specified behavior. + private final val etaExpandKeepsStar = true + + object dropRepeatedParamType extends TypeMap { + def apply(tp: Type): Type = tp match { + case MethodType(params, restpe) => + MethodType(params, apply(restpe)) + case PolyType(tparams, restpe) => + PolyType(tparams, apply(restpe)) + case TypeRef(_, RepeatedParamClass, arg :: Nil) => + seqType(arg) + case _ => + if (etaExpandKeepsStar) tp else mapOver(tp) + } + } + // Hash consing -------------------------------------------------------------- private val initialUniquesCapacity = 4096 diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 71b983f53d..c0160d5d34 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -632,7 +632,7 @@ trait Namers { self: Analyzer => false } - val tpe1 = tpe.deconst + val tpe1 = dropRepeatedParamType(tpe.deconst) val tpe2 = tpe1.widen // This infers Foo.type instead of "object Foo" |