Skip to content

Commit 9f9f944

Browse files
committed
See through static calls on inner objects
1 parent b38aef5 commit 9f9f944

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

compiler/src/dotty/tools/dotc/transform/init/Checking.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ object Checking {
9595
&& (obj.enclosingClass == state.thisClass
9696
|| obj.appearsInside(state.thisClass) && state.superConstrCalled)
9797

98+
/** Whether the obj is directly nested inside the current class */
99+
private def isNestedObject(obj: Global)(using state: State): Boolean =
100+
obj.symbol.owner == state.thisClass
101+
98102
// ------- checking construtor ---------------------------
99103

100104
/** Check that the given concrete class may be initialized safely
@@ -257,6 +261,9 @@ object Checking {
257261
val target = resolve(obj.moduleClass, sym)
258262
if isObjectAccessSafe(obj) then
259263
check(MethodCall(ThisRef()(obj.source), target)(eff.source))
264+
else if isNestedObject(obj) then
265+
val pot = FieldReturn(ThisRef()(obj.source), obj.symbol)(obj.source)
266+
check(MethodCall(pot, target)(eff.source))
260267
else
261268
state.dependencies += StaticCall(obj.moduleClass, target)(state.path)
262269
Errors.empty

tests/init/neg/global-cycle12.scala

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// from Scala.js
2+
object Names {
3+
private final val ConstructorSimpleEncodedName: String =
4+
"<init>"
5+
6+
final class SimpleMethodName(encoded: String)
7+
8+
object SimpleMethodName {
9+
def apply(name: String): SimpleMethodName =
10+
val res = name == ConstructorSimpleEncodedName
11+
new SimpleMethodName(name)
12+
}
13+
14+
val ConstructorSimpleName: SimpleMethodName =
15+
SimpleMethodName(ConstructorSimpleEncodedName)
16+
}
17+
18+
object A { // error
19+
val n: Int = B.m
20+
}
21+
22+
object B {
23+
val m: Int = A.n
24+
}

tests/init/neg/t3273.check

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22
4 | val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error
33
| ^^^^^^^^^^^^^^^
44
| Promoting the value to fully-initialized is unsafe.
5-
| Calling trace:
5+
| Calling trace (full):
66
| -> val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error [ t3273.scala:4 ]
77
|
88
| The unsafe promotion may cause the following problem(s):
99
|
10-
| 1. Access non-initialized value num1. Calling trace:
10+
| 1. Access non-initialized value num1. Calling trace (full):
1111
| -> val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error [ t3273.scala:4 ]
1212
-- Error: tests/init/neg/t3273.scala:5:61 ------------------------------------------------------------------------------
1313
5 | val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1515
| Promoting the value to fully-initialized is unsafe.
16-
| Calling trace:
16+
| Calling trace (full):
1717
| -> val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error [ t3273.scala:5 ]
1818
|
1919
| The unsafe promotion may cause the following problem(s):
2020
|
21-
| 1. Access non-initialized value num2. Calling trace:
21+
| 1. Access non-initialized value num2. Calling trace (full):
2222
| -> val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error [ t3273.scala:5 ]

0 commit comments

Comments
 (0)