Skip to content

Commit 6b12bf0

Browse files
Deprecation warnings for old syntax: var x = _ (#18821)
First part #18861 * In `3.4` we emit the deprecation warning * In `future` we emit we make this syntax an error * Add patch. Not ideal because we need to use the full path of `uninitialized` ```scala //> using options -source future var x: Int = _ // error ``` ```diff //> using options -rewrite -source 3.4-migration - var x: Int = _ + var x: Int = scala.compiletime.uninitialized ```
2 parents a7aa5f0 + 951bbae commit 6b12bf0

File tree

19 files changed

+72
-22
lines changed

19 files changed

+72
-22
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+8-5
Original file line numberDiff line numberDiff line change
@@ -3673,11 +3673,14 @@ object Parsers {
36733673
subExpr() match
36743674
case rhs0 @ Ident(name) if placeholderParams.nonEmpty && name == placeholderParams.head.name
36753675
&& !tpt.isEmpty && mods.is(Mutable) && lhs.forall(_.isInstanceOf[Ident]) =>
3676-
if sourceVersion.isAtLeast(future) then
3677-
deprecationWarning(
3678-
em"""`= _` has been deprecated; use `= uninitialized` instead.
3679-
|`uninitialized` can be imported with `scala.compiletime.uninitialized`.""",
3680-
rhsOffset)
3676+
report.gradualErrorOrMigrationWarning(
3677+
em"""`= _` has been deprecated; use `= uninitialized` instead.
3678+
|`uninitialized` can be imported with `scala.compiletime.uninitialized`.${rewriteNotice(`3.4-migration`)}""",
3679+
in.sourcePos(rhsOffset),
3680+
warnFrom = `3.4`,
3681+
errorFrom = future)
3682+
if sourceVersion.isMigrating && sourceVersion.isAtLeast(`3.4-migration`) then
3683+
patch(source, Span(rhsOffset, rhsOffset + 1), "scala.compiletime.uninitialized")
36813684
placeholderParams = placeholderParams.tail
36823685
atSpan(rhs0.span) { Ident(nme.WILDCARD) }
36833686
case rhs0 => rhs0

compiler/test/dotty/tools/dotc/CompilationTests.scala

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class CompilationTests {
6060
compileFile("tests/rewrites/rewrites.scala", defaultOptions.and("-source", "3.0-migration").and("-rewrite", "-indent")),
6161
compileFile("tests/rewrites/rewrites3x.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
6262
compileFile("tests/rewrites/rewrites3x-fatal-warnings.scala", defaultOptions.and("-rewrite", "-source", "future-migration", "-Xfatal-warnings")),
63+
compileFile("tests/rewrites/uninitialized-var.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
6364
compileFile("tests/rewrites/with-type-operator.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
6465
compileFile("tests/rewrites/private-this.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
6566
compileFile("tests/rewrites/filtering-fors.scala", defaultOptions.and("-rewrite", "-source", "3.2-migration")),

language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala

+5-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import scala.collection._
1515
import scala.jdk.CollectionConverters._
1616
import scala.util.control.NonFatal
1717
import scala.io.Codec
18+
import scala.compiletime.uninitialized
1819

1920
import dotc._
2021
import ast.{Trees, tpd, untpd}
@@ -54,14 +55,14 @@ class DottyLanguageServer extends LanguageServer
5455
import lsp4j.jsonrpc.messages.{Either => JEither}
5556
import lsp4j._
5657

57-
private var rootUri: String = _
58+
private var rootUri: String = uninitialized
5859

59-
private var myClient: DottyClient = _
60+
private var myClient: DottyClient = uninitialized
6061
def client: DottyClient = myClient
6162

62-
private var myDrivers: mutable.Map[ProjectConfig, InteractiveDriver] = _
63+
private var myDrivers: mutable.Map[ProjectConfig, InteractiveDriver] = uninitialized
6364

64-
private var myDependentProjects: mutable.Map[ProjectConfig, mutable.Set[ProjectConfig]] = _
65+
private var myDependentProjects: mutable.Map[ProjectConfig, mutable.Set[ProjectConfig]] = uninitialized
6566

6667
def drivers: Map[ProjectConfig, InteractiveDriver] = thisServer.synchronized {
6768
if myDrivers == null then

language-server/test/dotty/tools/languageserver/util/PositionContext.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ package dotty.tools.languageserver.util
33
import dotty.tools.languageserver.util.embedded.CodeMarker
44
import dotty.tools.languageserver.util.server.TestFile
55

6+
import scala.compiletime.uninitialized
7+
68
class PositionContext(positionMap: Map[CodeMarker, (TestFile, Int, Int)]) {
7-
private var lastKey: CodeMarker = _
8-
private var lastValue: (TestFile, Int, Int) = _
9+
private var lastKey: CodeMarker = uninitialized
10+
private var lastValue: (TestFile, Int, Int) = uninitialized
911
def positionOf(pos: CodeMarker): (TestFile, Int, Int) = {
1012
if (lastKey eq pos) lastValue
1113
else {

language-server/test/dotty/tools/languageserver/util/server/TestServer.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import java.nio.file.{Files, Path}
77
import java.nio.charset.StandardCharsets
88
import java.util
99

10+
import scala.compiletime.uninitialized
11+
1012
import dotty.tools.dotc.Main
1113
import dotty.tools.dotc.reporting.{Reporter, ThrowingReporter}
1214
import dotty.tools.io.Directory
@@ -17,7 +19,7 @@ import org.eclipse.lsp4j.{ DidOpenTextDocumentParams, InitializeParams, Initiali
1719
class TestServer(testFolder: Path, projects: List[Project]) {
1820

1921
val server = new DottyLanguageServer
20-
var client: TestClient = _
22+
var client: TestClient = uninitialized
2123

2224
init()
2325

library/src/scala/util/control/NonLocalReturns.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package scala.util.control
22

3+
import scala.compiletime.uninitialized
4+
35
/** Library implementation of nonlocal return.
46
*
57
* Usage:
@@ -21,7 +23,7 @@ package scala.util.control
2123
object NonLocalReturns {
2224
@deprecated("Use scala.util.boundary.Break instead", "3.3")
2325
class ReturnThrowable[T] extends ControlThrowable {
24-
private var myResult: T = _
26+
private var myResult: T = uninitialized
2527
def throwReturn(result: T): Nothing = {
2628
myResult = result
2729
throw this

presentation-compiler/src/main/dotty/tools/pc/MetalsDriver.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import dotty.tools.dotc.interactive.InteractiveDriver
77
import dotty.tools.dotc.reporting.Diagnostic
88
import dotty.tools.dotc.util.SourceFile
99

10+
import scala.compiletime.uninitialized
11+
1012
/**
1113
* MetalsDriver is a wrapper class that provides a compilation cache for InteractiveDriver.
1214
* MetalsDriver skips running compilation if
@@ -29,7 +31,7 @@ class MetalsDriver(
2931
override val settings: List[String]
3032
) extends InteractiveDriver(settings):
3133

32-
@volatile private var lastCompiledURI: URI = _
34+
@volatile private var lastCompiledURI: URI = uninitialized
3335

3436
private def alreadyCompiled(uri: URI, content: Array[Char]): Boolean =
3537
compilationUnits.get(uri) match

project/Build.scala

+1
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,7 @@ object Build {
12671267
ivyConfigurations += SourceDeps.hide,
12681268
transitiveClassifiers := Seq("sources"),
12691269
Compile / scalacOptions ++= Seq("-Yexplicit-nulls", "-Ysafe-init"),
1270+
Compile / scalacOptions ++= Seq("-source", "3.3"), // To avoid fatal migration warnings
12701271
Compile / sourceGenerators += Def.task {
12711272
val s = streams.value
12721273
val cacheDir = s.cacheDirectory

sbt-test/compilerReporter/i14576/Test.scala

-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,5 @@ object Test:
1010
def f(x: Text) = println(x.str)
1111
f("abc")
1212

13-
// private[this] and = _ are deprecated under -source:future
14-
private[this] var x: AnyRef = _
15-
1613
// under -source:future, `_` is deprecated for wildcard arguments of types: use `?` instead
1714
val xs: List[_] = Nil

sbt-test/compilerReporter/i14576/build.sbt

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ lazy val root = (project in file("."))
2424
},
2525
assertDeprecationSummary := {
2626
assert {
27-
FakePrintWriter.messages.exists(_.contains("there were 2 deprecation warnings; re-run with -deprecation for details"))
27+
FakePrintWriter.messages.exists(_.contains("there was 1 deprecation warning; re-run with -deprecation for details"))
2828
}
2929
},
3030
assertNoDeprecationSummary := {

tests/neg/i4812.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//> using options -Werror
22
object Test:
3-
var prev: Any = _
3+
var prev: Any = scala.compiletime.uninitialized
44

55
def test[T](x: T): T =
66
class A(val elem: (T, Boolean))
@@ -55,7 +55,7 @@ object Test:
5555

5656
def test6[T](x: T): T =
5757
class A { var b: B = null }
58-
class B { var a: A = null; var elem: T = _ }
58+
class B { var a: A = null; var elem: T = scala.compiletime.uninitialized }
5959
prev match
6060
case prev: A => // error: the type test for A cannot be checked at runtime
6161
prev.b.elem
@@ -88,7 +88,7 @@ object Test:
8888
case x: B => x
8989

9090
sealed class A
91-
var prevA: A = _
91+
var prevA: A = scala.compiletime.uninitialized
9292
def test10: A =
9393
val methodCallId = System.nanoTime()
9494
class B(val id: Long) extends A

tests/neg/uninitialized-3.4.check

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- Error: tests/neg/uninitialized-3.4.scala:7:15 -----------------------------------------------------------------------
2+
7 | var a: Int = _ // error: migration warning
3+
| ^
4+
| `= _` has been deprecated; use `= uninitialized` instead.
5+
| `uninitialized` can be imported with `scala.compiletime.uninitialized`.
6+
| This construct can be rewritten automatically under -rewrite -source 3.4-migration.

tests/neg/uninitialized-3.4.scala

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//> using options -Werror
2+
3+
import scala.language.`3.4`
4+
import scala.compiletime.uninitialized
5+
6+
class Foo:
7+
var a: Int = _ // error: migration warning
8+
var b: Int = uninitialized
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//> using options -Werror
2+
3+
import scala.language.`future-migration`
4+
import scala.compiletime.uninitialized
5+
6+
class Foo:
7+
var a: Int = _ // error: migration warning
8+
var b: Int = uninitialized

tests/neg/uninitialized-future.scala

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import scala.language.future
2+
import scala.compiletime.uninitialized
3+
4+
class Foo:
5+
var a: Int = _ // error
6+
var b: Int = uninitialized

tests/patmat/i12805-fallout.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import scala.annotation.unchecked.uncheckedVariance
2+
import scala.compiletime.uninitialized
23

34
type Untyped = Null
45

@@ -7,7 +8,7 @@ class Type
78
abstract class Tree[-T >: Untyped] {
89
type ThisTree[T >: Untyped] <: Tree[T]
910

10-
protected var myTpe: T @uncheckedVariance = _
11+
protected var myTpe: T @uncheckedVariance = uninitialized
1112

1213
def withType(tpe: Type): ThisTree[Type] = {
1314
val tree = this.asInstanceOf[ThisTree[Type]]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import scala.language.`future-migration`
2+
import scala.compiletime.uninitialized
3+
4+
class Foo:
5+
var a: Int = _ // warn
6+
var b: Int = uninitialized
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class Foo:
2+
var a: Int = scala.compiletime.uninitialized
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class Foo:
2+
var a: Int = _

0 commit comments

Comments
 (0)