Skip to content

Commit 94307e8

Browse files
committed
WIP: broken
1 parent af404e3 commit 94307e8

File tree

19 files changed

+132
-10
lines changed

19 files changed

+132
-10
lines changed

compiler/src/dotty/tools/dotc/Run.scala

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ import scala.io.Codec
3939
/** A compiler run. Exports various methods to compile source files */
4040
class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with ConstraintRunInfo {
4141

42+
val uuid = java.util.UUID.randomUUID.toString
43+
4244
/** Default timeout to stop looking for further implicit suggestions, in ms.
4345
* This is usually for the first import suggestion; subsequent suggestions
4446
* may get smaller timeouts. @see ImportSuggestions.reduceTimeBudget
@@ -202,6 +204,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
202204

203205
def compile(files: List[AbstractFile]): Unit =
204206
try
207+
report.echo(s"!!! BEGIN RUN $uuid on ${files.mkString(", ")}")
205208
val sources = files.map(runContext.getSource(_))
206209
compileSources(sources)
207210
catch

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

+4
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ object SymDenotations {
168168
atPhase(validFor.firstPhaseId)(completer.complete(this))
169169
}
170170

171+
protected[dotc] var infoTracer: String | Null = null
172+
171173
protected[dotc] def info_=(tp: Type): Unit = {
172174
/* // DEBUG
173175
def illegal: String = s"illegal type for $this: $tp"
@@ -180,6 +182,8 @@ object SymDenotations {
180182
}
181183
*/
182184
if (Config.checkNoSkolemsInInfo) assertNoSkolems(tp)
185+
if SymbolCapturing.doCapture(symbol) then
186+
infoTracer = Thread.currentThread().getStackTrace().mkString("\n ", "\n ", "")
183187
myInfo = tp
184188
}
185189

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

