Skip to content

Commit 168e47a

Browse files
committed
Deprecation warnings for old syntax: _ type wildcards
* In `3.4` we emit the deprecation warning and enable the patch with `-rewrite`. * In `future` we emit we make this syntax an error
1 parent 8cb4945 commit 168e47a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+170
-109
lines changed

Diff for: compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+9-3
Original file line numberDiff line numberDiff line change
@@ -1870,9 +1870,15 @@ object Parsers {
18701870
val start = in.skipToken()
18711871
Ident(tpnme.USCOREkw).withSpan(Span(start, in.lastOffset, start))
18721872
else
1873-
if !inTypeMatchPattern && sourceVersion.isAtLeast(future) then
1874-
deprecationWarning(em"`_` is deprecated for wildcard arguments of types: use `?` instead")
1875-
patch(source, Span(in.offset, in.offset + 1), "?")
1873+
if !inTypeMatchPattern then
1874+
report.gradualErrorOrMigrationWarning(
1875+
em"`_` is deprecated for wildcard arguments of types: use `?` instead${rewriteNotice(`3.4-migration`)}",
1876+
in.sourcePos(),
1877+
warnFrom = `3.4`,
1878+
errorFrom = future)
1879+
if sourceVersion.isMigrating && sourceVersion.isAtLeast(`3.4-migration`) then
1880+
patch(source, Span(in.offset, in.offset + 1), "?")
1881+
end if
18761882
val start = in.skipToken()
18771883
typeBounds().withSpan(Span(start, in.lastOffset, start))
18781884
// Allow symbols -_ and +_ through for compatibility with code written using kind-projector in Scala 3 underscore mode.

Diff for: compiler/test-resources/repl/i13208.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
//> using options -source:future -deprecation
1+
//> using options -source:3.4-migration
22
scala> type M[X] = X match { case Int => String case _ => Int }
33
scala> type N[X] = X match { case List[_] => Int }

Diff for: compiler/test-resources/repl/i6643

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
scala> import scala.collection._
22
scala>:type 1
33
Int
4-
scala> object IterableTest { def g[CC[_] <: Iterable[_] with IterableOps[_, _, _]](from: CC[Int]): IterableFactory[CC] = ??? }
4+
scala> object IterableTest { def g[CC[_] <: Iterable[?] with IterableOps[?, ?, ?]](from: CC[Int]): IterableFactory[CC] = ??? }
55
1 warning found
66
-- [E003] Syntax Warning: ------------------------------------------------------
7-
1 | object IterableTest { def g[CC[_] <: Iterable[_] with IterableOps[_, _, _]](from: CC[Int]): IterableFactory[CC] = ??? }
7+
1 | object IterableTest { def g[CC[_] <: Iterable[?] with IterableOps[?, ?, ?]](from: CC[Int]): IterableFactory[CC] = ??? }
88
| ^^^^
99
| with as a type operator has been deprecated; use & instead
1010
|

Diff for: project/Build.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1266,8 +1266,8 @@ object Build {
12661266
libraryDependencies += ("org.scalameta" % "mtags-shared_2.13.12" % mtagsVersion % SourceDeps),
12671267
ivyConfigurations += SourceDeps.hide,
12681268
transitiveClassifiers := Seq("sources"),
1269+
scalacOptions ++= Seq("-source", "3.3"), // To avoid fatal migration warnings
12691270
Compile / scalacOptions ++= Seq("-Yexplicit-nulls", "-Ysafe-init"),
1270-
Compile / scalacOptions ++= Seq("-source", "3.3"), // To avoid fatal migration warnings
12711271
Compile / sourceGenerators += Def.task {
12721272
val s = streams.value
12731273
val cacheDir = s.cacheDirectory

Diff for: sbt-test/compilerReporter/i14576/Test.scala

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

13-
// under -source:future, `_` is deprecated for wildcard arguments of types: use `?` instead
14-
val xs: List[_] = Nil
13+
@deprecated("", "") def deprecatedFun(): Unit = ()
14+
deprecatedFun()

Diff for: scaladoc-testcases/src/tests/exports1.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class A: //unexpected
1616
= 1
1717
type HKT[T[_], X] //expected: final type HKT = [T[_], X] =>> a.HKT[T, X]
1818
= T[X]
19-
type SomeRandomType = (List[_] | Seq[_]) & String //expected: final type SomeRandomType = a.SomeRandomType
19+
type SomeRandomType = (List[?] | Seq[?]) & String //expected: final type SomeRandomType = a.SomeRandomType
2020
def x[T[_], X](x: X): HKT[T, X] //expected: def x[T[_], X](x: X): A.this.HKT[T, X]
2121
= ???
2222
def fn[T, U]: T => U

Diff for: scaladoc-testcases/src/tests/hkts.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ trait Case14[C[_]]
4646
class SomeClass extends Case14[List]
4747

4848

49-
def method1[E, T](value: List[_ >: E]): Int = 0
49+
def method1[E, T](value: List[? >: E]): Int = 0
5050
def method2[F[+X] <: Option[X], A](fa: F[A]): A = fa.get
5151

5252
import scala.collection.immutable.ArraySeq

Diff for: scaladoc-testcases/src/tests/snippetTestcase2.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package tests
22
package snippetTestcase2
33

44
trait Quotes2[A] {
5-
val r1: r1Module[_] = ???
5+
val r1: r1Module[?] = ???
66
trait r1Module[A] {
77
type X
88
object Y {

Diff for: scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,5 @@ class ScaladocSettings extends SettingGroup with AllScalaSettings:
133133
"List of quick links that is displayed in the header of documentation."
134134
)
135135

136-
def scaladocSpecificSettings: Set[Setting[_]] =
136+
def scaladocSpecificSettings: Set[Setting[?]] =
137137
Set(sourceLinks, legacySourceLink, syntax, revision, externalDocumentationMappings, socialLinks, skipById, skipByRegex, deprecatedSkipPackages, docRootContent, snippetCompiler, generateInkuire, defaultTemplate, scastieConfiguration, quickLinks)

Diff for: scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite
144144
(("1900","01","01"), name)
145145

146146
def dateFrom(tf: TemplateFile, default: String = "1900-01-01"): String =
147-
val pageSettings = tf.settings.get("page").collect{ case m: Map[String @unchecked, _] => m }
147+
val pageSettings = tf.settings.get("page").collect{ case m: Map[String @unchecked, ?] => m }
148148
pageSettings.flatMap(_.get("date").collect{ case s: String => s}).getOrElse(default) // blogs without date are last
149149

150150
val posts = List(rootPath.resolve("_posts"))

Diff for: scaladoc/src/dotty/tools/scaladoc/site/common.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def loadTemplateFile(file: File, defaultTitle: Option[TemplateName] = None)(usin
9494
}.map(_.stripPrefix("\"").stripSuffix("\""))
9595

9696
def listSetting(settings: Map[String, Object], name: String): Option[List[String]] = settings.get(name).map {
97-
case elems: List[_] => elems.zipWithIndex.map {
97+
case elems: List[?] => elems.zipWithIndex.map {
9898
case (s: String, _) => s
9999
case (other, index) =>
100100
throw new RuntimeException(s"Expected a string at index $index for $name in $file but got $other")

Diff for: scaladoc/src/dotty/tools/scaladoc/site/templates.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ case class TemplateFile(
103103
)
104104

105105
def asJavaElement(o: Object): Object = o match
106-
case m: Map[_, _] => m.transform {
106+
case m: Map[?, ?] => m.transform {
107107
case (k: String, v: Object) => asJavaElement(v)
108108
}.asJava
109-
case l: List[_] => l.map(x => asJavaElement(x.asInstanceOf[Object])).asJava
109+
case l: List[?] => l.map(x => asJavaElement(x.asInstanceOf[Object])).asJava
110110
case other => other
111111

112112
// Library requires mutable maps..

Diff for: scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import dotty.tools.dotc.util.{ SourcePosition, NoSourcePosition, SourceFile, NoS
2121
import scala.util.{ Try, Success, Failure }
2222

2323
class SnippetCompiler(
24-
val snippetCompilerSettings: Seq[SnippetCompilerSetting[_]],
24+
val snippetCompilerSettings: Seq[SnippetCompilerSetting[?]],
2525
target: AbstractFile = new VirtualDirectory("(memory)")
2626
):
2727
object SnippetDriver extends Driver:

Diff for: scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/DocFlexmarkExtension.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ case class DocFlexmarkRenderer(renderLink: (DocLink, String) => String)
7272
html.raw(renderLink(node.target, node.body))
7373

7474
object Render extends NodeRenderer:
75-
override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[_]] =
75+
override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[?]] =
7676
JSet(
7777
new NodeRenderingHandler(classOf[DocLinkNode], Handler),
7878
)

Diff for: scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SectionRenderingExtension.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ object SectionRenderingExtension extends HtmlRenderer.HtmlRendererExtension:
5959

6060

6161
object Render extends NodeRenderer:
62-
override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[_]] =
62+
override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[?]] =
6363
JSet(
6464
new NodeRenderingHandler(classOf[Section], SectionHandler),
6565
new NodeRenderingHandler(classOf[AnchorLink], AnchorLinkHandler)

Diff for: scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderingExtension.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ object SnippetRenderingExtension extends HtmlRenderer.HtmlRendererExtension:
3535
html.raw(SnippetRenderer.renderSnippet(node.getContentChars.toString, node.getInfo.toString.split(" ").headOption))
3636

3737
object Render extends NodeRenderer:
38-
override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[_]] =
38+
override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[?]] =
3939
JSet(
4040
new NodeRenderingHandler(classOf[ExtendedFencedCodeBlock], ExtendedFencedCodeBlockHandler),
4141
new NodeRenderingHandler(classOf[FencedCodeBlock], FencedCodeBlockHandler)

Diff for: staging/src/scala/quoted/staging/ExprCompilationUnit.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ import dotty.tools.dotc.CompilationUnit
55
import dotty.tools.dotc.util.NoSource
66

77
/** Compilation unit containing the contents of a quoted expression */
8-
private class ExprCompilationUnit(val exprBuilder: Quotes => Expr[_]) extends CompilationUnit(NoSource)
8+
private class ExprCompilationUnit(val exprBuilder: Quotes => Expr[?]) extends CompilationUnit(NoSource)

Diff for: staging/src/scala/quoted/staging/QuoteCompiler.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ private class QuoteCompiler extends Compiler:
114114
/** Unpickle and optionally compile the expression.
115115
* Returns either `Left` with name of the classfile generated or `Right` with the value contained in the expression.
116116
*/
117-
def compileExpr(exprBuilder: Quotes => Expr[_]): Either[String, Any] =
117+
def compileExpr(exprBuilder: Quotes => Expr[?]): Either[String, Any] =
118118
val units = new ExprCompilationUnit(exprBuilder) :: Nil
119119
compileUnits(units)
120120
result

Diff for: tests/init/pos/Properties.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import java.util.jar.Attributes.Name as AttributeName
1515

1616
private[scala] trait PropertiesTrait {
1717
protected def propCategory: String // specializes the remainder of the values
18-
protected def pickJarBasedOn: Class[_] // props file comes from jar containing this
18+
protected def pickJarBasedOn: Class[?] // props file comes from jar containing this
1919

2020
/** The name of the properties file */
2121
protected val propFilename = "/" + propCategory + ".properties"

Diff for: tests/neg-deep-subtype/i4297.scala

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
class Test {
44
def test[X <: Option[Int]](x: X) = x.isInstanceOf[Some[Int]]
55
def test1[Y <: Int, X <: Option[Y]](x: X) = x.isInstanceOf[Some[Int]]
6-
def test2(x: Any) = x.isInstanceOf[Function1[Nothing, _]]
7-
def test3a(x: Any) = x.isInstanceOf[Function1[Any, _]] // error
8-
def test3b(x: Any) = x.isInstanceOf[Function1[Int, _]] // error
9-
def test4[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, _]] // error
6+
def test2(x: Any) = x.isInstanceOf[Function1[Nothing, ?]]
7+
def test3a(x: Any) = x.isInstanceOf[Function1[Any, ?]] // error
8+
def test3b(x: Any) = x.isInstanceOf[Function1[Int, ?]] // error
9+
def test4[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, ?]] // error
1010
def test5[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, Unit]] // error
1111
def test6[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, Any]] // error
12-
def test7[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[_, Unit]]
12+
def test7[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[?, Unit]]
1313
}

Diff for: tests/neg-deep-subtype/i5826b.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
class Foo {
44
def test1[A]: List[Int] | A => Int = {
5-
case ls: List[_] => ls.head // error
5+
case ls: List[?] => ls.head // error
66
case _ => 0
77
}
88

99
def test2[A]: List[Int] | A => Int = {
10-
case ls: List[_] => ls.size
10+
case ls: List[?] => ls.size
1111
case _ => 0
1212
}
1313
}

Diff for: tests/neg-deep-subtype/or-type-trees.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ object Test1 {
1414

1515
def foo3(myTree: Tree | (Context => Tree)) =
1616
myTree match
17-
case treeFn: (_ => _) => // ok
17+
case treeFn: (? => ?) => // ok
1818
case _ =>
1919
}
2020

@@ -35,6 +35,6 @@ object Test2 {
3535

3636
def foo3(myTree: Tree[Type] | (Context => Tree[Type])) =
3737
myTree match
38-
case treeFn: (_ => _) => // ok
38+
case treeFn: (? => ?) => // ok
3939
case _ =>
4040
}

Diff for: tests/neg-deep-subtype/t2755.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ object Test {
99
case x: Array[Float] => x.sum.toInt
1010
case x: Array[String] => x.size
1111
case x: Array[AnyRef] => 5
12-
case x: Array[_] => 6
12+
case x: Array[?] => 6
1313
case _ => 7
1414
}
15-
def f2(a: Array[_]) = a match {
15+
def f2(a: Array[?]) = a match {
1616
case x: Array[Int] => x(0)
1717
case x: Array[Double] => 2
1818
case x: Array[Float] => x.sum.toInt
1919
case x: Array[String] => x.size
2020
case x: Array[AnyRef] => 5
21-
case x: Array[_] => 6
21+
case x: Array[?] => 6
2222
case _ => 7 // error: only null is matched
2323
}
2424
def f3[T](a: Array[T]) = a match {
@@ -27,7 +27,7 @@ object Test {
2727
case x: Array[Float] => x.sum.toInt
2828
case x: Array[String] => x.size
2929
case x: Array[AnyRef] => 5
30-
case x: Array[_] => 6
30+
case x: Array[?] => 6
3131
case _ => 7 // error: only null is matched
3232
}
3333

Diff for: tests/neg/IsInstanceOfClassTag.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object IsInstanceOfClassTag {
1717
xs.head.substring(0)
1818
}
1919

20-
safeCast[List[_]](List[Int](1)) match {
20+
safeCast[List[?]](List[Int](1)) match {
2121
case None =>
2222
case Some(xs) =>
2323
xs.head.substring(0) // error

Diff for: tests/neg/IsInstanceOfClassTag2.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ object IsInstanceOfClassTag {
1616
case Some(xs) =>
1717
}
1818

19-
safeCast[List[_]](List[Int](1)) match {
19+
safeCast[List[?]](List[Int](1)) match {
2020
case None =>
2121
case Some(xs) =>
2222
}

Diff for: tests/neg/i12284.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
trait I[F[_], A]
22

33
def magic[F[_], A](in: I[F, A]): F[A] =
4-
val deps: Vector[I[F, _]] = ???
4+
val deps: Vector[I[F, ?]] = ???
55
val xx = deps.map(i => magic(i))
66
val y: Vector[F[Any]] = xx // error
77
???

Diff for: tests/neg/i15662.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
case class Composite[T](v: T)
44

5-
def m(composite: Composite[_]): Unit =
5+
def m(composite: Composite[?]): Unit =
66
composite match {
77
case Composite[Int](v) => println(v) // error: cannot be checked at runtime
88
}
99

10-
def m2(composite: Composite[_]): Unit =
10+
def m2(composite: Composite[?]): Unit =
1111
composite match {
1212
case Composite(v) => println(v) // ok
1313
}

Diff for: tests/neg/i15893.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@ transparent inline def transparentInlineMod2(inline n: NatT): NatT = inline n m
2727
def dependentlyTypedMod2[N <: NatT](n: N): Mod2[N] = n match
2828
case Zero(): Zero => Zero() // error
2929
case Succ(Zero()): Succ[Zero] => Succ(Zero()) // error
30-
case Succ(Succ(predPredN)): Succ[Succ[_]] => dependentlyTypedMod2(predPredN) // error
30+
case Succ(Succ(predPredN)): Succ[Succ[?]] => dependentlyTypedMod2(predPredN) // error
3131

3232
inline def inlineDependentlyTypedMod2[N <: NatT](inline n: N): Mod2[N] = inline n match
3333
case Zero(): Zero => Zero() // error
3434
case Succ(Zero()): Succ[Zero] => Succ(Zero()) // error
35-
case Succ(Succ(predPredN)): Succ[Succ[_]] => inlineDependentlyTypedMod2(predPredN) // error
35+
case Succ(Succ(predPredN)): Succ[Succ[?]] => inlineDependentlyTypedMod2(predPredN) // error
3636

3737
transparent inline def transparentInlineDependentlyTypedMod2[N <: NatT](inline n: N): Mod2[N] = inline n match
3838
case Zero(): Zero => Zero() // error
3939
case Succ(Zero()): Succ[Zero] => Succ(Zero()) // error
40-
case Succ(Succ(predPredN)): Succ[Succ[_]] => transparentInlineDependentlyTypedMod2(predPredN) // error
40+
case Succ(Succ(predPredN)): Succ[Succ[?]] => transparentInlineDependentlyTypedMod2(predPredN) // error
4141

4242
def foo(n: NatT): NatT = mod2(n) match
4343
case Succ(Zero()) => Zero()

Diff for: tests/neg/i4382.check

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
-- [E043] Type Error: tests/neg/i4382.scala:3:10 -----------------------------------------------------------------------
2-
3 | def v1: Id[_] = ??? // error
2+
3 | def v1: Id[?] = ??? // error
33
| ^^^^^
44
| unreducible application of higher-kinded type App.Id to wildcard arguments
55
|
66
| longer explanation available when compiling with `-explain`
77
-- [E043] Type Error: tests/neg/i4382.scala:6:10 -----------------------------------------------------------------------
8-
6 | def v2: HkL[_] = ??? // error
8+
6 | def v2: HkL[?] = ??? // error
99
| ^^^^^^
1010
| unreducible application of higher-kinded type App.HkL to wildcard arguments
1111
|
1212
| longer explanation available when compiling with `-explain`
1313
-- [E043] Type Error: tests/neg/i4382.scala:9:10 -----------------------------------------------------------------------
14-
9 | def v3: HkU[_] = ??? // error
14+
9 | def v3: HkU[?] = ??? // error
1515
| ^^^^^^
1616
| unreducible application of higher-kinded type App.HkU to wildcard arguments
1717
|
1818
| longer explanation available when compiling with `-explain`
1919
-- [E043] Type Error: tests/neg/i4382.scala:12:10 ----------------------------------------------------------------------
20-
12 | def v4: HkAbs[_] = ??? // error
20+
12 | def v4: HkAbs[?] = ??? // error
2121
| ^^^^^^^^
2222
| unreducible application of higher-kinded type App.HkAbs to wildcard arguments
2323
|

Diff for: tests/neg/i4382.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
object App {
22
type Id[A] >: A <: A
3-
def v1: Id[_] = ??? // error
3+
def v1: Id[?] = ??? // error
44

55
type HkL[A] >: A
6-
def v2: HkL[_] = ??? // error
6+
def v2: HkL[?] = ??? // error
77

88
type HkU[A] <: A
9-
def v3: HkU[_] = ??? // error
9+
def v3: HkU[?] = ??? // error
1010

1111
type HkAbs[A]
12-
def v4: HkAbs[_] = ??? // error
12+
def v4: HkAbs[?] = ??? // error
1313
}

0 commit comments

Comments
 (0)