Skip to content

Commit 6f6f5f9

Browse files
committed
Only final lazy vals can be paths.
Reason: They might be overridden by other lazy vals that are not realizable, and therefore risk creating bad bounds.
1 parent 5c641c9 commit 6f6f5f9

File tree

4 files changed

+36
-4
lines changed

4 files changed

+36
-4
lines changed

src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,9 @@ object SymDenotations {
525525
/** Is this a denotation of a realizable term (or an arbitrary type)? */
526526
final def isRealizable(implicit ctx: Context) =
527527
is(Stable) || isType || {
528-
val isRealizable = !is(Lazy, butNot = Module) || ctx.realizability(info) == TypeOps.Realizable
528+
val isRealizable =
529+
!is(Lazy, butNot = Module) ||
530+
is(Final) && ctx.realizability(info) == TypeOps.Realizable
529531
isRealizable && { setFlag(Stable); true }
530532
}
531533

test/dotc/tests.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ class tests extends CompilerTest {
156156
@Test def neg_i705 = compileFile(negDir, "i705-inner-value-class", xerrors = 7)
157157
@Test def neg_i866 = compileFile(negDir, "i866", xerrors = 2)
158158
@Test def neg_i974 = compileFile(negDir, "i974", xerrors = 2)
159-
@Test def neg_i1050 = compileFile(negDir, "i1050", xerrors = 3)
159+
@Test def neg_i1050 = compileFile(negDir, "i1050", xerrors = 5)
160+
@Test def neg_i1050a = compileFile(negDir, "i1050a", xerrors = 2)
160161
@Test def neg_moduleSubtyping = compileFile(negDir, "moduleSubtyping", xerrors = 4)
161162
@Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2)
162163
@Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8)

tests/neg/i1050.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ object Tiark1 {
3939
trait A { type L <: Nothing }
4040
trait B { type L >: Any}
4141
trait U {
42-
val p: B
42+
lazy val p: B
4343
def brand(x: Any): p.L = x // error: not final
4444
}
4545
trait V extends U {
@@ -53,7 +53,7 @@ object Tiark2 {
5353
trait B { type L >: Any}
5454
trait U {
5555
type X <: B
56-
val p: X
56+
lazy val p: X
5757
def brand(x: Any): p.L = x // error: not final
5858
}
5959
trait V extends U {

tests/neg/i1050a.scala

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
object Tiark1 {
2+
trait A { type L <: Nothing }
3+
trait B { type L >: Any}
4+
trait U {
5+
val p: B
6+
def brand(x: Any): p.L = x // error: not final
7+
}
8+
trait V extends U {
9+
lazy val p: A & B = ???
10+
}
11+
val v = new V {}
12+
v.brand("boom!")
13+
}
14+
object Tiark2 {
15+
trait A { type L <: Nothing }
16+
trait B { type L >: Any}
17+
trait U {
18+
type X <: B
19+
val p: X
20+
def brand(x: Any): p.L = x // error: not final
21+
}
22+
trait V extends U {
23+
type X = B & A
24+
lazy val p: X = ???
25+
}
26+
val v = new V {}
27+
v.brand("boom!"): Nothing
28+
}
29+

0 commit comments

Comments
 (0)