aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-02-12 18:07:36 +0100
committerMartin Odersky <odersky@gmail.com>2014-02-12 18:07:36 +0100
commit80acc2d331cf8359c00d9a15c8cc10d537be503a (patch)
tree52665a28aed3fd663dccd26d2c8f89b89b5f5479 /src/dotty/tools/dotc
parenta6c50c1872cff7ffb20388c7ac2197d983085625 (diff)
downloaddotty-80acc2d331cf8359c00d9a15c8cc10d537be503a.tar.gz
dotty-80acc2d331cf8359c00d9a15c8cc10d537be503a.tar.bz2
dotty-80acc2d331cf8359c00d9a15c8cc10d537be503a.zip
Some changes in the interest of speedups.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala4
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala1
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala22
-rw-r--r--src/dotty/tools/dotc/core/Types.scala82
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala6
-rw-r--r--src/dotty/tools/dotc/printing/PlainPrinter.scala8
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala4
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala33
9 files changed, 89 insertions, 73 deletions
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index 77983830c..a8da15bd7 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -108,12 +108,12 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def apply(tp: Type) = tp match {
case tp: TermRef if toAvoid(tp) && variance > 0 =>
apply(tp.info)
- case tp @ TypeRef(pre, _) if toAvoid(pre) =>
+ case tp: TypeRef if toAvoid(tp.prefix) =>
tp.info match {
case TypeAlias(ref) => apply(ref)
case _ => mapOver(tp)
}
- case tp @ RefinedType(parent, _) =>
+ case tp: RefinedType =>
val tp1 @ RefinedType(parent1, _) = mapOver(tp)
if (tp1.refinedInfo existsPart toAvoid) {
typr.println(s"dropping refinement from $tp1")
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 5ca53b04e..1e4d0f47a 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -769,6 +769,7 @@ object Denotations {
/** An exception for accessing symbols that are no longer valid in current run */
class StaleSymbol(msg: => String) extends Exception {
+ util.Stats.record("stale symbol")
override def getMessage() = msg
}
}
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index 1a782ac63..6e984e43c 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -47,6 +47,28 @@ trait TypeOps { this: Context =>
def apply(tp: Type) = asSeenFrom(tp, pre, cls, this)
}
+ /** Implementation of Types#simplified */
+ final def simplify(tp: Type, theMap: SimplifyMap): Type = tp match {
+ case tp: NamedType =>
+ tp.derivedSelect(simplify(tp.prefix, theMap))
+ case _: ThisType | NoPrefix =>
+ tp
+ case tp: RefinedType =>
+ tp.derivedRefinedType(simplify(tp.parent, theMap), tp.refinedName, simplify(tp.refinedInfo, theMap))
+ case AndType(l, r) =>
+ simplify(l, theMap) & simplify(r, theMap)
+ case OrType(l, r) =>
+ simplify(l, theMap) | simplify(r, theMap)
+ case tp: PolyParam =>
+ typerState.constraint.typeVarOfParam(tp) orElse tp
+ case _ =>
+ (if (theMap != null) theMap else new SimplifyMap).mapOver(tp)
+ }
+
+ class SimplifyMap extends TypeMap {
+ def apply(tp: Type) = simplify(tp, this)
+ }
+
final def isVolatile(tp: Type): Boolean = {
/** Pre-filter to avoid expensive DNF computation */
def needsChecking(tp: Type, isPart: Boolean): Boolean = tp match {
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 71218680a..b99162383 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -26,6 +26,7 @@ import Uniques._
import collection.{mutable, Seq, breakOut}
import config.Config
import config.Printers._
+import annotation.tailrec
import language.implicitConversions
object Types {
@@ -342,45 +343,52 @@ object Types {
* flags in `excluded` from consideration.
*/
final def findMember(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Denotation = try {
- this match {
+ @tailrec def go(tp: Type): Denotation = tp match {
case tp: RefinedType =>
- val pdenot = tp.parent.findMember(name, pre, excluded)
- if (name eq tp.refinedName) {
- val rinfo = tp.refinedInfo.substThis(tp, pre)
- if (name.isTypeName) // simplified case that runs more efficiently
- pdenot.asSingleDenotation.derivedSingleDenotation(pdenot.symbol, rinfo)
- else
- pdenot & (new JointRefDenotation(NoSymbol, rinfo, Period.allInRun(ctx.runId)), pre)
- } else pdenot
+ if (name eq tp.refinedName) goRefined(tp) else go(tp.parent)
case tp: ThisType =>
- val d = tp.underlying.findMember(name, pre, excluded)
- if (d.exists) d
- else
- // There is a special case to handle:
- // trait Super { this: Sub => private class Inner {} println(this.Inner) }
- // class Sub extends Super
- // When resolving Super.this.Inner, the normal logic goes to the self type and
- // looks for Inner from there. But this fails because Inner is private.
- // We fix the problem by having the following fallback case, which links up the
- // member in Super instead of Sub.
- // As an example of this in the wild, see
- // loadClassWithPrivateInnerAndSubSelf in ShowClassTests
- tp.cls.typeRef.findMember(name, pre, excluded) orElse d
+ goThis(tp)
case tp: TypeRef =>
tp.denot.findMember(name, pre, excluded)
case tp: TypeProxy =>
- tp.underlying.findMember(name, pre, excluded)
+ go(tp.underlying)
case tp: ClassInfo =>
tp.cls.findMember(name, pre, excluded)
case AndType(l, r) =>
- l.findMember(name, pre, excluded) & (r.findMember(name, pre, excluded), pre)
+ goAnd(l, r)
case OrType(l, r) =>
- l.findMember(name, pre, excluded) | (r.findMember(name, pre, excluded), pre)
+ goOr(l, r)
case ErrorType =>
ctx.newErrorSymbol(pre.classSymbol orElse defn.RootClass, name)
case _ =>
NoDenotation
}
+ def goRefined(tp: RefinedType) = {
+ val pdenot = go(tp.parent)
+ val rinfo = tp.refinedInfo.substThis(tp, pre)
+ if (name.isTypeName) // simplified case that runs more efficiently
+ pdenot.asSingleDenotation.derivedSingleDenotation(pdenot.symbol, rinfo)
+ else
+ pdenot & (new JointRefDenotation(NoSymbol, rinfo, Period.allInRun(ctx.runId)), pre)
+ }
+ def goThis(tp: ThisType) = {
+ val d = go(tp.underlying)
+ if (d.exists) d
+ else
+ // There is a special case to handle:
+ // trait Super { this: Sub => private class Inner {} println(this.Inner) }
+ // class Sub extends Super
+ // When resolving Super.this.Inner, the normal logic goes to the self type and
+ // looks for Inner from there. But this fails because Inner is private.
+ // We fix the problem by having the following fallback case, which links up the
+ // member in Super instead of Sub.
+ // As an example of this in the wild, see
+ // loadClassWithPrivateInnerAndSubSelf in ShowClassTests
+ go(tp.cls.typeRef) orElse d
+ }
+ def goAnd(l: Type, r: Type) = go(l) & (go(r), pre)
+ def goOr(l: Type, r: Type) = go(l) | (go(r), pre)
+ go(this)
} catch {
case ex: MergeError =>
throw new MergeError(s"${ex.getMessage} as members of type ${pre.show}")
@@ -843,26 +851,12 @@ object Types {
/** A simplified version of this type which is equivalent wrt =:= to this type.
* This applies a typemap to the type which (as all typemaps) follows type
* variable instances and reduces typerefs over refined types. It also
- * re-evaluatesall occurrences of And/OrType with &/| because
+ * re-evaluates all occurrences of And/OrType with &/| because
* what was a union or intersection of type variables might be a simpler type
* after the type variables are instantiated. Finally, it
* maps poly params in the current constraint set back to their type vars.
*/
- def simplified(implicit ctx: Context) = {
- class Simplify extends TypeMap {
- def apply(tp: Type): Type = tp match {
- case AndType(l, r) =>
- this(l) & this(r)
- case OrType(l, r) =>
- this(l) | this(r)
- case tp: PolyParam =>
- ctx.typerState.constraint.typeVarOfParam(tp) orElse tp
- case _ =>
- mapOver(tp)
- }
- }
- new Simplify().apply(this)
- }
+ def simplified(implicit ctx: Context) = ctx.simplify(this, null)
/** customized hash code of this type.
* NotCached for uncached types. Cached types
@@ -2096,7 +2090,8 @@ object Types {
tp.derivedSelect(this(tp.prefix))
case _: ThisType
- | _: BoundType => tp
+ | _: BoundType
+ | NoPrefix => tp
case tp: RefinedType =>
tp.derivedRefinedType(this(tp.parent), tp.refinedName, this(tp.refinedInfo))
@@ -2217,7 +2212,8 @@ object Types {
this(x, tp.prefix)
case _: ThisType
- | _: BoundType => x
+ | _: BoundType
+ | NoPrefix => x
case tp: RefinedType =>
this(this(x, tp.parent), tp.refinedInfo)
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index 0fc661842..1395b4f43 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -239,13 +239,13 @@ class ClassfileParser(
case BOOL_TAG => defn.BooleanType
case 'L' =>
def processInner(tp: Type): Type = tp match {
- case tp @ TypeRef(pre, name) if !(tp.symbol.owner is Flags.ModuleClass) =>
- TypeRef(processInner(pre.widen), name)
+ case tp: TypeRef if !(tp.symbol.owner is Flags.ModuleClass) =>
+ TypeRef(processInner(tp.prefix.widen), tp.name)
case _ =>
tp
}
def processClassType(tp: Type): Type = tp match {
- case tp @ TypeRef(pre, name) =>
+ case tp: TypeRef =>
if (sig(index) == '<') {
accept('<')
var tp1: Type = tp
diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala
index 71c255c17..84936fbac 100644
--- a/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -100,8 +100,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
toText(tp.underlying) ~ ".type"
case tp: SingletonType =>
toText(tp.underlying) ~ "(" ~ toTextRef(tp) ~ ")"
- case tp @ TypeRef(pre, name) =>
- toTextPrefix(pre) ~ selectionString(tp)
+ case tp: TypeRef =>
+ toTextPrefix(tp.prefix) ~ selectionString(tp)
case tp: RefinedType =>
// return tp.toString // !!! DEBUG
val parent :: (refined: List[RefinedType]) =
@@ -187,8 +187,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
/** The string representation of this type used as a prefix */
protected def toTextRef(tp: SingletonType): Text = controlled {
tp match {
- case tp @ TermRef(pre, name) =>
- toTextPrefix(pre) ~ selectionString(tp)
+ case tp: TermRef =>
+ toTextPrefix(tp.prefix) ~ selectionString(tp)
case ThisType(cls) =>
nameString(cls) + ".this"
case SuperType(thistpe: SingletonType, _) =>
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index df00280ac..87f9fc29e 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -57,7 +57,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
tp match {
case ThisType(cls) =>
if (isOmittablePrefix(cls)) return ""
- case tp @ TermRef(pre, name) =>
+ case tp @ TermRef(pre, _) =>
val sym = tp.symbol
if (sym.isPackageObject) return toTextPrefix(pre)
if (isOmittablePrefix(sym)) return ""
@@ -109,7 +109,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
}
case tp: ViewProto =>
return toText(tp.argType) ~ " ?=>? " ~ toText(tp.resultType)
- case tp @ TypeRef(pre, name) =>
+ case tp: TypeRef =>
if (tp.symbol is TypeParam | TypeArgument) {
return tp.info match {
case TypeAlias(hi) => toText(hi)
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 63117e2ac..15dd0e9ad 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -223,7 +223,7 @@ trait Applications extends Compatibility { self: Typer =>
if (meth.isClassConstructor) {
// default getters for class constructors are found in the companion object
mpre.baseType(cls) match {
- case TypeRef(clspre, _) => ref(clspre, cls.companionModule)
+ case tp: TypeRef => ref(tp.prefix, cls.companionModule)
case _ => NoType
}
} else mpre
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 8c066cdd0..25721ad74 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -63,26 +63,23 @@ class Typer extends Namer with Applications with Implicits {
*/
private var importedFromRoot: Set[Symbol] = Set()
- /** A denotation exists really if it exists and does not point to a stale symbol.
- def reallyExists(denot: Denotation)(implicit ctx: Context): Boolean = denot match {
- case denot: SymDenotation =>
- denot.ensureCompleted
- denot.exists && !denot.isAbsent
- case _ =>
- true
- }*/
-
- /** A denotation exists really if it exists and does not point to a stale symbol. */
- def reallyExists(denot: Denotation)(implicit ctx: Context): Boolean =
- try
- denot.exists && {
+ /** A denotation exists really if it exists and does not point to a stale symbol. */
+ final def reallyExists(denot: Denotation)(implicit ctx: Context): Boolean = try
+ denot match {
+ case denot: SymDenotation =>
+ denot.exists && {
+ denot.ensureCompleted
+ !denot.isAbsent
+ }
+ case denot: SingleDenotation =>
val sym = denot.symbol
- sym.ensureCompleted
- (sym eq NoSymbol) || !sym.isAbsent
- }
- catch {
- case ex: StaleSymbol => false
+ (sym eq NoSymbol) || reallyExists(sym.denot)
+ case _ =>
+ true
}
+ catch {
+ case ex: StaleSymbol => false
+ }
/** The type of a selection with `name` of a tree with type `site`.
*/