Skip to content

Commit 07a2e41

Browse files
committed
WIP: Use initialization checker for soundness
-- Warning: tests/init/neg/i11572.scala:8:6 ------------------------------------ 8 | val t: Bounded = new Bounded { | ^ | Access non-initialized value t. Calling trace: | -> } [ i11572.scala:11 ] | -> override type T >: t.T <: t.T [ i11572.scala:10 ] 1 warning found
1 parent 45d0678 commit 07a2e41

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ object Summarization {
140140
val Summary(pots, effs) = analyze(selector)
141141
val init = Summary(Potentials.empty, pots.promote(selector) ++ effs)
142142
cases.foldLeft(init) { (acc, cas) =>
143-
acc union analyze(cas.body)
143+
acc + analyze(cas.body)
144144
}
145145

146146
// case CaseDef(pat, guard, body) =>
@@ -162,7 +162,7 @@ object Summarization {
162162

163163
case Try(block, cases, finalizer) =>
164164
val Summary(pots, effs) = cases.foldLeft(analyze(block)) { (acc, cas) =>
165-
acc union analyze(cas.body)
165+
acc + analyze(cas.body)
166166
}
167167
val Summary(_, eff2) = if (finalizer.isEmpty) Summary.empty else analyze(finalizer)
168168
Summary(pots, effs ++ eff2)
@@ -199,8 +199,22 @@ object Summarization {
199199
Summary(pots.promote(ddef) ++ effs)
200200
}
201201

202-
case _: TypeDef =>
203-
Summary.empty
202+
case tdef: TypeDef =>
203+
if tdef.isClassDef then Summary.empty
204+
else {
205+
var summary = Summary.empty
206+
val tp = tdef.symbol.info
207+
val traverser = new TypeTraverser {
208+
def traverse(tp: Type): Unit = tp match {
209+
case tp: TermRef =>
210+
summary = summary + analyze(tp, tdef.rhs)
211+
case _ =>
212+
traverseChildren(tp)
213+
}
214+
}
215+
traverser.traverse(tp)
216+
summary
217+
}
204218

205219
case _: Import | _: Export =>
206220
Summary.empty

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import config.Printers.init
1414
import Potentials._, Effects._, Util._
1515

1616
case class Summary(pots: Potentials, effs: Effects) {
17-
def union(summary2: Summary): Summary =
17+
def +(summary2: Summary): Summary =
1818
Summary(pots ++ summary2.pots, this.effs ++ summary2.effs)
1919

2020
def +(pot: Potential): Summary =

tests/init/neg/i11572.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class A {
2+
trait Cov[+X] {
3+
def get: X
4+
}
5+
trait Bounded {
6+
type T >: Cov[Int] <: Cov[String]
7+
}
8+
val t: Bounded = new Bounded { // error
9+
// Note: using this instead of t produces an error (as expected)
10+
override type T >: t.T <: t.T
11+
}
12+
13+
val covInt = new Cov[Int] {
14+
override def get: Int = 3
15+
}
16+
val str: String = ((covInt: t.T): Cov[String]).get // ClassCastException: class Integer cannot be cast to class String
17+
}

0 commit comments

Comments
 (0)