Skip to content

Commit 8cee412

Browse files
committed
Use correct owner for summarizing effects in parent calls
1 parent 8afbb49 commit 8cee412

File tree

3 files changed

+89
-3
lines changed

3 files changed

+89
-3
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ object Checking {
9393
val cls = cdef.symbol.asClass
9494
val tpl = cdef.rhs.asInstanceOf[Template]
9595

96+
if state.parentsInited.contains(cls) then return
97+
9698
// mark current class as initialized, required for linearization
9799
state.parentsInited += cls
98100

@@ -101,7 +103,7 @@ object Checking {
101103
case vdef : ValDef =>
102104
val summary = Summarization.analyze(vdef.rhs)
103105
theEnv.summaryOf(cls).cacheFor(vdef.symbol, summary)
104-
if (!vdef.symbol.is(Flags.Lazy)) {
106+
if (!vdef.symbol.isOneOf(Flags.Lazy | Flags.Deferred)) {
105107
checkEffects(summary.effs)
106108
traceIndented(vdef.symbol.show + " initialized", init)
107109
state.fieldsInited += vdef.symbol
@@ -170,7 +172,7 @@ object Checking {
170172

171173
case ref =>
172174
val cls = ref.tpe.classSymbol.asClass
173-
if (!state.parentsInited.contains(cls) && cls.primaryConstructor.exists)
175+
if (cls.primaryConstructor.exists)
174176
checkConstructor(cls.primaryConstructor, ref.tpe, ref)
175177
}
176178

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ object Summarization {
318318
val ctor = cls.primaryConstructor
319319
val prefixEff =
320320
if tref.prefix == NoPrefix then Effects.empty
321-
else Summarization.analyze(tref.prefix, ref)(env.withOwner(ctor.owner)).effs
321+
else Summarization.analyze(tref.prefix, ref).effs
322322

323323
prefixEff + MethodCall(ThisRef()(ref), ctor)(ref)
324324
}

tests/init/crash/matthias4.scala

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
object A requires B {
3+
B.X getX() {
4+
return B.getX();
5+
}
6+
void setX(B.X x) {}
7+
}
8+
object B {
9+
class X {}
10+
X getX() {
11+
return new X();
12+
}
13+
void setX(X x) {}
14+
}
15+
object C requires B {
16+
object A;
17+
void test() {
18+
A.setX(B.getX());
19+
}
20+
}
21+
*/
22+
23+
trait _a extends AnyRef with _b {
24+
val a: _a;
25+
val A: A;
26+
type A <: a.AObject;
27+
trait AObject {
28+
def getX(): B.X;
29+
def setX(x: B.X): Unit;
30+
}
31+
}
32+
trait a123 extends AnyRef with _a with _b {
33+
val a: this.type = this;
34+
val A: A = new A();
35+
class A() extends AObject {
36+
def getX(): B.X = B.getX();
37+
def setX(x: B.X) = B.setX(x);
38+
}
39+
}
40+
41+
trait _b {
42+
val b: _b;
43+
val B: B;
44+
type B <: b.BObject;
45+
trait BObject {
46+
type X;
47+
def getX(): X;
48+
def setX(x: X): Unit;
49+
}
50+
}
51+
abstract class b() extends AnyRef with _b {
52+
val b: this.type = this;
53+
val B: B = new B();
54+
class B() extends BObject {
55+
class X() {}
56+
def getX(): X = new X();
57+
def setX(x: X) = ();
58+
}
59+
}
60+
61+
trait _m {
62+
val m: _m;
63+
val M: M;
64+
type M <: m.MObject;
65+
trait MObject {}
66+
}
67+
abstract class m() extends AnyRef with _m with _b {
68+
val m: this.type = this;
69+
val M: M = new M();
70+
class M() extends MObject with a123 with Linker {
71+
def test() = {
72+
val x: B.X = B.getX();
73+
A.setX(x);
74+
}
75+
}
76+
trait Linker {
77+
val b: m.this.b.type = m.this.b;
78+
val B: m.this.B.type = m.this.B;
79+
type B = m.this.B;
80+
val m: m.this.m.type = m.this.m;
81+
val M: m.this.M.type = m.this.M;
82+
type M = m.this.M;
83+
}
84+
}

0 commit comments

Comments
 (0)