summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-11-04 00:07:36 +0000
committerPaul Phillips <paulp@improving.org>2010-11-04 00:07:36 +0000
commit379af580e2c8cf0ce5309fc0b31702f79e415abe (patch)
treecf741eb0d27624d6130bb5bc7f403ec7fb05af1d /src/compiler/scala/tools
parentde012b3a6d04f1e7a9fd6fecd403e0492f6ad7c1 (diff)
downloadscala-379af580e2c8cf0ce5309fc0b31702f79e415abe.tar.gz
scala-379af580e2c8cf0ce5309fc0b31702f79e415abe.tar.bz2
scala-379af580e2c8cf0ce5309fc0b31702f79e415abe.zip
Determined that half a dozen ways of checking f...
Determined that half a dozen ways of checking for varargs and by-name-ness in param lists exceeded the legal limit. Also assessed that names which are only used as type names would be a lot easier to deal with if we created them as type names up front. Performed the changes implied by the preceding along with a partial cleanup on TreeInfo which one can see hasn't had a good look in a long time. (And still hasn't.) No review.
Diffstat (limited to 'src/compiler/scala/tools')
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeInfo.scala84
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala26
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala8
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala6
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala21
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Names.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala12
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala27
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala125
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala17
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala20
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala24
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala81
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala30
20 files changed, 263 insertions, 254 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index a47200a63d..073bebad04 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -316,7 +316,7 @@ abstract class TreeGen {
Apply(Select(monitor, Object_synchronized), List(body))
def wildcardStar(tree: Tree) =
- atPos(tree.pos) { Typed(tree, Ident(nme.WILDCARD_STAR.toTypeName)) }
+ atPos(tree.pos) { Typed(tree, Ident(nme.WILDCARD_STAR)) }
def paramToArg(vparam: Symbol) = {
val arg = Ident(vparam)
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
index 443a5a724b..8be793343e 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
@@ -16,14 +16,10 @@ import util.HashSet
* @version 1.0
*/
abstract class TreeInfo {
-
val trees: SymbolTable
import trees._
import definitions.ThrowableClass
- def isTerm(tree: Tree): Boolean = tree.isTerm
- def isType(tree: Tree): Boolean = tree.isType
-
def isOwnerDefinition(tree: Tree): Boolean = tree match {
case PackageDef(_, _)
| ClassDef(_, _, _, _)
@@ -101,9 +97,9 @@ abstract class TreeInfo {
}
def mayBeVarGetter(sym: Symbol) = sym.info match {
- case PolyType(List(), _) => sym.owner.isClass && !sym.isStable
- case mt: MethodType => mt.isImplicit && sym.owner.isClass && !sym.isStable
- case _ => false
+ case PolyType(Nil, _) => sym.owner.isClass && !sym.isStable
+ case mt @ MethodType(_, _) => mt.isImplicit && sym.owner.isClass && !sym.isStable
+ case _ => false
}
def isVariableOrGetter(tree: Tree) = {
@@ -135,17 +131,14 @@ abstract class TreeInfo {
case _ => false
}
- def isSelfOrSuperConstrCall(tree: Tree): Boolean = methPart(tree) match {
- case Ident(nme.CONSTRUCTOR)
- | Select(This(_), nme.CONSTRUCTOR)
- | Select(Super(_, _), nme.CONSTRUCTOR) => true
- case _ => false
- }
+ def isSelfOrSuperConstrCall(tree: Tree) =
+ isSelfConstrCall(tree) || isSuperConstrCall(tree)
/** Is tree a variable pattern */
def isVarPattern(pat: Tree): Boolean = pat match {
- case Ident(name) => isVariableName(name) && !pat.isInstanceOf[BackQuotedIdent]
- case _ => false
+ case _: BackQuotedIdent => false
+ case x: Ident => isVariableName(x.name)
+ case _ => false
}
/** The first constructor definitions in `stats' */
@@ -162,7 +155,7 @@ abstract class TreeInfo {
/** The value definitions marked PRESUPER in this statement sequence */
def preSuperFields(stats: List[Tree]): List[ValDef] =
- for (vdef @ ValDef(mods, _, _, _) <- stats if mods hasFlag PRESUPER) yield vdef
+ stats collect { case vd: ValDef if isEarlyValDef(vd) => vd }
def isEarlyDef(tree: Tree) = tree match {
case TypeDef(mods, _, _, _) => mods hasFlag PRESUPER
@@ -180,25 +173,23 @@ abstract class TreeInfo {
case _ => false
}
- /** Is type a of the form T* ? */
+ /** Is tpt of the form T* ? */
def isRepeatedParamType(tpt: Tree) = tpt match {
- case AppliedTypeTree(Select(_, rp), _) =>
- rp == nme.REPEATED_PARAM_CLASS_NAME.toTypeName ||
- rp == nme.JAVA_REPEATED_PARAM_CLASS_NAME.toTypeName
- case TypeTree() => definitions.isRepeatedParamType(tpt.tpe)
- case _ => false
+ case TypeTree() => definitions.isRepeatedParamType(tpt.tpe)
+ case AppliedTypeTree(Select(_, nme.REPEATED_PARAM_CLASS_NAME), _) => true
+ case AppliedTypeTree(Select(_, nme.JAVA_REPEATED_PARAM_CLASS_NAME), _) => true
+ case _ => false
}
/** Is tpt a by-name parameter type? */
def isByNameParamType(tpt: Tree) = tpt match {
- case AppliedTypeTree(Select(_, n), _) => n == nme.BYNAME_PARAM_CLASS_NAME.toTypeName
- case TypeTree() => tpt.tpe.typeSymbol == definitions.ByNameParamClass
- case _ => false
+ case TypeTree() => definitions.isByNameParamType(tpt.tpe)
+ case AppliedTypeTree(Select(_, nme.BYNAME_PARAM_CLASS_NAME), _) => true
+ case _ => false
}
/** Is name a left-associative operator? */
- def isLeftAssoc(operator: Name): Boolean =
- operator.length > 0 && operator(operator.length - 1) != ':'
+ def isLeftAssoc(operator: Name) = operator.nonEmpty && (operator.endChar != ':')
private val reserved = Set[Name](nme.false_, nme.true_, nme.null_)
@@ -216,26 +207,33 @@ abstract class TreeInfo {
/** can this type be a type pattern */
def mayBeTypePat(tree: Tree): Boolean = tree match {
- case CompoundTypeTree(Template(tps, _, List())) => tps exists mayBeTypePat
- case Annotated(_, tp) => mayBeTypePat(tp)
- case AppliedTypeTree(constr, args) =>
- mayBeTypePat(constr) || args.exists(_.isInstanceOf[Bind])
- case SelectFromTypeTree(tp, _) => mayBeTypePat(tp)
- case _ => false
+ case CompoundTypeTree(Template(tps, _, Nil)) => tps exists mayBeTypePat
+ case Annotated(_, tp) => mayBeTypePat(tp)
+ case AppliedTypeTree(constr, args) => mayBeTypePat(constr) || args.exists(_.isInstanceOf[Bind])
+ case SelectFromTypeTree(tp, _) => mayBeTypePat(tp)
+ case _ => false
}
/** Is this argument node of the form <expr> : _* ?
*/
def isWildcardStarArg(tree: Tree): Boolean = tree match {
- case Typed(expr, Ident(name)) => name == nme.WILDCARD_STAR.toTypeName
- case _ => false
+ case Typed(_, Ident(nme.WILDCARD_STAR)) => true
+ case _ => false
+ }
+ def isWildcardStarArgList(trees: List[Tree]) =
+ trees.nonEmpty && isWildcardStarArg(trees.last)
+
+ /** Is the argument a (possibly bound) _ arg?
+ */
+ def isWildcardArg(tree: Tree): Boolean = unbind(tree) match {
+ case Ident(nme.WILDCARD) => true
+ case _ => false
}
/** Is this pattern node a catch-all (wildcard or variable) pattern? */
def isDefaultCase(cdef: CaseDef) = cdef match {
- case CaseDef(Ident(nme.WILDCARD), EmptyTree, _) => true
- case CaseDef(Bind(_, Ident(nme.WILDCARD)), EmptyTree, _) => true
- case _ => false
+ case CaseDef(pat, EmptyTree, _) => isWildcardArg(pat)
+ case _ => false
}
/** Does this CaseDef catch Throwable? */
@@ -280,12 +278,10 @@ abstract class TreeInfo {
*/
/** Is this pattern node a sequence-valued pattern? */
- def isSequenceValued(tree: Tree): Boolean = tree match {
- case Bind(_, body) => isSequenceValued(body)
- case ArrayValue(_, _) => true
- case Star(_) => true
- case Alternative(ts) => ts exists isSequenceValued
- case _ => false
+ def isSequenceValued(tree: Tree): Boolean = unbind(tree) match {
+ case Alternative(ts) => ts exists isSequenceValued
+ case ArrayValue(_, _) | Star(_) => true
+ case _ => false
}
/** The underlying pattern ignoring any bindings */
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index b3aaf02195..5a63b49aac 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -443,14 +443,12 @@ self =>
def errorTermTree = Literal(Constant(null)).setPos(o2p(in.offset))
def errorPatternTree = Ident(nme.WILDCARD).setPos(o2p(in.offset))
- /** Check that type parameter is not by name T* */
- def checkNotByName(t: Tree) = t match {
- case AppliedTypeTree(Select(_, n), _) =>
- if (n == nme.BYNAME_PARAM_CLASS_NAME.toTypeName)
- syntaxError(t.pos, "no by-name parameter type allowed here", false)
- else if (n == nme.REPEATED_PARAM_CLASS_NAME.toTypeName)
- syntaxError(t.pos, "no * parameter type allowed here", false)
- case _ =>
+ /** Check that type parameter is not by name or repeated */
+ def checkNotByNameOrVarargs(tpt: Tree) = {
+ if (treeInfo isByNameParamType tpt)
+ syntaxError(tpt.pos, "no by-name parameter type allowed here", false)
+ else if (treeInfo isRepeatedParamType tpt)
+ syntaxError(tpt.pos, "no * parameter type allowed here", false)
}
/** Check that tree is a legal clause of a forSome */
@@ -867,7 +865,7 @@ self =>
makeFunctionTypeTree(ts, typ(isPattern))
}
else {
- ts foreach checkNotByName
+ ts foreach checkNotByNameOrVarargs
val tuple = atPos(start) { makeTupleType(ts, true) }
infixTypeRest(
compoundTypeRest(
@@ -1036,12 +1034,12 @@ self =>
// copy-paste (with change) from def paramType
if (in.token == ARROW) {
in.nextToken()
- val tycon = atPos(start) { rootScalaDot(nme.BYNAME_PARAM_CLASS_NAME.toTypeName) }
+ val tycon = atPos(start) { rootScalaDot(nme.BYNAME_PARAM_CLASS_NAME) }
atPos(start) { AppliedTypeTree(tycon, List(typ())) }
} else {
val t = typ()
if (isIdent && in.name == STAR) {
- val tycon = atPos(in.skipToken()) { rootScalaDot(nme.REPEATED_PARAM_CLASS_NAME.toTypeName) }
+ val tycon = atPos(in.skipToken()) { rootScalaDot(nme.REPEATED_PARAM_CLASS_NAME) }
atPos(start) { AppliedTypeTree(tycon, List(t)) }
} else t
}
@@ -1195,7 +1193,7 @@ self =>
if (isIdent && in.name == nme.STAR) {
in.nextToken()
t = atPos(t.pos.startOrPoint, colonPos) {
- Typed(t, atPos(uscorePos) { Ident(nme.WILDCARD_STAR.toTypeName) })
+ Typed(t, atPos(uscorePos) { Ident(nme.WILDCARD_STAR) })
}
} else {
syntaxErrorOrIncomplete("`*' expected", true)
@@ -1917,7 +1915,7 @@ self =>
if (in.token == ARROW) {
atPos(in.skipToken()) {
AppliedTypeTree(
- rootScalaDot(nme.BYNAME_PARAM_CLASS_NAME.toTypeName), List(typ()))
+ rootScalaDot(nme.BYNAME_PARAM_CLASS_NAME), List(typ()))
}
} else {
val t = typ()
@@ -1925,7 +1923,7 @@ self =>
in.nextToken()
atPos(t.pos.startOrPoint, t.pos.point) {
AppliedTypeTree(
- rootScalaDot(nme.REPEATED_PARAM_CLASS_NAME.toTypeName), List(t))
+ rootScalaDot(nme.REPEATED_PARAM_CLASS_NAME), List(t))
}
} else t
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
index 86c79eb733..f0d1c536c4 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
@@ -58,7 +58,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean)
private def LL[A](x: A*): List[List[A]] = List(List(x:_*))
private def const(x: Any) = Literal(Constant(x))
private def wild = Ident(nme.WILDCARD)
- private def wildStar = Ident(nme.WILDCARD_STAR.toTypeName)
+ private def wildStar = Ident(nme.WILDCARD_STAR)
private def _scala(name: Name) = Select(Select(Ident(nme.ROOTPKG), nme.scala_), name)
private def _scala_xml(name: Name) = Select(_scala(_xml), name)
diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
index bf5a364515..5e44d519cf 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
@@ -25,7 +25,7 @@ package icode
trait TypeKinds { self: ICodes =>
import global._
- import definitions.{ ArrayClass, AnyRefClass, ObjectClass, NullClass, NothingClass }
+ import definitions.{ ArrayClass, AnyRefClass, ObjectClass, NullClass, NothingClass, arrayType }
import icodes.checkerDebug
/** A map from scala primitive Types to ICode TypeKinds */
@@ -56,9 +56,9 @@ trait TypeKinds { self: ICodes =>
def toType: Type = (reversePrimitiveMap get this) map (_.tpe) getOrElse {
this match {
- case REFERENCE(cls) => cls.tpe
- case ARRAY(elem) => typeRef(ArrayClass.typeConstructor.prefix, ArrayClass, List(elem.toType))
- case _ => abort("Unknown type kind.")
+ case REFERENCE(cls) => cls.tpe
+ case ARRAY(elem) => arrayType(elem.toType)
+ case _ => abort("Unknown type kind.")
}
}
def toTypeAt(ph: Phase): Type = atPhase(ph)(toType)
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 569b0d2a30..080af68d27 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -514,13 +514,13 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
appendTypes0(tp.args.init, ", ")
nameBuffer append ") ⇒ "
appendType0(tp.args.last)
- case tp: TypeRef if (tp.typeSymbol == definitions.RepeatedParamClass) =>
+ case tp: TypeRef if definitions.isScalaRepeatedParamType(tp) =>
appendType0(tp.args.head)
nameBuffer append '*'
- case tp: TypeRef if (tp.typeSymbol == definitions.ByNameParamClass) =>
+ case tp: TypeRef if definitions.isByNameParamType(tp) =>
nameBuffer append "⇒ "
appendType0(tp.args.head)
- case tp: TypeRef if (definitions.isTupleTypeOrSubtype(tp)) =>
+ case tp: TypeRef if definitions.isTupleTypeOrSubtype(tp) =>
nameBuffer append '('
appendTypes0(tp.args, ", ")
nameBuffer append ')'
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 1dfab2a98a..63c62d8d1e 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -487,7 +487,7 @@ trait JavaParsers extends JavaScanners {
if (in.token == DOTDOTDOT) {
in.nextToken
t = atPos(t.pos) {
- AppliedTypeTree(scalaDot(nme.JAVA_REPEATED_PARAM_CLASS_NAME.toTypeName), List(t))
+ AppliedTypeTree(scalaDot(nme.JAVA_REPEATED_PARAM_CLASS_NAME), List(t))
}
}
varDecl(in.currentPos, Modifiers(Flags.JAVA | Flags.PARAM), t, ident())
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 20f6ed9e5a..6a9cdf6961 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -182,8 +182,23 @@ trait Definitions extends reflect.generic.StandardDefinitions {
tparam => arrayType(tparam.typeConstructor)
)
- def isRepeatedParamType(tp: Type) =
- tp.typeSymbol == RepeatedParamClass || tp.typeSymbol == JavaRepeatedParamClass
+ def isByNameParamType(tp: Type) = tp.typeSymbol == ByNameParamClass
+ def isScalaRepeatedParamType(tp: Type) = tp.typeSymbol == RepeatedParamClass
+ def isJavaRepeatedParamType(tp: Type) = tp.typeSymbol == JavaRepeatedParamClass
+ def isRepeatedParamType(tp: Type) = isScalaRepeatedParamType(tp) || isJavaRepeatedParamType(tp)
+
+ def isScalaVarArgs(params: List[Symbol]) = params.nonEmpty && isScalaRepeatedParamType(params.last.tpe)
+ def isVarArgsList(params: List[Symbol]) = params.nonEmpty && isRepeatedParamType(params.last.tpe)
+ def isVarArgTypes(formals: List[Type]) = formals.nonEmpty && isRepeatedParamType(formals.last)
+
+ def isPrimitiveArray(tp: Type) = tp match {
+ case TypeRef(_, ArrayClass, arg :: Nil) => isValueClass(arg.typeSymbol)
+ case _ => false
+ }
+ def isArrayOfSymbol(tp: Type, elem: Symbol) = tp match {
+ case TypeRef(_, ArrayClass, arg :: Nil) => arg.typeSymbol == elem
+ case _ => false
+ }
lazy val ByNameParamClass = newCovariantPolyClass(
ScalaPackageClass,
@@ -362,7 +377,7 @@ trait Definitions extends reflect.generic.StandardDefinitions {
false
}
- def seqType(arg: Type) = typeRef(SeqClass.typeConstructor.prefix, SeqClass, List(arg))
+ def seqType(arg: Type) = typeRef(SeqClass.typeConstructor.prefix, SeqClass, List(arg))
def arrayType(arg: Type) = typeRef(ArrayClass.typeConstructor.prefix, ArrayClass, List(arg))
def ClassType(arg: Type) =
diff --git a/src/compiler/scala/tools/nsc/symtab/Names.scala b/src/compiler/scala/tools/nsc/symtab/Names.scala
index 8cf95197c6..0c473c33ef 100644
--- a/src/compiler/scala/tools/nsc/symtab/Names.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Names.scala
@@ -160,6 +160,7 @@ trait Names extends reflect.generic.Names {
*/
final def length: Int = len
final def isEmpty = length == 0
+ final def nonEmpty = !isEmpty
def isTermName: Boolean
def isTypeName: Boolean
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 82bd274e66..98582cff03 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -95,13 +95,16 @@ trait StdNames extends reflect.generic.StdNames with NameManglers {
/** Internal names */
val ANYNAME = newTermName("<anyname>")
- val BYNAME_PARAM_CLASS_NAME = newTermName("<byname>")
val EQUALS_PATTERN_NAME = newTermName("<equals>")
val ERROR = newTermName("<error>")
- val JAVA_REPEATED_PARAM_CLASS_NAME = newTermName("<repeated...>")
- val LOCALCHILD = newTypeName("<local child>")
val NOSYMBOL = newTermName("<none>")
- val REPEATED_PARAM_CLASS_NAME = newTermName("<repeated>")
+
+ /** TYPE names. */
+ val BYNAME_PARAM_CLASS_NAME = newTypeName("<byname>")
+ val JAVA_REPEATED_PARAM_CLASS_NAME = newTypeName("<repeated...>")
+ val LOCALCHILD = newTypeName("<local child>")
+ val REPEATED_PARAM_CLASS_NAME = newTypeName("<repeated>")
+ val WILDCARD_STAR = newTypeName("_*")
val CONSTRUCTOR = newTermName("<init>")
val INITIALIZER = newTermName("<init>")
@@ -119,7 +122,6 @@ trait StdNames extends reflect.generic.StdNames with NameManglers {
val TYPE_ = newTermName("TYPE")
val WILDCARD = newTermName("_")
- val WILDCARD_STAR = newTermName("_*")
val STAR = newTermName("*")
val MINUS = encode("-")
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 108bb2f8cc..96a7654c68 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -818,10 +818,6 @@ trait Types extends reflect.generic.Types { self: SymbolTable =>
typeVarToOriginMap(this) eq this
}
- /** Is this type a varargs parameter?
- */
- def isVarargs: Boolean = typeSymbol == RepeatedParamClass
-
/** If this is a symbol loader type, load and assign a new type to
* `sym'.
*/
@@ -1910,17 +1906,18 @@ A type's typeSymbol should never be inspected directly.
override def safeToString: String = {
if (!settings.debug.value) {
- if (sym == RepeatedParamClass && !args.isEmpty)
- return args(0).toString + "*"
- if (sym == ByNameParamClass && !args.isEmpty)
- return "=> " + args(0).toString
- if (isFunctionType(this))
- return normalize.typeArgs.init.mkString("(", ", ", ")") + " => " + normalize.typeArgs.last
- if (isTupleTypeOrSubtype(this))
- return normalize.typeArgs.mkString("(", ", ", if (normalize.typeArgs.length == 1) ",)" else ")")
- if (sym.isAliasType && (prefixChain exists (_.termSymbol.isSynthetic))) {
- val normed = normalize;
- if (normed ne this) return normed.toString
+ this match {
+ case TypeRef(_, RepeatedParamClass, arg :: _) => return arg + "*"
+ case TypeRef(_, ByNameParamClass, arg :: _) => return "=> " + arg
+ case _ =>
+ if (isFunctionType(this))
+ return normalize.typeArgs.init.mkString("(", ", ", ")") + " => " + normalize.typeArgs.last
+ else if (isTupleTypeOrSubtype(this))
+ return normalize.typeArgs.mkString("(", ", ", if (normalize.typeArgs.length == 1) ",)" else ")")
+ else if (sym.isAliasType && prefixChain.exists(_.termSymbol.isSynthetic)) {
+ val normed = normalize;
+ if (normed ne this) return normed.toString
+ }
}
}
val monopart =
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 525815a6b2..2c47239a92 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -670,7 +670,7 @@ abstract class ClassfileParser {
t
}
val newParams = method.newSyntheticValueParams(
- formals.init ::: List(appliedType(definitions.JavaRepeatedParamClass.typeConstructor, List(elemtp))))
+ formals.init :+ appliedType(definitions.JavaRepeatedParamClass.typeConstructor, List(elemtp)))
MethodType(newParams, rtpe)
case PolyType(tparams, rtpe) =>
PolyType(tparams, arrayToRepeated(rtpe))
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 26c1efbf91..63f4c05def 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -180,8 +180,8 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
*/
def isByNameRef(tree: Tree): Boolean =
tree.isTerm && tree.hasSymbol &&
- tree.symbol.tpe.typeSymbol == ByNameParamClass &&
- !byNameArgs.contains(tree)
+ isByNameParamType(tree.symbol.tpe) &&
+ !byNameArgs(tree)
/** Uncurry a type of a tree node.
* This function is sensitive to whether or not we are in a pattern -- when in a pattern
@@ -385,78 +385,71 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
}
def transformArgs(pos: Position, fun: Symbol, args: List[Tree], formals: List[Type]) = {
- val isJava = fun hasFlag JAVA
- val args1 = formals.lastOption match {
- case Some(lastFormal) if isRepeatedParamType(lastFormal) =>
-
- def mkArrayValue(ts: List[Tree], elemtp: Type) =
- ArrayValue(TypeTree(elemtp), ts) setType arrayType(elemtp)
-
- // when calling into scala varargs, make sure it's a sequence.
- def arrayToSequence(tree: Tree, elemtp: Type) = {
- atPhase(phase.next) {
- localTyper.typedPos(pos) {
- val pt = arrayType(elemtp)
- val adaptedTree = // might need to cast to Array[elemtp], as arrays are not covariant
- if (tree.tpe <:< pt) tree
- else gen.mkCastArray(tree, elemtp, pt)
-
- gen.mkWrapArray(adaptedTree, elemtp)
- }
+ val isJava = fun.isJavaDefined
+ def transformVarargs(varargsElemType: Type) = {
+ def mkArrayValue(ts: List[Tree], elemtp: Type) =
+ ArrayValue(TypeTree(elemtp), ts) setType arrayType(elemtp)
+
+ // when calling into scala varargs, make sure it's a sequence.
+ def arrayToSequence(tree: Tree, elemtp: Type) = {
+ atPhase(phase.next) {
+ localTyper.typedPos(pos) {
+ val pt = arrayType(elemtp)
+ val adaptedTree = // might need to cast to Array[elemtp], as arrays are not covariant
+ if (tree.tpe <:< pt) tree
+ else gen.mkCastArray(tree, elemtp, pt)
+
+ gen.mkWrapArray(adaptedTree, elemtp)
}
}
+ }
- // when calling into java varargs, make sure it's an array - see bug #1360
- def sequenceToArray(tree: Tree) = {
- val toArraySym = tree.tpe member nme.toArray
- assert(toArraySym != NoSymbol)
- def getManifest(tp: Type): Tree = {
- val manifestOpt = localTyper.findManifest(tp, false)
- if (!manifestOpt.tree.isEmpty) manifestOpt.tree
- else if (tp.bounds.hi ne tp) getManifest(tp.bounds.hi)
- else localTyper.getManifestTree(tree.pos, tp, false)
- }
- atPhase(phase.next) {
- localTyper.typedPos(pos) {
- Apply(gen.mkAttributedSelect(tree, toArraySym), List(getManifest(tree.tpe.typeArgs.head)))
- }
+ // when calling into java varargs, make sure it's an array - see bug #1360
+ def sequenceToArray(tree: Tree) = {
+ val toArraySym = tree.tpe member nme.toArray
+ assert(toArraySym != NoSymbol)
+ def getManifest(tp: Type): Tree = {
+ val manifestOpt = localTyper.findManifest(tp, false)
+ if (!manifestOpt.tree.isEmpty) manifestOpt.tree
+ else if (tp.bounds.hi ne tp) getManifest(tp.bounds.hi)
+ else localTyper.getManifestTree(tree.pos, tp, false)
+ }
+ atPhase(phase.next) {
+ localTyper.typedPos(pos) {
+ Apply(gen.mkAttributedSelect(tree, toArraySym), List(getManifest(tree.tpe.typeArgs.head)))
}
}
+ }
- val lastElemType = lastFormal.typeArgs.head
- var suffix: Tree =
- if (!args.isEmpty && (treeInfo isWildcardStarArg args.last)) {
- val Typed(tree, _) = args.last;
- if (isJava)
- if (tree.tpe.typeSymbol == ArrayClass) tree
- else sequenceToArray(tree)
- else
- if (tree.tpe.typeSymbol isSubClass TraversableClass) tree
- else arrayToSequence(tree, lastElemType)
- } else {
- val tree = mkArrayValue(args drop (formals.length - 1), lastElemType)
- if (isJava || inPattern) tree
- else arrayToSequence(tree, lastElemType)
- }
+ var suffix: Tree =
+ if (treeInfo isWildcardStarArgList args) {
+ val Typed(tree, _) = args.last;
+ if (isJava)
+ if (tree.tpe.typeSymbol == ArrayClass) tree
+ else sequenceToArray(tree)
+ else
+ if (tree.tpe.typeSymbol isSubClass TraversableClass) tree // @PP: I suspect this should be SeqClass
+ else arrayToSequence(tree, varargsElemType)
+ } else {
+ val tree = mkArrayValue(args drop (formals.length - 1), varargsElemType)
+ if (isJava || inPattern) tree
+ else arrayToSequence(tree, varargsElemType)
+ }
- atPhase(phase.next) {
- if (isJava &&
- suffix.tpe.typeSymbol == ArrayClass &&
- isValueClass(suffix.tpe.typeArgs.head.typeSymbol) &&
- { val lastFormal2 = fun.tpe.params.last.tpe
- lastFormal2.typeSymbol == ArrayClass &&
- lastFormal2.typeArgs.head.typeSymbol == ObjectClass
- })
- suffix = localTyper.typedPos(pos) {
- gen.mkRuntimeCall("toObjectArray", List(suffix))
- }
+ atPhase(phase.next) {
+ if (isJava && isPrimitiveArray(suffix.tpe) && isArrayOfSymbol(fun.tpe.params.last.tpe, ObjectClass)) {
+ suffix = localTyper.typedPos(pos) {
+ gen.mkRuntimeCall("toObjectArray", List(suffix))
+ }
}
- args.take(formals.length - 1) ::: List(suffix setType lastFormal)
- case _ =>
- args
+ }
+ args.take(formals.length - 1) :+ (suffix setType formals.last)
}
+
+ val args1 = if (isVarArgTypes(formals)) transformVarargs(formals.last.typeArgs.head) else args
+
(formals, args1).zipped map { (formal, arg) =>
- if (formal.typeSymbol != ByNameParamClass) {
+ if (!isByNameParamType(formal)) {
arg
} else if (isByNameRef(arg)) {
byNameArgs.addEntry(arg)
@@ -686,7 +679,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
case Apply(Apply(fn, args), args1) =>
treeCopy.Apply(tree, fn, args ::: args1)
case Ident(name) =>
- assert(name != nme.WILDCARD_STAR.toTypeName)
+ assert(name != nme.WILDCARD_STAR)
applyUnary()
case Select(_, _) | TypeApply(_, _) =>
applyUnary()
@@ -733,7 +726,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
traverse(fn)
(fn.symbol.paramss.head zip args) foreach {
case (param, arg) =>
- if (param.tpe != null && param.tpe.typeSymbol == ByNameParamClass)
+ if (param.tpe != null && isByNameParamType(param.tpe))
withEscaping(traverse(arg))
else
traverse(arg)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 095094579a..66cd76f800 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -28,9 +28,6 @@ trait Infer {
private def assertNonCyclic(tvar: TypeVar) =
assert(tvar.constr.inst != tvar, tvar.origin)
- def isVarArgs(params: List[Symbol]) = !params.isEmpty && isRepeatedParamType(params.last.tpe)
- def isVarArgTpes(formals: List[Type]) = !formals.isEmpty && isRepeatedParamType(formals.last)
-
/** The formal parameter types corresponding to <code>formals</code>.
* If <code>formals</code> has a repeated last parameter, a list of
* (nargs - params.length + 1) copies of its type is returned.
@@ -41,10 +38,10 @@ trait Infer {
*/
def formalTypes(formals: List[Type], nargs: Int, removeByName: Boolean = true, removeRepeated: Boolean = true): List[Type] = {
val formals1 = if (removeByName) formals mapConserve {
- case TypeRef(_, sym, List(arg)) if (sym == ByNameParamClass) => arg
+ case TypeRef(_, ByNameParamClass, List(arg)) => arg
case formal => formal
} else formals
- if (isVarArgTpes(formals1) && (removeRepeated || formals.length != nargs)) {
+ if (isVarArgTypes(formals1) && (removeRepeated || formals.length != nargs)) {
val ft = formals1.last.normalize.typeArgs.head
formals1.init ::: (for (i <- List.range(formals1.length - 1, nargs)) yield ft)
} else formals1
@@ -685,7 +682,7 @@ trait Infer {
alts exists (alt => hasExactlyNumParams(pre.memberType(alt), n))
case _ =>
val len = tp.params.length
- len == n || isVarArgs(tp.params) && len <= n + 1
+ len == n || isVarArgsList(tp.params) && len <= n + 1
}
/**
@@ -738,7 +735,7 @@ trait Infer {
* tupled and n-ary methods, but thiws is something for a future major revision.
*/
def isUnitForVarArgs(args: List[AnyRef], params: List[Symbol]): Boolean =
- args.length == 0 && params.length == 2 && isVarArgs(params)
+ args.isEmpty && params.length == 2 && isVarArgsList(params)
/** Is there an instantiation of free type variables <code>undetparams</code>
* such that function type <code>ftpe</code> is applicable to
@@ -876,7 +873,7 @@ trait Infer {
isAsSpecific(ftpe1.resultType, ftpe2)
case MethodType(params @ (x :: xs), _) =>
var argtpes = params map (_.tpe)
- if (isVarArgs(params) && isVarArgs(ftpe2.params))
+ if (isVarArgsList(params) && isVarArgsList(ftpe2.params))
argtpes = argtpes map (argtpe =>
if (isRepeatedParamType(argtpe)) argtpe.typeArgs.head else argtpe)
isApplicable(List(), ftpe2, argtpes, WildcardType)
@@ -1585,7 +1582,7 @@ trait Infer {
//log("applicable: "+ (allApplicable map pre.memberType))
if (varArgsOnly)
- allApplicable = allApplicable filter (alt => isVarArgs(alt.tpe.params))
+ allApplicable = allApplicable filter (alt => isVarArgsList(alt.tpe.params))
// if there are multiple, drop those that use a default
// (keep those that use vararg / tupling conversion)
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 04c6dbe4a0..151a851f23 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -250,10 +250,10 @@ trait NamesDefaults { self: Analyzer =>
def argValDefs(args: List[Tree], paramTypes: List[Type], blockTyper: Typer): List[ValDef] = {
val context = blockTyper.context
val symPs = (args, paramTypes).zipped map ((arg, tpe) => {
- val byName = tpe.typeSymbol == ByNameParamClass
+ val byName = isByNameParamType(tpe)
val (argTpe, repeated) =
- if (tpe.typeSymbol == RepeatedParamClass) arg match {
- case Typed(expr, tpt @ Ident(name)) if name == nme.WILDCARD_STAR.toTypeName =>
+ if (isScalaRepeatedParamType(tpe)) arg match {
+ case Typed(expr, Ident(nme.WILDCARD_STAR)) =>
(expr.tpe, true)
case _ =>
(seqType(arg.tpe), true)
@@ -271,7 +271,7 @@ trait NamesDefaults { self: Analyzer =>
// () => { val x = 1; x }, the owner of symbol x must change (to the apply method of the function).
val body = if (byName) blockTyper.typed(Function(List(), resetLocalAttrs(arg)))
else if (repeated) arg match {
- case Typed(expr, tpt @ Ident(name)) if name == nme.WILDCARD_STAR.toTypeName =>
+ case Typed(expr, Ident(nme.WILDCARD_STAR)) =>
expr
case _ =>
val factory = Select(gen.mkAttributedRef(SeqModule), nme.apply)
@@ -314,8 +314,8 @@ trait NamesDefaults { self: Analyzer =>
val ref = gen.mkAttributedRef(vDef.symbol)
atPos(vDef.pos.focus) {
// for by-name parameters, the local value is a nullary function returning the argument
- if (tpe.typeSymbol == ByNameParamClass) Apply(ref, List())
- else if (tpe.typeSymbol == RepeatedParamClass) Typed(ref, Ident(nme.WILDCARD_STAR.toTypeName))
+ if (isByNameParamType(tpe)) Apply(ref, List())
+ else if (isScalaRepeatedParamType(tpe)) Typed(ref, Ident(nme.WILDCARD_STAR))
else ref
}
})
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 78341f6046..c49acf3f01 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -81,7 +81,7 @@ abstract class RefChecks extends InfoTransform {
val toScalaRepeatedParam = new TypeMap {
def apply(tp: Type): Type = tp match {
- case tp @ TypeRef(pre, JavaRepeatedParamClass, args) =>
+ case TypeRef(pre, JavaRepeatedParamClass, args) =>
typeRef(pre, RepeatedParamClass, args)
case _ =>
mapOver(tp)
@@ -122,20 +122,15 @@ abstract class RefChecks extends InfoTransform {
// Override checking ------------------------------------------------------------
def hasRepeatedParam(tp: Type): Boolean = tp match {
- case MethodType(formals, restpe) =>
- formals.nonEmpty && formals.last.tpe.typeSymbol == RepeatedParamClass ||
- hasRepeatedParam(restpe)
- case PolyType(_, restpe) =>
- hasRepeatedParam(restpe)
- case _ =>
- false
+ case MethodType(formals, restpe) => isScalaVarArgs(formals) || hasRepeatedParam(restpe)
+ case PolyType(_, restpe) => hasRepeatedParam(restpe)
+ case _ => false
}
/** Add bridges for vararg methods that extend Java vararg methods
*/
def addVarargBridges(clazz: Symbol): List[Tree] = {
val self = clazz.thisType
-
val bridges = new ListBuffer[Tree]
def varargBridge(member: Symbol, bridgetpe: Type): Tree = {
@@ -1343,14 +1338,14 @@ abstract class RefChecks extends InfoTransform {
enterReference(tree.pos, tpt.tpe.typeSymbol)
tree
- case Typed(expr, tpt @ Ident(name)) if name == nme.WILDCARD_STAR.toTypeName && !isRepeatedParamArg(tree) =>
+ case Typed(_, Ident(nme.WILDCARD_STAR)) if !isRepeatedParamArg(tree) =>
unit.error(tree.pos, "no `: _*' annotation allowed here\n"+
"(such annotations are only allowed in arguments to *-parameters)")
tree
case Ident(name) =>
transformCaseApply(tree,
- if (name != nme.WILDCARD && name != nme.WILDCARD_STAR.toTypeName) {
+ if (name != nme.WILDCARD && name != nme.WILDCARD_STAR) {
assert(sym != NoSymbol, tree) //debug
enterReference(tree.pos, sym)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 7f8359fb94..023d159d07 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -25,10 +25,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
// inherits abstract value `global' and class `Phase' from Transform
import global._
- import definitions.{
- IntClass, UnitClass, ByNameParamClass, Any_asInstanceOf,
- Any_isInstanceOf, Object_isInstanceOf, Object_##, Object_==, Object_!=
- }
+ import definitions.{ UnitClass, isRepeatedParamType, isByNameParamType, Any_asInstanceOf }
import analyzer.{ restrictionError }
/** the following two members override abstract members in Transform */
@@ -48,7 +45,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
private def transformArgs(args: List[Tree], params: List[Symbol]) =
((args, params).zipped map { (arg, param) =>
- if (param.tpe.typeSymbol == ByNameParamClass)
+ if (isByNameParamType(param.tpe))
withInvalidOwner { checkPackedConforms(transform(arg), param.tpe.typeArgs.head) }
else transform(arg)
}) :::
@@ -128,13 +125,10 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
// Disallow some super.XX calls targeting Any methods which would
// otherwise lead to either a compiler crash or runtime failure.
- private def isDisallowed(sym: Symbol) = (
- (sym == Any_isInstanceOf) ||
- (sym == Object_isInstanceOf) ||
- (sym == Object_==) ||
- (sym == Object_!=) ||
- (sym == Object_##)
- )
+ private lazy val isDisallowed = {
+ import definitions._
+ Set(Any_isInstanceOf, Object_isInstanceOf, Object_==, Object_!=, Object_##)
+ }
override def transform(tree: Tree): Tree = {
val sym = tree.symbol
@@ -355,7 +349,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
if (sym.isSubClass(ownerClass)) true else false
case _ => false
}
- if (definitions.isRepeatedParamType(v.info)) {
+ if (isRepeatedParamType(v.info)) {
res = gen.wildcardStar(res)
log("adapted to wildcard star: " + res)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index d5bb546b7f..76359ed46c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -41,6 +41,30 @@ trait TypeDiagnostics {
private def currentUnit = currentRun.currentUnit
+ /** For ease of debugging. The mode definitions are in Typers.scala.
+ */
+ private val modeNameMap = Map[Int, String](
+ (1 << 0) -> "EXPRmode",
+ (1 << 1) -> "PATTERNmode",
+ (1 << 2) -> "TYPEmode",
+ (1 << 3) -> "SCCmode",
+ (1 << 4) -> "FUNmode",
+ (1 << 5) -> "POLYmode",
+ (1 << 6) -> "QUALmode",
+ (1 << 7) -> "TAPPmode",
+ (1 << 8) -> "SUPERCONSTRmode",
+ (1 << 9) -> "SNDTRYmode",
+ (1 << 10) -> "LHSmode",
+ (1 << 11) -> "<DOES NOT EXIST mode>",
+ (1 << 12) -> "STARmode",
+ (1 << 13) -> "ALTmode",
+ (1 << 14) -> "HKmode",
+ (1 << 15) -> "BYVALmode",
+ (1 << 16) -> "TYPEPATmode"
+ )
+ def modeString(mode: Int): String =
+ (modeNameMap filterKeys (bit => (bit & mode) != 0)).values mkString " "
+
/** It can be quite difficult to know which of the many functions called "error"
* is being called at any given point in the compiler. To alleviate this I am
* renaming such functions inside this trait based on where it originated.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index ceae787b1d..4b64feb99f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -647,7 +647,7 @@ trait Typers { self: Analyzer =>
} else if ((mode & (EXPRmode | QUALmode)) == EXPRmode && !sym.isValue && !phase.erasedTypes) { // (2)
errorTree(tree, sym+" is not a value")
} else {
- if (sym.isStable && pre.isStable && tree.tpe.typeSymbol != ByNameParamClass &&
+ if (sym.isStable && pre.isStable && !isByNameParamType(tree.tpe) &&
(isStableContext(tree, mode, pt) || sym.isModule && !sym.isMethod))
tree.setType(singleType(pre, sym))
else tree
@@ -793,8 +793,8 @@ trait Typers { self: Analyzer =>
adapt(tree, mode, pt, original)
case PolyType(List(), restpe) => // (2)
adapt(tree setType restpe, mode, pt, original)
- case TypeRef(_, sym, List(arg))
- if ((mode & EXPRmode) != 0 && sym == ByNameParamClass) => // (2)
+ case TypeRef(_, ByNameParamClass, List(arg))
+ if ((mode & EXPRmode) != 0) => // (2)
adapt(tree setType arg, mode, pt, original)
case tr @ TypeRef(_, sym, _)
if sym.isAliasType && tr.normalize.isInstanceOf[ExistentialType] &&
@@ -2200,11 +2200,13 @@ trait Typers { self: Analyzer =>
args mapConserve (arg => typedArg(arg, mode, 0, WildcardType))
def typedArgs(args: List[Tree], mode: Int, originalFormals: List[Type], adaptedFormals: List[Type]) = {
- var newmodes = originalFormals map ((tp: Type) => if (tp.typeSymbol != ByNameParamClass) BYVALmode else 0)
- if (isVarArgTpes(originalFormals)) // TR check really necessary?
- newmodes = newmodes.take(newmodes.length-1) ::: List.fill(args.length - originalFormals.length + 1)(STARmode | BYVALmode)
- for (((arg, formal), m) <- ((args zip adaptedFormals) zip newmodes)) yield
+ var newmodes = originalFormals map (tp => if (isByNameParamType(tp)) 0 else BYVALmode)
+ if (isVarArgTypes(originalFormals)) // TR check really necessary?
+ newmodes = newmodes.init ::: List.fill(args.length - originalFormals.length + 1)(STARmode | BYVALmode)
+
+ (args, adaptedFormals, newmodes).zipped map { (arg, formal, m) =>
typedArg(arg, mode, m, formal)
+ }
}
/** Does function need to be instantiated, because a missing parameter
@@ -2238,14 +2240,14 @@ trait Typers { self: Analyzer =>
context.namedApplyBlockInfo exists (_._1 == tree)
def callToCompanionConstr(context: Context, calledFun: Symbol) = {
- if (calledFun.isConstructor) {
+ calledFun.isConstructor && {
val methCtx = context.enclMethod
- if (methCtx != NoContext) {
+ (methCtx != NoContext) && {
val contextFun = methCtx.tree.symbol
contextFun.isPrimaryConstructor && contextFun.owner.isModuleClass &&
companionModuleOf(calledFun.owner, context).moduleClass == contextFun.owner
- } else false
- } else false
+ }
+ }
}
def doTypedApply(tree: Tree, fun0: Tree, args: List[Tree], mode: Int, pt: Type): Tree = {
@@ -2303,8 +2305,7 @@ trait Typers { self: Analyzer =>
arg1
}
context.undetparams = undetparams
- inferMethodAlternative(fun, undetparams, argtpes.toList, pt,
- varArgsOnly = args.nonEmpty && treeInfo.isWildcardStarArg(args.last))
+ inferMethodAlternative(fun, undetparams, argtpes.toList, pt, varArgsOnly = treeInfo.isWildcardStarArgList(args))
doTypedApply(tree, adapt(fun, funMode(mode), WildcardType), args1, mode, pt)
case mt @ MethodType(params, _) =>
@@ -2477,7 +2478,7 @@ trait Typers { self: Analyzer =>
def typedArgToPoly(arg: Tree, formal: Type): Tree = { //TR TODO: cleanup
val lenientPt = formal.instantiateTypeParams(tparams, lenientTargs)
val newmode =
- if (remainingParams.head.typeSymbol == ByNameParamClass) POLYmode
+ if (isByNameParamType(remainingParams.head)) POLYmode
else POLYmode | BYVALmode
if (remainingParams.tail.nonEmpty) remainingParams = remainingParams.tail
// println("typedArgToPoly(arg, formal): "+(arg, formal))
@@ -3963,35 +3964,33 @@ trait Typers { self: Analyzer =>
case Typed(expr, Function(List(), EmptyTree)) =>
typedEta(checkDead(typed1(expr, mode, pt)))
- case Typed(expr, tpt) =>
- if (treeInfo.isWildcardStarArg(tree)) {
- val expr0 = typed(expr, mode & stickyModes, WildcardType)
- def subArrayType(pt: Type) =
- if (isValueClass(pt.typeSymbol) || !isFullyDefined(pt)) arrayType(pt)
- else {
- val tparam = context.owner freshExistential "" setInfo TypeBounds(NothingClass.tpe, pt)
- ExistentialType(List(tparam), arrayType(tparam.tpe))
- }
- val (expr1, baseClass) =
- if (expr0.tpe.typeSymbol == ArrayClass)
- (adapt(expr0, mode & stickyModes, subArrayType(pt)), ArrayClass)
- else
- (adapt(expr0, mode & stickyModes, seqType(pt)), SeqClass)
- expr1.tpe.baseType(baseClass) match {
- case TypeRef(_, _, List(elemtp)) =>
- treeCopy.Typed(tree, expr1, tpt setType elemtp) setType elemtp
- case _ =>
- setError(tree)
+ case Typed(expr, tpt @ Ident(nme.WILDCARD_STAR)) =>
+ val expr0 = typed(expr, mode & stickyModes, WildcardType)
+ def subArrayType(pt: Type) =
+ if (isValueClass(pt.typeSymbol) || !isFullyDefined(pt)) arrayType(pt)
+ else {
+ val tparam = context.owner freshExistential "" setInfo TypeBounds(NothingClass.tpe, pt)
+ ExistentialType(List(tparam), arrayType(tparam.tpe))
}
- } else {
- val tpt1 = typedType(tpt, mode)
- val expr1 = typed(expr, mode & stickyModes, tpt1.tpe.deconst)
- val owntype =
- if (isPatternMode) inferTypedPattern(tpt1.pos, tpt1.tpe, pt)
- else tpt1.tpe
- //Console.println(typed pattern: "+tree+":"+", tp = "+tpt1.tpe+", pt = "+pt+" ==> "+owntype)//DEBUG
- treeCopy.Typed(tree, expr1, tpt1) setType owntype
+ val (expr1, baseClass) = expr0.tpe.typeSymbol match {
+ case ArrayClass => (adapt(expr0, mode & stickyModes, subArrayType(pt)), ArrayClass)
+ case _ => (adapt(expr0, mode & stickyModes, seqType(pt)), SeqClass)
}
+ expr1.tpe.baseType(baseClass) match {
+ case TypeRef(_, _, List(elemtp)) =>
+ treeCopy.Typed(tree, expr1, tpt setType elemtp) setType elemtp
+ case _ =>
+ setError(tree)
+ }
+
+ case Typed(expr, tpt) =>
+ val tpt1 = typedType(tpt, mode)
+ val expr1 = typed(expr, mode & stickyModes, tpt1.tpe.deconst)
+ val owntype =
+ if (isPatternMode) inferTypedPattern(tpt1.pos, tpt1.tpe, pt)
+ else tpt1.tpe
+ //Console.println(typed pattern: "+tree+":"+", tp = "+tpt1.tpe+", pt = "+pt+" ==> "+owntype)//DEBUG
+ treeCopy.Typed(tree, expr1, tpt1) setType owntype
case TypeApply(fun, args) =>
// @M: kind-arity checking is done here and in adapt, full kind-checking is in checkKindBounds (in Infer)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 409cc30291..80b264821a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -19,10 +19,7 @@ trait Unapplies extends ast.TreeDSL
import global._
import definitions._
import CODE.{ CASE => _, _ }
-
- private def isVarargs(vd: ValDef) = treeInfo isRepeatedParamType vd.tpt
- private def isByName(vd: ValDef) = treeInfo isByNameParamType vd.tpt
- private def toIdent(x: DefTree) = Ident(x.name) setPos x.pos.focus
+ import treeInfo.{ isRepeatedParamType, isByNameParamType }
/** returns type list for return type of the extraction */
def unapplyTypeList(ufn: Symbol, ufntpe: Type) = {
@@ -66,10 +63,10 @@ trait Unapplies extends ast.TreeDSL
case OptionClass | SomeClass =>
val ts = unapplyTypeListFromReturnType(tp1)
val last1 = (ts.last baseType SeqClass) match {
- case TypeRef(pre, seqClass, args) => typeRef(pre, RepeatedParamClass, args) // XXX seqClass or SeqClass?
+ case TypeRef(pre, SeqClass, args) => typeRef(pre, RepeatedParamClass, args)
case _ => throw new TypeError("last not seq")
}
- ts.init ::: List(last1)
+ ts.init :+ last1
case _ =>
throw new TypeError("result type "+tp+" of unapply not in {Option[_], Some[_]}")
}
@@ -92,10 +89,9 @@ trait Unapplies extends ast.TreeDSL
case unapp => unapp
}
/** returns unapply member's parameter type. */
- def unapplyParameterType(extractor: Symbol) = {
- val ps = extractor.tpe.params
- if (ps.length == 1) ps.head.tpe.typeSymbol
- else NoSymbol
+ def unapplyParameterType(extractor: Symbol) = extractor.tpe.params match {
+ case p :: Nil => p.tpe.typeSymbol
+ case _ => NoSymbol
}
def copyUntyped[T <: Tree](tree: T): T =
@@ -107,6 +103,8 @@ trait Unapplies extends ast.TreeDSL
returning[TypeDef](copy.duplicate)(UnTyper traverse _)
}
+ private def toIdent(x: DefTree) = Ident(x.name) setPos x.pos.focus
+
private def classType(cdef: ClassDef, tparams: List[TypeDef]): Tree = {
val tycon = REF(cdef.symbol)
if (tparams.isEmpty) tycon else AppliedTypeTree(tycon, tparams map toIdent)
@@ -136,7 +134,7 @@ trait Unapplies extends ast.TreeDSL
// > MaxFunctionArity is caught in Namers, but for nice error reporting instead of
// an abrupt crash we trim the list here.
def primaries = constrParamss(cdef).head take MaxFunctionArity map (_.tpt)
- def inheritFromFun = !(cdef.mods hasFlag ABSTRACT) && cdef.tparams.isEmpty && constrParamss(cdef).length == 1
+ def inheritFromFun = !cdef.mods.hasAbstractFlag && cdef.tparams.isEmpty && constrParamss(cdef).length == 1
def createFun = gen.scalaFunctionConstr(primaries, toIdent(cdef), abstractFun = true)
def parents = if (inheritFromFun) List(createFun) else Nil
def toString = DefDef(
@@ -151,7 +149,7 @@ trait Unapplies extends ast.TreeDSL
}
def companionModuleDef(cdef: ClassDef, parents: List[Tree] = Nil, body: List[Tree] = Nil): ModuleDef = atPos(cdef.pos.focus) {
- val allParents = parents ::: List( gen.scalaScalaObjectConstr)
+ val allParents = parents :+ gen.scalaScalaObjectConstr
ModuleDef(
Modifiers(cdef.mods.flags & AccessFlags | SYNTHETIC, cdef.mods.privateWithin),
cdef.name.toTermName,
@@ -177,8 +175,8 @@ trait Unapplies extends ast.TreeDSL
val tparams = cdef.tparams map copyUntypedInvariant
val paramName = newTermName("x$0")
val method = constrParamss(cdef) match {
- case xs :: _ if !xs.isEmpty && isVarargs(xs.last) => nme.unapplySeq
- case _ => nme.unapply
+ case xs :: _ if xs.nonEmpty && isRepeatedParamType(xs.last.tpt) => nme.unapplySeq
+ case _ => nme.unapply
}
val cparams = List(ValDef(Modifiers(PARAM | SYNTHETIC), paramName, classType(cdef, tparams), EmptyTree))
val ifNull = if (constrParamss(cdef).head.size == 0) FALSE else REF(NoneModule)
@@ -190,11 +188,11 @@ trait Unapplies extends ast.TreeDSL
}
def caseClassCopyMeth(cdef: ClassDef): Option[DefDef] = {
- def isDisallowed(vd: ValDef) = isVarargs(vd) || isByName(vd)
+ def isDisallowed(vd: ValDef) = isRepeatedParamType(vd.tpt) || isByNameParamType(vd.tpt)
val cparamss = constrParamss(cdef)
val flat = cparamss flatten
- if (flat.isEmpty || (cdef.symbol hasFlag ABSTRACT) || (flat exists isDisallowed)) None
+ if (flat.isEmpty || cdef.symbol.hasAbstractFlag || (flat exists isDisallowed)) None
else {
val tparams = cdef.tparams map copyUntypedInvariant
// the parameter types have to be exactly the same as the constructor's parameter types; so it's