Skip to content

Commit

Permalink
Deprecation warnings for old syntax: var x = _
Browse files Browse the repository at this point in the history
* 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`
  • Loading branch information
nicolasstucki committed Nov 9, 2023
1 parent a90db4f commit 951bbae
Show file tree
Hide file tree
Showing 19 changed files with 72 additions and 22 deletions.
13 changes: 8 additions & 5 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3665,11 +3665,14 @@ object Parsers {
subExpr() match
case rhs0 @ Ident(name) if placeholderParams.nonEmpty && name == placeholderParams.head.name
&& !tpt.isEmpty && mods.is(Mutable) && lhs.forall(_.isInstanceOf[Ident]) =>
if sourceVersion.isAtLeast(future) then
deprecationWarning(
em"""`= _` has been deprecated; use `= uninitialized` instead.
|`uninitialized` can be imported with `scala.compiletime.uninitialized`.""",
rhsOffset)
report.gradualErrorOrMigrationWarning(
em"""`= _` has been deprecated; use `= uninitialized` instead.
|`uninitialized` can be imported with `scala.compiletime.uninitialized`.${rewriteNotice(`3.4-migration`)}""",
in.sourcePos(rhsOffset),
warnFrom = `3.4`,
errorFrom = future)
if sourceVersion.isMigrating && sourceVersion.isAtLeast(`3.4-migration`) then
patch(source, Span(rhsOffset, rhsOffset + 1), "scala.compiletime.uninitialized")
placeholderParams = placeholderParams.tail
atSpan(rhs0.span) { Ident(nme.WILDCARD) }
case rhs0 => rhs0
Expand Down
1 change: 1 addition & 0 deletions compiler/test/dotty/tools/dotc/CompilationTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class CompilationTests {
compileFile("tests/rewrites/rewrites.scala", defaultOptions.and("-source", "3.0-migration").and("-rewrite", "-indent")),
compileFile("tests/rewrites/rewrites3x.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
compileFile("tests/rewrites/rewrites3x-fatal-warnings.scala", defaultOptions.and("-rewrite", "-source", "future-migration", "-Xfatal-warnings")),
compileFile("tests/rewrites/uninitialized-var.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
compileFile("tests/rewrites/with-type-operator.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
compileFile("tests/rewrites/private-this.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
compileFile("tests/rewrites/filtering-fors.scala", defaultOptions.and("-rewrite", "-source", "3.2-migration")),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import scala.collection._
import scala.jdk.CollectionConverters._
import scala.util.control.NonFatal
import scala.io.Codec
import scala.compiletime.uninitialized

import dotc._
import ast.{Trees, tpd, untpd}
Expand Down Expand Up @@ -54,14 +55,14 @@ class DottyLanguageServer extends LanguageServer
import lsp4j.jsonrpc.messages.{Either => JEither}
import lsp4j._

private var rootUri: String = _
private var rootUri: String = uninitialized

private var myClient: DottyClient = _
private var myClient: DottyClient = uninitialized
def client: DottyClient = myClient

private var myDrivers: mutable.Map[ProjectConfig, InteractiveDriver] = _
private var myDrivers: mutable.Map[ProjectConfig, InteractiveDriver] = uninitialized

private var myDependentProjects: mutable.Map[ProjectConfig, mutable.Set[ProjectConfig]] = _
private var myDependentProjects: mutable.Map[ProjectConfig, mutable.Set[ProjectConfig]] = uninitialized

def drivers: Map[ProjectConfig, InteractiveDriver] = thisServer.synchronized {
if myDrivers == null then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package dotty.tools.languageserver.util
import dotty.tools.languageserver.util.embedded.CodeMarker
import dotty.tools.languageserver.util.server.TestFile

import scala.compiletime.uninitialized

class PositionContext(positionMap: Map[CodeMarker, (TestFile, Int, Int)]) {
private var lastKey: CodeMarker = _
private var lastValue: (TestFile, Int, Int) = _
private var lastKey: CodeMarker = uninitialized
private var lastValue: (TestFile, Int, Int) = uninitialized
def positionOf(pos: CodeMarker): (TestFile, Int, Int) = {
if (lastKey eq pos) lastValue
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import java.nio.file.{Files, Path}
import java.nio.charset.StandardCharsets
import java.util

import scala.compiletime.uninitialized

import dotty.tools.dotc.Main
import dotty.tools.dotc.reporting.{Reporter, ThrowingReporter}
import dotty.tools.io.Directory
Expand All @@ -17,7 +19,7 @@ import org.eclipse.lsp4j.{ DidOpenTextDocumentParams, InitializeParams, Initiali
class TestServer(testFolder: Path, projects: List[Project]) {

val server = new DottyLanguageServer
var client: TestClient = _
var client: TestClient = uninitialized

init()

Expand Down
4 changes: 3 additions & 1 deletion library/src/scala/util/control/NonLocalReturns.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package scala.util.control

import scala.compiletime.uninitialized

/** Library implementation of nonlocal return.
*
* Usage:
Expand All @@ -21,7 +23,7 @@ package scala.util.control
object NonLocalReturns {
@deprecated("Use scala.util.boundary.Break instead", "3.3")
class ReturnThrowable[T] extends ControlThrowable {
private var myResult: T = _
private var myResult: T = uninitialized
def throwReturn(result: T): Nothing = {
myResult = result
throw this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import dotty.tools.dotc.interactive.InteractiveDriver
import dotty.tools.dotc.reporting.Diagnostic
import dotty.tools.dotc.util.SourceFile

import scala.compiletime.uninitialized

/**
* MetalsDriver is a wrapper class that provides a compilation cache for InteractiveDriver.
* MetalsDriver skips running compilation if
Expand All @@ -29,7 +31,7 @@ class MetalsDriver(
override val settings: List[String]
) extends InteractiveDriver(settings):

@volatile private var lastCompiledURI: URI = _
@volatile private var lastCompiledURI: URI = uninitialized

private def alreadyCompiled(uri: URI, content: Array[Char]): Boolean =
compilationUnits.get(uri) match
Expand Down
1 change: 1 addition & 0 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,7 @@ object Build {
ivyConfigurations += SourceDeps.hide,
transitiveClassifiers := Seq("sources"),
Compile / scalacOptions ++= Seq("-Yexplicit-nulls", "-Ysafe-init"),
Compile / scalacOptions ++= Seq("-source", "3.3"), // To avoid fatal migration warnings
Compile / sourceGenerators += Def.task {
val s = streams.value
val cacheDir = s.cacheDirectory
Expand Down
3 changes: 0 additions & 3 deletions sbt-test/compilerReporter/i14576/Test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,5 @@ object Test:
def f(x: Text) = println(x.str)
f("abc")

// private[this] and = _ are deprecated under -source:future
private[this] var x: AnyRef = _

// under -source:future, `_` is deprecated for wildcard arguments of types: use `?` instead
val xs: List[_] = Nil
2 changes: 1 addition & 1 deletion sbt-test/compilerReporter/i14576/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ lazy val root = (project in file("."))
},
assertDeprecationSummary := {
assert {
FakePrintWriter.messages.exists(_.contains("there were 2 deprecation warnings; re-run with -deprecation for details"))
FakePrintWriter.messages.exists(_.contains("there was 1 deprecation warning; re-run with -deprecation for details"))
}
},
assertNoDeprecationSummary := {
Expand Down
6 changes: 3 additions & 3 deletions tests/neg/i4812.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//> using options -Werror
object Test:
var prev: Any = _
var prev: Any = scala.compiletime.uninitialized

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

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

sealed class A
var prevA: A = _
var prevA: A = scala.compiletime.uninitialized
def test10: A =
val methodCallId = System.nanoTime()
class B(val id: Long) extends A
Expand Down
6 changes: 6 additions & 0 deletions tests/neg/uninitialized-3.4.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-- Error: tests/neg/uninitialized-3.4.scala:7:15 -----------------------------------------------------------------------
7 | var a: Int = _ // error: migration warning
| ^
| `= _` has been deprecated; use `= uninitialized` instead.
| `uninitialized` can be imported with `scala.compiletime.uninitialized`.
| This construct can be rewritten automatically under -rewrite -source 3.4-migration.
8 changes: 8 additions & 0 deletions tests/neg/uninitialized-3.4.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//> using options -Werror

import scala.language.`3.4`
import scala.compiletime.uninitialized

class Foo:
var a: Int = _ // error: migration warning
var b: Int = uninitialized
8 changes: 8 additions & 0 deletions tests/neg/uninitialized-future-migration.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//> using options -Werror

import scala.language.`future-migration`
import scala.compiletime.uninitialized

class Foo:
var a: Int = _ // error: migration warning
var b: Int = uninitialized
6 changes: 6 additions & 0 deletions tests/neg/uninitialized-future.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import scala.language.future
import scala.compiletime.uninitialized

class Foo:
var a: Int = _ // error
var b: Int = uninitialized
3 changes: 2 additions & 1 deletion tests/patmat/i12805-fallout.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import scala.annotation.unchecked.uncheckedVariance
import scala.compiletime.uninitialized

type Untyped = Null

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

protected var myTpe: T @uncheckedVariance = _
protected var myTpe: T @uncheckedVariance = uninitialized

def withType(tpe: Type): ThisTree[Type] = {
val tree = this.asInstanceOf[ThisTree[Type]]
Expand Down
6 changes: 6 additions & 0 deletions tests/pos/uninitialized-future-migration.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import scala.language.`future-migration`
import scala.compiletime.uninitialized

class Foo:
var a: Int = _ // warn
var b: Int = uninitialized
2 changes: 2 additions & 0 deletions tests/rewrites/uninitialized-var.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class Foo:
var a: Int = scala.compiletime.uninitialized
2 changes: 2 additions & 0 deletions tests/rewrites/uninitialized-var.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class Foo:
var a: Int = _

0 comments on commit 951bbae

Please sign in to comment.