+2
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ object SymbolLoaders {
271271
for (classRep <- classReps)
272272
if (!maybeModuleClass(classRep) && hasFlatName(classRep) == flat &&
273273
(!flat || isAbsent(classRep))) // on 2nd enter of flat names, check that the name has not been entered before
274+
if packageName == "a" then
275+
report.echo(s"initialising ${classRep} for ${root.symbol} in package $packageName")
274276
initializeFromClassPath(root.symbol, classRep)
275277
for (classRep <- classReps)
276278
if (maybeModuleClass(classRep) && hasFlatName(classRep) == flat &&

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

+27-6
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ import scala.collection.JavaConverters._
3535
import scala.annotation.internal.sharable
3636
import config.Printers.typr
3737

38+
object SymbolCapturing {
39+
def ids = Set(
40+
2844, // a.Foo$.foo (before)
41+
2756, // a.Foo (before)
42+
4949, // a.Foo$.foo (after)
43+
2756, // a.Foo (after)
44+
)
45+
def doCapture(sym: Symbol): Boolean = ids.contains(sym.id)
46+
}
47+
3848
object Symbols {
3949

4050
implicit def eqSymbol: CanEqual[Symbol, Symbol] = CanEqual.derived
@@ -46,12 +56,19 @@ object Symbols {
4656
* @param coord The coordinates of the symbol (a position or an index)
4757
* @param id A unique identifier of the symbol (unique per ContextBase)
4858
*/
49-
class Symbol private[Symbols] (private var myCoord: Coord, val id: Int)
59+
class Symbol private[Symbols] (private var myCoord: Coord, val id: Int, val runUUID: String = "<no uuid>")
5060
extends Designator, ParamInfo, SrcPos, printing.Showable {
5161

5262
type ThisName <: Name
5363

54-
//assert(id != 723)
64+
val tracer: String | Null =
65+
if SymbolCapturing.doCapture(this) then
66+
val tracer = Thread.currentThread().getStackTrace().mkString("\n ", "\n ", "\n")
67+
tracer
68+
else
69+
null
70+
71+
// assert(id != 723)
5572

5673
def coord: Coord = myCoord
5774

@@ -76,6 +93,10 @@ object Symbols {
7693

7794
/** Set defining tree if this symbol retains its definition tree */
7895
def defTree_=(tree: Tree)(using Context): Unit =
96+
val fname = denot.fullName.toString
97+
if fname.contains("a.Foo") || fname.contains("a.Bar") then
98+
if tracer != null then
99+
report.echo(i"`${denot.fullName}.defTree = $tree` [did assign? $retainsDefTree, id? ${id}, phase? ${ctx.phase.phaseName}, run? $runUUID]")//, $tracer]")
79100
if (retainsDefTree) myDefTree = tree
80101

81102
/** Does this symbol retain its definition tree?
@@ -368,8 +389,8 @@ object Symbols {
368389
type TermSymbol = Symbol { type ThisName = TermName }
369390
type TypeSymbol = Symbol { type ThisName = TypeName }
370391

371-
class ClassSymbol private[Symbols] (coord: Coord, val assocFile: AbstractFile, id: Int)
372-
extends Symbol(coord, id) {
392+
class ClassSymbol private[Symbols] (coord: Coord, val assocFile: AbstractFile, id: Int, runUUID: String)
393+
extends Symbol(coord, id, runUUID) {
373394

374395
type ThisName = TypeName
375396

@@ -516,7 +537,7 @@ object Symbols {
516537
info: Type,
517538
privateWithin: Symbol = NoSymbol,
518539
coord: Coord = NoCoord)(using Context): Symbol { type ThisName = N } = {
519-
val sym = new Symbol(coord, ctx.base.nextSymId).asInstanceOf[Symbol { type ThisName = N }]
540+
val sym = new Symbol(coord, ctx.base.nextSymId, Option(ctx.run).map(_.uuid).getOrElse("<no run>")).asInstanceOf[Symbol { type ThisName = N }]
520541
val denot = SymDenotation(sym, owner, name, flags, info, privateWithin)
521542
sym.denot = denot
522543
sym
@@ -534,7 +555,7 @@ object Symbols {
534555
coord: Coord = NoCoord,
535556
assocFile: AbstractFile = null)(using Context): ClassSymbol
536557
= {
537-
val cls = new ClassSymbol(coord, assocFile, ctx.base.nextSymId)
558+
val cls = new ClassSymbol(coord, assocFile, ctx.base.nextSymId, Option(ctx.run).map(_.uuid).getOrElse("<no uuid>"))
538559
val denot = SymDenotation(cls, owner, name, flags, infoFn(cls), privateWithin)
539560
cls.denot = denot
540561
cls

compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,10 @@ private class ExtractAPICollector(using Context) extends ThunkHolder {
720720
sym.defTree match
721721
case defTree: ValOrDefDef =>
722722
h = inlineReferenceHash(sym, defTree.rhs, h)
723-
case _ =>
724-
h = err(i"inline method reference `${ref.name}`", ref.name, ref, h)
723+
case tree =>
724+
val trace = if sym.tracer != null then s"created at: ${sym.tracer}" else "no tracer"
725+
val infoTrace = if sym.denot.infoTracer != null then s"info assigned at: ${sym.denot.infoTracer}" else "no info tracer"
726+
h = err(i"inline method reference `${ref.name}` [tree? ${tree.show}, symId? ${sym.id}, run? ${sym.runUUID}, $trace, $infoTrace]", ref.name, ref, h)
725727
case _ =>
726728

727729
// FIXME: If `p` is a tree we should probably take its type into account

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

+3
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,9 @@ class Namer { typer: Typer =>
12551255

12561256
/** The type signature of a ClassDef with given symbol */
12571257
override def completeInCreationContext(denot: SymDenotation): Unit = {
1258+
if SymbolCapturing.doCapture(cls) then
1259+
val trace = if cls.tracer != null then s"created: ${cls.tracer}" else "no trace"
1260+
report.echo(i"forcing class ${cls.denot.fullName} [id? ${cls.id}, trace? $trace]")
12581261
val parents = impl.parents
12591262

12601263
/* The type of a parent constructor. Types constructor arguments

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -2552,7 +2552,10 @@ class Typer extends Namer
25522552
// If it exists, complete the class containing the top-level definitions
25532553
// before typing any statement in the package to avoid cycles as in i13669.scala
25542554
val topLevelClassName = desugar.packageObjectName(ctx.source).moduleClassName
2555-
pkg.moduleClass.info.decls.lookup(topLevelClassName).ensureCompleted()
2555+
val cls = pkg.moduleClass.info.decls.lookup(topLevelClassName)
2556+
// if SymbolCapturing.doCapture(cls.id) then
2557+
// report.echo(i"forcing top level class ${cls.denot.fullName} [id? ${cls.id}, run? ${cls.runUUID}, from? ${String.valueOf(trace)}]")
2558+
cls.ensureCompleted()
25562559
var stats1 = typedStats(tree.stats, pkg.moduleClass)._1
25572560
if (!ctx.isAfterTyper)
25582561
stats1 = stats1 ++ typedBlockStats(MainProxies.mainProxies(stats1))._1
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package a
2+
package b
3+
4+
object Bar:
5+
inline def Bar = Foo.foo

library/src-bootstrapped/a/zz.scala

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package a
2+
3+
object Foo:
4+
inline def foo: Nothing =
5+
???
6+
???
7+
???

library/src/scala/compiletime/package.scala

-1
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,3 @@ def byName[T](x: => T): T = x
188188
*/
189189
extension [T](x: T)
190190
transparent inline def asMatchable: x.type & Matchable = x.asInstanceOf[x.type & Matchable]
191-

project/Build.scala

+2
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ object Build {
257257
(Compile / resourceDirectory) := baseDirectory.value / "resources",
258258
(Test / resourceDirectory) := baseDirectory.value / "test-resources",
259259

260+
disableDocSetting,
261+
260262
// Prevent sbt from rewriting our dependencies
261263
scalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(false))),
262264

sandbox/scalajs/src/hello.scala

+2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ trait MyTrait {
88
}
99

1010
object HelloWorld extends MyTrait {
11+
1112
def main(args: Array[String]): Unit = {
1213
println("hello dotty.js!")
1314
println(foo(4))
15+
// println(compiletime.foo)
1416
}
1517
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package a
2+
3+
import a.Errors.myerror
4+
5+
object Utils:
6+
7+
inline def testTypeChecks: Nothing =
8+
myerror("foo...")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import sbt.internal.inc.Analysis
2+
import complete.DefaultParsers._
3+
4+
// Reset compiler iterations, necessary because tests run in batch mode
5+
val recordPreviousIterations = taskKey[Unit]("Record previous iterations.")
6+
recordPreviousIterations := {
7+
val log = streams.value.log
8+
CompileState.previousIterations = {
9+
val previousAnalysis = (previousCompile in Compile).value.analysis.asScala
10+
previousAnalysis match {
11+
case None =>
12+
log.info("No previous analysis detected")
13+
0
14+
case Some(a: Analysis) => a.compilations.allCompilations.size
15+
}
16+
}
17+
}
18+
19+
val checkIterations = inputKey[Unit]("Verifies the accumulated number of iterations of incremental compilation.")
20+
21+
checkIterations := {
22+
val expected: Int = (Space ~> NatBasic).parsed
23+
val actual: Int = ((compile in Compile).value match { case a: Analysis => a.compilations.allCompilations.size }) - CompileState.previousIterations
24+
assert(expected == actual, s"Expected $expected compilations, got $actual")
25+
}
26+
27+
Compile/scalacOptions ++= Seq("-sourcepath", (Compile / sourceDirectories).value.map(_.getAbsolutePath).distinct.mkString(java.io.File.pathSeparator))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package a
2+
3+
object Errors:
4+
5+
inline def myerror(inline msg: String): Nothing =
6+
???
7+
???
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// This is necessary because tests are run in batch mode
2+
object CompileState {
3+
@volatile var previousIterations: Int = -1
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import sbt._
2+
import Keys._
3+
4+
object DottyInjectedPlugin extends AutoPlugin {
5+
override def requires = plugins.JvmPlugin
6+
override def trigger = allRequirements
7+
8+
override val projectSettings = Seq(
9+
scalaVersion := sys.props("plugin.scalaVersion")
10+
)
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
> compile
2+
> recordPreviousIterations
3+
# Force recompilation of a-testing-package because a.myerror, called by a.testing.myTypeChecks, has changed
4+
$ copy-file changes/zz1.scala zz.scala
5+
> compile
6+
# 1 to recompile a-package, then 1 more to recompile a-testing-package due to a.myerror change
7+
> checkIterations 2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package a
2+
3+
object Errors:
4+
5+
inline def myerror(inline msg: String): Nothing = ???

0 commit comments

Comments
 (0)