Skip to content

Commit ed386bd

Browse files
committed
Store message expressions of ErrorTypes in separate map.
Message expressions usually capture contexts, which can cause space leaks if an error type is stored in a retained tree.
1 parent 93e7fd3 commit ed386bd

File tree

6 files changed

+28
-7
lines changed

6 files changed

+28
-7
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ object desugar {
7575
else {
7676
def msg =
7777
s"no matching symbol for ${tp.symbol.showLocated} in ${defctx.owner} / ${defctx.effectiveScope}"
78-
if (ctx.reporter.errorsReported) new ErrorType(msg)
78+
if (ctx.reporter.errorsReported) ErrorType(msg)
7979
else throw new java.lang.Error(msg)
8080
}
8181
case _ =>

compiler/src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import Implicits.ContextualImplicits
2424
import config.Settings._
2525
import config.Config
2626
import reporting._
27+
import reporting.diagnostic.Message
2728
import collection.mutable
2829
import collection.immutable.BitSet
2930
import printing._
@@ -636,6 +637,12 @@ object Contexts {
636637
*/
637638
private[dotty] var unsafeNonvariant: RunId = NoRunId
638639

640+
/** A map from ErrorType to associated message computation. We use this map
641+
* instead of storing message computations directly in ErrorTypes in order
642+
* to avoid space leaks - the message computation usually captures a context.
643+
*/
644+
private[core] val errorTypeMsg = mutable.Map[ErrorType, () => Message]()
645+
639646
// Phases state
640647

641648
private[core] var phasesPlan: List[List[Phase]] = _
@@ -662,6 +669,7 @@ object Contexts {
662669

663670
def reset() = {
664671
for ((_, set) <- uniqueSets) set.clear()
672+
errorTypeMsg.clear()
665673
}
666674

667675
// Test that access is single threaded

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1904,7 +1904,7 @@ object SymDenotations {
19041904
case denot: ClassDenotation =>
19051905
ClassInfo(denot.owner.thisType, denot.classSymbol, Nil, EmptyScope)
19061906
case _ =>
1907-
new ErrorType(errMsg)
1907+
ErrorType(errMsg)
19081908
}
19091909
denot.privateWithin = NoSymbol
19101910
}

compiler/src/dotty/tools/dotc/core/Symbols.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ trait Symbols { this: Context =>
298298
def newSkolem(tp: Type) = newSymbol(defn.RootClass, nme.SKOLEM, SyntheticArtifact | Permanent, tp)
299299

300300
def newErrorSymbol(owner: Symbol, name: Name, msg: => Message) = {
301-
val errType = new ErrorType(msg)
301+
val errType = ErrorType(msg)
302302
newSymbol(owner, name, SyntheticArtifact,
303303
if (name.isTypeName) TypeAlias(errType) else errType)
304304
}

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3553,11 +3553,24 @@ object Types {
35533553
*/
35543554
abstract class FlexType extends UncachedGroundType with ValueType
35553555

3556-
class ErrorType(_msg: => Message) extends FlexType {
3557-
def msg = _msg
3556+
class ErrorType private[Types] () extends FlexType {
3557+
def msg(implicit ctx: Context): Message =
3558+
ctx.errorTypeMsg.get(this) match {
3559+
case Some(msgFun) => msgFun()
3560+
case None => "error message from previous run no longer available"
3561+
}
3562+
}
3563+
object ErrorType {
3564+
def apply(msg: => Message)(implicit ctx: Context): ErrorType = {
3565+
val et = new ErrorType
3566+
ctx.base.errorTypeMsg(et) = () => msg
3567+
et
3568+
}
35583569
}
35593570

3560-
object UnspecifiedErrorType extends ErrorType("unspecified error")
3571+
object UnspecifiedErrorType extends ErrorType() {
3572+
override def msg(implicit ctx: Context): Message = "unspecified error"
3573+
}
35613574

35623575
/* Type used to track Select nodes that could not resolve a member and their qualifier is a scala.Dynamic. */
35633576
object TryDynamicCallType extends FlexType

compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ object ErrorReporting {
2323

2424
def errorType(msg: => Message, pos: Position)(implicit ctx: Context): ErrorType = {
2525
ctx.error(msg, pos)
26-
new ErrorType(msg)
26+
ErrorType(msg)
2727
}
2828

2929
def cyclicErrorMsg(ex: CyclicReference)(implicit ctx: Context) = {

0 commit comments

Comments
 (0)