Skip to content

Commit 82d76e8

Browse files
Merge pull request #8603 from dotty-staging/fix-performance
Fix performance degradation: make message fields lazy
2 parents d0bab30 + a535680 commit 82d76e8

File tree

90 files changed

+1324
-3434
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+1324
-3434
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import NameKinds.{UniqueName, EvidenceParamName, DefaultGetterName}
1010
import typer.{FrontEnd, Namer}
1111
import util.{Property, SourceFile, SourcePosition}
1212
import collection.mutable.ListBuffer
13-
import reporting.diagnostic.messages._
13+
import reporting.messages._
1414
import reporting.trace
1515
import annotation.constructorOnly
1616
import printing.Formatting.hl
@@ -981,7 +981,7 @@ object desugar {
981981
var name = mdef.name
982982
if (name.isEmpty) name = name.likeSpaced(inventGivenOrExtensionName(impl))
983983
if (ctx.owner == defn.ScalaPackageClass && defn.reservedScalaClassNames.contains(name.toTypeName)) {
984-
def kind = if (name.isTypeName) "class" else "object"
984+
val kind = if (name.isTypeName) "class" else "object"
985985
ctx.error(IllegalRedefinitionOfStandardKind(kind, name), mdef.sourcePos)
986986
name = name.errorName
987987
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import util.Spans._
99
import util.CommentParsing._
1010
import util.Property.Key
1111
import parsing.Parsers.Parser
12-
import reporting.diagnostic.messages.ProperDefinitionNotFound
12+
import reporting.messages.ProperDefinitionNotFound
1313

1414
object Comments {
1515
val ContextDoc: Key[ContextDocstrings] = new Key[ContextDocstrings]

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import Implicits.ContextualImplicits
2121
import config.Settings._
2222
import config.Config
2323
import reporting._
24-
import reporting.diagnostic.Message
2524
import io.{AbstractFile, NoAbstractFile, PlainFile, Path}
2625
import scala.io.Codec
2726
import collection.mutable
@@ -750,11 +749,11 @@ object Contexts {
750749
* of underlying during a controlled operation exists. */
751750
private[core] val pendingUnderlying: mutable.HashSet[Type] = new mutable.HashSet[Type]
752751

753-
/** A map from ErrorType to associated message computation. We use this map
754-
* instead of storing message computations directly in ErrorTypes in order
755-
* to avoid space leaks - the message computation usually captures a context.
752+
/** A map from ErrorType to associated message. We use this map
753+
* instead of storing messages directly in ErrorTypes in order
754+
* to avoid space leaks - the message usually captures a context.
756755
*/
757-
private[core] val errorTypeMsg: mutable.Map[Types.ErrorType, () => Message] = mutable.Map()
756+
private[core] val errorTypeMsg: mutable.Map[Types.ErrorType, Message] = mutable.Map()
758757

759758
// Phases state
760759

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@ import util.Stats
2020
import java.util.WeakHashMap
2121
import scala.util.control.NonFatal
2222
import config.Config
23-
import reporting.diagnostic.Message
24-
import reporting.diagnostic.messages.BadSymbolicReference
25-
import reporting.trace
23+
import reporting.{Message, trace}
24+
import reporting.messages.BadSymbolicReference
2625
import collection.mutable
2726
import transform.TypeUtils._
2827

@@ -2368,7 +2367,7 @@ object SymDenotations {
23682367
/** A completer for missing references */
23692368
class StubInfo() extends LazyType {
23702369

2371-
def initializeToDefaults(denot: SymDenotation, errMsg: => Message)(implicit ctx: Context): Unit = {
2370+
def initializeToDefaults(denot: SymDenotation, errMsg: Message)(implicit ctx: Context): Unit = {
23722371
denot.info = denot match {
23732372
case denot: ClassDenotation =>
23742373
ClassInfo(denot.owner.thisType, denot.classSymbol, Nil, EmptyScope)
@@ -2380,7 +2379,7 @@ object SymDenotations {
23802379

23812380
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
23822381
val sym = denot.symbol
2383-
def errMsg = BadSymbolicReference(denot)
2382+
val errMsg = BadSymbolicReference(denot)
23842383
ctx.error(errMsg, sym.sourcePos)
23852384
if (ctx.debug) throw new scala.Error()
23862385
initializeToDefaults(denot, errMsg)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import tpd.{Tree, TreeProvider, TreeOps}
2323
import ast.TreeTypeMap
2424
import Constants.Constant
2525
import Variances.{Variance, varianceFromInt}
26-
import reporting.diagnostic.Message
26+
import reporting.Message
2727
import collection.mutable
2828
import io.AbstractFile
2929
import language.implicitConversions
@@ -300,7 +300,7 @@ trait Symbols { this: Context =>
300300
*/
301301
def newSkolem(tp: Type): TermSymbol = newSymbol(defn.RootClass, nme.SKOLEM, SyntheticArtifact | NonMember | Permanent, tp)
302302

303-
def newErrorSymbol(owner: Symbol, name: Name, msg: => Message): Symbol = {
303+
def newErrorSymbol(owner: Symbol, name: Name, msg: Message): Symbol = {
304304
val errType = ErrorType(msg)
305305
newSymbol(owner, name, SyntheticArtifact,
306306
if (name.isTypeName) TypeAlias(errType) else errType)

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import Contexts._
1010
import SymDenotations._
1111
import Denotations._
1212
import Decorators._
13-
import reporting.diagnostic.Message
14-
import reporting.diagnostic.messages._
13+
import reporting.{Message, NoExplanation}
14+
import reporting.messages._
1515
import ast.untpd
1616
import config.Printers.cyclicErrors
1717

@@ -69,7 +69,7 @@ class RecursionOverflow(val op: String, details: => String, val previous: Throwa
6969
(rs.map(_.explanation): List[String]).mkString("\n ", "\n| ", "")
7070
}
7171

72-
override def produceMessage(implicit ctx: Context): Message = {
72+
override def produceMessage(implicit ctx: Context): Message = NoExplanation {
7373
val mostCommon = recursions.groupBy(_.op).toList.maxBy(_._2.map(_.weight).sum)._2.reverse
7474
s"""Recursion limit exceeded.
7575
|Maybe there is an illegal cyclic reference?

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ import Decorators._
1212
import StdNames._
1313
import collection.mutable
1414
import ast.tpd._
15-
import reporting.trace
16-
import reporting.diagnostic.Message
15+
import reporting.{trace, Message}
1716
import config.Printers.{gadts, typr}
1817
import typer.Applications._
1918
import typer.ProtoTypes._
@@ -516,7 +515,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
516515
def dynamicsEnabled: Boolean =
517516
featureEnabled(nme.dynamics)
518517

519-
def testScala2CompatMode(msg: => Message, pos: SourcePosition, replace: => Unit = ()): Boolean = {
518+
def testScala2CompatMode(msg: Message, pos: SourcePosition, replace: => Unit = ()): Boolean = {
520519
if (scala2CompatMode) {
521520
migrationWarning(msg, pos)
522521
replace

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

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import CheckRealizable._
2121
import Variances.{Variance, varianceFromInt, varianceToInt, setStructuralVariances, Invariant}
2222
import util.Stats._
2323
import util.SimpleIdentitySet
24-
import reporting.diagnostic.Message
2524
import ast.tpd._
2625
import ast.TreeTypeMap
2726
import printing.Texts._
@@ -34,7 +33,7 @@ import annotation.{tailrec, constructorOnly}
3433
import language.implicitConversions
3534
import scala.util.hashing.{ MurmurHash3 => hashing }
3635
import config.Printers.{core, typr}
37-
import reporting.trace
36+
import reporting.{trace, Message}
3837
import java.lang.ref.WeakReference
3938

4039
import scala.annotation.internal.sharable
@@ -4650,19 +4649,16 @@ object Types {
46504649
def msg(implicit ctx: Context): Message
46514650
}
46524651

4653-
object ErrorType {
4654-
def apply(msg: => Message)(implicit ctx: Context): ErrorType = {
4655-
val et = new ErrorType {
4656-
def msg(implicit ctx: Context): Message =
4657-
ctx.base.errorTypeMsg.get(this) match {
4658-
case Some(msgFun) => msgFun()
4652+
object ErrorType:
4653+
def apply(m: Message)(implicit ctx: Context): ErrorType =
4654+
val et = new ErrorType:
4655+
def msg(using ctx: Context): Message =
4656+
ctx.base.errorTypeMsg.get(this) match
4657+
case Some(m) => m
46594658
case None => "error message from previous run no longer available"
4660-
}
4661-
}
4662-
ctx.base.errorTypeMsg(et) = () => msg
4659+
ctx.base.errorTypeMsg(et) = m
46634660
et
4664-
}
4665-
}
4661+
end ErrorType
46664662

46674663
object UnspecifiedErrorType extends ErrorType {
46684664
override def msg(implicit ctx: Context): Message = "unspecified error"

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import scala.collection.mutable
2828
import scala.collection.mutable.ListBuffer
2929
import scala.annotation.switch
3030
import reporting.trace
31-
import dotty.tools.dotc.reporting.diagnostic.messages.FailureToEliminateExistential
31+
import dotty.tools.dotc.reporting.messages.FailureToEliminateExistential
3232

3333
object Scala2Unpickler {
3434

compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import ast.{Trees, tpd}
1717
import core._, core.Decorators._
1818
import Contexts._, Names._, NameOps._, Symbols._, SymDenotations._, Trees._, Types._
1919
import classpath._
20-
import reporting._, reporting.diagnostic.MessageContainer
20+
import reporting._
2121
import util._
2222

2323
/** A Driver subclass designed to be used from IDEs */
@@ -138,9 +138,9 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
138138
(fromSource ++ fromClassPath).distinct
139139
}
140140

141-
def run(uri: URI, sourceCode: String): List[MessageContainer] = run(uri, toSource(uri, sourceCode))
141+
def run(uri: URI, sourceCode: String): List[Diagnostic] = run(uri, toSource(uri, sourceCode))
142142

143-
def run(uri: URI, source: SourceFile): List[MessageContainer] = {
143+
def run(uri: URI, source: SourceFile): List[Diagnostic] = {
144144
val previousCtx = myCtx
145145
try {
146146
val reporter =

compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import Symbols._
1919
import ast.Trees._
2020
import Decorators._
2121
import StdNames._
22-
import dotty.tools.dotc.reporting.diagnostic.messages.IdentifierExpected
22+
import dotty.tools.dotc.reporting.messages.IdentifierExpected
2323
import dotty.tools.dotc.util.SourceFile
2424
import util.Spans._
2525
import scala.collection.mutable.ListBuffer

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ import rewrites.Rewrites.{patch, overlapsPatch}
3030
object Parsers {
3131

3232
import ast.untpd._
33-
import reporting.diagnostic.Message
34-
import reporting.diagnostic.messages._
33+
import reporting.Message
34+
import reporting.messages._
3535

3636
case class OpInfo(operand: Tree, operator: Ident, offset: Offset)
3737

@@ -131,7 +131,7 @@ object Parsers {
131131
/** Issue an error at given offset if beyond last error offset
132132
* and update lastErrorOffset.
133133
*/
134-
def syntaxError(msg: => Message, offset: Int = in.offset): Unit =
134+
def syntaxError(msg: Message, offset: Int = in.offset): Unit =
135135
if (offset > lastErrorOffset) {
136136
val length = if (offset == in.offset && in.name != null) in.name.show.length else 0
137137
syntaxError(msg, Span(offset, offset + length))
@@ -141,7 +141,7 @@ object Parsers {
141141
/** Unconditionally issue an error at given span, without
142142
* updating lastErrorOffset.
143143
*/
144-
def syntaxError(msg: => Message, span: Span): Unit =
144+
def syntaxError(msg: Message, span: Span): Unit =
145145
ctx.error(msg, source.atSpan(span))
146146

147147
def unimplementedExpr(implicit ctx: Context): Select =
@@ -308,23 +308,23 @@ object Parsers {
308308
}
309309
}
310310

311-
def warning(msg: => Message, sourcePos: SourcePosition): Unit =
311+
def warning(msg: Message, sourcePos: SourcePosition): Unit =
312312
ctx.warning(msg, sourcePos)
313313

314-
def warning(msg: => Message, offset: Int = in.offset): Unit =
314+
def warning(msg: Message, offset: Int = in.offset): Unit =
315315
ctx.warning(msg, source.atSpan(Span(offset)))
316316

317-
def deprecationWarning(msg: => Message, offset: Int = in.offset): Unit =
317+
def deprecationWarning(msg: Message, offset: Int = in.offset): Unit =
318318
ctx.deprecationWarning(msg, source.atSpan(Span(offset)))
319319

320320
/** Issue an error at current offset that input is incomplete */
321-
def incompleteInputError(msg: => Message): Unit =
321+
def incompleteInputError(msg: Message): Unit =
322322
ctx.incompleteInputError(msg, source.atSpan(Span(in.offset)))
323323

324324
/** If at end of file, issue an incompleteInputError.
325325
* Otherwise issue a syntax error and skip to next safe point.
326326
*/
327-
def syntaxErrorOrIncomplete(msg: => Message, offset: Int = in.offset): Unit =
327+
def syntaxErrorOrIncomplete(msg: Message, offset: Int = in.offset): Unit =
328328
if (in.token == EOF) incompleteInputError(msg)
329329
else {
330330
syntaxError(msg, offset)

compiler/src/dotty/tools/dotc/printing/Formatting.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Texts._, Types._, Flags._, Symbols._, Contexts._
66
import collection.mutable
77
import Decorators._
88
import scala.util.control.NonFatal
9-
import reporting.diagnostic.MessageContainer
9+
import reporting.Message
1010
import util.DiffUtil
1111
import Highlighting._
1212

@@ -88,7 +88,7 @@ object Formatting {
8888
}
8989

9090
private def wrapNonSensical(arg: Any, str: String)(implicit ctx: Context): String = {
91-
import MessageContainer._
91+
import Message._
9292
def isSensical(arg: Any): Boolean = arg match {
9393
case tpe: Type =>
9494
tpe.exists && !tpe.isErroneous

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
170170
(" <: " ~ toText(bound) provided !bound.isAny)
171171
}.close
172172
case tp: ErrorType =>
173-
s"<error ${tp.msg.msg}>"
173+
s"<error ${tp.msg.rawMessage}>"
174174
case tp: WildcardType =>
175175
if (tp.optBounds.exists) "<?" ~ toTextRHS(tp.bounds) ~ ">" else "<?>"
176176
case NoType =>

compiler/src/dotty/tools/dotc/reporting/ConsoleReporter.scala

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ package reporting
44

55
import core.Contexts._
66
import java.io.{ BufferedReader, PrintWriter }
7-
import diagnostic.MessageContainer
8-
import diagnostic.messages.{ Error, ConditionalWarning }
7+
import Diagnostic.{ Error, ConditionalWarning }
98

109
/**
1110
* This class implements a Reporter that displays messages on a text console
@@ -15,28 +14,28 @@ class ConsoleReporter(
1514
writer: PrintWriter = new PrintWriter(Console.err, true)
1615
) extends AbstractReporter {
1716

18-
import MessageContainer._
17+
import Diagnostic._
1918

2019
/** Prints the message. */
2120
def printMessage(msg: String): Unit = { writer.print(msg + "\n"); writer.flush() }
2221

2322
/** Prints the message with the given position indication. */
24-
def doReport(m: MessageContainer)(implicit ctx: Context): Unit = {
25-
val didPrint = m match {
26-
case m: Error =>
27-
printMessage(messageAndPos(m.contained, m.pos, diagnosticLevel(m)))
23+
def doReport(dia: Diagnostic)(implicit ctx: Context): Unit = {
24+
val didPrint = dia match {
25+
case dia: Error =>
26+
printMessage(messageAndPos(dia.msg, dia.pos, diagnosticLevel(dia)))
2827
if (ctx.settings.Xprompt.value) Reporter.displayPrompt(reader, writer)
2928
true
30-
case m: ConditionalWarning if !m.enablingOption.value =>
29+
case dia: ConditionalWarning if !dia.enablingOption.value =>
3130
false
32-
case m =>
33-
printMessage(messageAndPos(m.contained, m.pos, diagnosticLevel(m)))
31+
case dia =>
32+
printMessage(messageAndPos(dia.msg, dia.pos, diagnosticLevel(dia)))
3433
true
3534
}
3635

37-
if (didPrint && ctx.shouldExplain(m))
38-
printMessage(explanation(m.contained))
39-
else if (didPrint && m.contained.explanation.nonEmpty)
36+
if (didPrint && shouldExplain(dia))
37+
printMessage(explanation(dia.msg))
38+
else if (didPrint && dia.msg.explanation.nonEmpty)
4039
printMessage("\nlonger explanation available when compiling with `-explain`")
4140
}
4241

0 commit comments

Comments
 (0)