summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala126
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala33
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala133
-rw-r--r--src/compiler/scala/reflect/internal/transform/Erasure.scala5
-rw-r--r--src/compiler/scala/reflect/runtime/JavaToScala.scala4
-rw-r--r--src/compiler/scala/reflect/runtime/Loaders.scala9
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala11
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala36
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala41
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala123
18 files changed, 302 insertions, 269 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 89183b99c7..907e8e30ff 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -263,16 +263,19 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Create a new getter for current symbol (which must be a field)
*/
- final def newGetter: Symbol = {
- val getter = owner.newMethod(focusPos(pos), nme.getterName(name)).setFlag(getterFlags(flags))
- getter.privateWithin = privateWithin
- getter.setInfo(MethodType(List(), tpe))
- }
+ final def newGetter: Symbol = (
+ owner.newMethod(focusPos(pos), nme.getterName(name))
+ setFlag getterFlags(flags)
+ setPrivateWithin privateWithin
+ setInfo MethodType(Nil, tpe)
+ )
final def newErrorClass(name: TypeName) = {
- val clazz = newClass(pos, name).setFlag(SYNTHETIC | IS_ERROR)
- clazz.setInfo(ClassInfoType(List(), new ErrorScope(this), clazz))
- clazz
+ val clazz = newClass(pos, name)
+ ( clazz
+ setFlag (SYNTHETIC | IS_ERROR)
+ setInfo ClassInfoType(Nil, new ErrorScope(this), clazz)
+ )
}
final def newErrorSymbol(name: Name): Symbol = name match {
@@ -859,6 +862,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private[this] var _privateWithin: Symbol = _
def privateWithin = _privateWithin
def privateWithin_=(sym: Symbol) { _privateWithin = sym }
+ def setPrivateWithin(sym: Symbol): this.type = { privateWithin_=(sym) ; this }
/** Does symbol have a private or protected qualifier set? */
final def hasAccessBoundary = (privateWithin != null) && (privateWithin != NoSymbol)
@@ -930,9 +934,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
/** Set initial info. */
- def setInfo(info: Type): this.type = { info_=(info); this }
-
- def setInfoOwnerAdjusted(info: Type): this.type = setInfo(info.atOwner(this))
+ def setInfo(info: Type): this.type = { info_=(info); this }
+ /** Modifies this symbol's info in place. */
+ def modifyInfo(f: Type => Type): this.type = setInfo(f(info))
+ /** Substitute second list of symbols for first in current info. */
+ def substInfo(syms0: List[Symbol], syms1: List[Symbol]) = modifyInfo(_.substSym(syms0, syms1))
+ def setInfoOwnerAdjusted(info: Type): this.type = setInfo(info atOwner this)
/** Set new info valid from start of this phase. */
final def updateInfo(info: Type): Symbol = {
@@ -1123,7 +1130,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
val oldsyms = oldsymbuf.toList
val newsyms = newsymbuf.toList
for (sym <- newsyms) {
- addMember(thistp, tp, sym.setInfo(sym.info.substThis(this, thistp).substSym(oldsyms, newsyms)))
+ addMember(thistp, tp, sym modifyInfo (_ substThisAndSym(this, thistp, oldsyms, newsyms)))
}
tp
}
@@ -1134,11 +1141,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def existentialBound: Type =
if (this.isClass)
- polyType(this.typeParams, TypeBounds.upper(this.classBound))
+ polyType(this.typeParams, TypeBounds.upper(this.classBound))
else if (this.isAbstractType)
- this.info
+ this.info
else if (this.isTerm)
- TypeBounds.upper(intersectionType(List(this.tpe, SingletonClass.tpe)))
+ singletonBounds(this.tpe)
else
abort("unexpected alias type: "+this)
@@ -1286,9 +1293,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** A clone of this symbol, but with given owner. */
final def cloneSymbol(owner: Symbol): Symbol = {
val newSym = cloneSymbolImpl(owner)
- newSym.privateWithin = privateWithin
- newSym.setInfo(info.cloneInfo(newSym))
- .setFlag(this.rawflags).setAnnotations(this.annotations)
+ ( newSym
+ setPrivateWithin privateWithin
+ setInfo (info cloneInfo newSym)
+ setFlag this.rawflags
+ setAnnotations this.annotations
+ )
}
/** Internal method to clone a symbol's implementation without flags or type. */
@@ -2234,7 +2244,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
def cloneSymbolImpl(owner: Symbol): Symbol =
- new TypeSymbol(owner, pos, name) //.toTypeName)
+ new TypeSymbol(owner, pos, name)
incCounter(typeSymbolCount)
}
@@ -2442,16 +2452,80 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def originalEnclosingMethod = this
}
- private def cloneAndSubstInfos[T <: Symbol](syms: List[T])(f: T => Symbol): List[T] = {
- val syms1 = syms map (s => f(s).asInstanceOf[T])
- syms1 map (sym1 => sym1 setInfo sym1.info.substSym(syms, syms1))
+ /** Derives a new list of symbols from the given list by mapping the given
+ * list across the given function. Then fixes the info of all the new symbols
+ * by substituting the new symbols for the original symbols.
+ *
+ * @param syms the prototypical symbols
+ * @param symFn the function to create new symbols
+ * @return the new list of info-adjusted symbols
+ */
+ def deriveSymbols(syms: List[Symbol], symFn: Symbol => Symbol): List[Symbol] = {
+ val syms1 = syms map symFn
+ syms1 map (_ substInfo (syms, syms1))
+ }
+
+ /** Derives a new Type by first deriving new symbols as in deriveSymbols,
+ * then performing the same oldSyms => newSyms substitution on `tpe` as is
+ * performed on the symbol infos in deriveSymbols.
+ *
+ * @param syms the prototypical symbols
+ * @param symFn the function to create new symbols
+ * @param tpe the prototypical type
+ * @return the new symbol-subsituted type
+ */
+ def deriveType(syms: List[Symbol], symFn: Symbol => Symbol)(tpe: Type): Type = {
+ val syms1 = deriveSymbols(syms, symFn)
+ tpe.substSym(syms, syms1)
+ }
+ /** Derives a new Type by instantiating the given list of symbols as
+ * WildcardTypes.
+ *
+ * @param syms the symbols to replace
+ * @return the new type with WildcardType replacing those syms
+ */
+ def deriveTypeWithWildcards(syms: List[Symbol])(tpe: Type): Type = {
+ if (syms.isEmpty) tpe
+ else tpe.instantiateTypeParams(syms, syms map (_ => WildcardType))
}
+ /** Convenience functions which derive symbols by cloning.
+ */
+ def cloneSymbols(syms: List[Symbol]): List[Symbol] =
+ deriveSymbols(syms, _.cloneSymbol)
+ def cloneSymbolsAtOwner(syms: List[Symbol], owner: Symbol): List[Symbol] =
+ deriveSymbols(syms, _ cloneSymbol owner)
+
+ /** Clone symbols and apply the given function to each new symbol's info.
+ *
+ * @param syms the prototypical symbols
+ * @param infoFn the function to apply to the infos
+ * @return the newly created, info-adjusted symbols
+ */
+ def cloneSymbolsAndModify(syms: List[Symbol], infoFn: Type => Type): List[Symbol] =
+ cloneSymbols(syms) map (_ modifyInfo infoFn)
- def cloneSymbols[T <: Symbol](syms: List[T]): List[T] =
- cloneAndSubstInfos(syms)(_.cloneSymbol)
+ /** Functions which perform the standard clone/substituting on the given symbols and type,
+ * then call the creator function with the new symbols and type as arguments.
+ */
+ def createFromClonedSymbols[T](syms: List[Symbol], tpe: Type)(creator: (List[Symbol], Type) => T): T = {
+ val syms1 = cloneSymbols(syms)
+ creator(syms1, tpe.substSym(syms, syms1))
+ }
+ def createFromClonedSymbolsAtOwner[T](syms: List[Symbol], owner: Symbol, tpe: Type)(creator: (List[Symbol], Type) => T): T = {
+ val syms1 = cloneSymbolsAtOwner(syms, owner)
+ creator(syms1, tpe.substSym(syms, syms1))
+ }
- def cloneSymbols[T <: Symbol](syms: List[T], owner: Symbol): List[T] =
- cloneAndSubstInfos(syms)(_ cloneSymbol owner)
+ /** Create a new existential type skolem with the given owner and origin.
+ */
+ def newExistentialSkolem(sym: Symbol, owner: Symbol, origin: AnyRef): TypeSkolem = {
+ val skolem = new TypeSkolem(owner, sym.pos, sym.name.toTypeName, origin)
+ ( skolem
+ setInfo (sym.info cloneInfo skolem)
+ setFlag (sym.flags | EXISTENTIAL)
+ resetFlag PARAM
+ )
+ }
/** An exception for cyclic references of symbol definitions */
case class CyclicReference(sym: Symbol, info: Type)
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index 1ccd668fd6..ff1b759290 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -332,37 +332,26 @@ trait Trees extends api.Trees { self: SymbolTable =>
override def toString = substituterString("Symbol", "Tree", from, to)
}
- class TreeTypeSubstituter(val from: List[Symbol], val to: List[Type]) extends Traverser {
- val typeSubst = new SubstTypeMap(from, to)
- def isEmpty = from.isEmpty && to.isEmpty
-
+ class TypeMapTreeSubstituter(val typeMap: TypeMap) extends Traverser {
override def traverse(tree: Tree) {
- if (tree.tpe ne null) tree.tpe = typeSubst(tree.tpe)
- if (tree.isDef) {
- val sym = tree.symbol
- val info1 = typeSubst(sym.info)
- if (info1 ne sym.info) sym.setInfo(info1)
- }
+ if (tree.tpe ne null)
+ tree.tpe = typeMap(tree.tpe)
+ if (tree.isDef)
+ tree.symbol modifyInfo typeMap
+
super.traverse(tree)
}
override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate)
+ }
+
+ class TreeTypeSubstituter(val from: List[Symbol], val to: List[Type]) extends TypeMapTreeSubstituter(new SubstTypeMap(from, to)) {
+ def isEmpty = from.isEmpty && to.isEmpty
override def toString() = "TreeTypeSubstituter("+from+","+to+")"
}
lazy val EmptyTreeTypeSubstituter = new TreeTypeSubstituter(List(), List())
- class TreeSymSubstTraverser(val from: List[Symbol], val to: List[Symbol]) extends Traverser {
- val subst = new SubstSymMap(from, to)
- override def traverse(tree: Tree) {
- if (tree.tpe ne null) tree.tpe = subst(tree.tpe)
- if (tree.isDef) {
- val sym = tree.symbol
- val info1 = subst(sym.info)
- if (info1 ne sym.info) sym.setInfo(info1)
- }
- super.traverse(tree)
- }
- override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate)
+ class TreeSymSubstTraverser(val from: List[Symbol], val to: List[Symbol]) extends TypeMapTreeSubstituter(new SubstSymMap(from, to)) {
override def toString() = "TreeSymSubstTraverser/" + substituterString("Symbol", "Symbol", from, to)
}
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 7322eec1df..f8255bc846 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -577,11 +577,8 @@ trait Types extends api.Types { self: SymbolTable =>
val tp1 = existentialAbstraction(m.capturedParams, tp)
val result: Type =
if (m.capturedSkolems.isEmpty) tp1
- else {
- val captured = cloneSymbols(m.capturedSkolems)
- captured foreach (_ setFlag CAPTURED)
- tp1.substSym(m.capturedSkolems, captured)
- }
+ else deriveType(m.capturedSkolems, _.cloneSymbol setFlag CAPTURED)(tp1)
+
stopTimer(asSeenFromNanos, start)
result
}
@@ -639,9 +636,15 @@ trait Types extends api.Types { self: SymbolTable =>
*/
def substThis(from: Symbol, to: Type): Type =
new SubstThisMap(from, to) apply this
+ def substThis(from: Symbol, to: Symbol): Type =
+ substThis(from, to.thisType)
- def substSuper(from: Type, to: Type): Type =
- new SubstSuperMap(from, to) apply this
+ /** Performs both substThis and substSym in one traversal.
+ */
+ def substThisAndSym(from: Symbol, to: Type, symsFrom: List[Symbol], symsTo: List[Symbol]): Type = {
+ if (symsFrom eq symsTo) substThis(from, to)
+ else new SubstThisAndSymMap(from, to, symsFrom, symsTo) apply this
+ }
/** Returns all parts of this type which satisfy predicate `p` */
def filter(p: Type => Boolean): List[Type] = new FilterTypeCollector(p).collect(this).toList
@@ -1122,7 +1125,16 @@ trait Types extends api.Types { self: SymbolTable =>
// override def isNullable: Boolean = true
override def kind = "WildcardType"
}
-
+ /** BoundedWildcardTypes, used only during type inference, are created in
+ * two places that I can find:
+ *
+ * 1. If the expected type of an expression is an existential type,
+ * its hidden symbols are replaced with bounded wildcards.
+ * 2. When an implicit conversion is being sought based in part on
+ * the name of a method in the converted type, a HasMethodMatching
+ * type is created: a MethodType with parameters typed as
+ * BoundedWildcardTypes.
+ */
case class BoundedWildcardType(override val bounds: TypeBounds) extends Type {
override def isWildcard = true
override def safeToString: String = "?" + bounds
@@ -1730,7 +1742,6 @@ trait Types extends api.Types { self: SymbolTable =>
private var normalized: Type = null
-
override def isStable: Boolean = {
sym == NothingClass ||
sym == SingletonClass ||
@@ -1861,6 +1872,7 @@ A type's typeSymbol should never be inspected directly.
override def typeArgs: List[Type] = args
private def typeArgsOrDummies = if (!isHigherKinded) args else dummyArgs
// def hasFishyArgs = args == dummyArgs
+ private def argsMatchTypeParams = sameLength(sym.info.typeParams, args)
// @MAT was typeSymbol.unsafeTypeParams, but typeSymbol normalizes now
private def typeParamsDirect =
@@ -1888,7 +1900,7 @@ A type's typeSymbol should never be inspected directly.
// A reference (in a Scala program) to a type that has type
// parameters, but where the reference does not include type
// arguments. Note that it doesn't matter whether the symbol refers
- // to a java or scala symbol, it does matter whether it occurs in
+ // to a java or scala symbol, but it does matter whether it occurs in
// java or scala code. TypeRefs w/o type params that occur in java
// signatures/code are considered raw types, and are represented as
// existential types.
@@ -1896,32 +1908,27 @@ A type's typeSymbol should never be inspected directly.
override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]): Type =
if (isHigherKinded) {
- val substTps = formals.intersect(typeParams)
-
- if (sameLength(substTps, typeParams))
+ if (sameLength(formals intersect typeParams, typeParams))
copyTypeRef(this, pre, sym, actuals)
- else if (sameLength(formals, actuals)) // partial application (needed in infer when bunching type arguments from classes and methods together)
- copyTypeRef(this, pre, sym, dummyArgs).subst(formals, actuals)
- else ErrorType
+ // partial application (needed in infer when bunching type arguments from classes and methods together)
+ else
+ copyTypeRef(this, pre, sym, dummyArgs).instantiateTypeParams(formals, actuals)
}
else
super.instantiateTypeParams(formals, actuals)
-
- /** @pre: sym.info.typeParams.length == typeArgs.length */
+ /** @pre: argsMatchTypeParams */
@inline private def betaReduce: Type = {
- if (settings.debug.value)
- assert(sym.info.typeParams.length == typeArgs.length, sym.info.typeParams + " and " + typeArgs)
// isHKSubType0 introduces synthetic type params so that
// betaReduce can first apply sym.info to typeArgs before calling
// asSeenFrom. asSeenFrom then skips synthetic type params, which
// are used to reduce HO subtyping to first-order subtyping, but
// which can't be instantiated from the given prefix and class.
transform(sym.info.resultType)
- //
// this crashes pos/depmet_implicit_tpbetareduce.scala
// appliedType(sym.info, typeArgs).asSeenFrom(pre, sym.owner)
}
+ private def isBetaReducible = sym.isAliasType && argsMatchTypeParams
// @M: initialize (by sym.info call) needed (see test/files/pos/ticket0137.scala)
@inline private def etaExpand: Type = {
@@ -1930,22 +1937,16 @@ A type's typeSymbol should never be inspected directly.
else typeFunAnon(tpars, copyTypeRef(this, pre, sym, tpars map (_.tpeHK))) // todo: also beta-reduce?
}
- override def dealias: Type =
- if (sym.isAliasType && sameLength(sym.info.typeParams, args)) {
- betaReduce.dealias
- } else this
+ override def dealias = if (isBetaReducible) betaReduce.dealias else this
- private def normalize0: Type =
+ private def normalize0: Type = (
if (pre eq WildcardType) WildcardType // arises when argument-dependent types are approximated (see def depoly in implicits)
else if (isHigherKinded) etaExpand // eta-expand, subtyping relies on eta-expansion of higher-kinded types
- else if (sym.isAliasType && sameLength(sym.info.typeParams, args))
- betaReduce.normalize // beta-reduce, but don't do partial application -- cycles have been checked in typeRef
- else if (sym.isRefinementClass)
- sym.info.normalize // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers
- else {
- if(sym.isAliasType) ErrorType //println("!!error: "+(pre, sym, sym.info, sym.info.typeParams, args))
- else super.normalize
- }
+ else if (isBetaReducible) betaReduce.normalize // beta-reduce, but don't do partial application -- cycles have been checked in typeRef
+ else if (sym.isRefinementClass) sym.info.normalize // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers
+ else if (sym.isAliasType) ErrorType //println("!!error: "+(pre, sym, sym.info, sym.info.typeParams, args))
+ else super.normalize
+ )
// TODO: test case that is compiled in a specific order and in different runs
override def normalize: Type = {
@@ -2128,7 +2129,7 @@ A type's typeSymbol should never be inspected directly.
override def safeToString = paramString(this) + resultType
override def cloneInfo(owner: Symbol) = {
- val vparams = cloneSymbols(params, owner)
+ val vparams = cloneSymbolsAtOwner(params, owner)
copyMethodType(this, vparams, resultType.substSym(params, vparams).cloneInfo(owner))
}
@@ -2208,7 +2209,7 @@ A type's typeSymbol should never be inspected directly.
override def safeToString = typeParamsString(this) + resultType
override def cloneInfo(owner: Symbol) = {
- val tparams = cloneSymbols(typeParams, owner)
+ val tparams = cloneSymbolsAtOwner(typeParams, owner)
PolyType(tparams, resultType.substSym(typeParams, tparams).cloneInfo(owner))
}
@@ -2253,20 +2254,8 @@ A type's typeSymbol should never be inspected directly.
override def baseTypeSeq = underlying.baseTypeSeq map maybeRewrap
override def isHigherKinded = false
- override def skolemizeExistential(owner: Symbol, origin: AnyRef) = {
- def mkSkolem(tparam: Symbol): Symbol = {
- val skolem = new TypeSkolem(
- if (owner == NoSymbol) tparam.owner else owner,
- tparam.pos, tparam.name.toTypeName, origin)
- skolem.setInfo(tparam.info.cloneInfo(skolem))
- .setFlag(tparam.flags | EXISTENTIAL)
- .resetFlag(PARAM)
- }
- val skolems = quantified map mkSkolem
- for (skolem <- skolems)
- skolem setInfo skolem.info.substSym(quantified, skolems)
- underlying.substSym(quantified, skolems)
- }
+ override def skolemizeExistential(owner: Symbol, origin: AnyRef) =
+ deriveType(quantified, tparam => newExistentialSkolem(tparam, owner orElse tparam.owner, origin))(underlying)
private def wildcardArgsString(available: Set[Symbol], args: List[Type]): List[String] = args match {
case TypeRef(_, sym, _) :: args1 if (available contains sym) =>
@@ -2297,10 +2286,8 @@ A type's typeSymbol should never be inspected directly.
if (settings.explaintypes.value) "("+str+")" else str
}
- override def cloneInfo(owner: Symbol) = {
- val tparams = cloneSymbols(quantified, owner)
- ExistentialType(tparams, underlying.substSym(quantified, tparams))
- }
+ override def cloneInfo(owner: Symbol) =
+ createFromClonedSymbolsAtOwner(quantified, owner, underlying)(ExistentialType(_, _))
override def atOwner(owner: Symbol) =
if (quantified exists (_.owner != owner)) cloneInfo(owner) else this
@@ -2369,6 +2356,16 @@ A type's typeSymbol should never be inspected directly.
}
}
+ // Not used yet.
+ object HasTypeParams {
+ def unapply(tp: Type): Option[(List[Symbol], Type)] = tp match {
+ case AnnotatedType(_, tp, _) => unapply(tp)
+ case ExistentialType(tparams, qtpe) => Some((tparams, qtpe))
+ case PolyType(tparams, restpe) => Some((tparams, restpe))
+ case _ => None
+ }
+ }
+
//@M
// a TypeVar used to be a case class with only an origin and a constr
// then, constr became mutable (to support UndoLog, I guess),
@@ -2879,7 +2876,8 @@ A type's typeSymbol should never be inspected directly.
val syms2 = result.decls.toList
val resultThis = result.typeSymbol.thisType
for (sym <- syms2)
- sym.setInfo(sym.info.substThis(original.typeSymbol, resultThis).substSym(syms1, syms2))
+ sym modifyInfo (_ substThisAndSym(original.typeSymbol, resultThis, syms1, syms2))
+
result
}
@@ -3469,7 +3467,7 @@ A type's typeSymbol should never be inspected directly.
result ne sym.info
}
// map is not the identity --> do cloning properly
- if (change) cloneSymbols(origSyms) map (s => s setInfo this(s.info))
+ if (change) cloneSymbolsAndModify(origSyms, TypeMap.this)
// fast path in case nothing changes due to map
else origSyms
}
@@ -3545,8 +3543,7 @@ A type's typeSymbol should never be inspected directly.
val eparams = for ((tparam, i) <- tparams.zipWithIndex) yield {
clazz.newExistential(clazz.pos, newTypeName("?"+i)).setInfo(tparam.info.bounds)
}
- for (tparam <- eparams) tparam setInfo tparam.info.substSym(tparams, eparams)
- eparams
+ eparams map (_ substInfo (tparams, eparams))
}
// note: it's important to write the two tests in this order,
@@ -3769,14 +3766,11 @@ A type's typeSymbol should never be inspected directly.
protected def renameBoundSyms(tp: Type): Type = tp match {
case MethodType(ps, restp) =>
- val ps1 = cloneSymbols(ps)
- copyMethodType(tp, ps1, renameBoundSyms(restp.substSym(ps, ps1)))
+ createFromClonedSymbols(ps, restp)((ps1, tp1) => copyMethodType(tp, ps1, renameBoundSyms(tp1)))
case PolyType(bs, restp) =>
- val bs1 = cloneSymbols(bs)
- PolyType(bs1, renameBoundSyms(restp.substSym(bs, bs1)))
+ createFromClonedSymbols(bs, restp)((ps1, tp1) => PolyType(ps1, renameBoundSyms(tp1)))
case ExistentialType(bs, restp) =>
- val bs1 = cloneSymbols(bs)
- ExistentialType(bs1, restp.substSym(bs, bs1))
+ createFromClonedSymbols(bs, restp)(ExistentialType(_, _))
case _ =>
tp
}
@@ -3899,9 +3893,12 @@ A type's typeSymbol should never be inspected directly.
case _ => mapOver(tp)
}
}
-
- class SubstSuperMap(from: Type, to: Type) extends TypeMap {
- def apply(tp: Type): Type = if (tp eq from) to else mapOver(tp)
+ class SubstThisAndSymMap(fromThis: Symbol, toThis: Type, fromSyms: List[Symbol], toSyms: List[Symbol])
+ extends SubstSymMap(fromSyms, toSyms) {
+ override def apply(tp: Type): Type = tp match {
+ case ThisType(sym) if sym == fromThis => apply(toThis)
+ case _ => super.apply(tp)
+ }
}
class SubstWildcardMap(from: List[Symbol]) extends TypeMap {
@@ -4594,7 +4591,7 @@ A type's typeSymbol should never be inspected directly.
sym2 =>
var e1 = s1.lookupEntry(sym2.name)
(e1 ne null) && {
- val substSym = sym2.info.substThis(sym2.owner, e1.sym.owner.thisType)
+ val substSym = sym2.info.substThis(sym2.owner, e1.sym.owner)
var isEqual = false
while (!isEqual && (e1 ne null)) {
isEqual = e1.sym.info =:= substSym
diff --git a/src/compiler/scala/reflect/internal/transform/Erasure.scala b/src/compiler/scala/reflect/internal/transform/Erasure.scala
index cac60deaf7..9648befb49 100644
--- a/src/compiler/scala/reflect/internal/transform/Erasure.scala
+++ b/src/compiler/scala/reflect/internal/transform/Erasure.scala
@@ -88,9 +88,8 @@ trait Erasure {
apply(restpe)
case mt @ MethodType(params, restpe) =>
MethodType(
- cloneSymbols(params) map (p => p.setInfo(apply(p.tpe))),
+ cloneSymbolsAndModify(params, ErasureMap.this),
if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass)
- // else if (!settings.YdepMethTpes.value) apply(restpe)
// this replaces each typeref that refers to an argument
// by the type `p.tpe` of the actual argument p (p in params)
else apply(mt.resultType(params map (_.tpe))))
@@ -247,7 +246,7 @@ trait Erasure {
if (sym.isClassConstructor)
tp match {
case MethodType(params, TypeRef(pre, sym1, args)) =>
- MethodType(cloneSymbols(params) map (p => p.setInfo(erasure(sym, p.tpe))),
+ MethodType(cloneSymbolsAndModify(params, erasure(sym, _)),
typeRef(erasure(sym, pre), sym1, args))
}
else if (sym.name == nme.apply)
diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala
index b1e4a2a3e0..5297ea6db4 100644
--- a/src/compiler/scala/reflect/runtime/JavaToScala.scala
+++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala
@@ -64,7 +64,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
* ScalaSignature or ScalaLongSignature annotation.
*/
def unpickleClass(clazz: Symbol, module: Symbol, jclazz: jClass[_]): Unit = {
- def markAbsent(tpe: Type) = List(clazz, module, module.moduleClass) foreach (_ setInfo tpe)
+ def markAbsent(tpe: Type) = setAllInfos(clazz, module, tpe)
def handleError(ex: Exception) = {
markAbsent(ErrorType)
if (settings.debug.value) ex.printStackTrace()
@@ -126,7 +126,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
private class TypeParamCompleter(jtvar: jTypeVariable[_ <: GenericDeclaration]) extends LazyType {
override def load(sym: Symbol) = complete(sym)
override def complete(sym: Symbol) = {
- sym setInfo TypeBounds(NothingClass.tpe, glb(jtvar.getBounds.toList map typeToScala map objToAny))
+ sym setInfo TypeBounds.upper(glb(jtvar.getBounds.toList map typeToScala map objToAny))
}
}
diff --git a/src/compiler/scala/reflect/runtime/Loaders.scala b/src/compiler/scala/reflect/runtime/Loaders.scala
index eaf3c82d5a..35b3a16dc2 100644
--- a/src/compiler/scala/reflect/runtime/Loaders.scala
+++ b/src/compiler/scala/reflect/runtime/Loaders.scala
@@ -71,12 +71,13 @@ trait Loaders { self: SymbolTable =>
(clazz, module)
}
- protected def initClassModule(clazz: Symbol, module: Symbol, completer: LazyType) = {
- clazz.setInfo(completer)
- module.setInfo(completer)
- module.moduleClass.setInfo(completer)
+ protected def setAllInfos(clazz: Symbol, module: Symbol, info: Type) = {
+ List(clazz, module, module.moduleClass) foreach (_ setInfo info)
}
+ protected def initClassModule(clazz: Symbol, module: Symbol, completer: LazyType) =
+ setAllInfos(clazz, module, completer)
+
/** The type completer for packages.
*/
class LazyPackageType extends LazyType {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 01b1882481..7dc9b25015 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -1230,9 +1230,7 @@ abstract class ClassfileParser {
class LazyAliasType(alias: Symbol) extends LazyType {
override def complete(sym: Symbol) {
- alias.initialize
- val tparams1 = cloneSymbols(alias.typeParams)
- sym.setInfo(typeFun(tparams1, alias.tpe.substSym(alias.typeParams, tparams1)))
+ sym setInfo createFromClonedSymbols(alias.initialize.typeParams, alias.tpe)(typeFun)
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index f364c75a21..00b72bdc1c 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -400,11 +400,12 @@ abstract class Constructors extends Transform with ast.TreeDSL {
/** Create a getter or a setter and enter into `clazz` scope
*/
def addAccessor(sym: Symbol, name: TermName, flags: Long) = {
- val m = clazz.newMethod(sym.pos, name)
- .setFlag(flags & ~LOCAL & ~PRIVATE)
- m.privateWithin = clazz
- clazz.info.decls.enter(m)
- m
+ val m = (
+ clazz.newMethod(sym.pos, name)
+ setFlag (flags & ~LOCAL & ~PRIVATE)
+ setPrivateWithin clazz
+ )
+ clazz.info.decls enter m
}
def addGetter(sym: Symbol): Symbol = {
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index ad4b1f2429..443a6140dc 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -112,7 +112,7 @@ abstract class LambdaLift extends InfoTransform {
// would have the signature
// closure: (x$1: Int)() => Int
if (sym.isParameter && sym.owner.info.paramss.exists(_ contains sym))
- sym.owner.setInfo(sym.owner.info.cloneInfo(sym.owner))
+ sym.owner modifyInfo (_ cloneInfo sym.owner)
}
changedFreeVars = true
debuglog("" + sym + " is free in " + enclosure);
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 0b58e407a6..97f204bc41 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -447,10 +447,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// log("producing type params: " + cloned.map(t => (t, t.tpe.bounds.hi)))
for ((orig, cln) <- syms zip cloned) {
cln.removeAnnotation(SpecializedClass)
- if (env.contains(orig)) cln.setInfo(TypeBounds(cln.info.bounds.lo, AnyRefClass.tpe))
+ if (env.contains(orig))
+ cln modifyInfo (info => TypeBounds(info.bounds.lo, AnyRefClass.tpe))
}
- for (sym <- cloned) sym.setInfo(sym.info.substSym(syms, cloned))
- cloned
+ cloned map (_ substInfo (syms, cloned))
}
/** Maps AnyRef bindings from a raw environment (holding AnyRefs) into type parameters from
@@ -510,7 +510,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// log("new tparams " + newClassTParams.zip(newClassTParams map {s => (s.tpe, s.tpe.bounds.hi)}) + ", in env: " + env)
def applyContext(tpe: Type) =
- subst(env, tpe).subst(survivedParams, newClassTParams map (_.tpe))
+ subst(env, tpe).instantiateTypeParams(survivedParams, newClassTParams map (_.tpe))
/** Return a list of specialized parents to be re-mixed in a specialized subclass.
* Assuming env = [T -> Int] and
@@ -567,8 +567,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
def enterMember(sym: Symbol): Symbol = {
typeEnv(sym) = fullEnv ++ typeEnv(sym) // append the full environment
- sym.setInfo(sym.info.substThis(clazz, ThisType(cls)).subst(oldClassTParams, newClassTParams map (_.tpe)))
-
+ sym modifyInfo (_.substThis(clazz, cls).instantiateTypeParams(oldClassTParams, newClassTParams map (_.tpe)))
// we remove any default parameters. At this point, they have been all
// resolved by the type checker. Later on, erasure re-typechecks everything and
// chokes if it finds default parameters for specialized members, even though
@@ -669,7 +668,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
setFlag (OVERRIDE | SPECIALIZED)
resetFlag (DEFERRED | CASEACCESSOR | PARAMACCESSOR | LAZY)
)
- sym1 setInfo sym1.info.asSeenFrom(clazz.tpe, sym1.owner)
+ sym1 modifyInfo (_ asSeenFrom (clazz.tpe, sym1.owner))
}
val specVal = specializedOverload(cls, m, env)
@@ -794,10 +793,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
typeEnv(specMember) = outerEnv ++ env
val tps1 = produceTypeParameters(tps, specMember, env)
- tps1 foreach (tp => tp.setInfo(tp.info.subst(keys, vals)))
+ tps1 foreach (_ modifyInfo (_.instantiateTypeParams(keys, vals)))
// the cloneInfo is necessary so that method parameter symbols are cloned at the new owner
- val methodType = sym.info.resultType.subst(keys ++ tps, vals ++ tps1.map(_.tpe)).cloneInfo(specMember)
+ val methodType = sym.info.resultType.instantiateTypeParams(keys ++ tps, vals ++ tps1.map(_.tpe)).cloneInfo(specMember)
specMember setInfo polyType(tps1, methodType)
debuglog("expanded member: " + sym + ": " + sym.info +
@@ -863,9 +862,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
specMember.name = specializedName(sym, env)
(specMember
- setInfo subst(env, specMember.info.asSeenFrom(owner.thisType, sym.owner))
- setFlag (SPECIALIZED)
- resetFlag (DEFERRED | CASEACCESSOR | ACCESSOR | LAZY)
+ modifyInfo (info => subst(env, info.asSeenFrom(owner.thisType, sym.owner)))
+ setFlag (SPECIALIZED)
+ resetFlag (DEFERRED | CASEACCESSOR | ACCESSOR | LAZY)
)
}
@@ -1056,12 +1055,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
(new FullTypeMap(keys, values))(tpe)
}
- private def subst(env: TypeEnv)(decl: Symbol): Symbol = {
- decl setInfo (subst(env, decl.info) match {
- case MethodType(args, _) if decl.isConstructor => MethodType(args, decl.owner.tpe)
- case tpe => tpe
- })
- }
+ private def subst(env: TypeEnv)(decl: Symbol): Symbol =
+ decl modifyInfo (info =>
+ if (decl.isConstructor) MethodType(subst(env, info).params, decl.owner.tpe)
+ else subst(env, info)
+ )
/** Checks if the type parameter symbol is not specialized
* and is used as type parameters when extending a class with a specialized
@@ -1578,7 +1576,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// create fresh symbols for value parameters to hold the skolem types
val vparamss1 = List(for (vdef <- vparamss.head; param = vdef.symbol) yield {
- ValDef(param.cloneSymbol(symbol).setInfo(param.info.substSym(oldtparams, newtparams)))
+ ValDef(param cloneSymbol symbol substInfo (oldtparams, newtparams))
})
// replace value and type parameters of the old method with the new ones
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index 5013e8f21d..ca16e491e2 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -133,7 +133,7 @@ abstract class TailCalls extends Transform {
label setInfo MethodType(thisParam :: method.tpe.params, method.tpe.finalResultType)
}
if (isEligible)
- label setInfo label.tpe.substSym(method.tpe.typeParams, tparams)
+ label substInfo (method.tpe.typeParams, tparams)
}
def enclosingType = method.enclClass.typeOfThis
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 45834055a9..c5237b4d59 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -80,6 +80,12 @@ abstract class UnCurry extends InfoTransform
private val newMembers = mutable.ArrayBuffer[Tree]()
private val repeatedParams = mutable.Map[Symbol, List[ValDef]]()
+ @inline private def withInPattern[T](value: Boolean)(body: => T): T = {
+ inPattern = value
+ try body
+ finally inPattern = !value
+ }
+
private lazy val serialVersionUIDAnnotation =
AnnotationInfo(SerialVersionUIDAttr.tpe, List(Literal(Constant(0))), List())
@@ -513,9 +519,7 @@ abstract class UnCurry extends InfoTransform
}
*/
case UnApply(fn, args) =>
- inPattern = false
- val fn1 = transform(fn)
- inPattern = true
+ val fn1 = withInPattern(false)(transform(fn))
val args1 = transformTrees(fn.symbol.name match {
case nme.unapply => args
case nme.unapplySeq => transformArgs(tree.pos, fn.symbol, args, analyzer.unapplyTypeListFromReturnTypeSeq(fn.tpe))
@@ -543,9 +547,7 @@ abstract class UnCurry extends InfoTransform
else super.transform(tree)
case CaseDef(pat, guard, body) =>
- inPattern = true
- val pat1 = transform(pat)
- inPattern = false
+ val pat1 = withInPattern(true)(transform(pat))
treeCopy.CaseDef(tree, pat1, transform(guard), transform(body))
case fun @ Function(_, _) =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 2c32d22081..b67198a292 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -297,8 +297,7 @@ trait Implicits {
case _ => tp
}
def stripped(tp: Type): Type = {
- val tparams = freeTypeParametersNoSkolems.collect(tp)
- tp.subst(tparams, tparams map (t => WildcardType))
+ deriveTypeWithWildcards(freeTypeParametersNoSkolems.collect(tp))(tp)
}
def sum(xs: List[Int]) = (0 /: xs)(_ + _)
def complexity(tp: Type): Int = tp.normalize match {
@@ -371,11 +370,7 @@ trait Implicits {
/** The type parameters to instantiate */
val undetParams = if (isView) List() else context.outer.undetparams
-
- def approximate(tp: Type) =
- if (undetParams.isEmpty) tp
- else tp.instantiateTypeParams(undetParams, undetParams map (_ => WildcardType))
-
+ def approximate(tp: Type) = deriveTypeWithWildcards(undetParams)(tp)
val wildPt = approximate(pt)
/** Try to construct a typed tree from given implicit info with given
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index cb548ffdab..68c84b8e15 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -304,25 +304,29 @@ trait Infer {
)
}
else {
- if(sym1.isTerm)
+ if (sym1.isTerm)
sym1.cookJavaRawInfo() // xform java rawtypes into existentials
- var owntype = try{
- pre.memberType(sym1)
- } catch {
- case ex: MalformedType =>
- if (settings.debug.value) ex.printStackTrace
- val sym2 = underlyingSymbol(sym1)
- val itype = pre.memberType(sym2)
- new AccessError(tree, sym, pre,
- "\n because its instance type "+itype+
- (if ("malformed type: "+itype.toString==ex.msg) " is malformed"
- else " contains a "+ex.msg)).emit()
- ErrorType
+ val owntype = {
+ try pre.memberType(sym1)
+ catch {
+ case ex: MalformedType =>
+ if (settings.debug.value) ex.printStackTrace
+ val sym2 = underlyingSymbol(sym1)
+ val itype = pre.memberType(sym2)
+ new AccessError(tree, sym, pre,
+ "\n because its instance type "+itype+
+ (if ("malformed type: "+itype.toString==ex.msg) " is malformed"
+ else " contains a "+ex.msg)).emit()
+ ErrorType
+ }
+ }
+ tree setSymbol sym1 setType {
+ pre match {
+ case _: SuperType => owntype map (tp => if (tp eq pre) site.symbol.thisType else tp)
+ case _ => owntype
+ }
}
- if (pre.isInstanceOf[SuperType])
- owntype = owntype.substSuper(pre, site.symbol.thisType)
- tree setSymbol sym1 setType owntype
}
}
@@ -905,8 +909,7 @@ trait Infer {
case NullaryMethodType(restpe) => // strip nullary method type, which used to be done by the polytype case below
isApplicable(undetparams, restpe, argtpes0, pt)
case PolyType(tparams, restpe) =>
- val tparams1 = cloneSymbols(tparams)
- isApplicable(tparams1 ::: undetparams, restpe.substSym(tparams, tparams1), argtpes0, pt)
+ createFromClonedSymbols(tparams, restpe)((tps1, restpe1) => isApplicable(tps1 ::: undetparams, restpe1, argtpes0, pt))
case ErrorType =>
true
case _ =>
@@ -1278,7 +1281,7 @@ trait Infer {
case Nil => Nil
case xs =>
// #3890
- val xs1 = treeSubst.typeSubst mapOver xs
+ val xs1 = treeSubst.typeMap mapOver xs
if (xs ne xs1)
new TreeSymSubstTraverser(xs, xs1) traverseTrees fn :: args
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 9e0f70a32c..fe474e5d3d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -130,9 +130,8 @@ trait Namers extends MethodSynthesis {
)
def setPrivateWithin[Sym <: Symbol](tree: Tree, sym: Sym, mods: Modifiers): Sym = {
- if (!sym.isPrivateLocal && mods.hasAccessBoundary)
- sym.privateWithin = typer.qualifyingClass(tree, mods.privateWithin, true)
- sym
+ if (sym.isPrivateLocal || !mods.hasAccessBoundary) sym
+ else sym setPrivateWithin typer.qualifyingClass(tree, mods.privateWithin, true)
}
def setPrivateWithin(tree: MemberDef, sym: Symbol): Symbol =
setPrivateWithin(tree, sym, tree.mods)
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 1c4355b3bd..66a7f90f0a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1562,14 +1562,11 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
}
val existentialParams = new ListBuffer[Symbol]
- doTypeTraversal(tree) { // check all bounds, except those that are
- // existential type parameters
+ doTypeTraversal(tree) { // check all bounds, except those that are existential type parameters
case ExistentialType(tparams, tpe) =>
existentialParams ++= tparams
case t: TypeRef =>
- val exparams = existentialParams.toList
- val wildcards = exparams map (_ => WildcardType)
- checkTypeRef(t.subst(exparams, wildcards), tree.pos)
+ checkTypeRef(deriveTypeWithWildcards(existentialParams.toList)(t), tree.pos)
case _ =>
}
tree
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index eca33b1aa7..3591732c70 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -54,10 +54,9 @@ trait SyntheticMethods extends ast.TreeDSL {
case tp => tp
}
- def makeMethodPublic(method: Symbol): Symbol = {
- method.privateWithin = NoSymbol
- method resetFlag AccessFlags
- }
+ def makeMethodPublic(method: Symbol): Symbol = (
+ method setPrivateWithin NoSymbol resetFlag AccessFlags
+ )
def methodArg(method: Symbol, idx: Int): Tree = Ident(method.paramss.head(idx))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index fd75b03297..65eb6466df 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -999,7 +999,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
//
// val x = expr
context.unit.warning(tree.pos, "recovering from existential Skolem type error in tree \n" + tree + "\nwith type " + tree.tpe + "\n expected type = " + pt + "\n context = " + context.tree)
- adapt(tree, mode, pt.subst(pt.existentialSkolems, pt.existentialSkolems map (_ => WildcardType)))
+ adapt(tree, mode, deriveTypeWithWildcards(pt.existentialSkolems)(pt))
} else
throw ex
}
@@ -1650,7 +1650,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
silent(_.typedTypeConstructor(stringParser(repl).typ())) match {
case tpt: Tree =>
val alias = enclClass.newAliasType(useCase.pos, name.toTypeName)
- val tparams = cloneSymbols(tpt.tpe.typeSymbol.typeParams, alias)
+ val tparams = cloneSymbolsAtOwner(tpt.tpe.typeSymbol.typeParams, alias)
alias setInfo typeFun(tparams, appliedType(tpt.tpe, tparams map (_.tpe)))
context.scope.enter(alias)
case _ =>
@@ -1851,23 +1851,23 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def matchesVisibleMember(member: Symbol) = visibleMembers exists { vis =>
(member.name == vis.name) &&
- (member.tpe <:< vis.tpe.substThis(vis.owner, ThisType(classDef.symbol)))
+ (member.tpe <:< vis.tpe.substThis(vis.owner, classDef.symbol))
}
// The block is an anonymous class definitions/instantiation pair
// -> members that are hidden by the type of the block are made private
- ( classDecls filter (member =>
+ val toHide = (
+ classDecls filter (member =>
member.isTerm
&& member.isPossibleInRefinement
&& member.isPublic
&& !matchesVisibleMember(member)
+ ) map (member => member
+ resetFlag (PROTECTED | LOCAL)
+ setFlag (PRIVATE | SYNTHETIC_PRIVATE)
+ setPrivateWithin NoSymbol
)
- foreach { member =>
- member resetFlag (PROTECTED | LOCAL)
- member setFlag (PRIVATE | SYNTHETIC_PRIVATE)
- syntheticPrivates += member
- member.privateWithin = NoSymbol
- }
)
+ syntheticPrivates ++= toHide
case _ =>
}
}
@@ -2495,18 +2495,18 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (args.length > MaxTupleArity)
error(fun.pos, "too many arguments for unapply pattern, maximum = "+MaxTupleArity)
- def freshArgType(tp: Type): (Type, List[Symbol]) = tp match {
+ //
+ def freshArgType(tp: Type): (List[Symbol], Type) = tp match {
case MethodType(param :: _, _) =>
- (param.tpe, Nil)
- case PolyType(tparams, restype) =>
- val tparams1 = cloneSymbols(tparams)
- (freshArgType(restype)._1.substSym(tparams, tparams1), tparams1)
+ (Nil, param.tpe)
+ case PolyType(tparams, restpe) =>
+ createFromClonedSymbols(tparams, freshArgType(restpe)._2)((ps, t) => ((ps, t)))
case OverloadedType(_, _) =>
error(fun.pos, "cannot resolve overloaded unapply")
- (ErrorType, Nil)
+ (Nil, ErrorType)
case _ =>
error(fun.pos, "an unapply method must accept a single argument.")
- (ErrorType, Nil)
+ (Nil, ErrorType)
}
val unapp = unapplyMember(otpe)
@@ -2516,20 +2516,15 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (!isApplicableSafe(Nil, unappType, List(pt), WildcardType)) {
//Console.println("UNAPP: need to typetest, arg.tpe = "+arg.tpe+", unappType = "+unappType)
- val (unappFormal, freeVars) = freshArgType(unappType.skolemizeExistential(context.owner, tree))
- val context1 = context.makeNewScope(context.tree, context.owner)
- freeVars foreach context1.scope.enter
+ val (freeVars, unappFormal) = freshArgType(unappType.skolemizeExistential(context.owner, tree))
+ val unapplyContext = context.makeNewScope(context.tree, context.owner)
+ freeVars foreach unapplyContext.scope.enter
- val typer1 = newTyper(context1)
+ val typer1 = newTyper(unapplyContext)
val pattp = typer1.infer.inferTypedPattern(tree.pos, unappFormal, arg.tpe)
// turn any unresolved type variables in freevars into existential skolems
- val skolems = freeVars map { fv =>
- val skolem = new TypeSkolem(context1.owner, fun.pos, fv.name.toTypeName, fv)
- skolem.setInfo(fv.info.cloneInfo(skolem))
- .setFlag(fv.flags | EXISTENTIAL).resetFlag(PARAM)
- skolem
- }
+ val skolems = freeVars map (fv => newExistentialSkolem(fv, unapplyContext.owner, fv))
arg.tpe = pattp.substSym(freeVars, skolems)
argDummy setInfo arg.tpe
}
@@ -2796,7 +2791,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
* also replaced, except for term symbols of an Ident tree, where
* only the type of the Ident is changed.
*/
- protected def existentialTransform(rawSyms: List[Symbol], tp: Type) = {
+ protected def existentialTransform[T](rawSyms: List[Symbol], tp: Type)(creator: (List[Symbol], Type) => T): T = {
val typeParams: List[Symbol] = rawSyms map { sym =>
val name = sym.name match {
case x: TypeName => x
@@ -2812,28 +2807,19 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// tpeHK for when they are: "if a type constructor is expected/allowed,
// tpeHK must be called instead of tpe."
val typeParamTypes = typeParams map (_.tpeHK)
- (
- typeParams map (tparam => tparam setInfo tparam.info.subst(rawSyms, typeParamTypes)),
- tp.subst(rawSyms, typeParamTypes)
- )
+ def doSubst(info: Type) = info.subst(rawSyms, typeParamTypes)
+
+ creator(typeParams map (_ modifyInfo doSubst), doSubst(tp))
}
/** Compute an existential type from raw hidden symbols `syms` and type `tp`
*/
def packSymbols(hidden: List[Symbol], tp: Type): Type =
if (hidden.isEmpty) tp
- else {
-// Console.println("original type: "+tp)
-// Console.println("hidden symbols: "+hidden)
- val (tparams, tp1) = existentialTransform(hidden, tp)
-// Console.println("tparams: "+tparams+", result: "+tp1)
- val res = existentialAbstraction(tparams, tp1)
-// Console.println("final result: "+res)
- res
- }
+ else existentialTransform(hidden, tp)(existentialAbstraction)
def isCapturedExistential(sym: Symbol) =
- ((sym hasFlag EXISTENTIAL) && (sym hasFlag CAPTURED)) // todo refine this
+ sym hasAllFlags (EXISTENTIAL | CAPTURED) // todo refine this
def packCaptured(tpe: Type): Type = {
val captured = mutable.Set[Symbol]()
@@ -2931,12 +2917,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def skolemizeTypeParams(tparams: List[TypeDef]): List[TypeDef] = {
class Deskolemizer extends LazyType {
override val typeParams = tparams map (_.symbol)
- val typeSkolems = typeParams map (_.newTypeSkolem) map (_ setInfo this)
- def substitute() = {
- // Replace the symbols
- (tparams, typeSkolems).zipped foreach (_.symbol = _)
- tparams
- }
+ val typeSkolems = typeParams map (_.newTypeSkolem setInfo this)
+ // Replace the symbols
+ def substitute() = (tparams, typeSkolems).zipped map (_ setSymbol _)
override def complete(sym: Symbol) {
// The info of a skolem is the skolemized info of the
// actual type parameter of the skolem
@@ -2969,9 +2952,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (vd.symbol.tpe.isVolatile)
error(vd.pos, "illegal abstraction from value with volatile type "+vd.symbol.tpe)
val tpt1 = typedType(tree.tpt, mode)
- val (typeParams, tpe) = existentialTransform(tree.whereClauses map (_.symbol), tpt1.tpe)
- //println(tpe + ": " + tpe.getClass )
- TypeTree(ExistentialType(typeParams, tpe)) setOriginal tree
+ existentialTransform(tree.whereClauses map (_.symbol), tpt1.tpe)((tparams, tp) =>
+ TypeTree(ExistentialType(tparams, tp)) setOriginal tree
+ )
}
// lifted out of typed1 because it's needed in typedImplicit0
@@ -3059,26 +3042,24 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (!settings.selfInAnnots.value)
NoSymbol
else
- arg1.tpe.selfsym match {
- case NoSymbol =>
- /* Implementation limitation: Currently this
- * can cause cyclical reference errors even
- * when the self symbol is not referenced at all.
- * Surely at least some of these cases can be
- * fixed by proper use of LazyType's. Lex tinkered
- * on this but did not succeed, so is leaving
- * it alone for now. Example code with the problem:
- * class peer extends Annotation
- * class NPE[T <: NPE[T] @peer]
- *
- * (Note: -Yself-in-annots must be on to see the problem)
- * */
- val sym =
- context.owner.newLocalDummy(ann.pos)
- .newValue(ann.pos, nme.self)
- sym.setInfo(arg1.tpe.withoutAnnotations)
- sym
- case sym => sym
+ arg1.tpe.selfsym orElse {
+ /* Implementation limitation: Currently this
+ * can cause cyclical reference errors even
+ * when the self symbol is not referenced at all.
+ * Surely at least some of these cases can be
+ * fixed by proper use of LazyType's. Lex tinkered
+ * on this but did not succeed, so is leaving
+ * it alone for now. Example code with the problem:
+ * class peer extends Annotation
+ * class NPE[T <: NPE[T] @peer]
+ *
+ * (Note: -Yself-in-annots must be on to see the problem)
+ * */
+ ( context.owner
+ newLocalDummy (ann.pos)
+ newValue (ann.pos, nme.self)
+ setInfo (arg1.tpe.withoutAnnotations)
+ )
}
val ainfo = typedAnnotation(ann, annotMode, selfsym)