Skip to content

Commit 73ba485

Browse files
authored
Refactor the abstract domain of global init checker to compile http4s (#22179)
This is a draft PR that contains fixes to the initialization checker, so that it can successfully check http4s in community-build [test_scala2_library_tasty]
2 parents 8b04ba8 + 773880f commit 73ba485

18 files changed

+361
-108
lines changed

Diff for: compiler/src/dotty/tools/dotc/transform/init/Objects.scala

+288-98
Large diffs are not rendered by default.

Diff for: compiler/test/dotc/neg-init-global-scala2-library-tasty.excludelist

-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
## See #18882
22
patmat.scala
33
t9312.scala
4-
unapplySeq-implicit-arg.scala
5-
unapplySeq-implicit-arg2.scala
6-
unapplySeq-implicit-arg3.scala
74
ScalaCheck.scala
85
mutable-read8.scala
96
TypeCast.scala

Diff for: compiler/test/dotty/tools/dotc/CompilationTests.scala

+4
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ class CompilationTests {
233233
implicit val testGroup: TestGroup = TestGroup("checkInitGlobal")
234234
compileFilesInDir("tests/init-global/warn", defaultOptions.and("-Ysafe-init-global"), FileFilter.exclude(TestSources.negInitGlobalScala2LibraryTastyExcludelisted)).checkWarnings()
235235
compileFilesInDir("tests/init-global/pos", defaultOptions.and("-Ysafe-init-global", "-Xfatal-warnings"), FileFilter.exclude(TestSources.posInitGlobalScala2LibraryTastyExcludelisted)).checkCompile()
236+
if Properties.usingScalaLibraryTasty && !Properties.usingScalaLibraryCCTasty then
237+
compileFilesInDir("tests/init-global/warn-tasty", defaultOptions.and("-Ysafe-init-global"), FileFilter.exclude(TestSources.negInitGlobalScala2LibraryTastyExcludelisted)).checkWarnings()
238+
compileFilesInDir("tests/init-global/pos-tasty", defaultOptions.and("-Ysafe-init-global", "-Xfatal-warnings"), FileFilter.exclude(TestSources.posInitGlobalScala2LibraryTastyExcludelisted)).checkCompile()
239+
end if
236240
}
237241

238242
// initialization tests

Diff for: tests/init-global/pos/arithmetic.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object A:
2+
val a = f(10)
3+
val b = -a
4+
val c = b.toDouble
5+
def f(x: Int) = x * 2 + 5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package p
2+
package object a {
3+
val b = 10
4+
implicit class CI(s: StringContext) {
5+
def ci(args: Any*) = 10
6+
}
7+
}
8+
9+
import p.a._
10+
11+
object A:
12+
val f = b // p.a(ObjectRef(p.a)).b
13+
def foo(s: String): String = s
14+
val f1 = ci"a" // => p.a(Package(p).select(a)).CI(StringContext"a").ci()
15+
16+
File renamed without changes.
File renamed without changes.

Diff for: tests/init-global/warn/unapplySeq-implicit-arg.check renamed to tests/init-global/warn-tasty/unapplySeq-implicit-arg.check

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
-- Warning: tests/init-global/warn/unapplySeq-implicit-arg.scala:11:20 -------------------------------------------------
1+
-- Warning: tests/init-global/warn-tasty/unapplySeq-implicit-arg.scala:11:20 -------------------------------------------
22
11 | val i2: Int = Seq(i2) match // warn
33
| ^^
44
| Access uninitialized field value i2. Calling trace:

Diff for: tests/init-global/warn/unapplySeq-implicit-arg2.check renamed to tests/init-global/warn-tasty/unapplySeq-implicit-arg2.check

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
-- Warning: tests/init-global/warn/unapplySeq-implicit-arg2.scala:4:9 --------------------------------------------------
1+
-- Warning: tests/init-global/warn-tasty/unapplySeq-implicit-arg2.scala:4:9 --------------------------------------------
22
4 | Some(i1 +: seqi) // warn
33
| ^^
44
|Access uninitialized field value i1. Calling trace:

Diff for: tests/init-global/warn/unapplySeq-implicit-arg3.check renamed to tests/init-global/warn-tasty/unapplySeq-implicit-arg3.check

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
-- Warning: tests/init-global/warn/unapplySeq-implicit-arg3.scala:3:27 -------------------------------------------------
1+
-- Warning: tests/init-global/warn-tasty/unapplySeq-implicit-arg3.scala:3:27 -------------------------------------------
22
3 | def m(seq: Seq[Int]) = i1 +: seq // warn
33
| ^^
44
|Access uninitialized field value i1. Calling trace:

Diff for: tests/init-global/warn/mutable-array.check

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
-- Warning: tests/init-global/warn/mutable-array.scala:8:19 ------------------------------------------------------------
2-
8 | val x: Int = box.value // warn
1+
-- Warning: tests/init-global/warn/mutable-array.scala:9:19 ------------------------------------------------------------
2+
9 | val x: Int = box.value // warn
33
| ^^^^^^^^^
44
|Reading mutable state of object A during initialization of object B.
55
|Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace:
66
|├── object B: [ mutable-array.scala:5 ]
77
|│ ^
8-
|└── val x: Int = box.value // warn [ mutable-array.scala:8 ]
8+
|└── val x: Int = box.value // warn [ mutable-array.scala:9 ]
99
| ^^^^^^^^^
1010
|The mutable state is created through:
1111
|├── object A: [ mutable-array.scala:1 ]

Diff for: tests/init-global/warn/mutable-array.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ object A:
33
val box: Box = new Box(0)
44

55
object B:
6-
val boxes: Array[A.Box] = Array(A.box)
6+
val boxes = new Array[A.Box](2)
7+
boxes(0) = A.box
78
val box: A.Box = boxes(0)
89
val x: Int = box.value // warn

Diff for: tests/init-global/warn/widen.check

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- Warning: tests/init-global/warn/widen.scala:13:13 -------------------------------------------------------------------
2+
13 | t.foo() // warn
3+
| ^^^^^^^
4+
| Value is unknown to the checker due to widening. Calling trace:
5+
| ├── object O: [ widen.scala:9 ]
6+
| │ ^
7+
| ├── val a = bar(new C) [ widen.scala:20 ]
8+
| │ ^^^^^^^^^^
9+
| ├── def bar(t: T) = { [ widen.scala:10 ]
10+
| │ ^
11+
| ├── new A [ widen.scala:18 ]
12+
| │ ^^^^^
13+
| ├── class A { [ widen.scala:11 ]
14+
| │ ^
15+
| ├── val b = new B [ widen.scala:16 ]
16+
| │ ^^^^^
17+
| ├── class B { [ widen.scala:12 ]
18+
| │ ^
19+
| └── t.foo() // warn [ widen.scala:13 ]
20+
| ^^^^^^^

Diff for: tests/init-global/warn/widen.scala

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
trait T {
2+
def foo(): Unit
3+
}
4+
5+
class C extends T {
6+
def foo(): Unit = println("Calling foo on an instance of C!")
7+
}
8+
9+
object O:
10+
def bar(t: T) = {
11+
class A {
12+
class B {
13+
t.foo() // warn
14+
}
15+
16+
val b = new B
17+
}
18+
new A
19+
}
20+
val a = bar(new C)

0 commit comments

Comments
 (0)