-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Use unitialized
for wildcard initializers
#11231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
33501d3
eab08cf
f073d15
c1b17aa
60f7f69
5543550
493082b
90907ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--- | ||
layout: doc-page | ||
title: "Dropped: wildcard initializer" | ||
--- | ||
|
||
The syntax | ||
```scala | ||
var x: A = _ | ||
``` | ||
that was used to indicate an uninitialized field, has been dropped. | ||
At its place there is a special value `uninitialized` in the `scala.compiletime` package. To get an uninitialized field, you now write | ||
nicolasstucki marked this conversation as resolved.
Show resolved
Hide resolved
|
||
```scala | ||
import scala.compiletime.uninitialized | ||
|
||
var x: A = uninitialized | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently, we also support var a = uninitialized[A] This seems to be leaking implementation details. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right. We it's better to define it like this: @compileTimeOnly("`uninitialized` can only be used as the right hand side of a mutable field definition")
def uninitialized: Nothing = ??? |
||
``` | ||
To enable cross-compilation, `_` is still supported, but it will be dropped in a future 3.x version. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import compiletime.uninitialized | ||
|
||
class Memo[A](x: => A): | ||
private var cached: A = _ // error | ||
private var known: Boolean = false | ||
def force = | ||
if !known then | ||
known = true | ||
cached = x | ||
cached |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
-- Error: tests/neg/i11225.scala:5:16 ---------------------------------------------------------------------------------- | ||
5 | val x1: Int = uninitialized // error | ||
| ^^^^^^^^^^^^^ | ||
| `uninitialized` can only be used as the right hand side of a mutable field definition | ||
-- Error: tests/neg/i11225.scala:6:28 ---------------------------------------------------------------------------------- | ||
6 | var x2: Int = if ??? then uninitialized else uninitialized // error // error | ||
| ^^^^^^^^^^^^^ | ||
| `uninitialized` can only be used as the right hand side of a mutable field definition | ||
-- Error: tests/neg/i11225.scala:6:47 ---------------------------------------------------------------------------------- | ||
6 | var x2: Int = if ??? then uninitialized else uninitialized // error // error | ||
| ^^^^^^^^^^^^^ | ||
| `uninitialized` can only be used as the right hand side of a mutable field definition | ||
-- Error: tests/neg/i11225.scala:9:28 ---------------------------------------------------------------------------------- | ||
9 | var x5: () => Int = () => uninitialized // error | ||
| ^^^^^^^^^^^^^ | ||
| `uninitialized` can only be used as the right hand side of a mutable field definition | ||
-- Error: tests/neg/i11225.scala:10:18 --------------------------------------------------------------------------------- | ||
10 | var x6: Int = { uninitialized } // error | ||
| ^^^^^^^^^^^^^ | ||
| `uninitialized` can only be used as the right hand side of a mutable field definition | ||
nicolasstucki marked this conversation as resolved.
Show resolved
Hide resolved
|
||
-- Error: tests/neg/i11225.scala:13:22 --------------------------------------------------------------------------------- | ||
13 | var cached: Int = uninitialized // error | ||
| ^^^^^^^^^^^^^ | ||
| `uninitialized` can only be used as the right hand side of a mutable field definition | ||
-- Error: tests/neg/i11225.scala:14:30 --------------------------------------------------------------------------------- | ||
14 | cached = if x then 1 else uninitialized // error | ||
| ^^^^^^^^^^^^^ | ||
| `uninitialized` can only be used as the right hand side of a mutable field definition | ||
-- Error: tests/neg/i11225.scala:17:4 ---------------------------------------------------------------------------------- | ||
17 | uninitialized // error | ||
| ^^^^^^^^^^^^^ | ||
| `uninitialized` can only be used as the right hand side of a mutable field definition | ||
-- Error: tests/neg/i11225.scala:18:4 ---------------------------------------------------------------------------------- | ||
18 | uninitialized // error | ||
| ^^^^^^^^^^^^^ | ||
| `uninitialized` can only be used as the right hand side of a mutable field definition | ||
-- Error: tests/neg/i11225.scala:23:4 ---------------------------------------------------------------------------------- | ||
23 | uninitialized // error | ||
| ^^^^^^^^^^^^^ | ||
| `uninitialized` can only be used as the right hand side of a mutable field definition | ||
-- Error: tests/neg/i11225.scala:30:16 --------------------------------------------------------------------------------- | ||
30 | var x7: Int = uni // error | ||
| ^^^ | ||
| `uninitialized` can only be used as the right hand side of a mutable field definition | ||
| This location contains code that was inlined from i11225.scala:25 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import compiletime.uninitialized | ||
|
||
class Test: | ||
|
||
val x1: Int = uninitialized // error | ||
var x2: Int = if ??? then uninitialized else uninitialized // error // error | ||
var x3: Int = if true then uninitialized else 1 // ok | ||
var x4: Int = if false then uninitialized else 1 // ok | ||
var x5: () => Int = () => uninitialized // error | ||
var x6: Int = { uninitialized } // error | ||
|
||
def f(x: Boolean) = | ||
var cached: Int = uninitialized // error | ||
cached = if x then 1 else uninitialized // error | ||
|
||
var c: Int = | ||
uninitialized // error | ||
uninitialized // error | ||
2 | ||
|
||
var d: Int = | ||
println("pseudo init") | ||
uninitialized // error | ||
|
||
transparent inline def uni = uninitialized | ||
|
||
inline def g(inline x: Int): Unit = () | ||
def f2 = g(uninitialized) // this one is ok since `uninitialized` is inlined away | ||
|
||
var x7: Int = uni // error | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be ok as the code we end up with is var x7: Int = uni // ok
// after inlining
var x7: Int = uninitialized // still ok There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Otherwise, we would need to make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's an error since we end up with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then it would be inconsistent with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need not overthink this. The intention is that you should not use |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
|
||
class Regress { | ||
var v: Int = _ | ||
var v: Int = compiletime.uninitialized | ||
def f = 42 | ||
var w: Int = (_) // error: not default value syntax | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uninitialized
is not erased anymore and the transformation has nothing to do with pruning erased definitions. It is also unrelated toerased
in general as this operation does produce a value at runtime (even though it is elided). This should be done somewhere else. FirstTransform might be a good candidate as we are transformingvar x: T = uninitialized
to the canonical form that erasure understands.