Skip to content

Commit 74bcfd7

Browse files
committed
Fix #5854: check type annotations for soundness
1 parent fe38137 commit 74bcfd7

File tree

3 files changed

+46
-17
lines changed

3 files changed

+46
-17
lines changed

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

+17-17
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ object Summarization {
107107

108108
case Typed(expr, tpt) =>
109109
if (tpt.tpe.hasAnnotation(defn.UncheckedAnnot)) Summary.empty
110-
else analyze(expr)
110+
else analyze(expr) ++ effectsOfType(tpt.tpe, tpt)
111111

112112
case NamedArg(name, arg) =>
113113
analyze(arg)
@@ -201,20 +201,7 @@ object Summarization {
201201

202202
case tdef: TypeDef =>
203203
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 TermRef(_: SingletonType, _) =>
210-
summary = summary + analyze(tp, tdef.rhs)
211-
case _ =>
212-
traverseChildren(tp)
213-
}
214-
}
215-
traverser.traverse(tp)
216-
summary
217-
}
204+
else Summary(effectsOfType(tdef.symbol.info, tdef.rhs))
218205

219206
case _: Import | _: Export =>
220207
Summary.empty
@@ -227,6 +214,19 @@ object Summarization {
227214
else summary
228215
}
229216

217+
private def effectsOfType(tp: Type, source: Tree)(implicit env: Env): Effects =
218+
var summary = Summary.empty
219+
val traverser = new TypeTraverser {
220+
def traverse(tp: Type): Unit = tp match {
221+
case TermRef(_: SingletonType, _) =>
222+
summary = summary + analyze(tp, source)
223+
case _ =>
224+
traverseChildren(tp)
225+
}
226+
}
227+
traverser.traverse(tp)
228+
summary.effs
229+
230230
def analyze(tp: Type, source: Tree)(implicit env: Env): Summary =
231231
trace("summarizing " + tp.show, init, s => s.asInstanceOf[Summary].show) {
232232
val summary: Summary = tp match {
@@ -257,8 +257,8 @@ object Summarization {
257257
}
258258
Summary(pots2, effs)
259259

260-
case _: TermParamRef =>
261-
// possible from type definitions
260+
case _: TermParamRef | _: RecThis =>
261+
// possible from checking effects of types
262262
Summary.empty
263263

264264
case _ =>

Diff for: tests/init/neg/i5854.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class B {
2+
val a: String = (((1: Any): b.A): Nothing): String
3+
val b: { type A >: Any <: Nothing } = loop() // error
4+
def loop(): Nothing = loop()
5+
}

Diff for: tests/neg-strict/i5854.scala

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
object bar {
2+
trait Sub {
3+
type M
4+
type L <: M
5+
type U >: M
6+
type M2 >: L <: U
7+
}
8+
class Box[V](val v: V)
9+
10+
class Caster[LL, UU] {
11+
trait S2 {
12+
type L = LL
13+
type U = UU
14+
}
15+
final lazy val nothing: Nothing = nothing
16+
final lazy val sub: S2 & Sub = nothing
17+
final lazy val box : Box[S2 & Sub] = new Box(nothing)
18+
def upcast(t: box.v.M2): box.v.M2 = t // error // error
19+
}
20+
def main(args : Array[String]) : Unit = {
21+
val zero : String = (new Caster[Int,String]()).upcast(0)
22+
println("...")
23+
}
24+
}

0 commit comments

Comments
 (0)