Skip to content

Commit 80acc2d

Browse files
committed
Some changes in the interest of speedups.
1 parent a6c50c1 commit 80acc2d

File tree

9 files changed

+89
-73
lines changed

9 files changed

+89
-73
lines changed

src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,12 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
108108
def apply(tp: Type) = tp match {
109109
case tp: TermRef if toAvoid(tp) && variance > 0 =>
110110
apply(tp.info)
111-
case tp @ TypeRef(pre, _) if toAvoid(pre) =>
111+
case tp: TypeRef if toAvoid(tp.prefix) =>
112112
tp.info match {
113113
case TypeAlias(ref) => apply(ref)
114114
case _ => mapOver(tp)
115115
}
116-
case tp @ RefinedType(parent, _) =>
116+
case tp: RefinedType =>
117117
val tp1 @ RefinedType(parent1, _) = mapOver(tp)
118118
if (tp1.refinedInfo existsPart toAvoid) {
119119
typr.println(s"dropping refinement from $tp1")

src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,7 @@ object Denotations {
769769

770770
/** An exception for accessing symbols that are no longer valid in current run */
771771
class StaleSymbol(msg: => String) extends Exception {
772+
util.Stats.record("stale symbol")
772773
override def getMessage() = msg
773774
}
774775
}

src/dotty/tools/dotc/core/TypeOps.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,28 @@ trait TypeOps { this: Context =>
4747
def apply(tp: Type) = asSeenFrom(tp, pre, cls, this)
4848
}
4949

50+
/** Implementation of Types#simplified */
51+
final def simplify(tp: Type, theMap: SimplifyMap): Type = tp match {
52+
case tp: NamedType =>
53+
tp.derivedSelect(simplify(tp.prefix, theMap))
54+
case _: ThisType | NoPrefix =>
55+
tp
56+
case tp: RefinedType =>
57+
tp.derivedRefinedType(simplify(tp.parent, theMap), tp.refinedName, simplify(tp.refinedInfo, theMap))
58+
case AndType(l, r) =>
59+
simplify(l, theMap) & simplify(r, theMap)
60+
case OrType(l, r) =>
61+
simplify(l, theMap) | simplify(r, theMap)
62+
case tp: PolyParam =>
63+
typerState.constraint.typeVarOfParam(tp) orElse tp
64+
case _ =>
65+
(if (theMap != null) theMap else new SimplifyMap).mapOver(tp)
66+
}
67+
68+
class SimplifyMap extends TypeMap {
69+
def apply(tp: Type) = simplify(tp, this)
70+
}
71+
5072
final def isVolatile(tp: Type): Boolean = {
5173
/** Pre-filter to avoid expensive DNF computation */
5274
def needsChecking(tp: Type, isPart: Boolean): Boolean = tp match {

src/dotty/tools/dotc/core/Types.scala

Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import Uniques._
2626
import collection.{mutable, Seq, breakOut}
2727
import config.Config
2828
import config.Printers._
29+
import annotation.tailrec
2930
import language.implicitConversions
3031

3132
object Types {
@@ -342,45 +343,52 @@ object Types {
342343
* flags in `excluded` from consideration.
343344
*/
344345
final def findMember(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Denotation = try {
345-
this match {
346+
@tailrec def go(tp: Type): Denotation = tp match {
346347
case tp: RefinedType =>
347-
val pdenot = tp.parent.findMember(name, pre, excluded)
348-
if (name eq tp.refinedName) {
349-
val rinfo = tp.refinedInfo.substThis(tp, pre)
350-
if (name.isTypeName) // simplified case that runs more efficiently
351-
pdenot.asSingleDenotation.derivedSingleDenotation(pdenot.symbol, rinfo)
352-
else
353-
pdenot & (new JointRefDenotation(NoSymbol, rinfo, Period.allInRun(ctx.runId)), pre)
354-
} else pdenot
348+
if (name eq tp.refinedName) goRefined(tp) else go(tp.parent)
355349
case tp: ThisType =>
356-
val d = tp.underlying.findMember(name, pre, excluded)
357-
if (d.exists) d
358-
else
359-
// There is a special case to handle:
360-
// trait Super { this: Sub => private class Inner {} println(this.Inner) }
361-
// class Sub extends Super
362-
// When resolving Super.this.Inner, the normal logic goes to the self type and
363-
// looks for Inner from there. But this fails because Inner is private.
364-
// We fix the problem by having the following fallback case, which links up the
365-
// member in Super instead of Sub.
366-
// As an example of this in the wild, see
367-
// loadClassWithPrivateInnerAndSubSelf in ShowClassTests
368-
tp.cls.typeRef.findMember(name, pre, excluded) orElse d
350+
goThis(tp)
369351
case tp: TypeRef =>
370352
tp.denot.findMember(name, pre, excluded)
371353
case tp: TypeProxy =>
372-
tp.underlying.findMember(name, pre, excluded)
354+
go(tp.underlying)
373355
case tp: ClassInfo =>
374356
tp.cls.findMember(name, pre, excluded)
375357
case AndType(l, r) =>
376-
l.findMember(name, pre, excluded) & (r.findMember(name, pre, excluded), pre)
358+
goAnd(l, r)
377359
case OrType(l, r) =>
378-
l.findMember(name, pre, excluded) | (r.findMember(name, pre, excluded), pre)
360+
goOr(l, r)
379361
case ErrorType =>
380362
ctx.newErrorSymbol(pre.classSymbol orElse defn.RootClass, name)
381363
case _ =>
382364
NoDenotation
383365
}
366+
def goRefined(tp: RefinedType) = {
367+
val pdenot = go(tp.parent)
368+
val rinfo = tp.refinedInfo.substThis(tp, pre)
369+
if (name.isTypeName) // simplified case that runs more efficiently
370+
pdenot.asSingleDenotation.derivedSingleDenotation(pdenot.symbol, rinfo)
371+
else
372+
pdenot & (new JointRefDenotation(NoSymbol, rinfo, Period.allInRun(ctx.runId)), pre)
373+
}
374+
def goThis(tp: ThisType) = {
375+
val d = go(tp.underlying)
376+
if (d.exists) d
377+
else
378+
// There is a special case to handle:
379+
// trait Super { this: Sub => private class Inner {} println(this.Inner) }
380+
// class Sub extends Super
381+
// When resolving Super.this.Inner, the normal logic goes to the self type and
382+
// looks for Inner from there. But this fails because Inner is private.
383+
// We fix the problem by having the following fallback case, which links up the
384+
// member in Super instead of Sub.
385+
// As an example of this in the wild, see
386+
// loadClassWithPrivateInnerAndSubSelf in ShowClassTests
387+
go(tp.cls.typeRef) orElse d
388+
}
389+
def goAnd(l: Type, r: Type) = go(l) & (go(r), pre)
390+
def goOr(l: Type, r: Type) = go(l) | (go(r), pre)
391+
go(this)
384392
} catch {
385393
case ex: MergeError =>
386394
throw new MergeError(s"${ex.getMessage} as members of type ${pre.show}")
@@ -843,26 +851,12 @@ object Types {
843851
/** A simplified version of this type which is equivalent wrt =:= to this type.
844852
* This applies a typemap to the type which (as all typemaps) follows type
845853
* variable instances and reduces typerefs over refined types. It also
846-
* re-evaluatesall occurrences of And/OrType with &/| because
854+
* re-evaluates all occurrences of And/OrType with &/| because
847855
* what was a union or intersection of type variables might be a simpler type
848856
* after the type variables are instantiated. Finally, it
849857
* maps poly params in the current constraint set back to their type vars.
850858
*/
851-
def simplified(implicit ctx: Context) = {
852-
class Simplify extends TypeMap {
853-
def apply(tp: Type): Type = tp match {
854-
case AndType(l, r) =>
855-
this(l) & this(r)
856-
case OrType(l, r) =>
857-
this(l) | this(r)
858-
case tp: PolyParam =>
859-
ctx.typerState.constraint.typeVarOfParam(tp) orElse tp
860-
case _ =>
861-
mapOver(tp)
862-
}
863-
}
864-
new Simplify().apply(this)
865-
}
859+
def simplified(implicit ctx: Context) = ctx.simplify(this, null)
866860

867861
/** customized hash code of this type.
868862
* NotCached for uncached types. Cached types
@@ -2096,7 +2090,8 @@ object Types {
20962090
tp.derivedSelect(this(tp.prefix))
20972091

20982092
case _: ThisType
2099-
| _: BoundType => tp
2093+
| _: BoundType
2094+
| NoPrefix => tp
21002095

21012096
case tp: RefinedType =>
21022097
tp.derivedRefinedType(this(tp.parent), tp.refinedName, this(tp.refinedInfo))
@@ -2217,7 +2212,8 @@ object Types {
22172212
this(x, tp.prefix)
22182213

22192214
case _: ThisType
2220-
| _: BoundType => x
2215+
| _: BoundType
2216+
| NoPrefix => x
22212217

22222218
case tp: RefinedType =>
22232219
this(this(x, tp.parent), tp.refinedInfo)

src/dotty/tools/dotc/core/pickling/ClassfileParser.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,13 +239,13 @@ class ClassfileParser(
239239
case BOOL_TAG => defn.BooleanType
240240
case 'L' =>
241241
def processInner(tp: Type): Type = tp match {
242-
case tp @ TypeRef(pre, name) if !(tp.symbol.owner is Flags.ModuleClass) =>
243-
TypeRef(processInner(pre.widen), name)
242+
case tp: TypeRef if !(tp.symbol.owner is Flags.ModuleClass) =>
243+
TypeRef(processInner(tp.prefix.widen), tp.name)
244244
case _ =>
245245
tp
246246
}
247247
def processClassType(tp: Type): Type = tp match {
248-
case tp @ TypeRef(pre, name) =>
248+
case tp: TypeRef =>
249249
if (sig(index) == '<') {
250250
accept('<')
251251
var tp1: Type = tp

src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
100100
toText(tp.underlying) ~ ".type"
101101
case tp: SingletonType =>
102102
toText(tp.underlying) ~ "(" ~ toTextRef(tp) ~ ")"
103-
case tp @ TypeRef(pre, name) =>
104-
toTextPrefix(pre) ~ selectionString(tp)
103+
case tp: TypeRef =>
104+
toTextPrefix(tp.prefix) ~ selectionString(tp)
105105
case tp: RefinedType =>
106106
// return tp.toString // !!! DEBUG
107107
val parent :: (refined: List[RefinedType]) =
@@ -187,8 +187,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
187187
/** The string representation of this type used as a prefix */
188188
protected def toTextRef(tp: SingletonType): Text = controlled {
189189
tp match {
190-
case tp @ TermRef(pre, name) =>
191-
toTextPrefix(pre) ~ selectionString(tp)
190+
case tp: TermRef =>
191+
toTextPrefix(tp.prefix) ~ selectionString(tp)
192192
case ThisType(cls) =>
193193
nameString(cls) + ".this"
194194
case SuperType(thistpe: SingletonType, _) =>

src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
5757
tp match {
5858
case ThisType(cls) =>
5959
if (isOmittablePrefix(cls)) return ""
60-
case tp @ TermRef(pre, name) =>
60+
case tp @ TermRef(pre, _) =>
6161
val sym = tp.symbol
6262
if (sym.isPackageObject) return toTextPrefix(pre)
6363
if (isOmittablePrefix(sym)) return ""
@@ -109,7 +109,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
109109
}
110110
case tp: ViewProto =>
111111
return toText(tp.argType) ~ " ?=>? " ~ toText(tp.resultType)
112-
case tp @ TypeRef(pre, name) =>
112+
case tp: TypeRef =>
113113
if (tp.symbol is TypeParam | TypeArgument) {
114114
return tp.info match {
115115
case TypeAlias(hi) => toText(hi)

src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ trait Applications extends Compatibility { self: Typer =>
223223
if (meth.isClassConstructor) {
224224
// default getters for class constructors are found in the companion object
225225
mpre.baseType(cls) match {
226-
case TypeRef(clspre, _) => ref(clspre, cls.companionModule)
226+
case tp: TypeRef => ref(tp.prefix, cls.companionModule)
227227
case _ => NoType
228228
}
229229
} else mpre

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -63,26 +63,23 @@ class Typer extends Namer with Applications with Implicits {
6363
*/
6464
private var importedFromRoot: Set[Symbol] = Set()
6565

66-
/** A denotation exists really if it exists and does not point to a stale symbol.
67-
def reallyExists(denot: Denotation)(implicit ctx: Context): Boolean = denot match {
68-
case denot: SymDenotation =>
69-
denot.ensureCompleted
70-
denot.exists && !denot.isAbsent
71-
case _ =>
72-
true
73-
}*/
74-
75-
/** A denotation exists really if it exists and does not point to a stale symbol. */
76-
def reallyExists(denot: Denotation)(implicit ctx: Context): Boolean =
77-
try
78-
denot.exists && {
66+
/** A denotation exists really if it exists and does not point to a stale symbol. */
67+
final def reallyExists(denot: Denotation)(implicit ctx: Context): Boolean = try
68+
denot match {
69+
case denot: SymDenotation =>
70+
denot.exists && {
71+
denot.ensureCompleted
72+
!denot.isAbsent
73+
}
74+
case denot: SingleDenotation =>
7975
val sym = denot.symbol
80-
sym.ensureCompleted
81-
(sym eq NoSymbol) || !sym.isAbsent
82-
}
83-
catch {
84-
case ex: StaleSymbol => false
76+
(sym eq NoSymbol) || reallyExists(sym.denot)
77+
case _ =>
78+
true
8579
}
80+
catch {
81+
case ex: StaleSymbol => false
82+
}
8683

8784
/** The type of a selection with `name` of a tree with type `site`.
8885
*/

0 commit comments

Comments
 (0)