Skip to content

Commit 6635990

Browse files
committed
WIP: broken
1 parent af404e3 commit 6635990

File tree

20 files changed

+144
-10
lines changed

20 files changed

+144
-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 symbol.id == 2765 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.toString.contains("compiletime2") then
275+
report.echo(s"${classReps} class reps found 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

+17-6
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,19 @@ object Symbols {
4646
* @param coord The coordinates of the symbol (a position or an index)
4747
* @param id A unique identifier of the symbol (unique per ContextBase)
4848
*/
49-
class Symbol private[Symbols] (private var myCoord: Coord, val id: Int)
49+
class Symbol private[Symbols] (private var myCoord: Coord, val id: Int, val runUUID: String = "<no uuid>")
5050
extends Designator, ParamInfo, SrcPos, printing.Showable {
5151

5252
type ThisName <: Name
5353

54-
//assert(id != 723)
54+
val tracer: String | Null =
55+
if id == 2760 /* myerror before */ || id == 2756 /* compiletime2.package$ before */ || id == 2765 /* myerror after */|| id == 2757 /* compiletime2.package before */|| id == 2753 /* compiletime2.package after */ then
56+
val tracer = Thread.currentThread().getStackTrace().mkString("\n ", "\n ", "\n")
57+
tracer
58+
else
59+
null
60+
61+
// assert(id != 723)
5562

5663
def coord: Coord = myCoord
5764

@@ -76,6 +83,10 @@ object Symbols {
7683

7784
/** Set defining tree if this symbol retains its definition tree */
7885
def defTree_=(tree: Tree)(using Context): Unit =
86+
val fname = denot.fullName.toString
87+
if fname.contains("scala.compiletime") && !fname.contains(".ops") then
88+
if tracer != null then
89+
report.echo(i"`${denot.fullName}.defTree = $tree` [did assign? $retainsDefTree, id? ${id}, phase? ${ctx.phase.phaseName}, run? $runUUID, $tracer]")
7990
if (retainsDefTree) myDefTree = tree
8091

8192
/** Does this symbol retain its definition tree?
@@ -368,8 +379,8 @@ object Symbols {
368379
type TermSymbol = Symbol { type ThisName = TermName }
369380
type TypeSymbol = Symbol { type ThisName = TypeName }
370381

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

374385
type ThisName = TypeName
375386

@@ -516,7 +527,7 @@ object Symbols {
516527
info: Type,
517528
privateWithin: Symbol = NoSymbol,
518529
coord: Coord = NoCoord)(using Context): Symbol { type ThisName = N } = {
519-
val sym = new Symbol(coord, ctx.base.nextSymId).asInstanceOf[Symbol { type ThisName = N }]
530+
val sym = new Symbol(coord, ctx.base.nextSymId, Option(ctx.run).map(_.uuid).getOrElse("<no run>")).asInstanceOf[Symbol { type ThisName = N }]
520531
val denot = SymDenotation(sym, owner, name, flags, info, privateWithin)
521532
sym.denot = denot
522533
sym
@@ -534,7 +545,7 @@ object Symbols {
534545
coord: Coord = NoCoord,
535546
assocFile: AbstractFile = null)(using Context): ClassSymbol
536547
= {
537-
val cls = new ClassSymbol(coord, assocFile, ctx.base.nextSymId)
548+
val cls = new ClassSymbol(coord, assocFile, ctx.base.nextSymId, Option(ctx.run).map(_.uuid).getOrElse("<no uuid>"))
538549
val denot = SymDenotation(cls, owner, name, flags, infoFn(cls), privateWithin)
539550
cls.denot = denot
540551
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/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+
val trace = if cls.denot.fullName.toString.contains("scala.compiletime2.package$package") then cls.tracer else "no trace"
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
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package scala.compiletime2
2+
3+
object Errors {
4+
inline def myerror(inline msg: String): Nothing =
5+
???
6+
???
7+
}
8+
// TODO try with https://github.com/lampepfl/dotty/pull/13973
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package scala.compiletime2
2+
3+
import scala.compiletime2.Errors.myerror
4+
5+
object Utils:
6+
7+
def typeChecks2: Boolean =
8+
myerror("foo")

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-
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package scala
2+
package compiletime3
3+
4+
inline def myerror(inline msg: String): Nothing = { ??? ; ??? }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package scala.compiletime3
2+
package testing3
3+
4+
/** Whether the code type checks in the current context?
5+
*
6+
* An inline definition with a call to `typeChecks` should be transparent.
7+
*
8+
* @param code The code to be type checked
9+
*
10+
* @return false if the code has syntax error or type error in the current context, otherwise returns true.
11+
*
12+
* The code should be a sequence of expressions or statements that may appear in a block.
13+
*/
14+
transparent inline def typeChecks2(inline code: String): Boolean =
15+
???
16+
// implemented in package dotty.tools.dotc.typer.Inliner.Intrinsics
17+
// myerror("Compiler bug: `typeChecks` was not checked by the compiler")

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+
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)