summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2010-01-06 16:46:48 +0000
committerMartin Odersky <odersky@gmail.com>2010-01-06 16:46:48 +0000
commit64b0678d3344380666d62c855cab2dad8a6ef08b (patch)
tree119bb1a3c7eb333f17442fcfc8ecd897e8665c83 /src
parente97ae22dd714d372e77608b01d980e66d5dbe081 (diff)
downloadscala-64b0678d3344380666d62c855cab2dad8a6ef08b.tar.gz
scala-64b0678d3344380666d62c855cab2dad8a6ef08b.tar.bz2
scala-64b0678d3344380666d62c855cab2dad8a6ef08b.zip
further speed improvements by eliminating most ...
further speed improvements by eliminating most uses of paramTypes. Knocks off about 3% of typer time. Not overwhelming but still worth doing. Review by rytz.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala112
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/LazyVals.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala16
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala39
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala22
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala31
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala4
11 files changed, 161 insertions, 92 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 0b0036fc54..be537010f6 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -795,8 +795,9 @@ trait Types {
var members: Scope = null
var member: Symbol = NoSymbol
var excluded = excludedFlags | DEFERRED
- var self: Type = null
var continue = true
+ lazy val self: Type = this.narrow
+ lazy val membertpe = self.memberType(member)
while (continue) {
continue = false
val bcs0 = baseClasses
@@ -820,24 +821,22 @@ trait Types {
} else if (member == NoSymbol) {
member = sym
} else if (members eq null) {
+// val start = startTimer(timer1)
if (member.name != sym.name ||
!(member == sym ||
member.owner != sym.owner &&
- !sym.hasFlag(PRIVATE) && {
- if (self eq null) self = this.narrow;
- (self.memberType(member) matches self.memberType(sym))
- })) {
+ !sym.hasFlag(PRIVATE) &&
+ (membertpe matches self.memberType(sym)))) {
members = new Scope(List(member, sym))
}
+// stopTimer(timer1, start)
} else {
var prevEntry = members.lookupEntry(sym.name)
while ((prevEntry ne null) &&
!(prevEntry.sym == sym ||
prevEntry.sym.owner != sym.owner &&
- !sym.hasFlag(PRIVATE) && {
- if (self eq null) self = this.narrow;
- (self.memberType(prevEntry.sym) matches self.memberType(sym))
- })) {
+ !sym.hasFlag(PRIVATE) &&
+ (self.memberType(prevEntry.sym) matches self.memberType(sym)))) {
prevEntry = members lookupNextEntry prevEntry
}
if (prevEntry eq null) {
@@ -1795,7 +1794,7 @@ A type's typeSymbol should never be inspected directly.
case class MethodType(override val params: List[Symbol],
override val resultType: Type) extends Type {
override val isTrivial: Boolean =
- paramTypes.forall(_.isTrivial) && resultType.isTrivial
+ params.forall(_.tpe.isTrivial) && resultType.isTrivial
//assert(paramTypes forall (pt => !pt.typeSymbol.isImplClass))//DEBUG
override def paramSectionCount: Int = resultType.paramSectionCount + 1
@@ -1909,6 +1908,10 @@ A type's typeSymbol should never be inspected directly.
override def boundSyms: List[Symbol] = quantified
override def prefix = maybeRewrap(underlying.prefix)
override def typeArgs = underlying.typeArgs map maybeRewrap
+ override def params = underlying.params mapConserve { param =>
+ val tpe1 = rewrap(param.tpe)
+ if (tpe1 eq param.tpe) param else param.cloneSymbol.setInfo(tpe1)
+ }
override def paramTypes = underlying.paramTypes map maybeRewrap
override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]) = {
// maybeRewrap(underlying.instantiateTypeParams(formals, actuals))
@@ -4151,7 +4154,7 @@ A type's typeSymbol should never be inspected directly.
tp1 match {
case MethodType(params1, res1) =>
(params1.length == params2.length &&
- matchingParams(tp1.paramTypes, tp2.paramTypes, tp1.isInstanceOf[JavaMethodType], tp2.isInstanceOf[JavaMethodType]) &&
+ matchingParams(params1, params2, tp1.isInstanceOf[JavaMethodType], tp2.isInstanceOf[JavaMethodType]) &&
(res1 <:< res2) &&
tp1.isInstanceOf[ImplicitMethodType] == tp2.isInstanceOf[ImplicitMethodType])
case _ =>
@@ -4244,13 +4247,71 @@ A type's typeSymbol should never be inspected directly.
}
/** A function implementing `tp1' matches `tp2' */
- def matchesType(tp1: Type, tp2: Type, alwaysMatchSimple: Boolean): Boolean = {
+ final def matchesType(tp1: Type, tp2: Type, alwaysMatchSimple: Boolean): Boolean = {
+ def matchesQuantified(tparams1: List[Symbol], tparams2: List[Symbol], res1: Type, res2: Type): Boolean =
+ tparams1.length == tparams2.length &&
+ matchesType(res1, res2.substSym(tparams2, tparams1), alwaysMatchSimple)
+ def lastTry =
+ tp2 match {
+ case ExistentialType(_, res2) if alwaysMatchSimple =>
+ matchesType(tp1, res2, true)
+ case MethodType(_, _) =>
+ false
+ case PolyType(tparams2, res2) =>
+ tparams2.isEmpty && matchesType(tp1, res2, alwaysMatchSimple)
+ case _ =>
+ alwaysMatchSimple || tp1 =:= tp2
+ }
+ tp1 match {
+ case MethodType(params1, res1) =>
+ tp2 match {
+ case MethodType(params2, res2) =>
+ params1.length == params2.length && // useful pre-secreening optimization
+ matchingParams(params1, params2, tp1.isInstanceOf[JavaMethodType], tp2.isInstanceOf[JavaMethodType]) &&
+ matchesType(res1, res2, alwaysMatchSimple) &&
+ tp1.isInstanceOf[ImplicitMethodType] == tp2.isInstanceOf[ImplicitMethodType]
+ case PolyType(List(), res2) =>
+ if (params1.isEmpty) matchesType(res1, res2, alwaysMatchSimple)
+ else matchesType(tp1, res2, alwaysMatchSimple)
+ case ExistentialType(_, res2) =>
+ alwaysMatchSimple && matchesType(tp1, res2, true)
+ case _ =>
+ false
+ }
+ case PolyType(tparams1, res1) =>
+ tp2 match {
+ case PolyType(tparams2, res2) =>
+ matchesQuantified(tparams1, tparams2, res1, res2)
+ case MethodType(List(), res2) if (tparams1.isEmpty) =>
+ matchesType(res1, res2, alwaysMatchSimple)
+ case ExistentialType(_, res2) =>
+ alwaysMatchSimple && matchesType(tp1, res2, true)
+ case _ =>
+ tparams1.isEmpty && matchesType(res1, tp2, alwaysMatchSimple)
+ }
+ case ExistentialType(tparams1, res1) =>
+ tp2 match {
+ case ExistentialType(tparams2, res2) =>
+ matchesQuantified(tparams1, tparams2, res1, res2)
+ case _ =>
+ if (alwaysMatchSimple) matchesType(res1, tp2, true)
+ else lastTry
+ }
+ case _ =>
+ lastTry
+ }
+ }
+
+/** matchesType above is an optimized version of the following implementation:
+
+ def matchesType2(tp1: Type, tp2: Type, alwaysMatchSimple: Boolean): Boolean = {
def matchesQuantified(tparams1: List[Symbol], tparams2: List[Symbol], res1: Type, res2: Type): Boolean =
tparams1.length == tparams2.length &&
matchesType(res1, res2.substSym(tparams2, tparams1), alwaysMatchSimple)
(tp1, tp2) match {
case (MethodType(params1, res1), MethodType(params2, res2)) =>
- matchingParams(tp1.paramTypes, tp2.paramTypes, tp1.isInstanceOf[JavaMethodType], tp2.isInstanceOf[JavaMethodType]) &&
+ params1.length == params2.length && // useful pre-secreening optimization
+ matchingParams(params1, params2, tp1.isInstanceOf[JavaMethodType], tp2.isInstanceOf[JavaMethodType]) &&
matchesType(res1, res2, alwaysMatchSimple) &&
tp1.isInstanceOf[ImplicitMethodType] == tp2.isInstanceOf[ImplicitMethodType]
case (PolyType(tparams1, res1), PolyType(tparams2, res2)) =>
@@ -4277,14 +4338,25 @@ A type's typeSymbol should never be inspected directly.
alwaysMatchSimple || tp1 =:= tp2
}
}
+*/
- /** Are `tps1' and `tps2' lists of pairwise equivalent types? */
- private def matchingParams(tps1: List[Type], tps2: List[Type], tps1isJava: Boolean, tps2isJava: Boolean): Boolean =
- (tps1.length == tps2.length) &&
- ((tps1, tps2).zipped forall ((tp1, tp2) =>
- (tp1 =:= tp2) ||
- tps1isJava && tp2.typeSymbol == ObjectClass && tp1.typeSymbol == AnyClass ||
- tps2isJava && tp1.typeSymbol == ObjectClass && tp2.typeSymbol == AnyClass))
+ /** Are `syms1' and `syms2' parameter lists with pairwise equivalent types? */
+ private def matchingParams(syms1: List[Symbol], syms2: List[Symbol], syms1isJava: Boolean, syms2isJava: Boolean): Boolean = syms1 match {
+ case Nil =>
+ syms2.isEmpty
+ case sym1 :: rest1 =>
+ syms2 match {
+ case Nil =>
+ false
+ case sym2 :: rest2 =>
+ val tp1 = sym1.tpe
+ val tp2 = sym2.tpe
+ (tp1 =:= tp2 ||
+ syms1isJava && tp2.typeSymbol == ObjectClass && tp1.typeSymbol == AnyClass ||
+ syms2isJava && tp1.typeSymbol == ObjectClass && tp2.typeSymbol == AnyClass) &&
+ matchingParams(rest1, rest2, syms1isJava, syms2isJava)
+ }
+ }
/** like map2, but returns list `xs' itself - instead of a copy - if function
* `f' maps all elements to themselves.
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 1fa81c8776..de9dadbd1f 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -497,7 +497,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
tree
else if (isValueClass(tree.tpe.typeSymbol) && !isValueClass(pt.typeSymbol))
adaptToType(box(tree), pt)
- else if (tree.tpe.isInstanceOf[MethodType] && tree.tpe.paramTypes.isEmpty) {
+ else if (tree.tpe.isInstanceOf[MethodType] && tree.tpe.params.isEmpty) {
if (!tree.symbol.isStable) assert(false, "adapt "+tree+":"+tree.tpe+" to "+pt)
adaptToType(Apply(tree, List()) setPos tree.pos setType tree.tpe.resultType, pt)
} else if (pt <:< tree.tpe)
@@ -597,7 +597,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
if (isValueClass(tree.symbol.owner) && !isValueClass(qual1.tpe.typeSymbol))
tree.symbol = NoSymbol
- else if (qual1.tpe.isInstanceOf[MethodType] && qual1.tpe.paramTypes.isEmpty) {
+ else if (qual1.tpe.isInstanceOf[MethodType] && qual1.tpe.params.isEmpty) {
assert(qual1.symbol.isStable, qual1.symbol);
qual1 = Apply(qual1, List()) setPos qual1.pos setType qual1.tpe.resultType
} else if (!(qual1.isInstanceOf[Super] || (qual1.tpe.typeSymbol isSubClass tree.symbol.owner))) {
diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
index b2f9489480..03339163a1 100644
--- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala
+++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
@@ -94,7 +94,9 @@ abstract class LazyVals extends Transform with ast.TreeDSL {
}
val bmps = bitmaps(methSym) map (ValDef(_, ZERO))
- def isMatch(params: List[Ident]) = (params.tail, methSym.tpe.paramTypes).zipped forall (_.tpe == _)
+
+ // Martin to Iulian: Don't we need to compare lengths here?
+ def isMatch(params: List[Ident]) = (params.tail, methSym.tpe.params).zipped forall (_.tpe == _.tpe)
if (bmps.isEmpty) rhs else rhs match {
case Block(assign, l @ LabelDef(name, params, rhs1))
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 8ea0b69049..fd5dd0f9a3 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -61,7 +61,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
tp match {
case MethodType(params, MethodType(params1, restpe)) =>
apply(MethodType(params ::: params1, restpe))
- case MethodType(formals, ExistentialType(tparams, restpe @ MethodType(_, _))) =>
+ case MethodType(params, ExistentialType(tparams, restpe @ MethodType(_, _))) =>
assert(false, "unexpected curried method types with intervening exitential")
tp0
case mt: ImplicitMethodType =>
@@ -189,8 +189,8 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
* additional parameter sections of a case class are skipped.
*/
def uncurryTreeType(tp: Type): Type = tp match {
- case MethodType(formals, MethodType(formals1, restpe)) if (inPattern) =>
- uncurryTreeType(MethodType(formals, restpe))
+ case MethodType(params, MethodType(params1, restpe)) if (inPattern) =>
+ uncurryTreeType(MethodType(params, restpe))
case _ =>
uncurry(tp)
}
@@ -451,13 +451,15 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
if (isJava &&
suffix.tpe.typeSymbol == ArrayClass &&
isValueClass(suffix.tpe.typeArgs.head.typeSymbol) &&
- fun.tpe.paramTypes.last.typeSymbol == ArrayClass &&
- fun.tpe.paramTypes.last.typeArgs.head.typeSymbol == ObjectClass)
+ { val lastFormal2 = fun.tpe.params.last.tpe
+ lastFormal2.typeSymbol == ArrayClass &&
+ lastFormal2.typeArgs.head.typeSymbol == ObjectClass
+ })
suffix = localTyper.typedPos(pos) {
gen.mkRuntimeCall("toObjectArray", List(suffix))
}
}
- args.take(formals.length - 1) ::: List(suffix setType formals.last)
+ args.take(formals.length - 1) ::: List(suffix setType lastFormal)
case _ =>
args
}
@@ -591,7 +593,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
transform(treeCopy.Apply(tree, fn, List(liftTree(args.head))))
} else {
withNeedLift(true) {
- val formals = fn.tpe.paramTypes;
+ val formals = fn.tpe.paramTypes
treeCopy.Apply(tree, transform(fn), transformTrees(transformArgs(tree.pos, fn.symbol, args, formals)))
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 27646363cb..9657cea101 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -642,6 +642,8 @@ self: Analyzer =>
* - the type itself
* - the parts of its immediate components (prefix and argument)
* - the parts of its base types
+ * - for alias types and abstract types, we take instead the parts
+ * - of their upper bounds.
* @return For those parts that refer to classes with companion objects that
* can be accessed with unambiguous stable prefixes, the implicits infos
* which are members of these companion objects.
@@ -675,7 +677,7 @@ self: Analyzer =>
args foreach getParts
}
} else if (sym.isAliasType) {
- getParts(tp.dealias)
+ getParts(tp.normalize)
} else if (sym.isAbstractType) {
getParts(tp.bounds.hi)
}
@@ -687,7 +689,9 @@ self: Analyzer =>
for (p <- ps) getParts(p)
case AnnotatedType(_, t, _) =>
getParts(t)
- case ExistentialType(tparams, t) =>
+ case ExistentialType(_, t) =>
+ getParts(t)
+ case PolyType(_, t) =>
getParts(t)
case _ =>
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index ad2c70c9ce..5c6788f0f6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -28,7 +28,8 @@ trait Infer {
private def assertNonCyclic(tvar: TypeVar) =
assert(tvar.constr.inst != tvar, tvar.origin)
- def isVarArgs(formals: List[Type]) = !formals.isEmpty && isRepeatedParamType(formals.last)
+ def isVarArgs(params: List[Symbol]) = !params.isEmpty && isRepeatedParamType(params.last.tpe)
+ def isVarArgTpes(formals: List[Type]) = !formals.isEmpty && isRepeatedParamType(formals.last)
def isWildcard(tp: Type) = tp match {
case WildcardType | BoundedWildcardType(_) => true
@@ -48,11 +49,11 @@ trait Infer {
/** This variant allows keeping ByName parameters. Useed in NamesDefaults. */
def formalTypes(formals: List[Type], nargs: Int, removeByName: Boolean): List[Type] = {
- val formals1 = if (removeByName) formals map {
+ val formals1 = if (removeByName) formals mapConserve {
case TypeRef(_, sym, List(arg)) if (sym == ByNameParamClass) => arg
case formal => formal
} else formals
- if (isVarArgs(formals1)) {
+ if (isVarArgTpes(formals1)) {
val ft = formals1.last.normalize.typeArgs.head
formals1.init ::: (for (i <- List.range(formals1.length - 1, nargs)) yield ft)
} else formals1
@@ -77,9 +78,11 @@ trait Infer {
//todo: remove comments around following privates; right now they cause an IllegalAccess
// error when built with scalac
- /*private*/ class NoInstance(msg: String) extends RuntimeException(msg) with ControlException
+ /*private*/
+ class NoInstance(msg: String) extends RuntimeException(msg) with ControlException
- /*private*/ class DeferredNoInstance(getmsg: () => String) extends NoInstance("") {
+ /*private*/
+ class DeferredNoInstance(getmsg: () => String) extends NoInstance("") {
override def getMessage(): String = getmsg()
}
@@ -494,7 +497,7 @@ trait Infer {
pt.typeSymbol == UnitClass || // can perform unit coercion
isCompatible(tp, pt) ||
tp.isInstanceOf[MethodType] && // can perform implicit () instantiation
- tp.paramTypes.length == 0 && isCompatible(tp.resultType, pt)
+ tp.params.isEmpty && isCompatible(tp.resultType, pt)
/** Like weakly compatible but don't apply any implicit conversions yet.
* Used when comparing the result type of a method with its prototype.
@@ -748,8 +751,10 @@ trait Infer {
case OverloadedType(pre, alts) =>
alts exists (alt => hasExactlyNumParams(pre.memberType(alt), n))
case _ =>
- formalTypes(tp.paramTypes, n).length == n
+ val len = tp.params.length
+ len == n || isVarArgs(tp.params) && len <= n + 1
}
+
/**
* Verifies whether the named application is valid. The logic is very
* similar to the one in NamesDefaults.removeNames.
@@ -815,13 +820,13 @@ trait Infer {
case ExistentialType(tparams, qtpe) =>
isApplicable(undetparams, qtpe, argtpes0, pt)
case MethodType(params, _) =>
- def paramType(param: Symbol) = param.tpe match {
- case TypeRef(_, sym, List(tpe)) if sym isNonBottomSubClass CodeClass =>
- tpe
- case tpe =>
- tpe
+ val formals0 = params map { param =>
+ param.tpe match {
+ case TypeRef(_, sym, List(tpe)) if sym isNonBottomSubClass CodeClass => tpe
+ case tpe => tpe
+ }
}
- val formals = formalTypes(params map paramType, argtpes0.length)
+ val formals = formalTypes(formals0, argtpes0.length)
def tryTupleApply: Boolean = {
// if 1 formal, 1 argtpe (a tuple), otherwise unmodified argtpes0
@@ -931,7 +936,7 @@ trait Infer {
isAsSpecific(ftpe1.resultType, ftpe2)
case MethodType(params @ (x :: xs), _) =>
var argtpes = params map (_.tpe)
- if (isVarArgs(argtpes) && isVarArgs(ftpe2.paramTypes))
+ if (isVarArgs(params) && isVarArgs(ftpe2.params))
argtpes = argtpes map (argtpe =>
if (isRepeatedParamType(argtpe)) argtpe.typeArgs.head else argtpe)
isApplicable(List(), ftpe2, argtpes, WildcardType)
@@ -1042,7 +1047,7 @@ trait Infer {
def isStrictlyBetter(tpe1: Type, tpe2: Type) = {
def isNullary(tpe: Type): Boolean = tpe match {
case tp: RewrappingTypeProxy => isNullary(tp.underlying)
- case _ => tpe.paramSectionCount == 0 || tpe.paramTypes.isEmpty
+ case _ => tpe.paramSectionCount == 0 || tpe.params.isEmpty
}
def isMethod(tpe: Type): Boolean = tpe match {
case tp: RewrappingTypeProxy => isMethod(tp.underlying)
@@ -1688,7 +1693,7 @@ trait Infer {
isApplicable(undetparams, followApply(pre.memberType(alt)), argtpes, pt))
if (varArgsOnly)
- allApplicable = allApplicable filter (alt => isVarArgs(alt.tpe.paramTypes))
+ allApplicable = allApplicable filter (alt => isVarArgs(alt.tpe.params))
// if there are multiple, drop those that use a default
// (keep those that use vararg / tupling conversion)
@@ -1701,7 +1706,7 @@ trait Infer {
alts map (_.tpe)
case t => List(t)
}
- mtypes.exists(t => t.paramTypes.length < argtpes.length || // tupling (*)
+ mtypes.exists(t => t.params.length < argtpes.length || // tupling (*)
hasExactlyNumParams(t, argtpes.length)) // same nb or vararg
// (*) more arguments than parameters, but still applicable: tuplig conversion works.
// todo: should not return "false" when paramTypes = (Unit) no argument is given
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 40eb72aaeb..1955348f91 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -874,14 +874,15 @@ trait Namers { self: Analyzer =>
}
for (vparams <- vparamss) {
- var pfs = resultPt.paramTypes
+ var pps = resultPt.params
for (vparam <- vparams) {
if (vparam.tpt.isEmpty) {
- vparam.tpt defineType pfs.head
+ val paramtpe = pps.head.tpe
+ vparam.symbol setInfo paramtpe
+ vparam.tpt defineType paramtpe
vparam.tpt setPos vparam.pos.focus
- vparam.symbol setInfo pfs.head
}
- pfs = pfs.tail
+ pps = pps.tail
}
resultPt = resultPt.resultType
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 835b6f2024..7b41c7b249 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -740,7 +740,7 @@ abstract class RefChecks extends InfoTransform {
sym = sym.info.bounds.hi.widen.typeSymbol
sym
}
- val formal = underlyingClass(fn.tpe.paramTypes.head)
+ val formal = underlyingClass(fn.tpe.params.head.tpe)
val actual = underlyingClass(args.head.tpe)
val receiver = underlyingClass(qual.tpe)
def nonSensibleWarning(what: String, alwaysEqual: Boolean) =
@@ -948,7 +948,7 @@ abstract class RefChecks extends InfoTransform {
private def isRepeatedParamArg(tree: Tree) = currentApplication match {
case Apply(fn, args) =>
!args.isEmpty && (args.last eq tree) &&
- fn.tpe.paramTypes.length == args.length && isRepeatedParamType(fn.tpe.paramTypes.last)
+ fn.tpe.params.length == args.length && isRepeatedParamType(fn.tpe.params.last.tpe)
case _ =>
false
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index d09cd85137..e59b469057 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -42,22 +42,14 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
case Some((_, buf)) => buf
case None => throw new AssertionError("no acc def buf for "+clazz)
}
-/*
- private def transformArgs(args: List[Tree], formals: List[Type]) = {
- if (!formals.isEmpty && formals.last.symbol == definitions.ByNameParamClass)
- ((args take (formals.length - 1) map transform) :::
- withInvalidOwner { args drop (formals.length - 1) map transform })
- else
- args map transform
- }
-*/
- private def transformArgs(args: List[Tree], formals: List[Type]) =
- ((args, formals).zipped map { (arg, formal) =>
- if (formal.typeSymbol == definitions.ByNameParamClass)
- withInvalidOwner { checkPackedConforms(transform(arg), formal.typeArgs.head) }
+
+ private def transformArgs(args: List[Tree], params: List[Symbol]) =
+ ((args, params).zipped map { (arg, param) =>
+ if (param.tpe.typeSymbol == definitions.ByNameParamClass)
+ withInvalidOwner { checkPackedConforms(transform(arg), param.tpe.typeArgs.head) }
else transform(arg)
}) :::
- (args drop formals.length map transform)
+ (args drop params.length map transform)
private def checkPackedConforms(tree: Tree, pt: Type): Tree = {
if (tree.tpe exists (_.typeSymbol.isExistentialSkolem)) {
@@ -223,7 +215,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
case Apply(fn, args) =>
assert(fn.tpe != null, tree)
- treeCopy.Apply(tree, transform(fn), transformArgs(args, fn.tpe.paramTypes))
+ treeCopy.Apply(tree, transform(fn), transformArgs(args, fn.tpe.params))
case Function(vparams, body) =>
withInvalidOwner {
treeCopy.Function(tree, vparams, transform(body))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 3611b32ba6..f29f6fa7a3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -685,7 +685,7 @@ trait Typers { self: Analyzer =>
case Select(qual, _) => qual.tpe
case _ => NoPrefix
}
- if (tree.tpe.isInstanceOf[MethodType] && pre.isStable && sym.tpe.paramTypes.isEmpty &&
+ if (tree.tpe.isInstanceOf[MethodType] && pre.isStable && sym.tpe.params.isEmpty &&
(isStableContext(tree, mode, pt) || sym.isModule))
tree.setType(MethodType(List(), singleType(pre, sym)))
else tree
@@ -820,7 +820,7 @@ trait Typers { self: Analyzer =>
if (!context.undetparams.isEmpty/* && (mode & POLYmode) == 0 disabled to make implicits in new collection work; we should revisit this. */) { // (9)
// println("adapt IMT: "+(context.undetparams, pt)) //@MDEBUG
context.undetparams = inferExprInstance(
- tree, context.extractUndetparams(), pt, mt.paramTypes exists isManifest)
+ tree, context.extractUndetparams(), pt, mt.params exists (p => isManifest(p.tpe)))
// if we are looking for a manifest, instantiate type to Nothing anyway,
// as we would get amnbiguity errors otherwise. Example
// Looking for a manifest of Nil: This mas many potential types,
@@ -1577,11 +1577,11 @@ trait Typers { self: Analyzer =>
def decompose(call: Tree): (Tree, List[Tree]) = call match {
case Apply(fn, args) =>
val (superConstr, args1) = decompose(fn)
- val formals = fn.tpe.paramTypes
- val args2 = if (formals.isEmpty || !isRepeatedParamType(formals.last)) args
- else args.take(formals.length - 1) ::: List(EmptyTree)
- if (args2.length != formals.length)
- assert(false, "mismatch " + clazz + " " + formals + " " + args2);//debug
+ val params = fn.tpe.params
+ val args2 = if (params.isEmpty || !isRepeatedParamType(params.last.tpe)) args
+ else args.take(params.length - 1) ::: List(EmptyTree)
+ if (args2.length != params.length)
+ assert(false, "mismatch " + clazz + " " + (params map (_.tpe)) + " " + args2);//debug
(superConstr, args1 ::: args2)
case Block(stats, expr) if !stats.isEmpty =>
decompose(stats.last)
@@ -1826,8 +1826,6 @@ trait Typers { self: Analyzer =>
transformedOrTyped(ddef.rhs, tpt1.tpe)
}
- checkMethodStructuralCompatible(meth)
-
if (meth.isPrimaryConstructor && meth.isClassConstructor &&
phase.id <= currentRun.typerPhase.id && !reporter.hasErrors)
computeParamAliases(meth.owner, vparamss1, rhs1)
@@ -2177,7 +2175,7 @@ trait Typers { self: Analyzer =>
def typedArgs(args: List[Tree], mode: Int, originalFormals: List[Type], adaptedFormals: List[Type]) = {
def newmode(i: Int) =
- if (isVarArgs(originalFormals) && i >= originalFormals.length - 1) STARmode else 0
+ if (isVarArgTpes(originalFormals) && i >= originalFormals.length - 1) STARmode else 0
for (((arg, formal), i) <- (args zip adaptedFormals).zipWithIndex) yield
typedArg(arg, mode, newmode(i), formal)
@@ -2213,14 +2211,6 @@ trait Typers { self: Analyzer =>
def isNamedApplyBlock(tree: Tree) =
context.namedApplyBlockInfo exists (_._1 == tree)
- /**
- * @param tree ...
- * @param fun0 ...
- * @param args ...
- * @param mode ...
- * @param pt ...
- * @return ...
- */
def doTypedApply(tree: Tree, fun0: Tree, args: List[Tree], mode: Int, pt: Type): Tree = {
var fun = fun0
if (fun.hasSymbol && (fun.symbol hasFlag OVERLOADED)) {
@@ -2281,8 +2271,9 @@ trait Typers { self: Analyzer =>
doTypedApply(tree, adapt(fun, funMode(mode), WildcardType), args1, mode, pt)
case mt @ MethodType(params, _) =>
+ val paramTypes = mt.paramTypes
// repeat vararg as often as needed, remove by-name
- val formals = formalTypes(mt.paramTypes, args.length)
+ val formals = formalTypes(paramTypes, args.length)
/** Try packing all arguments into a Tuple and apply `fun'
* to that. This is the last thing which is tried (after
@@ -2383,7 +2374,7 @@ trait Typers { self: Analyzer =>
} else {
val tparams = context.extractUndetparams()
if (tparams.isEmpty) { // all type params are defined
- val args1 = typedArgs(args, argMode(fun, mode), mt.paramTypes, formals)
+ val args1 = typedArgs(args, argMode(fun, mode), paramTypes, formals)
val restpe = mt.resultType(args1 map (_.tpe)) // instantiate dependent method types
def ifPatternSkipFormals(tp: Type) = tp match {
case MethodType(_, rtp) if ((mode & PATTERNmode) != 0) => rtp
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 812276612f..3898e46c0b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -94,8 +94,8 @@ trait Unapplies extends ast.TreeDSL
}
/** returns unapply member's parameter type. */
def unapplyParameterType(extractor: Symbol) = {
- val tps = extractor.tpe.paramTypes
- if (tps.length == 1) tps.head.typeSymbol
+ val ps = extractor.tpe.params
+ if (ps.length == 1) ps.head.tpe.typeSymbol
else NoSymbol
}