summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2008-02-08 18:28:09 +0000
committerMartin Odersky <odersky@gmail.com>2008-02-08 18:28:09 +0000
commitd3a71dbd88dd98006a893b35d52ad909c8cd10bb (patch)
tree6d5f7ceec3d52caf80789ad8d61f51ae2f006537 /src/compiler/scala/tools
parenta176556bea2482d4c3c86a3604ec1eaa16d0daf1 (diff)
downloadscala-d3a71dbd88dd98006a893b35d52ad909c8cd10bb.tar.gz
scala-d3a71dbd88dd98006a893b35d52ad909c8cd10bb.tar.bz2
scala-d3a71dbd88dd98006a893b35d52ad909c8cd10bb.zip
fixed missing deprecated warning on types; fixe...
fixed missing deprecated warning on types; fixed problem with traits in refinements.
Diffstat (limited to 'src/compiler/scala/tools')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala37
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala16
-rwxr-xr-xsrc/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala.notyet409
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala16
5 files changed, 469 insertions, 23 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index c50984bac2..03ea3c0b5a 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -6,6 +6,7 @@
package scala.tools.nsc.symtab
+import scala.collection.mutable.ListBuffer
import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.util.{Position, NoPosition, BatchSourceFile}
import Flags._
@@ -637,18 +638,46 @@ trait Symbols {
attributes.filter(_.atp.typeSymbol.isNonBottomSubClass(clazz))
/** The least proper supertype of a class; includes all parent types
- * and refinement where needed */
+ * and refinement where needed
+ */
def classBound: Type = {
val tp = refinedType(info.parents, owner)
val thistp = tp.typeSymbol.thisType
+ val oldsymbuf = new ListBuffer[Symbol]
+ val newsymbuf = new ListBuffer[Symbol]
for (sym <- info.decls.toList) {
- if (sym.isPublic && !sym.isClass && !sym.isConstructor)
- addMember(thistp, tp,
- sym.cloneSymbol(tp.typeSymbol).setInfo(sym.info.substThis(this, thistp)))
+ // todo: what about public references to private symbols?
+ if (sym.isPublic && !sym.isConstructor) {
+ oldsymbuf += sym
+ newsymbuf += (
+ if (sym.isClass)
+ tp.typeSymbol.newAbstractType(sym.pos, sym.name).setInfo(sym.existentialBound)
+ else
+ sym.cloneSymbol(tp.typeSymbol))
+ }
+ }
+ val oldsyms = oldsymbuf.toList
+ val newsyms = newsymbuf.toList
+ for (sym <- newsyms) {
+ addMember(thistp, tp, sym.setInfo(sym.info.substThis(this, thistp).substSym(oldsyms, newsyms)))
}
tp
}
+ /** If we quantify existentially over this symbol,
+ * the bound of the type variable that stands for it
+ * pre: symbol is a term, a class, or an abstract type (no alias type allowed)
+ */
+ def existentialBound: Type =
+ if (this.isClass)
+ polyType(this.typeParams, mkTypeBounds(AllClass.tpe, this.classBound))
+ else if (this.isAbstractType)
+ this.info
+ else if (this.isTerm)
+ mkTypeBounds(AllClass.tpe, intersectionType(List(this.tpe, SingletonClass.tpe)))
+ else
+ throw new Error("unexpected alias type: "+this)
+
/** Reset symbol to initial state
*/
def reset(completer: Type) {
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index ae04027c5f..aca7f823c1 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -435,12 +435,18 @@ trait Types {
/** Substitute symbols `to' for occurrences of symbols
* `from' in this type.
+ * !!! NOTE !!!: If you need to do a substThis and a substSym, the substThis has to come
+ * first, as otherwise symbols will immediately get rebound in typeRef to the old
+ * symbol.
*/
def substSym(from: List[Symbol], to: List[Symbol]): Type = if (from eq to) this
else new SubstSymMap(from, to) apply this
/** Substitute all occurrences of `ThisType(from)' in this type
* by `to'.
+ * !!! NOTE !!!: If you need to do a substThis and a substSym, the substThis has to come
+ * first, as otherwise symbols will immediately get rebound in typeRef to the old
+ * symbol.
*/
def substThis(from: Symbol, to: Type): Type =
new SubstThisMap(from, to) apply this
@@ -1835,7 +1841,11 @@ A type's typeSymbol should never be inspected directly.
if (owner.isClass && owner != pre.typeSymbol && !sym.isFinal && !sym.isClass) {
//Console.println("rebind "+pre+" "+sym)//DEBUG
val rebind = pre.nonPrivateMember(sym.name).suchThat(sym => sym.isType || sym.isStable)
- if (rebind == NoSymbol) sym else rebind
+ if (rebind == NoSymbol) sym
+ else {
+ // Console.println("rebound "+pre+" "+sym+" to "+rebind)//DEBUG
+ rebind
+ }
} else sym
}
@@ -1927,7 +1937,7 @@ 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.substSym(syms1, syms2).substThis(original.typeSymbol, resultThis))
+ sym.setInfo(sym.info.substThis(original.typeSymbol, resultThis).substSym(syms1, syms2))
result
}
@@ -4187,7 +4197,7 @@ A type's typeSymbol should never be inspected directly.
*/
def addMember(thistp: Type, tp: Type, sym: Symbol) {
assert(sym != NoSymbol)
- if (settings.debug.value) log("add member " + sym+":"+tp+" to "+thistp)
+ if (settings.debug.value) log("add member " + sym+":"+sym.info+" to "+thistp)
if (!(thistp specializes sym)) {
if (sym.isTerm)
for (alt <- tp.nonPrivateDecl(sym.name).alternatives)
diff --git a/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala.notyet b/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala.notyet
new file mode 100755
index 0000000000..57215d5b77
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala.notyet
@@ -0,0 +1,409 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2007 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id: RefChecks.scala 13735 2008-01-18 17:18:58Z odersky $
+
+package scala.tools.nsc.typechecker
+
+import symtab.Flags._
+import transform.InfoTransform
+import scala.tools.nsc.util.{Position, NoPosition}
+
+abstract class DeVirtualize extends InfoTransform {
+
+ import global._
+ import definitions._
+ import typer.{typed, typedOperator, atOwner}
+ import posAssigner.atPos
+
+ /** the following two members override abstract members in Transform */
+ val phaseName: String = "devirtualize"
+
+ /** The phase might set the following new flags: */
+ override def phaseNewFlags: Long = notOVERRIDE | notFINAL
+
+ def newTransformer(unit: CompilationUnit): DeVirtualizeTransformer =
+ new DeVirtualizeTransformer(unit)
+ override def changesBaseClasses = false
+
+ lazy val ownPhase = phaseNamed(phaseName)
+
+ def transformInfo(sym: Symbol, tp: Type): Type = devirtualizeMap(tp)
+
+ /* todo:
+ check: overriding classes must have same type params
+ virtual classes cannot have self types
+ */
+
+ /** Do the following transformations everywhere in a type:
+ *
+ * 1. If a class defines virtual classes VC, add abstract types VA,
+ * worker traits VT and factories VF instead (@see devirtualize).
+ * 2. Convert VC.this where VC is a virtual class to WT.this where WT is the worker trait for VC
+ * (@see workerTrait)
+ * 3. Convert TypeRef's to VC where VC is a virtual class to TypeRef's to AT, where AT
+ * is the abstract type corresponding to VC.
+ *
+ * Note: If a class inherits vc's from two different paths, a vc in the
+ * inheriting class has to be created beforehand. This is done in phase ???
+ */
+ object devirtualizeMap extends TypeMap {
+ def apply(tp: Type): Type = mapOver(tp) match {
+ case tp1 @ ClassInfoType(parents, decls, clazz) =>
+ val ds = decls.toList
+ if (ds exists (_.isVirtualClass)) {
+ transformOwnerInfo(clazz)
+ val decls1 = newScope(ds)
+ for (m <- m.info.decls)
+ if (m.isVirtualClass) devirtualize(m, decls1)
+ for (m <- classesInNeedOfFactories(clazz))
+ addFactory(m, clazz, decls1)
+ ClassInfoType(parents, decls1, clazz)
+ } else tp1
+ case ThisType(clazz) if clazz.isVirtualClass =>
+ ThisType(workerTrait(clazz))
+ case TypeRef(pre, clazz, args) if sym.isVirtualClass =>
+ TypeRef(pre, abstractType(clazz), args)
+ case _ =>
+ tp
+ }
+ }
+
+ /** Transform owner of given clazz symbol */
+ protected def transformOwnerInfo(clazz: Symbol) { atPhase(ownPhase.next) { clazz.owner.info } }
+
+ protected def workerTraitName(clazzName: Name) = newTypeName(clazzName+"$trait")
+ protected def concreteClassName(clazzName: Name) = newTypeName(clazzName+"$fix")
+ protected def factoryName(clazzName: Name) = newTermName("new$"+clazzName)
+
+ protected def definedVirtuals(clazz: Symbol) = m.info.decls.toList filter (_.isVirtual)
+
+ protected def classesInNeedOfFactories(clazz: Symbol) = atPhase(ownPhase) {
+ def isDefinedVirtual(c: Symbol) = c.isVirtualClass && c.owner == clazz
+ val buf: ListBuffer[Symbol]
+ for (m <- clazz.info.members)
+ if (m.isVirtualClass && !(m hasFlag ABSTRACT) && (m.baseClasses exists isDefinedVirtual))
+ buf += m
+ buf.toList
+ }
+
+ /** The abstract type corresponding to a virtual class. */
+ protected def abstractType(clazz: Symbol): Symbol = atPhase(ownPhase.next) {
+ val tsym = clazz.info.owner.member(clazz.name)
+ assert(tsym.isAbstractType, clazz)
+ tsym
+ }
+
+ /** The worker trait corresponding to a virtual class. */
+ protected def workerTrait(clazz: Symbol) = atPhase(ownPhase.next) {
+ val tsym = clazz.info.owner.member(workerTraitName(clazz.name))
+ assert(tsym.isTrait, clazz)
+ tsym
+ }
+
+ /** The factory corresponding to a virtual class. */
+ protected def factory(clazz: Symbol) = atPhase(ownPhase.next) {
+ val fsym = clazz.info.owner.member(factoryName(clazz.name.toTermName))
+ assert(fsym.isMethod, clazz)
+ fsym
+ }
+
+ /** A reference to workertrait VT[Us] as from symbol `base'. Renames type parameters
+ * Us to those of `base' and also substitutes this to this of base's owner.
+ */
+ protected def workerTypeRef(wtrait: Symbol, base: Symbol): Type =
+ wtrait.tpe.subst(wtrait.typeParams, base.typeParams).substThis(wtrait.owner, base.owner)
+
+ /** The flags that a worker trait can inherit from its virtual class */
+ protected val traitFlagMask = AccessFlags | FINAL
+
+ /** The flags that an abstract type can inherit from its virtual class */
+ protected val absTypeFlagMask = AccessFlags | DEFERRED
+
+ /** The flags that a factory method can inherit from its virtual class */
+ protected val factoryFlagMask = AccessFlags
+
+ /** Create a polytype with given type parameters and given type, or return just the type
+ * if type params is empty. */
+ protected def mkPolyType(tparams: List[Symbol], tp: Type) =
+ if (tparams.isEmpty) tp else PolyType(tparams, tp)
+
+ /** Set info of `dst' to `tp', potentially wrapped by copies of any type
+ * parameters of `src' */
+ def setPolyInfo(dst: Symbol, from: Symbol, tp: Type) = {
+ val tparams = cloneSymbols(from.typeParams, dst)
+ dst setInfo mkPolyType(tparams, tp subst (from.typeParams, tparams))
+ }
+
+ /** The virtual classes overridden by given virtual class `clazz'
+ * Classes appear in linearization order (with superclasses before subclasses)
+ */
+ protected def overriddenVirtuals(clazz: Symbol): List[Symbol] = atPhase(ownPhase) {
+ for (bc <- clazz.owner.info.baseClasses
+ oc <- bc.info.member(clazz.name).alternatives
+ if oc.isVirtualClass) yield oc
+ }.reverse
+
+
+ /** Replace a virtual class
+ *
+ * attrs mods class VC[Ts] <: Ps { decls }
+ *
+ * with overridden classes _VC[Us]'s
+ *
+ * by the following symbols
+ *
+ * attrs mods1 type VC[Ts] <: dvm(Ps) with _VC$trait[Ts]'s with VC$trait[Ts]
+ * attrs mods2 trait VC$trait[Ts] extends Object with ScalaObject {
+ * this: VC[Ts] with VC$trait[Ts] => decls1
+ * }
+ *
+ * Furthermore, for all virtual member classes VC which
+ * are not abstract and which are or inherit from a virtual class defined
+also add a factory:
+ *
+ * attrs mods3 def new$VC[Ts](): VC[Ts] = {
+ * class VC$fix extends VC$trait's[Ts] with VC$trait[Ts]
+ *
+ * where
+ *
+ * dvm is the devirtalization mapping which converts refs to
+ * virtual classes to refs to their abstract types (@see devirtualize)
+ * mods1 are the modifiers inherited from abstract types
+ * mods2 are the modifiers inherited from worker traits
+ * mods3 are the modifiers inherited from factories
+ * decls1 is decls but members that have an override modifier
+ * lose it and any final modifier as well.
+ */
+ protected def devirtualize(clazz: Symbol, scope: Scope) {
+ scope.unlink(clazz)
+
+ val cabstype = clazz.owner.newAbstractType(clazz.pos, clazz.name)
+ .setFlag(clazz.flags & absTypeFlagMask)
+ scope.enter(cabstype)
+
+ cabstype setInfo new LazyType {
+ override val typeParams = cloneSymbols(clazz.typeParams, cabstype)
+ override def complete(sym: Symbol) {
+ def parentTypeRef(tp: Type) =
+ devirtualizeMap(tp.subst(clazz.typeParams, typeParams))
+ val parents1 = clazz.info.parents map parentTypeRef
+ val parents2 = overriddenVirtuals(clazz) map (oc => workerTypeRef(workerTrait(oc), cabstype))
+ sym.setInfo(
+ mkPolyType(typeParams, mkTypeBounds(AllClass.tpe, intersectionType(parents1 ::: parents2))))
+ }
+ }
+
+ val wtrait = clazz.owner.newClass(clazz.pos, workerTraitName(clazz.name))
+ .setFlag(clazz.flags & traitFlagMask | TRAIT)
+ .setAttributes(clazz.atttributes)
+ scope.enter(wtrait)
+
+ val decls1 = clazz.info.decls.toList
+ for (val m <- decls1)
+ if (m hasFlag OVERRIDE) m serFlag (notOVERRIDE | notFINAL)
+ setPolyInfo(
+ wtrait, clazz,
+ ClassInfoType(List(ObjectClass.tpe, ScalaObjectClass.tpe), new Scope(decls1), wtrait))
+ wtrait.setTypeOfThis(intersectionType(List(cabstype.tpe, wtrait.tpe)), clazz)
+ }
+
+ def addFactory(clazz: Symbol, owner: Symbol, scope: Scope) {
+ val pos = if (clazz.owner == owner) clazz.pos else owner.pos
+ val factory = owner.newMethod(pos, factoryName(clazz))
+ .setFlag(clazz.flags & factoryFlagMask)
+ scope.enter(factory)
+ val cabstype = abstractType(clazz)
+ setPolyInfo(factory, cabstype, MethodType(List(), cabstype.tpe))
+ }
+
+ protected def concreteClassSym(clazz: Symbol, factory: Symbol) = {
+ val cclazz = factory.newClass(clazz.pos, concreteClassName(clazz))
+ .setFlag(clazz.flags)
+ .setAttributes(clazz.atttributes)
+
+ cclazz setInfo new LazyType {
+ override def complete(sym: Symbol) {
+ sym setInfo ClassInfoType(
+ overriddenVirtuals(clazz) map (oc => workerTypeRef(workerTrait(oc), factory))
+ new Scope(),
+ cclazz)
+ }
+ }
+
+ cclazz
+ }
+
+ /** (new VC).init() => new$VC
+ * add stuff to onwing class
+ * transform types
+ */
+ class DeVirtualizeTransformer(unit: CompilationUnit) extends TypingTransformer {
+
+ override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {
+ val stats1 = for (stat <- stats; stat1 <- transformStat(stat)) yield transform(stat1)
+ val newDefs = new ListBuffer[Tree]
+ if (currentOwner.isClass && currentOwner.info.decls.toList exists (_.isVirtualClass)) {
+ for (m <- classesInNeedOfFactories(currentOwner))
+ newDefs += factoryDef(m)
+ }
+ if (newDefs.isEmpty) stats1
+ else stats1 ::: newDefs.toList
+ }
+
+ protected def transformStat(tree: Tree): List[Tree] = tree match {
+ case ClassDef(mods, name, tparams, Template(parents, self, body)) if (tree.symbol.isVirtualClass) =>
+ val clazz = tree.symbol
+ val absTypeSym = abstractType(clazz)
+ val workerTraitSym = workerTrait(clazz)
+ val abstypeDef = TypeDef(abstractType(clazz))
+ val selfDef = ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(clazz.tpe), EmptyTree)
+ val traitTemplate = atPos(templ.pos) {
+ Template(
+ List.map2(workerTraitSym.parents, parents) ((ptpe, ptree) => TypeTree(ptpe) setPos ptree.pos),
+ selfDef, Modifiers(), List(List()), List(List()),
+ body)
+ }
+ new ChangeOwnerTraverser(templ.symbol.owner, workerTrait)(
+ new ChangeOwnerTraverser(templ.symbol, traitTemplate.symbol)(traitTemplate))
+ var newdefs = List(abstypeDef, traitTemplate)
+ if (!clazz.hasFlag(ABSTRACT)) {
+ val factorySym = factory(clazz)
+ val cclazzSym = concreteClassSym(clazz, factorySym)
+ def overrideBridge(m: Symbol) = atPos(m.pos) {
+ val bridge = m.cloneSymbol(cclazzSym)
+ .resetFlag(notOVERRIDE | notFINAL)
+ val superRef = Select(Super(cclazzSym, nme.EMPTY.toTypeName), m)
+ DefDef(bridge, vparamss => (superRef /: vparamss)((fn, vparams) =>
+ Apply(fn, vparams map (param => Ident(param.symbol) setPos param.pos))))
+ }
+ val overrideBridges =
+ for (m <- workerTraitSym.info.decls.toList if m hasFlag notOVERRIDE)
+ yield overrideBridge(m)
+ val cclazzDef = ClassDef(cclazzSym, Modifiers(), List(List()), List(List()), overrideBridges)
+ val factoryExpr = atPos(templ.pos) {
+ Block(cclazzDef, New(TypeTree(cclazzSym.tpe), List(List())))
+ }
+ val factoryDef = DefDef(factorySym, vparamss => factoryExpr)
+ newdefs = newdefs ::: List(factoryDef)
+ }
+ newdefs map localTyper.typed
+ case _ =>
+ List(tree)
+ }
+
+ override def transform(tree: Tree): Tree = tree match {
+ case ClassDef(mods, name, tparams, Template(parents, self, body)) =>
+
+ case This(_) | Super(_, _) if tree.symbol.isVirtualClass =>
+ tree setSymbol workerTrait(tree.symbol)
+ case Select(New(tpt), name) if (tree.symbol.isConstructor && tree.symbol.owner.isVirtualClass) =>
+ val clazz = tpt.tpe.typeSymbol
+ val fn = mkAttributedRef(factory(clazz))
+ val targs = tpt.tpe.typeArgs
+ atPos(tree.pos) {
+ if (targs.isEmpty) fn else TypeApply(fn, targs map TypeTree) setType tpt.tpe
+ }
+ case _ =>
+ super.transform(tree)
+ } setType devirtualizeMap(tree.tpe)
+
+ override def transformUnit(unit: CompilationUnit) = atPhase(ownPhase.next) {
+ super.transformUnit(unit)
+ }
+ }
+}
+
+
+
+
+ scope.enter(wtrait)
+
+ .setInfo
+ scope.enter(cabstype)
+
+ setPolyType(wtrait, ClassInfoType(
+ List(ObjectClass.tpe, ScalaObjectClass.tpe),
+ new Scope(clazz.info.decls),
+ wtrait))
+
+ setPolyType(cabstype, mkTypeBounds(
+ AllClass.tpe,
+ (overridden map (workerTrait(_).tpe)) ::: (clazz.parents map devirtualizeMap)))
+
+
+
+
+
+
+ val cfix = ...
+ val cfactory = ...
+ val virBound = {
+ mkTypeBounds(
+ AllClass.tpe,
+ c.info.parents ::: overridden.map(oc => virTrait(oc).tpe))
+
+ c.setInfo(mkTypeBounds(AllClass.tpe, intersectionType(
+ ).tpe), c.owner)))
+ }
+
+/*
+ class A {
+ class C[X, Y](x: X) <: { var y = x ; def f(z: Y): X }
+ class D[Y](z) extends C[Int, Y](f(z)) { override def f(z:Int) = 3 }
+ }
+ class B extends A {
+ class C[X, Y](x: X) <: { def g = 2 }
+ }
+
+maps to:
+
+ class A {
+ type C[X, Y] <: CT[X, Y]
+
+ trait CT[X, Y] { self: C => protected[this] val x: Int; val y = x; def f(z:Int) = z + 1 }
+
+ type D <: C with DT
+
+ trait DT extends { self: D => def f(z:Int) = z + 2 }
+
+ trait preDT extends { self: D => val z: Int; val x = f(z) }
+
+ def newC(x: Int): C
+ def newD(x: Int): D
+
+ //type C = CT
+ //type D = C with DT
+
+ class CC(_x:Int) extends { val x = _x } with CT
+
+ def newC[X, Y](x:Int): C =
+ new CC(x).asInstanceOf[C]
+
+ class DC(_z:Int) extends { val z = _z } with preDT with CT with DT {
+ override def f(z:Int) = super.f(z)
+ }
+
+ def newD(z:Int):D = new DC(z).asInstanceOf[D]
+ }
+
+ class B extends A {
+ type C <: CT with CT2
+
+ trait CT2 { self : C => def g = 2 }
+
+ //type C = CT with CT2
+ //type D = C with DT
+
+ class CC2(_x:Int) extends { val x = _x } with CT with CT2
+
+ def newC(x:Int): C = new CC2(x).asInstanceOf[C]
+
+ class DC2(_z:Int) extends { val z = _z } with preDT with CT with CT2
+ with DT { override def f(z:Int) = super.f(z) }
+
+ def newD(z:Int): D = new DC2(z).asInstanceOf[D]
+ }
+
+*/
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index bc8a15297e..fa37dd5786 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -684,6 +684,15 @@ abstract class RefChecks extends InfoTransform {
result
}
+ /** If symbol is deprecated and is not contained in a depreceated definition,
+ * issue a deprecated warning
+ */
+ def checkDeprecated(sym: Symbol, pos: Position) {
+ if (sym.isDeprecated && !currentOwner.ownerChain.exists(_.isDeprecated)) {
+ unit.deprecationWarning(pos, sym+sym.locationString+" is deprecated")
+ }
+ }
+
/** Check that a deprecated val or def does not override a
* concrete, non-deprecated method. If it does, then
* deprecation is meaningless.
@@ -736,6 +745,7 @@ abstract class RefChecks extends InfoTransform {
new TypeTraverser {
def traverse(tp: Type): TypeTraverser = tp match {
case TypeRef(pre, sym, args) =>
+ checkDeprecated(sym, tree.pos)
if (!tp.isHigherKinded) checkBounds(pre, sym.owner, sym.typeParams, args)
this
case _ =>
@@ -785,9 +795,7 @@ abstract class RefChecks extends InfoTransform {
}
case Select(qual, name) =>
- if (sym.isDeprecated && !currentOwner.ownerChain.exists(_.isDeprecated)) {
- unit.deprecationWarning(tree.pos, sym+sym.locationString+" is deprecated")
- }
+ checkDeprecated(sym, tree.pos)
if (currentClass != sym.owner && (sym hasFlag LOCAL)) {
var o = currentClass
var hidden = false
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 8f0efd5819..915a6a159e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1914,16 +1914,6 @@ trait Typers { self: Analyzer =>
}
}
- protected def existentialBound(sym: Symbol): Type =
- if (sym.isClass)
- polyType(sym.typeParams, mkTypeBounds(AllClass.tpe, sym.classBound))
- else if (sym.isAbstractType)
- sym.info
- else if (sym.isTerm)
- mkTypeBounds(AllClass.tpe, intersectionType(List(sym.tpe, SingletonClass.tpe)))
- else
- throw new Error("unexpected alias type: "+sym)
-
/** Given a set `rawSyms' of term- and type-symbols, and a type `tp'.
* produce a set of fresh type parameters and a type so that it can be
* abstracted to an existential type.
@@ -1943,7 +1933,7 @@ trait Typers { self: Analyzer =>
protected def existentialTransform(rawSyms: List[Symbol], tp: Type) = {
val typeParams: List[Symbol] = rawSyms map { sym =>
val name = if (sym.isType) sym.name else newTypeName(sym.name+".type")
- val bound = existentialBound(sym)
+ val bound = sym.existentialBound
val quantified: Symbol =
recycle(sym.owner.newAbstractType(sym.pos, name))
trackSetInfo(quantified setFlag EXISTENTIAL)(bound.cloneInfo(quantified))
@@ -2016,14 +2006,14 @@ trait Typers { self: Analyzer =>
!(localSyms contains sym) && !(boundSyms contains sym) ) {
if (sym.typeParams.isEmpty) {
localSyms += sym
- addLocals(existentialBound(sym))
+ addLocals(sym.existentialBound)
} else if (tp.typeArgs.isEmpty) {
unit.error(tree.pos,
"implementation restriction: can't existentially abstract over higher-kinded type" + tp)
} else {
val inst = new SymInstance(sym, tp)
if (!(localInstances contains inst)) {
- val bound = existentialBound(sym) match {
+ val bound = sym.existentialBound match {
case PolyType(tparams, restpe) =>
restpe.subst(tparams, tp.typeArgs)
case t =>