From c73a7f63c77077ff02f65ab18a4deab83c2f353d Mon Sep 17 00:00:00 2001 From: Solal Pirelli Date: Thu, 8 Jan 2026 09:49:58 +0100 Subject: [PATCH 01/12] Delete dead code --- .../src/dotty/tools/MainGenericCompiler.scala | 38 ------------------- compiler/src/dotty/tools/package.scala | 9 +---- 2 files changed, 1 insertion(+), 46 deletions(-) diff --git a/compiler/src/dotty/tools/MainGenericCompiler.scala b/compiler/src/dotty/tools/MainGenericCompiler.scala index 98b1b31f06a5..c43428dc0e7b 100644 --- a/compiler/src/dotty/tools/MainGenericCompiler.scala +++ b/compiler/src/dotty/tools/MainGenericCompiler.scala @@ -4,14 +4,7 @@ import scala.annotation.tailrec import scala.io.Source import scala.util.Try import java.io.File -import java.lang.Thread import scala.annotation.internal.sharable -import dotty.tools.dotc.util.ClasspathFromClassloader -import dotty.tools.dotc.config.Properties.envOrNone -import dotty.tools.io.Jar -import java.nio.file.Paths -import dotty.tools.dotc.config.CommandLineParser -import dotty.tools.scripting.StringDriver enum CompileMode: case Guess @@ -21,19 +14,14 @@ enum CompileMode: case Script case class CompileSettings( - verbose: Boolean = false, classPath: List[String] = List.empty, compileMode: CompileMode = CompileMode.Guess, exitCode: Int = 0, - javaArgs: List[String] = List.empty, javaProps: List[(String, String)] = List.empty, scalaArgs: List[String] = List.empty, residualArgs: List[String] = List.empty, scriptArgs: List[String] = List.empty, targetScript: String = "", - compiler: Boolean = false, - quiet: Boolean = false, - colors: Boolean = false, ) { def withCompileMode(em: CompileMode): CompileSettings = this.compileMode match case CompileMode.Guess => @@ -46,9 +34,6 @@ case class CompileSettings( def withScalaArgs(args: String*): CompileSettings = this.copy(scalaArgs = scalaArgs.appendedAll(args.toList.filter(_.nonEmpty))) - def withJavaArgs(args: String*): CompileSettings = - this.copy(javaArgs = javaArgs.appendedAll(args.toList.filter(_.nonEmpty))) - def withJavaProps(args: (String, String)*): CompileSettings = this.copy(javaProps = javaProps.appendedAll(args.toList)) @@ -65,18 +50,6 @@ case class CompileSettings( println(s"not found $file") this.copy(exitCode = 2) end withTargetScript - - def withCompiler: CompileSettings = - this.copy(compiler = true) - - def withQuiet: CompileSettings = - this.copy(quiet = true) - - def withColors: CompileSettings = - this.copy(colors = true) - - def withNoColors: CompileSettings = - this.copy(colors = false) } object MainGenericCompiler { @@ -97,7 +70,6 @@ object MainGenericCompiler { else (tail, cpEntries) - @sharable val javaOption = raw"""-J(.*)""".r @sharable val javaPropOption = raw"""-D(.+?)=(.?)""".r @tailrec def process(args: List[String], settings: CompileSettings): CompileSettings = args match @@ -107,8 +79,6 @@ object MainGenericCompiler { process(Nil, settings.withResidualArgs(tail.toList*)) case ("-v" | "-verbose" | "--verbose") :: tail => process(tail, settings.withScalaArgs("-verbose")) - case ("-q" | "-quiet") :: tail => - process(tail, settings.withQuiet) case "-script" :: targetScript :: tail => process(Nil, settings .withCompileMode(CompileMode.Script) @@ -121,12 +91,6 @@ object MainGenericCompiler { process(tail, settings.withCompileMode(CompileMode.Decompile)) case "-print-tasty" :: tail => process(tail, settings.withCompileMode(CompileMode.PrintTasty)) - case "-colors" :: tail => - process(tail, settings.withColors) - case "-no-colors" :: tail => - process(tail, settings.withNoColors) - case "-with-compiler" :: tail => - process(tail, settings.withCompiler) case ("-cp" | "-classpath" | "--class-path") :: cp :: tail => val (tailargs, newEntries) = processClasspath(cp, tail) process(tailargs, settings.copy(classPath = settings.classPath ++ newEntries.filter(_.nonEmpty))) @@ -136,8 +100,6 @@ object MainGenericCompiler { val tStopAtLvl="-XX:TieredStopAtLevel=1" println(s"ignoring deprecated -Oshort flag, please add `-J$addTC` and `-J$tStopAtLvl` flags manually") process(tail, settings) - case javaOption(stripped: String) :: tail => - process(tail, settings.withJavaArgs(stripped)) case javaPropOption(opt: String, value: String) :: tail => process(tail, settings.withJavaProps(opt -> value)) case arg :: tail => diff --git a/compiler/src/dotty/tools/package.scala b/compiler/src/dotty/tools/package.scala index 0da6e66fd824..098e9d637cb3 100644 --- a/compiler/src/dotty/tools/package.scala +++ b/compiler/src/dotty/tools/package.scala @@ -29,14 +29,7 @@ package object tools { def unreachable(x: Any = "<< this case was declared unreachable >>"): Nothing = throw new MatchError(x) - - transparent inline def assertShort(inline assertion: Boolean, inline message: Any = null): Unit = - if !assertion then - val msg = message - val e = if msg == null then AssertionError() else AssertionError("assertion failed: " + msg) - e.setStackTrace(Array()) - throw e - + // Ensure this object is already classloaded, since it's only actually used // when handling stack overflows and every operation (including class loading) // risks failing. From bc581c44d454d0fc25f8129ef647a9e0c749ffed Mon Sep 17 00:00:00 2001 From: Solal Pirelli Date: Thu, 8 Jan 2026 10:01:27 +0100 Subject: [PATCH 02/12] Cleanup --- .../src/dotty/tools/MainGenericCompiler.scala | 57 +++++++------------ .../tools/debug/ExpressionCompiler.scala | 2 +- .../dotty/tools/debug/ExtractExpression.scala | 2 +- .../dotty/tools/debug/InsertExpression.scala | 1 - .../tools/debug/ResolveReflectEval.scala | 1 - .../dotty/tools/dotc/CompilationUnit.scala | 1 - compiler/src/dotty/tools/dotc/Driver.scala | 1 - compiler/src/dotty/tools/dotc/Resident.scala | 2 +- .../src/dotty/tools/dotc/ast/Desugar.scala | 4 +- compiler/src/dotty/tools/dotc/ast/Trees.scala | 4 +- .../src/dotty/tools/dotc/cc/Capability.scala | 18 +++--- compiler/src/dotty/tools/dotc/cc/Setup.scala | 2 +- .../src/dotty/tools/dotc/cc/ccConfig.scala | 2 +- .../dotty/tools/dotc/core/SymbolLoaders.scala | 3 +- .../dotc/core/tasty/TastyUnpickler.scala | 1 - .../tools/dotc/coverage/Serializer.scala | 2 +- .../tools/dotc/parsing/JavaParsers.scala | 2 +- .../dotc/parsing/xml/SymbolicXMLBuilder.scala | 2 +- .../dotty/tools/dotc/plugins/Plugins.scala | 4 +- .../tools/dotc/printing/Formatting.scala | 2 - .../dotc/transform/UnrollDefinitions.scala | 6 +- .../src/dotty/tools/dotc/typer/Typer.scala | 2 +- .../src/dotty/tools/dotc/util/IntMap.scala | 2 +- compiler/src/dotty/tools/package.scala | 20 ++++--- .../tools/scripting/ScriptingDriver.scala | 6 +- compiler/src/dotty/tools/scripting/Util.scala | 4 +- 26 files changed, 62 insertions(+), 91 deletions(-) diff --git a/compiler/src/dotty/tools/MainGenericCompiler.scala b/compiler/src/dotty/tools/MainGenericCompiler.scala index c43428dc0e7b..de4682ab4380 100644 --- a/compiler/src/dotty/tools/MainGenericCompiler.scala +++ b/compiler/src/dotty/tools/MainGenericCompiler.scala @@ -2,9 +2,8 @@ package dotty.tools import scala.annotation.tailrec import scala.io.Source -import scala.util.Try +import scala.util.{Try, Success, Failure} import java.io.File -import scala.annotation.internal.sharable enum CompileMode: case Guess @@ -44,9 +43,9 @@ case class CompileSettings( this.copy(scriptArgs = scriptArgs.appendedAll(args.toList.filter(_.nonEmpty))) def withTargetScript(file: String): CompileSettings = - Try(Source.fromFile(file)).toOption match - case Some(_) => this.copy(targetScript = file) - case None => + Try(Source.fromFile(file)) match + case Success(_) => this.copy(targetScript = file) + case Failure(_) => println(s"not found $file") this.copy(exitCode = 2) end withTargetScript @@ -54,29 +53,29 @@ case class CompileSettings( object MainGenericCompiler { - val classpathSeparator: String = File.pathSeparator + private val classpathSeparator: String = File.pathSeparator + private val javaPropOption = raw"""-D(.+?)=(.?)""".r - def processClasspath(cp: String, tail: List[String]): (List[String], List[String]) = + private def processClasspath(cp: String, tail: List[String]): (List[String], List[String]) = val cpEntries = cp.split(classpathSeparator).toList val singleEntryClasspath: Boolean = cpEntries.take(2).size == 1 - val globdir: String = if singleEntryClasspath then cp.replaceAll("[\\\\/][^\\\\/]*$", "") else "" // slash/backslash agnostic - def validGlobbedJar(s: String): Boolean = s.startsWith(globdir) && ((s.toLowerCase.endsWith(".jar") || s.toLowerCase.endsWith(".zip"))) + val globDir: String = if singleEntryClasspath then cp.replaceAll("[\\\\/][^\\\\/]*$", "") else "" // slash/backslash agnostic + def validGlobbedJar(s: String): Boolean = s.startsWith(globDir) && (s.toLowerCase.endsWith(".jar") || s.toLowerCase.endsWith(".zip")) if singleEntryClasspath && validGlobbedJar(cpEntries.head) then // reassemble globbed wildcard classpath - // globdir is wildcard directory for globbed jar files, reconstruct the intended classpath - val cpJars = tail.takeWhile( f => validGlobbedJar(f) ) + // globDir is wildcard directory for globbed jar files, reconstruct the intended classpath + val cpJars = tail.takeWhile(validGlobbedJar) val remainingArgs = tail.drop(cpJars.size) (remainingArgs, cpEntries ++ cpJars) else (tail, cpEntries) - @sharable val javaPropOption = raw"""-D(.+?)=(.?)""".r @tailrec def process(args: List[String], settings: CompileSettings): CompileSettings = args match case Nil => settings case "--" :: tail => - process(Nil, settings.withResidualArgs(tail.toList*)) + settings.withResidualArgs(tail*) case ("-v" | "-verbose" | "--verbose") :: tail => process(tail, settings.withScalaArgs("-verbose")) case "-script" :: targetScript :: tail => @@ -92,8 +91,8 @@ object MainGenericCompiler { case "-print-tasty" :: tail => process(tail, settings.withCompileMode(CompileMode.PrintTasty)) case ("-cp" | "-classpath" | "--class-path") :: cp :: tail => - val (tailargs, newEntries) = processClasspath(cp, tail) - process(tailargs, settings.copy(classPath = settings.classPath ++ newEntries.filter(_.nonEmpty))) + val (tailArgs, newEntries) = processClasspath(cp, tail) + process(tailArgs, settings.copy(classPath = settings.classPath ++ newEntries.filter(_.nonEmpty))) case "-Oshort" :: tail => // Nothing is to be done here. Request that the user adds the relevant flags manually. val addTC="-XX:+TieredCompilation" @@ -110,40 +109,26 @@ object MainGenericCompiler { val settings = process(args.toList, CompileSettings()) if settings.exitCode != 0 then System.exit(settings.exitCode) - def classpathSetting = + val classpathSetting = if settings.classPath.isEmpty then List() else List("-classpath", settings.classPath.mkString(classpathSeparator)) - def reconstructedArgs() = - classpathSetting ++ settings.scalaArgs ++ settings.residualArgs + val properArgs = classpathSetting ++ settings.scalaArgs ++ settings.residualArgs - def addJavaProps(): Unit = - settings.javaProps.foreach { (k, v) => sys.props(k) = v } + settings.javaProps.foreach { (k, v) => sys.props(k) = v } - def run(settings: CompileSettings): Unit = settings.compileMode match - case CompileMode.Compile => - addJavaProps() - val properArgs = reconstructedArgs() + settings.compileMode match + case CompileMode.Guess | CompileMode.Compile => dotty.tools.dotc.Main.main(properArgs.toArray) case CompileMode.Decompile => - addJavaProps() - val properArgs = reconstructedArgs() dotty.tools.dotc.decompiler.Main.main(properArgs.toArray) case CompileMode.PrintTasty => - addJavaProps() - val properArgs = reconstructedArgs() dotty.tools.dotc.core.tasty.TastyPrinter.main(properArgs.toArray) case CompileMode.Script => // Naive copy from scalac bash script - addJavaProps() - val properArgs = - reconstructedArgs() + val fullArgs = + properArgs ++ List("-script", settings.targetScript) ++ settings.scriptArgs scripting.Main.main(properArgs.toArray) - case CompileMode.Guess => - run(settings.withCompileMode(CompileMode.Compile)) - end run - - run(settings) end main } diff --git a/compiler/src/dotty/tools/debug/ExpressionCompiler.scala b/compiler/src/dotty/tools/debug/ExpressionCompiler.scala index 83c20b0f54a7..9931aa94270c 100644 --- a/compiler/src/dotty/tools/debug/ExpressionCompiler.scala +++ b/compiler/src/dotty/tools/debug/ExpressionCompiler.scala @@ -14,7 +14,7 @@ import dotty.tools.dotc.transform.ElimByName * To do so, it extends the Compiler with 3 phases: * - InsertExpression: parses and inserts the expression in the original source tree * - ExtractExpression: extract the typed expression and places it in the new expression class - * - ResolveReflectEval: resolves local variables or inacessible members using reflection calls + * - ResolveReflectEval: resolves local variables or inaccessible members using reflection calls */ class ExpressionCompiler(config: ExpressionCompilerConfig) extends Compiler: diff --git a/compiler/src/dotty/tools/debug/ExtractExpression.scala b/compiler/src/dotty/tools/debug/ExtractExpression.scala index 151d75270c6e..68e35f7f17dc 100644 --- a/compiler/src/dotty/tools/debug/ExtractExpression.scala +++ b/compiler/src/dotty/tools/debug/ExtractExpression.scala @@ -18,7 +18,7 @@ import dotty.tools.dotc.util.SrcPos import scala.annotation.nowarn /** - * This phase extracts the typed expression from the source tree, transfoms it and places it + * This phase extracts the typed expression from the source tree, transforms it and places it * in the evaluate method of the Expression class. * * Before: diff --git a/compiler/src/dotty/tools/debug/InsertExpression.scala b/compiler/src/dotty/tools/debug/InsertExpression.scala index 17d2d7f6ea92..520b2cb9080a 100644 --- a/compiler/src/dotty/tools/debug/InsertExpression.scala +++ b/compiler/src/dotty/tools/debug/InsertExpression.scala @@ -7,7 +7,6 @@ import dotty.tools.dotc.core.Names.* import dotty.tools.dotc.core.Phases.Phase import dotty.tools.dotc.parsing.Parsers import dotty.tools.dotc.report -import dotty.tools.dotc.transform.MegaPhase.MiniPhase import dotty.tools.dotc.util.NoSourcePosition import dotty.tools.dotc.util.SourceFile import dotty.tools.dotc.util.SourcePosition diff --git a/compiler/src/dotty/tools/debug/ResolveReflectEval.scala b/compiler/src/dotty/tools/debug/ResolveReflectEval.scala index f79aa462fcb4..318fc4112e37 100644 --- a/compiler/src/dotty/tools/debug/ResolveReflectEval.scala +++ b/compiler/src/dotty/tools/debug/ResolveReflectEval.scala @@ -1,6 +1,5 @@ package dotty.tools.debug -import dotty.tools.dotc.core.SymUtils import dotty.tools.dotc.ast.tpd.* import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts.* diff --git a/compiler/src/dotty/tools/dotc/CompilationUnit.scala b/compiler/src/dotty/tools/dotc/CompilationUnit.scala index b627e149e5fb..33143a162169 100644 --- a/compiler/src/dotty/tools/dotc/CompilationUnit.scala +++ b/compiler/src/dotty/tools/dotc/CompilationUnit.scala @@ -14,7 +14,6 @@ import ast.Trees.{Import, Ident} import typer.Nullables import core.Decorators.* import config.{SourceVersion, Feature} -import StdNames.nme import scala.annotation.internal.sharable import scala.util.control.NoStackTrace import transform.MacroAnnotations.isMacroAnnotation diff --git a/compiler/src/dotty/tools/dotc/Driver.scala b/compiler/src/dotty/tools/dotc/Driver.scala index f8daabf3ec5d..2a4feea9ed05 100644 --- a/compiler/src/dotty/tools/dotc/Driver.scala +++ b/compiler/src/dotty/tools/dotc/Driver.scala @@ -9,7 +9,6 @@ import dotty.tools.dotc.ast.Positioned import dotty.tools.io.{AbstractFile, FileExtension} import reporting.* import core.Decorators.* -import config.Feature import util.chaining.* import scala.util.control.NonFatal diff --git a/compiler/src/dotty/tools/dotc/Resident.scala b/compiler/src/dotty/tools/dotc/Resident.scala index 5912825f712e..38343b2a568e 100644 --- a/compiler/src/dotty/tools/dotc/Resident.scala +++ b/compiler/src/dotty/tools/dotc/Resident.scala @@ -52,7 +52,7 @@ class Resident extends Driver { line = getLine() } if line.startsWith(quit) then ctx.reporter - else loop((line.split("\\s+")).asInstanceOf[Array[String]], nextCtx) + else loop(line.split("\\s+"), nextCtx) case None => prevCtx.reporter } diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 8a1ff74a0f13..5e5e1831f8e8 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -745,11 +745,11 @@ object desugar { if (originalVparamss.isEmpty) { // ensure parameter list is non-empty if (isCaseClass) report.error(CaseClassMissingParamList(cdef), namePos) - ListOfNil + List(Nil) } else if (isCaseClass && originalVparamss.head.exists(_.mods.isOneOf(GivenOrImplicit))) { report.error(CaseClassMissingNonImplicitParamList(cdef), namePos) - ListOfNil + List(Nil) } else originalVparamss.nestedMap(toMethParam(_, KeepAnnotations.All, keepDefault = true)) val derivedTparams = diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index 56a58d358b15..50d7a8c643a3 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -1149,7 +1149,7 @@ object Trees { end WithLazyFields - // ----- Generic Tree Instances, inherited from `tpt` and `untpd`. + // ----- Generic Tree Instances, inherited from `tpd` and `untpd`. abstract class Instance[T <: Untyped] { inst => @@ -1259,7 +1259,7 @@ object Trees { protected def postProcess(tree: Tree, copied: untpd.Tree): copied.ThisTree[T] protected def postProcess(tree: Tree, copied: untpd.MemberDef): copied.ThisTree[T] - /** Soucre of the copied tree */ + /** Source of the copied tree */ protected def sourceFile(tree: Tree): SourceFile = tree.source protected def finalize(tree: Tree, copied: untpd.Tree): copied.ThisTree[T] = diff --git a/compiler/src/dotty/tools/dotc/cc/Capability.scala b/compiler/src/dotty/tools/dotc/cc/Capability.scala index 0c2fe68fee23..4dd6220a4709 100644 --- a/compiler/src/dotty/tools/dotc/cc/Capability.scala +++ b/compiler/src/dotty/tools/dotc/cc/Capability.scala @@ -5,21 +5,17 @@ package cc import core.* import Types.*, Symbols.*, Contexts.*, Decorators.* import util.{SimpleIdentitySet, EqHashMap} -import util.common.alwaysTrue -import scala.collection.mutable -import CCState.* import Periods.{NoRunId, RunWidth} import compiletime.uninitialized import StdNames.nme import CaptureSet.{Refs, emptyRefs, VarState} -import Annotations.Annotation import Flags.* import config.Printers.capt import annotation.constructorOnly import ast.tpd import printing.{Printer, Showable} import printing.Texts.Text -import reporting.{Message, trace} +import reporting.Message import NameOps.isImpureFunction import annotation.internal.sharable import collection.immutable @@ -27,9 +23,9 @@ import collection.immutable /** Capabilities are members of capture sets. They partially overlap with types * as shown in the trait hierarchy below. * - * Capability --+-- RootCapabilty -----+-- GlobalCap - * | +-- FreshCap - * | +-- ResultCap + * Capability --+-- RootCapability -----+-- GlobalCap + * | +-- FreshCap + * | +-- ResultCap * | * +-- CoreCapability ----+-- ObjectCapability --+-- TermRef * | | +-- ThisType @@ -60,7 +56,7 @@ object Capabilities: nextRootId += 1 def descr(using Context): String - /** The base trait of all capabilties represented as types */ + /** The base trait of all capabilities represented as types */ trait CoreCapability extends TypeProxy, Capability: override def toText(printer: Printer): Text = printer.toText(this) @@ -140,7 +136,7 @@ object Capabilities: override def cached[C <: DerivedCapability](newRef: C): C = unsupported("cached") override def invalidateCaches() = () - /** The class of "fresh" roots. These do subsume other capabilties in scope. + /** The class of "fresh" roots. These do subsume other capabilities in scope. * They track with hidden sets which other capabilities were subsumed. * Hidden sets are inspected by separation checking. * @param owner the owner of the context in which the FreshCap was created @@ -198,7 +194,7 @@ object Capabilities: case _ => true /** Classify this FreshCap as `cls`, provided `isClassified` is still false. - * @param freeze Deterermines future `isClassified` state. + * @param freeze Determines future `isClassified` state. */ def adoptClassifier(cls: ClassSymbol, freeze: Boolean)(using Context): Unit = if !isClassified then diff --git a/compiler/src/dotty/tools/dotc/cc/Setup.scala b/compiler/src/dotty/tools/dotc/cc/Setup.scala index 7e5050b758fc..3204504c0650 100644 --- a/compiler/src/dotty/tools/dotc/cc/Setup.scala +++ b/compiler/src/dotty/tools/dotc/cc/Setup.scala @@ -87,7 +87,7 @@ object Setup: end Setup import Setup.* -/** Phase that sets up everthing for capture checking. +/** Phase that sets up everything for capture checking. * * A tree traverser that prepares a compilation unit to be capture checked. * It does the following: diff --git a/compiler/src/dotty/tools/dotc/cc/ccConfig.scala b/compiler/src/dotty/tools/dotc/cc/ccConfig.scala index e7d07f4f91eb..120b0cee82b8 100644 --- a/compiler/src/dotty/tools/dotc/cc/ccConfig.scala +++ b/compiler/src/dotty/tools/dotc/cc/ccConfig.scala @@ -7,7 +7,7 @@ import config.{Feature, SourceVersion} object ccConfig: - /** If enabled, cache capture sets of infos capabilties */ + /** If enabled, cache capture sets of infos capabilities */ inline val cacheCaptureSetOfInfo = false /** If this and `preTypeClosureResults` are both enabled, disable `preTypeClosureResults` diff --git a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala index c3337959cef6..3a639963659d 100644 --- a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -25,8 +25,7 @@ import ast.desugar import parsing.JavaParsers.OutlineJavaParser import parsing.Parsers.OutlineParser -import dotty.tools.tasty.{TastyHeaderUnpickler, UnpickleException, UnpicklerConfig, TastyVersion} -import dotty.tools.dotc.core.tasty.TastyUnpickler +import dotty.tools.tasty.UnpickleException import dotty.tools.tasty.besteffort.BestEffortTastyHeaderUnpickler object SymbolLoaders { diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala index 6ce27b8b77af..61a10491d8cc 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala @@ -13,7 +13,6 @@ import scala.collection.mutable import Names.{TermName, termName, EmptyTermName} import NameKinds.* import dotty.tools.tasty.TastyHeader -import dotty.tools.tasty.TastyBuffer.Addr case class CommonTastyHeader( uuid: UUID, diff --git a/compiler/src/dotty/tools/dotc/coverage/Serializer.scala b/compiler/src/dotty/tools/dotc/coverage/Serializer.scala index 21d3a83cb3a0..84392991aef3 100644 --- a/compiler/src/dotty/tools/dotc/coverage/Serializer.scala +++ b/compiler/src/dotty/tools/dotc/coverage/Serializer.scala @@ -142,7 +142,7 @@ object Serializer: val linesWithoutHeader = lines.dropWhile(_.startsWith("#")) val coverage = Coverage() - while !linesWithoutHeader.isEmpty do + while linesWithoutHeader.nonEmpty do val oneStatementLines = linesWithoutHeader.takeWhile(_ != "\f") coverage.addStatement(toStatement(oneStatementLines)) end while diff --git a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala index c15e6c93bf90..7112402945f2 100644 --- a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala @@ -1014,7 +1014,7 @@ object JavaParsers { val predefs = List( DefDef( nme.values, - ListOfNil, + List(Nil), arrayOf(enumType), unimplementedExpr).withMods(Modifiers(Flags.JavaDefined | Flags.JavaStatic | Flags.Method)), DefDef( diff --git a/compiler/src/dotty/tools/dotc/parsing/xml/SymbolicXMLBuilder.scala b/compiler/src/dotty/tools/dotc/parsing/xml/SymbolicXMLBuilder.scala index aa8532b1d969..79162c47b887 100644 --- a/compiler/src/dotty/tools/dotc/parsing/xml/SymbolicXMLBuilder.scala +++ b/compiler/src/dotty/tools/dotc/parsing/xml/SymbolicXMLBuilder.scala @@ -163,7 +163,7 @@ class SymbolicXMLBuilder(parser: Parser, preserveWS: Boolean)(using Context) { /** could optimize if args.length == 0, args.length == 1 AND args(0) is <: Node. */ def makeXMLseq(span: Span, args: collection.Seq[Tree]): Block = { - val buffer = ValDef(_buf, TypeTree(), New(_scala_xml_NodeBuffer, ListOfNil)) + val buffer = ValDef(_buf, TypeTree(), New(_scala_xml_NodeBuffer, List(Nil))) val applies = args filterNot isEmptyText map (t => Apply(Select(Ident(_buf), _plus), List(t))) atSpan(span)(new XMLBlock(buffer :: applies.toList, Ident(_buf)) ) diff --git a/compiler/src/dotty/tools/dotc/plugins/Plugins.scala b/compiler/src/dotty/tools/dotc/plugins/Plugins.scala index 6c162184f816..04d12a670f2b 100644 --- a/compiler/src/dotty/tools/dotc/plugins/Plugins.scala +++ b/compiler/src/dotty/tools/dotc/plugins/Plugins.scala @@ -4,14 +4,12 @@ package plugins import core.* import Contexts.* import Decorators.em -import config.{ PathResolver, Feature } +import config.PathResolver import dotty.tools.io.* import Phases.* import config.Printers.plugins.{ println => debug } import config.Properties -import scala.compiletime.uninitialized - /** Support for run-time loading of compiler plugins. * * @author Lex Spoon diff --git a/compiler/src/dotty/tools/dotc/printing/Formatting.scala b/compiler/src/dotty/tools/dotc/printing/Formatting.scala index daf4e70ad25a..1a8e61c32aeb 100644 --- a/compiler/src/dotty/tools/dotc/printing/Formatting.scala +++ b/compiler/src/dotty/tools/dotc/printing/Formatting.scala @@ -2,8 +2,6 @@ package dotty.tools package dotc package printing -import scala.collection.mutable - import core.* import Texts.*, Types.*, Flags.*, Symbols.*, Contexts.* import Decorators.* diff --git a/compiler/src/dotty/tools/dotc/transform/UnrollDefinitions.scala b/compiler/src/dotty/tools/dotc/transform/UnrollDefinitions.scala index bf9e20e68930..7c5c260402b9 100644 --- a/compiler/src/dotty/tools/dotc/transform/UnrollDefinitions.scala +++ b/compiler/src/dotty/tools/dotc/transform/UnrollDefinitions.scala @@ -5,7 +5,6 @@ import ast.tpd import ast.Trees.* import core.* import Flags.* -import Decorators.* import Contexts.* import Symbols.* import Constants.Constant @@ -14,15 +13,12 @@ import DenotTransformers.IdentityDenotTransformer import Names.* import dotty.tools.dotc.core.NameKinds.DefaultGetterName -import dotty.tools.dotc.core.Types.{MethodType, NamedType, PolyType, Type, NoPrefix, NoType} +import dotty.tools.dotc.core.Types.{NoPrefix, NoType} import dotty.tools.dotc.printing.Formatting.hl -import scala.collection.mutable -import scala.util.boundary, boundary.break import dotty.tools.dotc.core.StdNames.nme import dotty.tools.unreachable -import dotty.tools.dotc.util.Spans.Span /**Implementation of SIP-61. * Runs when `@unroll` annotations are found in a compilation unit, installing new definitions diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index dfa667573405..daf056eabe95 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -4387,7 +4387,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer alts.filter(_.info.isParameterless) match case alt :: Nil => readaptSimplified(tree.withType(alt)) case _ => - altDenots.find(_.info.paramInfoss == ListOfNil) match + altDenots.find(_.info.paramInfoss == List(Nil)) match case Some(alt) => readaptSimplified(tree.withType(altRef(alt))) case _ => error diff --git a/compiler/src/dotty/tools/dotc/util/IntMap.scala b/compiler/src/dotty/tools/dotc/util/IntMap.scala index 1d04567e99c7..896dd42c1e81 100644 --- a/compiler/src/dotty/tools/dotc/util/IntMap.scala +++ b/compiler/src/dotty/tools/dotc/util/IntMap.scala @@ -2,7 +2,7 @@ package dotty.tools.dotc.util import scala.compiletime.uninitialized -/** A dense map from some `Key` type to `Int. Dense means: All keys and values +/** A dense map from some `Key` type to `Int`. Dense means: All keys and values * are stored in arrays from 0 up to the size of the map. Keys and values * can be obtained by index using `key(index)` and `value(index)`. Values * can also be stored using `setValue(index, value)`. diff --git a/compiler/src/dotty/tools/package.scala b/compiler/src/dotty/tools/package.scala index 098e9d637cb3..bf1aad806c9c 100644 --- a/compiler/src/dotty/tools/package.scala +++ b/compiler/src/dotty/tools/package.scala @@ -2,12 +2,14 @@ package dotty package object tools { - val ListOfNil: List[Nil.type] = Nil :: Nil - /** Throws an `UnsupportedOperationException` with the given method name. */ def unsupported(methodName: String): Nothing = throw new UnsupportedOperationException(methodName) + /** Throws a `MatchError` with the given argument, or a default "unreachable" message. */ + def unreachable(x: Any = "<< this case was declared unreachable >>"): Nothing = + throw new MatchError(x) + /** Forward-ported from the explicit-nulls branch. */ extension [T](x: T | Null) /** Should be used when we know from the context that `x` is not null. @@ -15,21 +17,23 @@ package object tools { * occurrences of uncheckedNN. */ transparent inline def uncheckedNN: T = x.asInstanceOf[T] - end extension - object resultWrapper { + /** + * Infrastructure to shorten method calls by not requiring a lambda. + * Instead of `def f(x: ... => ...)` that must be called as, e.g., `f(x => x + 1)`, + * write `def f(x: WrappedResult[...] ?=> ...)`, use that parameter by creating a `WrappedResult`, + * and call `f(result + 1)`. + */ + private object resultWrapper { opaque type WrappedResult[T] = T private[tools] def unwrap[T](x: WrappedResult[T]): T = x private[tools] def wrap[T](x: T): WrappedResult[T] = x } type WrappedResult[T] = resultWrapper.WrappedResult[T] - def WrappedResult[T](x: T) = resultWrapper.wrap(x) + def WrappedResult[T](x: T): WrappedResult[T] = resultWrapper.wrap(x) def result[T](using x: WrappedResult[T]): T = resultWrapper.unwrap(x) - def unreachable(x: Any = "<< this case was declared unreachable >>"): Nothing = - throw new MatchError(x) - // Ensure this object is already classloaded, since it's only actually used // when handling stack overflows and every operation (including class loading) // risks failing. diff --git a/compiler/src/dotty/tools/scripting/ScriptingDriver.scala b/compiler/src/dotty/tools/scripting/ScriptingDriver.scala index e4c357494ff1..3750d0fdff9f 100755 --- a/compiler/src/dotty/tools/scripting/ScriptingDriver.scala +++ b/compiler/src/dotty/tools/scripting/ScriptingDriver.scala @@ -27,9 +27,9 @@ class ScriptingDriver(compilerArgs: Array[String], scriptFile: File, scriptArgs: val classpathEntries: Seq[Path] = ClassPath.expandPath(classpath, expandStar=true).map { Paths.get(_) } detectMainClassAndMethod(outDir, classpathEntries, scriptFile.toString) match case Right((mainClass, mainMethod)) => - val invokeMain: Boolean = Option(pack).map { func => - func(outDir, classpathEntries, mainClass) - }.getOrElse(true) + val invokeMain: Boolean = Option(pack).forall { func => + func(outDir, classpathEntries, mainClass) + } if invokeMain then mainMethod.invoke(null, scriptArgs) None case Left(ex) => Some(ex) diff --git a/compiler/src/dotty/tools/scripting/Util.scala b/compiler/src/dotty/tools/scripting/Util.scala index 5ce71aa7c130..b31e252c568a 100755 --- a/compiler/src/dotty/tools/scripting/Util.scala +++ b/compiler/src/dotty/tools/scripting/Util.scala @@ -1,8 +1,8 @@ package dotty.tools.scripting -import java.nio.file.{ Path } +import java.nio.file.Path import java.io.File -import java.net.{ URLClassLoader } +import java.net.URLClassLoader import java.lang.reflect.{ Modifier, Method } object Util: From 82aa1b1fdcdc19bceaa112872f2f1eee67d9a3e9 Mon Sep 17 00:00:00 2001 From: Solal Pirelli Date: Thu, 8 Jan 2026 11:21:43 +0100 Subject: [PATCH 03/12] Remove file disabled for 11+ years --- .../tools/dotc/ast/CheckTrees.scala.disabled | 258 ------------------ 1 file changed, 258 deletions(-) delete mode 100644 compiler/src/dotty/tools/dotc/ast/CheckTrees.scala.disabled diff --git a/compiler/src/dotty/tools/dotc/ast/CheckTrees.scala.disabled b/compiler/src/dotty/tools/dotc/ast/CheckTrees.scala.disabled deleted file mode 100644 index 08d409772331..000000000000 --- a/compiler/src/dotty/tools/dotc/ast/CheckTrees.scala.disabled +++ /dev/null @@ -1,258 +0,0 @@ -package dotty.tools -package dotc -package ast - -import core.* -import util.Spans.*, Types.*, Contexts.*, Constants.*, Names.*, Flags.* -import SymDenotations.*, Symbols.*, StdNames.*, Annotations.*, Trees.* - -// TODO: revise, integrate in a checking phase. -object CheckTrees { - - import tpd.* - - def check(p: Boolean, msg: => String = "")(using Context): Unit = assert(p, msg) - - def checkTypeArg(arg: Tree, bounds: TypeBounds)(using Context): Unit = { - check(arg.isValueType) - check(bounds contains arg.tpe) - } - - def escapingRefs(block: Block)(using Context): collection.Set[NamedType] = { - var hoisted: Set[Symbol] = Set() - lazy val locals = ctx.typeAssigner.localSyms(block.stats).toSet - def isLocal(sym: Symbol): Boolean = - (locals contains sym) && !isHoistableClass(sym) - def isHoistableClass(sym: Symbol) = - sym.isClass && { - (hoisted contains sym) || { - hoisted += sym - !classLeaks(sym.asClass) - } - } - def leakingTypes(tp: Type): collection.Set[NamedType] = - tp namedPartsWith (tp => isLocal(tp.symbol)) - def typeLeaks(tp: Type): Boolean = leakingTypes(tp).nonEmpty - def classLeaks(sym: ClassSymbol): Boolean = - (ctx.owner is Method) || // can't hoist classes out of method bodies - (sym.info.parents exists typeLeaks) || - (sym.decls.toList exists (t => typeLeaks(t.info))) - leakingTypes(block.tpe) - } - - def checkType(tree: Tree)(using Context): Unit = tree match { - case Ident(name) => - case Select(qualifier, name) => - check(qualifier.isValue) - check(qualifier.tpe =:= tree.tpe.normalizedPrefix) - val denot = qualifier.tpe.member(name) - check(denot.exists) - check(denot.hasAltWith(_.symbol == tree.symbol)) - case This(cls) => - case Super(qual, mixin) => - check(qual.isValue) - val cls = qual.tpe.typeSymbol - check(cls.isClass) - case Apply(fn, args) => - def checkArg(arg: Tree, name: Name, formal: Type): Unit = { - arg match { - case NamedArg(argName, _) => - check(argName == name) - case _ => - check(arg.isValue) - } - check(arg.tpe <:< formal) - } - val MethodType(paramNames, paramTypes) = fn.tpe.widen // checked already at construction - args.lazyZip(paramNames).lazyZip(paramTypes) foreach checkArg - case TypeApply(fn, args) => - val pt @ PolyType(_) = fn.tpe.widen // checked already at construction - args.lazyZip(pt.instantiateBounds(args map (_.tpe))) foreach checkTypeArg - case Literal(const: Constant) => - case New(tpt) => - check(tpt.isValueType) - val cls = tpt.tpe.typeSymbol - check(cls.isClass) - check(!(cls is AbstractOrTrait)) - case Pair(left, right) => - check(left.isValue) - check(right.isValue) - case Typed(expr, tpt) => - check(tpt.isValueType) - expr.tpe.widen match { - case tp: MethodType => - val cls = tpt.tpe.typeSymbol - check(cls.isClass) - check((cls is Trait) || - cls.primaryConstructor.info.paramTypess.flatten.isEmpty) - val absMembers = tpt.tpe.abstractTermMembers - check(absMembers.size == 1) - check(tp <:< absMembers.head.info) - case _ => - check(expr.isValueOrPattern) - check(expr.tpe <:< tpt.tpe.translateParameterized(defn.RepeatedParamClass, defn.SeqClass)) - } - case NamedArg(name, arg) => - case Assign(lhs, rhs) => - check(lhs.isValue); check(rhs.isValue) - lhs.tpe match { - case ltpe: TermRef => - check(ltpe.symbol is Mutable) - case _ => - check(false) - } - check(rhs.tpe <:< lhs.tpe.widen) - case tree @ Block(stats, expr) => - check(expr.isValue) - check(escapingRefs(tree).isEmpty) - case If(cond, thenp, elsep) => - check(cond.isValue); check(thenp.isValue); check(elsep.isValue) - check(cond.tpe isRef defn.BooleanClass) - case Closure(env, meth, target) => - meth.tpe.widen match { - case mt @ MethodType(_, paramTypes) => - if (target.isEmpty) { - check(env.length < paramTypes.length) - for ((arg, formal) <- env zip paramTypes) - check(arg.tpe <:< formal) - } - else - // env is stored in class, not method - target.tpe match { - case SAMType(targetMeth) => - check(mt <:< targetMeth.info) - } - } - case Match(selector, cases) => - check(selector.isValue) - // are any checks that relate selector and patterns desirable? - case CaseDef(pat, guard, body) => - check(pat.isValueOrPattern); check(guard.isValue); check(body.isValue) - check(guard.tpe.derivesFrom(defn.BooleanClass)) - case Return(expr, from) => - check(expr.isValue); check(from.isTerm) - check(from.tpe.termSymbol.isRealMethod) - case Try(block, handler, finalizer) => - check(block.isTerm) - check(finalizer.isTerm) - check(handler.isTerm) - check(handler.tpe derivesFrom defn.FunctionClass(1)) - check(handler.tpe.baseArgInfos(defn.FunctionClass(1)).head <:< defn.ThrowableType) - case Throw(expr) => - check(expr.isValue) - check(expr.tpe.derivesFrom(defn.ThrowableClass)) - case SeqLiteral(elems) => - val elemtp = tree.tpe.elemType - for (elem <- elems) { - check(elem.isValue) - check(elem.tpe <:< elemtp) - } - case TypeTree(original) => - if (!original.isEmpty) { - check(original.isValueType) - check(original.tpe == tree.tpe) - } - case SingletonTypeTree(ref) => - check(ref.isValue) - check(ref.symbol.isStable) - case SelectFromTypeTree(qualifier, name) => - check(qualifier.isValueType) - check(qualifier.tpe =:= tree.tpe.normalizedPrefix) - val denot = qualifier.tpe.member(name) - check(denot.exists) - check(denot.symbol == tree.symbol) - case AndTypeTree(left, right) => - check(left.isValueType); check(right.isValueType) - case OrTypeTree(left, right) => - check(left.isValueType); check(right.isValueType) - case RefinedTypeTree(tpt, refinements) => - check(tpt.isValueType) - def checkRefinements(forbidden: Set[Symbol], rs: List[Tree]): Unit = rs match { - case r :: rs1 => - val rsym = r.symbol - check(rsym.isTerm || rsym.isAbstractOrAliasType) - if (rsym.isAbstractType) check(tpt.tpe.member(rsym.name).exists) - check(rsym.info forallParts { - case nt: NamedType => !(forbidden contains nt.symbol) - case _ => true - }) - checkRefinements(forbidden - rsym, rs1) - case nil => - } - checkRefinements(ctx.typeAssigner.localSyms(refinements).toSet, refinements) - case AppliedTypeTree(tpt, args) => - check(tpt.isValueType) - val tparams = tpt.tpe.typeParams - check(sameLength(tparams, args)) - args.lazyZip(tparams map (_.info.bounds)) foreach checkTypeArg - case TypeBoundsTree(lo, hi) => - check(lo.isValueType); check(hi.isValueType) - check(lo.tpe <:< hi.tpe) - case Bind(sym, body) => - check(body.isValueOrPattern) - check(!(tree.symbol is Method)) - body match { - case Ident(nme.WILDCARD) => - case _ => check(body.tpe.widen =:= tree.symbol.info) - } - case Alternative(alts) => - for (alt <- alts) check(alt.isValueOrPattern) - case UnApply(fun, implicits, args) => // todo: review - check(fun.isTerm) - for (arg <- args) check(arg.isValueOrPattern) - val funtpe @ MethodType(_, _) = fun.tpe.widen - fun.symbol.name match { // check arg arity - case nme.unapplySeq => - // args need to be wrapped in (...: _*) - check(args.length == 1) - check(args.head.isInstanceOf[SeqLiteral]) - case nme.unapply => - val rtp = funtpe.resultType - if (rtp isRef defn.BooleanClass) - check(args.isEmpty) - else { - check(rtp isRef defn.OptionClass) - val normArgs = rtp.argTypesHi match { - case optionArg :: Nil => - optionArg.argTypesHi match { - case Nil => - optionArg :: Nil - case tupleArgs if defn.isTupleNType(optionArg) => - tupleArgs - } - case _ => - check(false) - Nil - } - check(sameLength(normArgs, args)) - } - } - case ValDef(mods, name, tpt, rhs) => - check(!(tree.symbol is Method)) - if (!rhs.isEmpty) { - check(rhs.isValue) - check(rhs.tpe <:< tpt.tpe) - } - case DefDef(mods, name, tparams, vparamss, tpt, rhs) => - check(tree.symbol is Method) - if (!rhs.isEmpty) { - check(rhs.isValue) - check(rhs.tpe <:< tpt.tpe) - } - case TypeDef(mods, name, tpt) => - check(tpt.isInstanceOf[Template] || tpt.tpe.isInstanceOf[TypeBounds]) - case Template(constr, parents, selfType, body) => - case Import(expr, selectors) => - check(expr.isValue) - check(expr.tpe.termSymbol.isStable) - case PackageDef(pid, stats) => - check(pid.isTerm) - check(pid.symbol is Package) - case Annotated(annot, arg) => - check(annot.isInstantiation) - check(annot.symbol.owner.isSubClass(defn.AnnotationClass)) - check(arg.isValueType || arg.isValue) - case EmptyTree => - } -} - From 2489cb18162d37f58429fcf2e920da4ece680743 Mon Sep 17 00:00:00 2001 From: Solal Pirelli Date: Thu, 8 Jan 2026 11:48:20 +0100 Subject: [PATCH 04/12] Remove class not used in 7+ years --- compiler/src/dotty/tools/dotc/util/DotClass.scala | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 compiler/src/dotty/tools/dotc/util/DotClass.scala diff --git a/compiler/src/dotty/tools/dotc/util/DotClass.scala b/compiler/src/dotty/tools/dotc/util/DotClass.scala deleted file mode 100644 index f9e7e97a219d..000000000000 --- a/compiler/src/dotty/tools/dotc/util/DotClass.scala +++ /dev/null @@ -1,8 +0,0 @@ -package dotty.tools.dotc.util - -/** Adds standard functionality to a class. - * For now: Just the `unsupported` method. - */ -class DotClass { - -} From 08f38f1c4a9554805b7ac93604dc6b69114b584d Mon Sep 17 00:00:00 2001 From: Solal Pirelli Date: Thu, 8 Jan 2026 11:55:21 +0100 Subject: [PATCH 05/12] Remove 10+ year old near empty worksheet --- compiler/src/dotty/tools/dotc/util/kwords.sc | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 compiler/src/dotty/tools/dotc/util/kwords.sc diff --git a/compiler/src/dotty/tools/dotc/util/kwords.sc b/compiler/src/dotty/tools/dotc/util/kwords.sc deleted file mode 100644 index 377be9dbcb65..000000000000 --- a/compiler/src/dotty/tools/dotc/util/kwords.sc +++ /dev/null @@ -1,18 +0,0 @@ -package dotty.tools.dotc.util - -import dotty.tools.dotc.parsing.* -import Scanners.* -import Tokens.* - -object kwords { - println("Welcome to the Scala worksheet") //> Welcome to the Scala worksheet - keywords.toList.map(tokenString) //> res0: List[String] = List(if, for, else, this, null, new, with, super, case, - //| case class, case object, val, abstract, final, private, protected, override - //| , implicit, var, def, type, extends, true, false, object, class, import, pac - //| kage, yield, do, trait, sealed, throw, try, catch, finally, while, return, m - //| atch, lazy, then, forSome, _, :, =, <-, =>, ';', ';', <:, >:, #, @, <%) - keywords.toList.filter(kw => tokenString(kw) == null) - //> res1: List[Int] = List() - canStartStatTokens3 contains CASE //> res2: Boolean = false - -} \ No newline at end of file From 4f08f737fc45481f0323356ecc36d5e30c1bc28d Mon Sep 17 00:00:00 2001 From: Solal Pirelli Date: Thu, 8 Jan 2026 15:22:37 +0100 Subject: [PATCH 06/12] More cleanup, remove one dependency of utils on non-utils --- .../tools/debug/ExpressionCompiler.scala | 1 - .../debug/ExpressionCompilerBridge.scala | 4 ---- .../debug/ExpressionCompilerConfig.scala | 6 +---- .../dotty/tools/debug/ExpressionStore.scala | 4 ---- .../dotty/tools/debug/ExtractExpression.scala | 8 ++----- .../src/dotty/tools/dotc/typer/Typer.scala | 10 ++++---- .../tools/dotc/util/CommentParsing.scala | 24 +++++++++---------- .../src/dotty/tools/dotc/util/LRUCache.scala | 4 ++-- .../src/dotty/tools/dotc/util/LinearMap.scala | 2 +- .../src/dotty/tools/dotc/util/LinearSet.scala | 2 +- .../dotty/tools/dotc/util/Signatures.scala | 3 +-- .../tools/dotc/util/SimpleIdentityMap.scala | 2 +- .../tools/dotc/util/SimpleIdentitySet.scala | 3 +-- .../dotty/tools/dotc/util/SourceFile.scala | 3 +-- .../src/dotty/tools/dotc/util/Spans.scala | 2 +- .../src/dotty/tools/dotc/util/Stats.scala | 2 +- .../src/dotty/tools/dotc/util/common.scala | 3 --- .../dotty/tools/dotc/util/concurrent.scala | 3 ++- 18 files changed, 31 insertions(+), 55 deletions(-) diff --git a/compiler/src/dotty/tools/debug/ExpressionCompiler.scala b/compiler/src/dotty/tools/debug/ExpressionCompiler.scala index 9931aa94270c..cb9c96b43a77 100644 --- a/compiler/src/dotty/tools/debug/ExpressionCompiler.scala +++ b/compiler/src/dotty/tools/debug/ExpressionCompiler.scala @@ -1,7 +1,6 @@ package dotty.tools.debug import dotty.tools.dotc.Compiler -import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Phases.Phase import dotty.tools.dotc.transform.ElimByName diff --git a/compiler/src/dotty/tools/debug/ExpressionCompilerBridge.scala b/compiler/src/dotty/tools/debug/ExpressionCompilerBridge.scala index 3ffbdc860abe..c596c6d4a1e0 100644 --- a/compiler/src/dotty/tools/debug/ExpressionCompilerBridge.scala +++ b/compiler/src/dotty/tools/debug/ExpressionCompilerBridge.scala @@ -1,11 +1,7 @@ package dotty.tools.debug import java.nio.file.Path -import java.util.function.Consumer -import java.{util => ju} -import scala.jdk.CollectionConverters.* import scala.util.control.NonFatal -import dotty.tools.dotc.reporting.StoreReporter import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.Driver diff --git a/compiler/src/dotty/tools/debug/ExpressionCompilerConfig.scala b/compiler/src/dotty/tools/debug/ExpressionCompilerConfig.scala index 895489143f9e..81bd66f0ea8b 100644 --- a/compiler/src/dotty/tools/debug/ExpressionCompilerConfig.scala +++ b/compiler/src/dotty/tools/debug/ExpressionCompilerConfig.scala @@ -1,12 +1,8 @@ package dotty.tools.debug -import dotty.tools.dotc.ast.tpd.* import dotty.tools.dotc.core.Symbols.* -import dotty.tools.dotc.core.Types.* import dotty.tools.dotc.core.Names.* -import dotty.tools.dotc.core.Flags.* import dotty.tools.dotc.core.Contexts.* -import dotty.tools.dotc.core.SymUtils import java.{util => ju} import ju.function.Consumer @@ -37,7 +33,7 @@ class ExpressionCompilerConfig private[debug] ( def withLocalVariables(localVariables: ju.Set[String]): ExpressionCompilerConfig = copy(localVariables = localVariables) def withErrorReporter(errorReporter: Consumer[String]): ExpressionCompilerConfig = copy(errorReporter = errorReporter) - private[debug] val expressionTermName: TermName = termName(outputClassName.toLowerCase.toString) + private[debug] val expressionTermName: TermName = termName(outputClassName.toLowerCase) private[debug] val expressionClassName: TypeName = typeName(outputClassName) private[debug] def expressionClass(using Context): ClassSymbol = diff --git a/compiler/src/dotty/tools/debug/ExpressionStore.scala b/compiler/src/dotty/tools/debug/ExpressionStore.scala index 3151c43b9a7a..8018d7ca306d 100644 --- a/compiler/src/dotty/tools/debug/ExpressionStore.scala +++ b/compiler/src/dotty/tools/debug/ExpressionStore.scala @@ -1,12 +1,8 @@ package dotty.tools.debug -import dotty.tools.dotc.ast.tpd.* import dotty.tools.dotc.core.Symbols.* -import dotty.tools.dotc.core.Types.* -import dotty.tools.dotc.core.Names.* import dotty.tools.dotc.core.Flags.* import dotty.tools.dotc.core.Contexts.* -import dotty.tools.dotc.core.SymUtils private class ExpressionStore: var symbol: TermSymbol | Null = null diff --git a/compiler/src/dotty/tools/debug/ExtractExpression.scala b/compiler/src/dotty/tools/debug/ExtractExpression.scala index 68e35f7f17dc..d87875d9018a 100644 --- a/compiler/src/dotty/tools/debug/ExtractExpression.scala +++ b/compiler/src/dotty/tools/debug/ExtractExpression.scala @@ -1,6 +1,5 @@ package dotty.tools.debug -import dotty.tools.dotc.core.SymUtils import dotty.tools.dotc.ast.tpd.* import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts.* @@ -14,9 +13,6 @@ import dotty.tools.dotc.core.SymDenotations.SymDenotation import dotty.tools.dotc.transform.MacroTransform import dotty.tools.dotc.core.Phases.* import dotty.tools.dotc.report -import dotty.tools.dotc.util.SrcPos -import scala.annotation.nowarn - /** * This phase extracts the typed expression from the source tree, transforms it and places it * in the evaluate method of the Expression class. @@ -110,7 +106,7 @@ private class ExtractExpression( case tree: (Ident | Select | This) if isStaticObject(tree.symbol) => getStaticObject(tree)(tree.symbol.moduleClass) - // non static this or outer this + // non-static this or outer this case tree: This if !tree.symbol.is(Package) => thisOrOuterValue(tree)(tree.symbol.enclosingClass.asClass) @@ -362,7 +358,7 @@ private class ExtractExpression( private def isLocalToExpression(symbol: Symbol)(using Context): Boolean = val evaluateMethod = config.evaluateMethod - symbol.ownersIterator.exists(_ == evaluateMethod) + symbol.ownersIterator.contains(evaluateMethod) private object ExtractExpression: val name: String = "extractExpression" diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index daf056eabe95..56d01edd2ecb 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -31,10 +31,8 @@ import EtaExpansion.etaExpand import TypeComparer.CompareResult import inlines.{Inlines, PrepareInlineable} import util.Spans.* -import util.chaining.* -import util.common.* import util.{Property, SimpleIdentityMap, SrcPos} -import Applications.{tupleComponentTypes, wrapDefs, defaultArgument} +import Applications.{wrapDefs, defaultArgument} import collection.mutable import Implicits.* @@ -48,13 +46,11 @@ import reporting.* import Nullables.* import NullOpsDecorator.* import cc.{CheckCaptures, isRetainsLike} -import config.Config import config.MigrationVersion import transform.CheckUnused.OriginalName import scala.annotation.{unchecked as _, *} import dotty.tools.dotc.util.chaining.* -import dotty.tools.dotc.ast.untpd.Mod object Typer { @@ -110,7 +106,6 @@ object Typer { */ private[typer] val HiddenSearchFailure = new Property.Key[List[SearchFailure]] - /** An attachment on a Typed node. Indicates that the Typed node was synthetically * inserted by the Typer phase. We might want to remove it for the purpose of inlining, * but only if it was not manually inserted by the user. @@ -126,6 +121,9 @@ object Typer { case _ => false } + /** Hoisted out for performance */ + private val alwaysWildcardType: Any => WildcardType.type = Function.const(WildcardType) + /** Add `fail` to the list of search failures attached to `tree` */ def rememberSearchFailure(tree: tpd.Tree, fail: SearchFailure) = tree.putAttachment(HiddenSearchFailure, diff --git a/compiler/src/dotty/tools/dotc/util/CommentParsing.scala b/compiler/src/dotty/tools/dotc/util/CommentParsing.scala index 56c72457d02a..99f8df5f349f 100644 --- a/compiler/src/dotty/tools/dotc/util/CommentParsing.scala +++ b/compiler/src/dotty/tools/dotc/util/CommentParsing.scala @@ -19,8 +19,8 @@ import scala.collection.mutable object CommentParsing { import Chars.* - /** Returns index of string `str` following `start` skipping longest - * sequence of whitespace characters characters (but no newlines) + /** Returns index of string `str` following `start` skipping + * sequence of whitespace characters (but no newlines) */ def skipWhitespace(str: String, start: Int): Int = if (start < str.length && isWhitespace(str.charAt(start))) skipWhitespace(str, start + 1) @@ -41,7 +41,7 @@ object CommentParsing { else start - /** Returns index of string `str` after `start` skipping longest + /** Returns index of string `str` after `start` skipping * sequence of space and tab characters, possibly also containing * a single `*` character or the `/``**` sequence. * @pre start == str.length || str(start) == `\n` @@ -50,8 +50,8 @@ object CommentParsing { if (start == str.length) start else { val idx = skipWhitespace(str, start + 1) - if (idx < str.length && (str.charAt(idx)) == '*') skipWhitespace(str, idx + 1) - else if (idx + 2 < str.length && (str.charAt(idx)) == '/' && (str.charAt(idx + 1)) == '*' && (str.charAt(idx + 2)) == '*') + if (idx < str.length && str.charAt(idx) == '*') skipWhitespace(str, idx + 1) + else if (idx + 2 < str.length && str.charAt(idx) == '/' && str.charAt(idx + 1) == '*' && str.charAt(idx + 2) == '*') skipWhitespace(str, idx + 3) else idx } @@ -59,8 +59,8 @@ object CommentParsing { /** Skips to next occurrence of `\n` or to the position after the `/``**` sequence following index `start`. */ def skipToEol(str: String, start: Int): Int = - if (start + 2 < str.length && (str.charAt(start)) == '/' && (str.charAt(start + 1)) == '*' && (str.charAt(start + 2)) == '*') start + 3 - else if (start < str.length && (str.charAt(start)) != '\n') skipToEol(str, start + 1) + if (start + 2 < str.length && str.charAt(start) == '/' && str.charAt(start + 1) == '*' && str.charAt(start + 2) == '*') start + 3 + else if (start < str.length && str.charAt(start) != '\n') skipToEol(str, start + 1) else start /** Returns first index following `start` and starting a line (i.e. after skipLineLead) or starting the comment @@ -81,7 +81,7 @@ object CommentParsing { else idx :: findAll(str, idx)(p) } - /** Produces a string index, which is a list of `sections`, i.e + /** Produces a string index, which is a list of `sections`, i.e., * pairs of start/end positions of all tagged sections in the string. * Every section starts with an at sign and extends to the next at sign, * or to the end of the comment string, but excluding the final two @@ -103,7 +103,7 @@ object CommentParsing { } /** - * Merge sections following an usecase into the usecase comment, so they + * Merge sections following a usecase into the usecase comment, so they * can override the parent symbol's sections */ def mergeUsecaseSections(str: String, idxs: List[Int]): List[Int] = @@ -163,7 +163,7 @@ object CommentParsing { /** Extracts variable name from a string, stripping any pair of surrounding braces */ def variableName(str: String): String = - if (str.length >= 2 && (str.charAt(0)) == '{' && (str.charAt(str.length - 1)) == '}') + if (str.length >= 2 && str.charAt(0) == '{' && str.charAt(str.length - 1) == '}') str.substring(1, str.length - 1) else str @@ -172,10 +172,10 @@ object CommentParsing { */ def skipVariable(str: String, start: Int): Int = { var idx = start - if (idx < str.length && (str.charAt(idx)) == '{') { + if (idx < str.length && str.charAt(idx) == '{') { while ({ idx += 1 - idx < str.length && (str.charAt(idx)) != '}' + idx < str.length && str.charAt(idx) != '}' }) () if (idx < str.length) idx + 1 else start diff --git a/compiler/src/dotty/tools/dotc/util/LRUCache.scala b/compiler/src/dotty/tools/dotc/util/LRUCache.scala index 4abe8962ae5b..82345f700aff 100644 --- a/compiler/src/dotty/tools/dotc/util/LRUCache.scala +++ b/compiler/src/dotty/tools/dotc/util/LRUCache.scala @@ -1,8 +1,8 @@ package dotty.tools.dotc.util -import reflect.ClassTag -import annotation.tailrec +import scala.reflect.ClassTag +import scala.annotation.tailrec /** A least-recently-used cache for Key -> Value computations * It currently keeps the last 8 associations, but this can be diff --git a/compiler/src/dotty/tools/dotc/util/LinearMap.scala b/compiler/src/dotty/tools/dotc/util/LinearMap.scala index 28a5daaefdba..a8e2f558c602 100644 --- a/compiler/src/dotty/tools/dotc/util/LinearMap.scala +++ b/compiler/src/dotty/tools/dotc/util/LinearMap.scala @@ -1,6 +1,6 @@ package dotty.tools.dotc.util -import collection.immutable +import scala.collection.immutable /** A linear map is a map where after an `updated` the previous map * value cannot be used anymore. The map is implemented as an immutable diff --git a/compiler/src/dotty/tools/dotc/util/LinearSet.scala b/compiler/src/dotty/tools/dotc/util/LinearSet.scala index d057c4ebeda9..52834f03bc42 100644 --- a/compiler/src/dotty/tools/dotc/util/LinearSet.scala +++ b/compiler/src/dotty/tools/dotc/util/LinearSet.scala @@ -1,6 +1,6 @@ package dotty.tools.dotc.util -import collection.immutable +import scala.collection.immutable /** A linear set is a set where after a `+` the previous set value cannot be * used anymore. The set is implemented as an immutable set for sizes <= 4 diff --git a/compiler/src/dotty/tools/dotc/util/Signatures.scala b/compiler/src/dotty/tools/dotc/util/Signatures.scala index 8bf720e388ea..09f14b6ebb9c 100644 --- a/compiler/src/dotty/tools/dotc/util/Signatures.scala +++ b/compiler/src/dotty/tools/dotc/util/Signatures.scala @@ -6,7 +6,6 @@ import dotty.tools.dotc.ast.Positioned import dotty.tools.dotc.ast.untpd import dotty.tools.dotc.core.NameOps.* import dotty.tools.dotc.core.StdNames.nme -import dotty.tools.dotc.core.Symbols.defn import ast.Trees.* import ast.tpd @@ -16,7 +15,7 @@ import core.Flags import core.Names.* import core.NameKinds import core.Types.* -import core.Symbols.{NoSymbol, isLocalToBlock} +import core.Symbols.isLocalToBlock import interactive.Interactive import util.Spans.Span import reporting.* diff --git a/compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala b/compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala index 2f202bc05921..0d945536864c 100644 --- a/compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala +++ b/compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala @@ -1,6 +1,6 @@ package dotty.tools.dotc.util -import collection.mutable.ListBuffer +import scala.collection.mutable.ListBuffer /** A simple linked map with `eq` as the key comparison, optimized for small maps. * It has linear complexity for `apply`, `updated`, and `remove`. diff --git a/compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala b/compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala index 1d8dc484c989..32fffbb3911d 100644 --- a/compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala +++ b/compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala @@ -1,7 +1,6 @@ package dotty.tools.dotc.util - -import collection.mutable +import scala.collection.mutable /** A simple linked set with `eq` as the comparison, optimized for small sets. * It has linear complexity for `contains`, `+`, and `-`. diff --git a/compiler/src/dotty/tools/dotc/util/SourceFile.scala b/compiler/src/dotty/tools/dotc/util/SourceFile.scala index 8800743c4f1c..0b002cd29fa5 100644 --- a/compiler/src/dotty/tools/dotc/util/SourceFile.scala +++ b/compiler/src/dotty/tools/dotc/util/SourceFile.scala @@ -20,9 +20,8 @@ import dotty.tools.dotc.util.chaining.* import java.io.File.separator import java.net.URI import java.nio.charset.StandardCharsets -import java.nio.file.{FileSystemException, NoSuchFileException, Paths} +import java.nio.file.{FileSystemException, Paths} import java.util.Optional -import java.util.concurrent.atomic.AtomicInteger import java.util.regex.Pattern object ScriptSourceFile { diff --git a/compiler/src/dotty/tools/dotc/util/Spans.scala b/compiler/src/dotty/tools/dotc/util/Spans.scala index 33346ad6da17..4d9137efb837 100644 --- a/compiler/src/dotty/tools/dotc/util/Spans.scala +++ b/compiler/src/dotty/tools/dotc/util/Spans.scala @@ -1,7 +1,7 @@ package dotty.tools.dotc package util -import language.implicitConversions +import scala.language.implicitConversions /** The offsets part of a full position, consisting of 2 or 3 entries: * - start: the start offset of the span, in characters from start of file diff --git a/compiler/src/dotty/tools/dotc/util/Stats.scala b/compiler/src/dotty/tools/dotc/util/Stats.scala index 2f4e3bd9cb4f..66308158d1f7 100644 --- a/compiler/src/dotty/tools/dotc/util/Stats.scala +++ b/compiler/src/dotty/tools/dotc/util/Stats.scala @@ -5,7 +5,7 @@ package util import scala.annotation.internal.sharable import core.Contexts.* -import collection.mutable +import scala.collection.mutable @sharable object Stats { diff --git a/compiler/src/dotty/tools/dotc/util/common.scala b/compiler/src/dotty/tools/dotc/util/common.scala index 85ce9a29f2df..8d0d7289c45b 100644 --- a/compiler/src/dotty/tools/dotc/util/common.scala +++ b/compiler/src/dotty/tools/dotc/util/common.scala @@ -1,13 +1,10 @@ package dotty.tools.dotc package util -import core.Types.WildcardType - /** Common values hoisted out for performance */ object common { val alwaysTrue: Any => Boolean = Function.const(true) val alwaysFalse: Any => Boolean = Function.const(false) val alwaysZero: Any => Int = Function.const(0) - val alwaysWildcardType: Any => WildcardType.type = Function.const(WildcardType) } diff --git a/compiler/src/dotty/tools/dotc/util/concurrent.scala b/compiler/src/dotty/tools/dotc/util/concurrent.scala index 2710aae6c9b0..cd83948ba58a 100644 --- a/compiler/src/dotty/tools/dotc/util/concurrent.scala +++ b/compiler/src/dotty/tools/dotc/util/concurrent.scala @@ -1,5 +1,6 @@ package dotty.tools.dotc.util -import scala.util.{Try, Failure, Success} + +import scala.util.{Try, Failure} import scala.collection.mutable.ArrayBuffer object concurrent: From 6f553c5ed7b72ed9a472b1ded49676d667e04426 Mon Sep 17 00:00:00 2001 From: Solal Pirelli Date: Thu, 8 Jan 2026 15:31:54 +0100 Subject: [PATCH 07/12] Remove more dead imports including the only 'semanticdb' use outside Compiler --- .../tools/dotc/transform/CheckShadowing.scala | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/CheckShadowing.scala b/compiler/src/dotty/tools/dotc/transform/CheckShadowing.scala index fe7ed64e3c82..64edbb8a70ff 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckShadowing.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckShadowing.scala @@ -1,37 +1,17 @@ package dotty.tools.dotc.transform import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.ast.Trees.EmptyTree -import dotty.tools.dotc.transform.MegaPhase import dotty.tools.dotc.transform.MegaPhase.MiniPhase import dotty.tools.dotc.report import dotty.tools.dotc.core.Contexts.* import dotty.tools.dotc.core.Flags.* import dotty.tools.dotc.util.{Property, SrcPos} -import dotty.tools.dotc.core.Symbols.ClassSymbol import dotty.tools.dotc.core.Names.Name import dotty.tools.dotc.core.Symbols.Symbol -import dotty.tools.dotc.core.Flags.EmptyFlags import dotty.tools.dotc.ast.tpd.TreeTraverser -import dotty.tools.dotc.core.Types.watchList -import dotty.tools.dotc.core.Types.NoType -import dotty.tools.dotc.core.Types.Type -import dotty.tools.dotc.core.Types -import dotty.tools.dotc.semanticdb.TypeOps -import dotty.tools.dotc.core.Symbols.{NoSymbol, isParamOrAccessor} -import scala.collection.mutable -import dotty.tools.dotc.core.Scopes.Scope -import scala.collection.immutable.HashMap import dotty.tools.dotc.core.Symbols -import dotty.tools.dotc.typer.ImportInfo -import dotty.tools.dotc.ast.untpd.ImportSelector -import dotty.tools.dotc.core.StdNames.nme -import dotty.tools.dotc.ast.untpd import dotty.tools.dotc.core.Denotations.SingleDenotation import dotty.tools.dotc.ast.Trees.Ident -import dotty.tools.dotc.core.Names.TypeName -import dotty.tools.dotc.core.Names.TermName -import dotty.tools.dotc.core.Mode.Type import dotty.tools.dotc.core.Names.SimpleName class CheckShadowing extends MiniPhase: From 291cc053b3f6c5f5ddf5fdb6bf671e7c805b7af7 Mon Sep 17 00:00:00 2001 From: Solal Pirelli Date: Thu, 8 Jan 2026 15:49:44 +0100 Subject: [PATCH 08/12] Restore ListOfNil --- compiler/src/dotty/tools/dotc/ast/Desugar.scala | 4 ++-- compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala | 2 +- .../src/dotty/tools/dotc/parsing/xml/SymbolicXMLBuilder.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Typer.scala | 2 +- compiler/src/dotty/tools/package.scala | 3 +++ 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 5e5e1831f8e8..8a1ff74a0f13 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -745,11 +745,11 @@ object desugar { if (originalVparamss.isEmpty) { // ensure parameter list is non-empty if (isCaseClass) report.error(CaseClassMissingParamList(cdef), namePos) - List(Nil) + ListOfNil } else if (isCaseClass && originalVparamss.head.exists(_.mods.isOneOf(GivenOrImplicit))) { report.error(CaseClassMissingNonImplicitParamList(cdef), namePos) - List(Nil) + ListOfNil } else originalVparamss.nestedMap(toMethParam(_, KeepAnnotations.All, keepDefault = true)) val derivedTparams = diff --git a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala index 7112402945f2..061516698d68 100644 --- a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala @@ -886,7 +886,7 @@ object JavaParsers { val accessors = (for (name, (tpt, annots)) <- fieldsByName yield - DefDef(name, List(Nil), adaptVarargsType(tpt), unimplementedExpr) + DefDef(name, ListOfNil, adaptVarargsType(tpt), unimplementedExpr) .withMods(Modifiers(Flags.JavaDefined | Flags.Method | Flags.Synthetic)) ).toList diff --git a/compiler/src/dotty/tools/dotc/parsing/xml/SymbolicXMLBuilder.scala b/compiler/src/dotty/tools/dotc/parsing/xml/SymbolicXMLBuilder.scala index 79162c47b887..aa8532b1d969 100644 --- a/compiler/src/dotty/tools/dotc/parsing/xml/SymbolicXMLBuilder.scala +++ b/compiler/src/dotty/tools/dotc/parsing/xml/SymbolicXMLBuilder.scala @@ -163,7 +163,7 @@ class SymbolicXMLBuilder(parser: Parser, preserveWS: Boolean)(using Context) { /** could optimize if args.length == 0, args.length == 1 AND args(0) is <: Node. */ def makeXMLseq(span: Span, args: collection.Seq[Tree]): Block = { - val buffer = ValDef(_buf, TypeTree(), New(_scala_xml_NodeBuffer, List(Nil))) + val buffer = ValDef(_buf, TypeTree(), New(_scala_xml_NodeBuffer, ListOfNil)) val applies = args filterNot isEmptyText map (t => Apply(Select(Ident(_buf), _plus), List(t))) atSpan(span)(new XMLBlock(buffer :: applies.toList, Ident(_buf)) ) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 56d01edd2ecb..651169bcce21 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -4385,7 +4385,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer alts.filter(_.info.isParameterless) match case alt :: Nil => readaptSimplified(tree.withType(alt)) case _ => - altDenots.find(_.info.paramInfoss == List(Nil)) match + altDenots.find(_.info.paramInfoss == ListOfNil) match case Some(alt) => readaptSimplified(tree.withType(altRef(alt))) case _ => error diff --git a/compiler/src/dotty/tools/package.scala b/compiler/src/dotty/tools/package.scala index bf1aad806c9c..475befce3807 100644 --- a/compiler/src/dotty/tools/package.scala +++ b/compiler/src/dotty/tools/package.scala @@ -2,6 +2,9 @@ package dotty package object tools { + /** Cached single-element list of Nil. (Whether this helps performance has not been tested) */ + val ListOfNil: List[Nil.type] = Nil :: Nil + /** Throws an `UnsupportedOperationException` with the given method name. */ def unsupported(methodName: String): Nothing = throw new UnsupportedOperationException(methodName) From fa339f67029180c58398376c2d0274408724a513 Mon Sep 17 00:00:00 2001 From: Solal Pirelli Date: Fri, 9 Jan 2026 11:04:26 +0100 Subject: [PATCH 09/12] PR feedback --- compiler/src/dotty/tools/debug/ExtractExpression.scala | 2 +- compiler/src/dotty/tools/dotc/cc/Capability.scala | 6 +++++- compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/debug/ExtractExpression.scala b/compiler/src/dotty/tools/debug/ExtractExpression.scala index d87875d9018a..71e7091b8ebf 100644 --- a/compiler/src/dotty/tools/debug/ExtractExpression.scala +++ b/compiler/src/dotty/tools/debug/ExtractExpression.scala @@ -358,7 +358,7 @@ private class ExtractExpression( private def isLocalToExpression(symbol: Symbol)(using Context): Boolean = val evaluateMethod = config.evaluateMethod - symbol.ownersIterator.contains(evaluateMethod) + symbol.ownersIterator.exists(_ == evaluateMethod) private object ExtractExpression: val name: String = "extractExpression" diff --git a/compiler/src/dotty/tools/dotc/cc/Capability.scala b/compiler/src/dotty/tools/dotc/cc/Capability.scala index 4dd6220a4709..f45c6d579ebb 100644 --- a/compiler/src/dotty/tools/dotc/cc/Capability.scala +++ b/compiler/src/dotty/tools/dotc/cc/Capability.scala @@ -5,17 +5,21 @@ package cc import core.* import Types.*, Symbols.*, Contexts.*, Decorators.* import util.{SimpleIdentitySet, EqHashMap} +import util.common.alwaysTrue +import scala.collection.mutable +import CCState.* import Periods.{NoRunId, RunWidth} import compiletime.uninitialized import StdNames.nme import CaptureSet.{Refs, emptyRefs, VarState} +import Annotations.Annotation import Flags.* import config.Printers.capt import annotation.constructorOnly import ast.tpd import printing.{Printer, Showable} import printing.Texts.Text -import reporting.Message +import reporting.{Message, trace} import NameOps.isImpureFunction import annotation.internal.sharable import collection.immutable diff --git a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala index 061516698d68..52fa946f9305 100644 --- a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala @@ -1014,7 +1014,7 @@ object JavaParsers { val predefs = List( DefDef( nme.values, - List(Nil), + ListOfNil, arrayOf(enumType), unimplementedExpr).withMods(Modifiers(Flags.JavaDefined | Flags.JavaStatic | Flags.Method)), DefDef( From 13956b960a9ccb2bbc7c6886566dd64817bd0bc2 Mon Sep 17 00:00:00 2001 From: Solal Pirelli Date: Fri, 9 Jan 2026 11:07:22 +0100 Subject: [PATCH 10/12] PR feedback --- compiler/src/dotty/tools/dotc/transform/UnrollDefinitions.scala | 1 + compiler/src/dotty/tools/dotc/typer/Typer.scala | 1 + 2 files changed, 2 insertions(+) diff --git a/compiler/src/dotty/tools/dotc/transform/UnrollDefinitions.scala b/compiler/src/dotty/tools/dotc/transform/UnrollDefinitions.scala index 7c5c260402b9..4aa598d1aa3f 100644 --- a/compiler/src/dotty/tools/dotc/transform/UnrollDefinitions.scala +++ b/compiler/src/dotty/tools/dotc/transform/UnrollDefinitions.scala @@ -5,6 +5,7 @@ import ast.tpd import ast.Trees.* import core.* import Flags.* +import Decorators.* import Contexts.* import Symbols.* import Constants.Constant diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 651169bcce21..27be413dbd84 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -31,6 +31,7 @@ import EtaExpansion.etaExpand import TypeComparer.CompareResult import inlines.{Inlines, PrepareInlineable} import util.Spans.* +import util.chaining.* import util.{Property, SimpleIdentityMap, SrcPos} import Applications.{wrapDefs, defaultArgument} From ac15a3888598322dfdb8657ed145d49921971561 Mon Sep 17 00:00:00 2001 From: Solal Pirelli Date: Tue, 13 Jan 2026 15:45:42 +0100 Subject: [PATCH 11/12] PR feedback --- compiler/src/dotty/tools/dotc/util/LinearMap.scala | 2 +- compiler/src/dotty/tools/dotc/util/LinearSet.scala | 2 +- compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala | 2 +- compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala | 2 +- compiler/src/dotty/tools/dotc/util/Spans.scala | 2 +- compiler/src/dotty/tools/dotc/util/Stats.scala | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/util/LinearMap.scala b/compiler/src/dotty/tools/dotc/util/LinearMap.scala index a8e2f558c602..28a5daaefdba 100644 --- a/compiler/src/dotty/tools/dotc/util/LinearMap.scala +++ b/compiler/src/dotty/tools/dotc/util/LinearMap.scala @@ -1,6 +1,6 @@ package dotty.tools.dotc.util -import scala.collection.immutable +import collection.immutable /** A linear map is a map where after an `updated` the previous map * value cannot be used anymore. The map is implemented as an immutable diff --git a/compiler/src/dotty/tools/dotc/util/LinearSet.scala b/compiler/src/dotty/tools/dotc/util/LinearSet.scala index 52834f03bc42..d057c4ebeda9 100644 --- a/compiler/src/dotty/tools/dotc/util/LinearSet.scala +++ b/compiler/src/dotty/tools/dotc/util/LinearSet.scala @@ -1,6 +1,6 @@ package dotty.tools.dotc.util -import scala.collection.immutable +import collection.immutable /** A linear set is a set where after a `+` the previous set value cannot be * used anymore. The set is implemented as an immutable set for sizes <= 4 diff --git a/compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala b/compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala index 0d945536864c..2f202bc05921 100644 --- a/compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala +++ b/compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala @@ -1,6 +1,6 @@ package dotty.tools.dotc.util -import scala.collection.mutable.ListBuffer +import collection.mutable.ListBuffer /** A simple linked map with `eq` as the key comparison, optimized for small maps. * It has linear complexity for `apply`, `updated`, and `remove`. diff --git a/compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala b/compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala index 32fffbb3911d..654681b2edef 100644 --- a/compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala +++ b/compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala @@ -1,6 +1,6 @@ package dotty.tools.dotc.util -import scala.collection.mutable +import collection.mutable /** A simple linked set with `eq` as the comparison, optimized for small sets. * It has linear complexity for `contains`, `+`, and `-`. diff --git a/compiler/src/dotty/tools/dotc/util/Spans.scala b/compiler/src/dotty/tools/dotc/util/Spans.scala index 4d9137efb837..33346ad6da17 100644 --- a/compiler/src/dotty/tools/dotc/util/Spans.scala +++ b/compiler/src/dotty/tools/dotc/util/Spans.scala @@ -1,7 +1,7 @@ package dotty.tools.dotc package util -import scala.language.implicitConversions +import language.implicitConversions /** The offsets part of a full position, consisting of 2 or 3 entries: * - start: the start offset of the span, in characters from start of file diff --git a/compiler/src/dotty/tools/dotc/util/Stats.scala b/compiler/src/dotty/tools/dotc/util/Stats.scala index 66308158d1f7..2f4e3bd9cb4f 100644 --- a/compiler/src/dotty/tools/dotc/util/Stats.scala +++ b/compiler/src/dotty/tools/dotc/util/Stats.scala @@ -5,7 +5,7 @@ package util import scala.annotation.internal.sharable import core.Contexts.* -import scala.collection.mutable +import collection.mutable @sharable object Stats { From 0eca63186e6555205335cd78d57a4b7f4ff082ae Mon Sep 17 00:00:00 2001 From: Solal Pirelli Date: Mon, 19 Jan 2026 14:08:03 +0100 Subject: [PATCH 12/12] Offline feedback --- compiler/src/dotty/tools/debug/ExpressionCompilerConfig.scala | 4 ++++ compiler/src/dotty/tools/debug/ExpressionStore.scala | 4 ++++ compiler/src/dotty/tools/dotc/typer/Typer.scala | 1 + compiler/src/dotty/tools/dotc/util/LRUCache.scala | 4 ++-- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/debug/ExpressionCompilerConfig.scala b/compiler/src/dotty/tools/debug/ExpressionCompilerConfig.scala index 81bd66f0ea8b..0a464299899f 100644 --- a/compiler/src/dotty/tools/debug/ExpressionCompilerConfig.scala +++ b/compiler/src/dotty/tools/debug/ExpressionCompilerConfig.scala @@ -1,8 +1,12 @@ package dotty.tools.debug +import dotty.tools.dotc.ast.tpd.* import dotty.tools.dotc.core.Symbols.* +import dotty.tools.dotc.core.Types.* import dotty.tools.dotc.core.Names.* +import dotty.tools.dotc.core.Flags.* import dotty.tools.dotc.core.Contexts.* +import dotty.tools.dotc.core.SymUtils import java.{util => ju} import ju.function.Consumer diff --git a/compiler/src/dotty/tools/debug/ExpressionStore.scala b/compiler/src/dotty/tools/debug/ExpressionStore.scala index 8018d7ca306d..3151c43b9a7a 100644 --- a/compiler/src/dotty/tools/debug/ExpressionStore.scala +++ b/compiler/src/dotty/tools/debug/ExpressionStore.scala @@ -1,8 +1,12 @@ package dotty.tools.debug +import dotty.tools.dotc.ast.tpd.* import dotty.tools.dotc.core.Symbols.* +import dotty.tools.dotc.core.Types.* +import dotty.tools.dotc.core.Names.* import dotty.tools.dotc.core.Flags.* import dotty.tools.dotc.core.Contexts.* +import dotty.tools.dotc.core.SymUtils private class ExpressionStore: var symbol: TermSymbol | Null = null diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 27be413dbd84..29be088643c6 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -32,6 +32,7 @@ import TypeComparer.CompareResult import inlines.{Inlines, PrepareInlineable} import util.Spans.* import util.chaining.* +import util.common.* import util.{Property, SimpleIdentityMap, SrcPos} import Applications.{wrapDefs, defaultArgument} diff --git a/compiler/src/dotty/tools/dotc/util/LRUCache.scala b/compiler/src/dotty/tools/dotc/util/LRUCache.scala index 82345f700aff..4abe8962ae5b 100644 --- a/compiler/src/dotty/tools/dotc/util/LRUCache.scala +++ b/compiler/src/dotty/tools/dotc/util/LRUCache.scala @@ -1,8 +1,8 @@ package dotty.tools.dotc.util -import scala.reflect.ClassTag -import scala.annotation.tailrec +import reflect.ClassTag +import annotation.tailrec /** A least-recently-used cache for Key -> Value computations * It currently keeps the last 8 associations, but this can be