Skip to content

Commit 522454b

Browse files
committed
Don't treat erased as late initialized
Since we will force erased expressions to be pure values, they are always initialized.
1 parent 8dfac82 commit 522454b

File tree

7 files changed

+13
-17
lines changed

7 files changed

+13
-17
lines changed

compiler/src/dotty/tools/dotc/core/CheckRealizable.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ object CheckRealizable {
4848

4949
def boundsRealizability(tp: Type)(using Context): Realizability =
5050
new CheckRealizable().boundsRealizability(tp)
51-
52-
private val LateInitializedFlags = Lazy | Erased
5351
}
5452

5553
/** Compute realizability status.
@@ -72,7 +70,7 @@ class CheckRealizable(using Context) {
7270
/** Is symbol's definitition a lazy or erased val?
7371
* (note we exclude modules here, because their realizability is ensured separately)
7472
*/
75-
private def isLateInitialized(sym: Symbol) = sym.isOneOf(LateInitializedFlags, butNot = Module)
73+
private def isLateInitialized(sym: Symbol) = sym.is(Lazy, butNot = Module)
7674

7775
/** The realizability status of given type `tp`*/
7876
def realizability(tp: Type): Realizability = tp.dealias match {
@@ -184,7 +182,7 @@ class CheckRealizable(using Context) {
184182
private def memberRealizability(tp: Type) = {
185183
def checkField(sofar: Realizability, fld: SingleDenotation): Realizability =
186184
sofar andAlso {
187-
if (checkedFields.contains(fld.symbol) || fld.symbol.isOneOf(Private | Mutable | LateInitializedFlags))
185+
if (checkedFields.contains(fld.symbol) || fld.symbol.isOneOf(Private | Mutable | Lazy))
188186
// if field is private it cannot be part of a visible path
189187
// if field is mutable it cannot be part of a path
190188
// if field is lazy or erased it does not need to be initialized when the owning object is

tests/neg/erased-path.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ trait Obj {
66
erased val s: Sys
77
lazy val t: Sys
88

9-
type S = s.X // error: not a legal path, since nonfinal
9+
type S = s.X // now OK, was error: not a legal path, since nonfinal
1010
type T = t.X // error: not a legal path, since nonfinal
1111
}

tests/neg/i4060.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ object App {
66
trait A { type L >: Any}
77
def upcast(erased a: A)(x: Any): a.L = x
88
erased val p: A { type L <: Nothing } = p
9-
def coerce(x: Any): Int = upcast(p)(x) // error
9+
def coerce(x: Any): Int = upcast(p)(x) // ok?
1010

1111
def coerceInline(x: Any): Int = upcast(compiletime.erasedValue[A {type L <: Nothing}])(x) // error
1212

1313
trait B { type L <: Nothing }
1414
def upcast_dep_parameter(erased a: B)(x: a.L) : Int = x
1515
erased val q : B { type L >: Any } = compiletime.erasedValue
1616

17-
def coerceInlineWithB(x: Any): Int = upcast_dep_parameter(q)(x) // error
17+
def coerceInlineWithB(x: Any): Int = upcast_dep_parameter(q)(x) // ok?
1818

1919
def main(args: Array[String]): Unit = {
2020
println(coerce("Uh oh!"))

tests/neg/erased-24.scala renamed to tests/pos/erased-24.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ object Test {
1212
null.asInstanceOf[foo.X] // ok
1313
}
1414

15-
def fun2(erased foo: Foo)(erased bar: foo.B): bar.X = { // error
16-
null.asInstanceOf[bar.X] // error
15+
def fun2(erased foo: Foo)(erased bar: foo.B): bar.X = { // was error
16+
null.asInstanceOf[bar.X] // was error
1717
}
1818
}
1919

tests/neg/erased-pathdep-1.scala renamed to tests/pos/erased-pathdep-1.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
//> using options -language:experimental.erasedDefinitions
22

3-
// Could become a neg test if we had totality checking for erased arguments
4-
53
object Test {
64

75
fun1(new Bar)
86
val _ = fun2(new Bar)
97
val _ = fun3(new Bar)
108

11-
def fun1[F >: Bar <: Foo](erased f: F): f.X = null.asInstanceOf[f.X] // error // error
12-
def fun2[F >: Bar <: Foo](erased f: F)(erased bar: f.B): f.B = null.asInstanceOf[f.B] // error // error // error
13-
def fun3[F >: Bar <: Foo](erased f: F)(erased b: f.B): b.X = null.asInstanceOf[b.X] // error // error // error
9+
def fun1[F >: Bar <: Foo](erased f: F): f.X = null.asInstanceOf[f.X]
10+
def fun2[F >: Bar <: Foo](erased f: F)(erased bar: f.B): f.B = null.asInstanceOf[f.B]
11+
def fun3[F >: Bar <: Foo](erased f: F)(erased b: f.B): b.X = null.asInstanceOf[b.X]
1412
}
1513

1614
class Foo {

tests/neg/erased-pathdep-2.scala renamed to tests/pos/erased-pathdep-2.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ object Test {
77
type F >: Bar <: Foo
88

99
class A(erased val f: F) {
10-
type F1 <: f.X // error
11-
type F2[Z <: f.X] // error
10+
type F1 <: f.X // was error
11+
type F2[Z <: f.X] // was error
1212
}
1313

1414
}

tests/neg/erased-singleton.scala renamed to tests/pos/erased-singleton.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ trait Sys
55
trait Obj {
66
erased val s: Sys
77

8-
type S = s.type // error: non final
8+
type S = s.type // now OK, was error: non final
99
}

0 commit comments

Comments
 (0)