Skip to content

Commit f6a5802

Browse files
committed
By-name parameters are not stable values.
1 parent 187c241 commit f6a5802

File tree

5 files changed

+30
-27
lines changed

5 files changed

+30
-27
lines changed

Diff for: src/dotty/tools/dotc/core/CheckRealizable.scala

+6-4
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,12 @@ class CheckRealizable(implicit ctx: Context) {
5858
*/
5959
private val checkedFields: mutable.Set[Symbol] = mutable.LinkedHashSet[Symbol]()
6060

61-
/** Is this type a path with some part that is initialized on use? */
61+
/** Is this type a path with some part that is initialized on use?
62+
* (note we exclude modules here, because their realizability is ensured separately).
63+
*/
6264
private def isLateInitialized(tp: Type): Boolean = tp.dealias match {
6365
case tp: TermRef =>
64-
tp.symbol.isLateInitialized || isLateInitialized(tp.prefix)
66+
tp.symbol.is(Lazy, butNot = Module) || isLateInitialized(tp.prefix)
6567
case _: SingletonType | NoPrefix =>
6668
false
6769
case tp: TypeRef =>
@@ -130,8 +132,8 @@ class CheckRealizable(implicit ctx: Context) {
130132
}
131133
if (ctx.settings.strict.value)
132134
// check fields only under strict mode for now.
133-
// Reason: We do track nulls, so an embedded field could well be nullable
134-
// which means it is not a path and need not be checked; but we cannot recognize
135+
// Reason: An embedded field could well be nullable, which means it
136+
// should not be part of a path and need not be checked; but we cannot recognize
135137
// this situation until we have a typesystem that tracks nullability.
136138
((Realizable: Realizability) /: tp.fields)(checkField)
137139
else

Diff for: src/dotty/tools/dotc/core/SymDenotations.scala

+1-7
Original file line numberDiff line numberDiff line change
@@ -521,13 +521,7 @@ object SymDenotations {
521521

522522
/** Is this a denotation of a stable term (or an arbitrary type)? */
523523
final def isStable(implicit ctx: Context) =
524-
isType || !is(UnstableValue, butNot = Stable)
525-
526-
/** Field is initialized on use, not on definition;
527-
* we do not count modules as fields here.
528-
*/
529-
final def isLateInitialized(implicit ctx: Context) =
530-
is(Lazy, butNot = Module) || is(Param) && info.isInstanceOf[ExprType]
524+
isType || is(Stable) || !(is(UnstableValue) || info.isInstanceOf[ExprType])
531525

532526
/** Is this a "real" method? A real method is a method which is:
533527
* - not an accessor

Diff for: test/dotc/tests.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,9 @@ class tests extends CompilerTest {
162162
@Test def neg_i803 = compileFile(negDir, "i803", xerrors = 2)
163163
@Test def neg_i866 = compileFile(negDir, "i866", xerrors = 2)
164164
@Test def neg_i974 = compileFile(negDir, "i974", xerrors = 2)
165-
@Test def neg_i1050 = compileFile(negDir, "i1050", List("-strict"), xerrors = 13)
165+
@Test def neg_i1050 = compileFile(negDir, "i1050", List("-strict"), xerrors = 11)
166166
@Test def neg_i1050a = compileFile(negDir, "i1050a", xerrors = 2)
167-
@Test def neg_i1050c = compileFile(negDir, "i1050c", xerrors = 4)
167+
@Test def neg_i1050c = compileFile(negDir, "i1050c", xerrors = 8)
168168
@Test def neg_moduleSubtyping = compileFile(negDir, "moduleSubtyping", xerrors = 4)
169169
@Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2)
170170
@Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8)

Diff for: tests/neg/i1050.scala

-14
Original file line numberDiff line numberDiff line change
@@ -80,20 +80,6 @@ object Tiark3 {
8080
val v = new V {}
8181
v.brand("boom!"): Nothing
8282
}
83-
object Tiark5 {
84-
trait A { type L <: Nothing }
85-
trait B { type L >: Any }
86-
def f(x: => A & B)(y: Any):Nothing = (y:x.L) // error: underlying conflicting bounds
87-
f(???)("boom!")
88-
}
89-
object Tiark5Inherited {
90-
trait A { type L <: Nothing }
91-
trait B { type L >: Any }
92-
trait A2 extends A
93-
trait B2 extends B
94-
def f(x: => A2 & B2)(y: Any):Nothing = (y:x.L) // error: underlying conflicting bounds
95-
f(???)("boom!")
96-
}
9783
object Tiark6 {
9884
trait B { type L >: Any }
9985
trait A { type L <: Nothing }

Diff for: tests/neg/i1050c.scala

+21
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,24 @@ object Tiark4 {
2929
object V { // error: cannot be instantiated
3030
type Y >: Any <: Nothing // error: only classes can have declared but undefined members
3131
}
32+
object Tiark5 {
33+
trait A { type L <: Nothing }
34+
trait B { type L >: Any }
35+
def f(x: => A & B)(y: Any):Nothing = (y:x.L) // error: underlying conflicting bounds
36+
f(???)("boom!")
37+
}
38+
object Tiark5Inherited {
39+
trait A { type L <: Nothing }
40+
trait B { type L >: Any }
41+
trait A2 extends A
42+
trait B2 extends B
43+
def f(x: => A2 & B2)(y: Any):Nothing = (y:x.L) // error: underlying conflicting bounds
44+
f(???)("boom!")
45+
}
46+
object Tiark7 {
47+
trait A { type L <: Nothing }
48+
trait B { type L >: Any }
49+
def f(x: => B)(y: Any):x.L = y // error: x is not stable
50+
def f1(x: => A & B)(y: Any):Nothing = f(x)(y) // error: type mismatch
51+
f1(???)("boom!"): Nothing
52+
}

0 commit comments

Comments
 (0)