Skip to content

Commit

Permalink
Cache signature in SingleDenotation for matchDegree; reduce denot cal…
Browse files Browse the repository at this point in the history
…ls in widens
  • Loading branch information
noti0na1 committed Sep 13, 2024
1 parent 8e9ded0 commit 7f9b452
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
28 changes: 26 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,30 @@ object Denotations {
throw ex
case _ => Signature.NotAMethod

private var myCurrentJavaSig: Signature = uninitialized
private var myCurrentJavaSigRunId: RunId = NoRunId
private var myCurrentScala2Sig: Signature = uninitialized
private var myCurrentScala2SigRunId: RunId = NoRunId
private var myCurrentSig: Signature = uninitialized
private var myCurrentSigRunId: RunId = NoRunId

def currentSignature(sourceLanguage: SourceLanguage)(using Context): Signature = sourceLanguage match
case SourceLanguage.Java =>
if myCurrentJavaSigRunId != ctx.runId then
myCurrentJavaSig = signature(sourceLanguage)
myCurrentJavaSigRunId = ctx.runId
myCurrentJavaSig
case SourceLanguage.Scala2 =>
if myCurrentScala2SigRunId != ctx.runId then
myCurrentScala2Sig = signature(sourceLanguage)
myCurrentScala2SigRunId = ctx.runId
myCurrentScala2Sig
case SourceLanguage.Scala3 =>
if myCurrentSigRunId != ctx.runId then
myCurrentSig = signature(sourceLanguage)
myCurrentSigRunId = ctx.runId
myCurrentSig

def derivedSingleDenotation(symbol: Symbol, info: Type, pre: Type = this.prefix, isRefinedMethod: Boolean = this.isRefinedMethod)(using Context): SingleDenotation =
if ((symbol eq this.symbol) && (info eq this.info) && (pre eq this.prefix) && (isRefinedMethod == this.isRefinedMethod)) this
else newLikeThis(symbol, info, pre, isRefinedMethod)
Expand Down Expand Up @@ -1033,8 +1057,8 @@ object Denotations {
val thisLanguage = SourceLanguage(symbol)
val otherLanguage = SourceLanguage(other.symbol)
val commonLanguage = SourceLanguage.commonLanguage(thisLanguage, otherLanguage)
val sig = signature(commonLanguage)
val otherSig = other.signature(commonLanguage)
val sig = currentSignature(commonLanguage)
val otherSig = other.currentSignature(commonLanguage)
sig.matchDegree(otherSig) match
case FullMatch =>
!alwaysCompareTypes || info.matches(other.info)
Expand Down
12 changes: 9 additions & 3 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,8 @@ object Types extends TypeUtils {
final def widen(using Context): Type = this match
case _: TypeRef | _: MethodOrPoly => this // fast path for most frequent cases
case tp: TermRef => // fast path for next most frequent case
if tp.isOverloaded then tp else tp.underlying.widen
val denot = tp.denot
if denot.isOverloaded then tp else denot.info.widen
case tp: SingletonType => tp.underlying.widen
case tp: ExprType => tp.resultType.widen
case tp =>
Expand All @@ -1325,15 +1326,20 @@ object Types extends TypeUtils {
* base type by applying one or more `underlying` dereferences.
*/
final def widenSingleton(using Context): Type = stripped match {
case tp: SingletonType if !tp.isOverloaded => tp.underlying.widenSingleton
case tp: TermRef =>
val denot = tp.denot
if denot.isOverloaded then this else denot.info.widenSingleton
case tp: SingletonType => tp.underlying.widenSingleton
case _ => this
}

/** Widen from TermRef to its underlying non-termref
* base type, while also skipping Expr types.
*/
final def widenTermRefExpr(using Context): Type = stripTypeVar match {
case tp: TermRef if !tp.isOverloaded => tp.underlying.widenExpr.widenTermRefExpr
case tp: TermRef =>
val denot = tp.denot
if denot.isOverloaded then this else denot.info.widenExpr.widenTermRefExpr
case _ => this
}

Expand Down

0 comments on commit 7f9b452

Please sign in to comment.