From b822bd02fb9ecd9dfb69ee6abf94fe56f3433cd0 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 1 Nov 2023 13:32:27 +0100 Subject: [PATCH] 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 --- .../dotty/tools/dotc/parsing/Parsers.scala | 12 ++++++++--- compiler/test-resources/repl/i13208.scala | 2 +- compiler/test-resources/repl/i6643 | 4 ++-- project/Build.scala | 2 +- sbt-test/compilerReporter/i14576/Test.scala | 4 ++-- scaladoc-testcases/src/tests/exports1.scala | 2 +- scaladoc-testcases/src/tests/hkts.scala | 2 +- .../src/tests/snippetTestcase2.scala | 2 +- .../tools/scaladoc/ScaladocSettings.scala | 2 +- .../scaladoc/site/StaticSiteLoader.scala | 2 +- .../dotty/tools/scaladoc/site/common.scala | 2 +- .../dotty/tools/scaladoc/site/templates.scala | 4 ++-- .../scaladoc/snippets/SnippetCompiler.scala | 2 +- .../markdown/DocFlexmarkExtension.scala | 2 +- .../markdown/SectionRenderingExtension.scala | 2 +- .../markdown/SnippetRenderingExtension.scala | 2 +- .../quoted/staging/ExprCompilationUnit.scala | 2 +- .../scala/quoted/staging/QuoteCompiler.scala | 2 +- tests/init/pos/Properties.scala | 2 +- tests/neg-deep-subtype/i4297.scala | 10 +++++----- tests/neg-deep-subtype/i5826b.scala | 4 ++-- tests/neg-deep-subtype/or-type-trees.scala | 4 ++-- tests/neg-deep-subtype/t2755.scala | 8 ++++---- tests/neg/IsInstanceOfClassTag.scala | 2 +- tests/neg/IsInstanceOfClassTag2.scala | 2 +- tests/neg/i12284.scala | 2 +- tests/neg/i15662.scala | 4 ++-- tests/neg/i15893.scala | 6 +++--- tests/neg/i18058.check | 2 +- tests/neg/i18058.scala | 2 +- tests/neg/i4382.check | 8 ++++---- tests/neg/i4382.scala | 8 ++++---- tests/neg/i4986c.scala | 2 +- tests/neg/i5077.scala | 2 +- tests/neg/i6724.check | 2 +- tests/neg/i6724.scala | 2 +- tests/neg/i8736.scala | 2 +- tests/neg/matchtype-seq.check | 4 ++-- tests/neg/matchtype-seq.scala | 4 ++-- tests/neg/type-test-syntesize-b.scala | 2 +- tests/neg/wildcard-type-syntax-3.4.check | 5 +++++ tests/neg/wildcard-type-syntax-3.4.scala | 8 ++++++++ ...ildcard-type-syntax-future-migration.scala | 8 ++++++++ tests/neg/wildcard-type-syntax-future.scala | 6 ++++++ tests/patmat/exhausting.scala | 4 ++-- tests/patmat/gadt.scala | 4 ++-- tests/patmat/gadt2.scala | 6 +++--- tests/patmat/gadt4.scala | 6 +++--- tests/patmat/gadt5.scala | 8 ++++---- tests/patmat/i12241.scala | 4 ++-- tests/patmat/i12805-fallout.scala | 2 +- tests/patmat/i4030.scala | 4 ++-- tests/patmat/i6197c.scala | 4 ++-- tests/patmat/i6197d.scala | 4 ++-- tests/patmat/t11620b.scala | 2 +- tests/patmat/t2425.scala | 4 ++-- tests/patmat/t3097.scala | 6 +++--- tests/patmat/t6450.scala | 2 +- tests/patmat/t9779.scala | 2 +- tests/pos/i15717.scala | 4 ++-- tests/pos/t6963c.scala | 12 +++++------ ...ildcard-type-syntax-future-migration.scala | 6 ++++++ tests/pos/wildcard-type-syntax.scala | 8 ++++++++ tests/semanticdb/metac.expect | 20 ++++++++++++++++--- 64 files changed, 168 insertions(+), 107 deletions(-) create mode 100644 tests/neg/wildcard-type-syntax-3.4.check create mode 100644 tests/neg/wildcard-type-syntax-3.4.scala create mode 100644 tests/neg/wildcard-type-syntax-future-migration.scala create mode 100644 tests/neg/wildcard-type-syntax-future.scala create mode 100644 tests/pos/wildcard-type-syntax-future-migration.scala create mode 100644 tests/pos/wildcard-type-syntax.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 58b9a933f0a8..23eeb711f965 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1870,9 +1870,15 @@ object Parsers { val start = in.skipToken() Ident(tpnme.USCOREkw).withSpan(Span(start, in.lastOffset, start)) else - if !inTypeMatchPattern && sourceVersion.isAtLeast(future) then - deprecationWarning(em"`_` is deprecated for wildcard arguments of types: use `?` instead") - patch(source, Span(in.offset, in.offset + 1), "?") + if !inTypeMatchPattern then + report.gradualErrorOrMigrationWarning( + em"`_` is deprecated for wildcard arguments of types: use `?` instead${rewriteNotice(`3.4-migration`)}", + in.sourcePos(), + warnFrom = `3.4`, + errorFrom = future) + if sourceVersion.isMigrating && sourceVersion.isAtLeast(`3.4-migration`) then + patch(source, Span(in.offset, in.offset + 1), "?") + end if val start = in.skipToken() typeBounds().withSpan(Span(start, in.lastOffset, start)) // Allow symbols -_ and +_ through for compatibility with code written using kind-projector in Scala 3 underscore mode. diff --git a/compiler/test-resources/repl/i13208.scala b/compiler/test-resources/repl/i13208.scala index 07cc67d3bf0b..6871a962105c 100644 --- a/compiler/test-resources/repl/i13208.scala +++ b/compiler/test-resources/repl/i13208.scala @@ -1,3 +1,3 @@ -//> using options -source:future -deprecation +//> using options -source:3.4-migration scala> type M[X] = X match { case Int => String case _ => Int } scala> type N[X] = X match { case List[_] => Int } diff --git a/compiler/test-resources/repl/i6643 b/compiler/test-resources/repl/i6643 index ff482d8ce5f1..fc58435c5fff 100644 --- a/compiler/test-resources/repl/i6643 +++ b/compiler/test-resources/repl/i6643 @@ -1,10 +1,10 @@ scala> import scala.collection._ scala>:type 1 Int -scala> object IterableTest { def g[CC[_] <: Iterable[_] with IterableOps[_, _, _]](from: CC[Int]): IterableFactory[CC] = ??? } +scala> object IterableTest { def g[CC[_] <: Iterable[?] with IterableOps[?, ?, ?]](from: CC[Int]): IterableFactory[CC] = ??? } 1 warning found -- [E003] Syntax Warning: ------------------------------------------------------ -1 | object IterableTest { def g[CC[_] <: Iterable[_] with IterableOps[_, _, _]](from: CC[Int]): IterableFactory[CC] = ??? } +1 | object IterableTest { def g[CC[_] <: Iterable[?] with IterableOps[?, ?, ?]](from: CC[Int]): IterableFactory[CC] = ??? } | ^^^^ | with as a type operator has been deprecated; use & instead | diff --git a/project/Build.scala b/project/Build.scala index ab4cfe19377b..7066deb8f7c2 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1266,8 +1266,8 @@ object Build { libraryDependencies += ("org.scalameta" % "mtags-shared_2.13.12" % mtagsVersion % SourceDeps), ivyConfigurations += SourceDeps.hide, transitiveClassifiers := Seq("sources"), + scalacOptions ++= Seq("-source", "3.3"), // To avoid fatal migration warnings 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 diff --git a/sbt-test/compilerReporter/i14576/Test.scala b/sbt-test/compilerReporter/i14576/Test.scala index 8be852b846a0..4f65c2267134 100644 --- a/sbt-test/compilerReporter/i14576/Test.scala +++ b/sbt-test/compilerReporter/i14576/Test.scala @@ -10,5 +10,5 @@ object Test: def f(x: Text) = println(x.str) f("abc") - // under -source:future, `_` is deprecated for wildcard arguments of types: use `?` instead - val xs: List[_] = Nil + @deprecated("", "") def deprecatedFun(): Unit = () + deprecatedFun() diff --git a/scaladoc-testcases/src/tests/exports1.scala b/scaladoc-testcases/src/tests/exports1.scala index 542880b3a590..f719bca35eb1 100644 --- a/scaladoc-testcases/src/tests/exports1.scala +++ b/scaladoc-testcases/src/tests/exports1.scala @@ -16,7 +16,7 @@ class A: //unexpected = 1 type HKT[T[_], X] //expected: final type HKT = [T[_], X] =>> a.HKT[T, X] = T[X] - type SomeRandomType = (List[_] | Seq[_]) & String //expected: final type SomeRandomType = a.SomeRandomType + type SomeRandomType = (List[?] | Seq[?]) & String //expected: final type SomeRandomType = a.SomeRandomType def x[T[_], X](x: X): HKT[T, X] //expected: def x[T[_], X](x: X): A.this.HKT[T, X] = ??? def fn[T, U]: T => U diff --git a/scaladoc-testcases/src/tests/hkts.scala b/scaladoc-testcases/src/tests/hkts.scala index d8e29d993821..c04fcf1e0cd1 100644 --- a/scaladoc-testcases/src/tests/hkts.scala +++ b/scaladoc-testcases/src/tests/hkts.scala @@ -46,7 +46,7 @@ trait Case14[C[_]] class SomeClass extends Case14[List] -def method1[E, T](value: List[_ >: E]): Int = 0 +def method1[E, T](value: List[? >: E]): Int = 0 def method2[F[+X] <: Option[X], A](fa: F[A]): A = fa.get import scala.collection.immutable.ArraySeq diff --git a/scaladoc-testcases/src/tests/snippetTestcase2.scala b/scaladoc-testcases/src/tests/snippetTestcase2.scala index c85207b46f59..6a26767efa86 100644 --- a/scaladoc-testcases/src/tests/snippetTestcase2.scala +++ b/scaladoc-testcases/src/tests/snippetTestcase2.scala @@ -2,7 +2,7 @@ package tests package snippetTestcase2 trait Quotes2[A] { - val r1: r1Module[_] = ??? + val r1: r1Module[?] = ??? trait r1Module[A] { type X object Y { diff --git a/scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala b/scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala index 57c2b2910d6a..403acb19305d 100644 --- a/scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala +++ b/scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala @@ -133,5 +133,5 @@ class ScaladocSettings extends SettingGroup with AllScalaSettings: "List of quick links that is displayed in the header of documentation." ) - def scaladocSpecificSettings: Set[Setting[_]] = + def scaladocSpecificSettings: Set[Setting[?]] = Set(sourceLinks, legacySourceLink, syntax, revision, externalDocumentationMappings, socialLinks, skipById, skipByRegex, deprecatedSkipPackages, docRootContent, snippetCompiler, generateInkuire, defaultTemplate, scastieConfiguration, quickLinks) diff --git a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala index 489720cc5936..e25639c36183 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala @@ -144,7 +144,7 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite (("1900","01","01"), name) def dateFrom(tf: TemplateFile, default: String = "1900-01-01"): String = - val pageSettings = tf.settings.get("page").collect{ case m: Map[String @unchecked, _] => m } + val pageSettings = tf.settings.get("page").collect{ case m: Map[String @unchecked, ?] => m } pageSettings.flatMap(_.get("date").collect{ case s: String => s}).getOrElse(default) // blogs without date are last val posts = List(rootPath.resolve("_posts")) diff --git a/scaladoc/src/dotty/tools/scaladoc/site/common.scala b/scaladoc/src/dotty/tools/scaladoc/site/common.scala index 0811d217537f..9e58dbe3cd28 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/common.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/common.scala @@ -94,7 +94,7 @@ def loadTemplateFile(file: File, defaultTitle: Option[TemplateName] = None)(usin }.map(_.stripPrefix("\"").stripSuffix("\"")) def listSetting(settings: Map[String, Object], name: String): Option[List[String]] = settings.get(name).map { - case elems: List[_] => elems.zipWithIndex.map { + case elems: List[?] => elems.zipWithIndex.map { case (s: String, _) => s case (other, index) => throw new RuntimeException(s"Expected a string at index $index for $name in $file but got $other") diff --git a/scaladoc/src/dotty/tools/scaladoc/site/templates.scala b/scaladoc/src/dotty/tools/scaladoc/site/templates.scala index 92e0096e5af1..c37ff8fe0200 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/templates.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/templates.scala @@ -103,10 +103,10 @@ case class TemplateFile( ) def asJavaElement(o: Object): Object = o match - case m: Map[_, _] => m.transform { + case m: Map[?, ?] => m.transform { case (k: String, v: Object) => asJavaElement(v) }.asJava - case l: List[_] => l.map(x => asJavaElement(x.asInstanceOf[Object])).asJava + case l: List[?] => l.map(x => asJavaElement(x.asInstanceOf[Object])).asJava case other => other // Library requires mutable maps.. diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala index 03fdd4e849ff..0ab5086e09d0 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala @@ -21,7 +21,7 @@ import dotty.tools.dotc.util.{ SourcePosition, NoSourcePosition, SourceFile, NoS import scala.util.{ Try, Success, Failure } class SnippetCompiler( - val snippetCompilerSettings: Seq[SnippetCompilerSetting[_]], + val snippetCompilerSettings: Seq[SnippetCompilerSetting[?]], target: AbstractFile = new VirtualDirectory("(memory)") ): object SnippetDriver extends Driver: diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/DocFlexmarkExtension.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/DocFlexmarkExtension.scala index d797eaed7fbf..d87a6692b99c 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/DocFlexmarkExtension.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/DocFlexmarkExtension.scala @@ -72,7 +72,7 @@ case class DocFlexmarkRenderer(renderLink: (DocLink, String) => String) html.raw(renderLink(node.target, node.body)) object Render extends NodeRenderer: - override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[_]] = + override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[?]] = JSet( new NodeRenderingHandler(classOf[DocLinkNode], Handler), ) diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SectionRenderingExtension.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SectionRenderingExtension.scala index 41c1c9c0fa42..0acb1c02a69e 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SectionRenderingExtension.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SectionRenderingExtension.scala @@ -59,7 +59,7 @@ object SectionRenderingExtension extends HtmlRenderer.HtmlRendererExtension: object Render extends NodeRenderer: - override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[_]] = + override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[?]] = JSet( new NodeRenderingHandler(classOf[Section], SectionHandler), new NodeRenderingHandler(classOf[AnchorLink], AnchorLinkHandler) diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderingExtension.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderingExtension.scala index e980c5fc44ef..d4a439042073 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderingExtension.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderingExtension.scala @@ -35,7 +35,7 @@ object SnippetRenderingExtension extends HtmlRenderer.HtmlRendererExtension: html.raw(SnippetRenderer.renderSnippet(node.getContentChars.toString, node.getInfo.toString.split(" ").headOption)) object Render extends NodeRenderer: - override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[_]] = + override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[?]] = JSet( new NodeRenderingHandler(classOf[ExtendedFencedCodeBlock], ExtendedFencedCodeBlockHandler), new NodeRenderingHandler(classOf[FencedCodeBlock], FencedCodeBlockHandler) diff --git a/staging/src/scala/quoted/staging/ExprCompilationUnit.scala b/staging/src/scala/quoted/staging/ExprCompilationUnit.scala index 6f95c252fd9d..ea1456527c8b 100644 --- a/staging/src/scala/quoted/staging/ExprCompilationUnit.scala +++ b/staging/src/scala/quoted/staging/ExprCompilationUnit.scala @@ -5,4 +5,4 @@ import dotty.tools.dotc.CompilationUnit import dotty.tools.dotc.util.NoSource /** Compilation unit containing the contents of a quoted expression */ -private class ExprCompilationUnit(val exprBuilder: Quotes => Expr[_]) extends CompilationUnit(NoSource) +private class ExprCompilationUnit(val exprBuilder: Quotes => Expr[?]) extends CompilationUnit(NoSource) diff --git a/staging/src/scala/quoted/staging/QuoteCompiler.scala b/staging/src/scala/quoted/staging/QuoteCompiler.scala index 308ef4ff86e4..ce20055493fa 100644 --- a/staging/src/scala/quoted/staging/QuoteCompiler.scala +++ b/staging/src/scala/quoted/staging/QuoteCompiler.scala @@ -114,7 +114,7 @@ private class QuoteCompiler extends Compiler: /** Unpickle and optionally compile the expression. * Returns either `Left` with name of the classfile generated or `Right` with the value contained in the expression. */ - def compileExpr(exprBuilder: Quotes => Expr[_]): Either[String, Any] = + def compileExpr(exprBuilder: Quotes => Expr[?]): Either[String, Any] = val units = new ExprCompilationUnit(exprBuilder) :: Nil compileUnits(units) result diff --git a/tests/init/pos/Properties.scala b/tests/init/pos/Properties.scala index 84d1e09a24f9..ba92dd54dc83 100644 --- a/tests/init/pos/Properties.scala +++ b/tests/init/pos/Properties.scala @@ -15,7 +15,7 @@ import java.util.jar.Attributes.Name as AttributeName private[scala] trait PropertiesTrait { protected def propCategory: String // specializes the remainder of the values - protected def pickJarBasedOn: Class[_] // props file comes from jar containing this + protected def pickJarBasedOn: Class[?] // props file comes from jar containing this /** The name of the properties file */ protected val propFilename = "/" + propCategory + ".properties" diff --git a/tests/neg-deep-subtype/i4297.scala b/tests/neg-deep-subtype/i4297.scala index 9112de9de79b..88e66c59d1b4 100644 --- a/tests/neg-deep-subtype/i4297.scala +++ b/tests/neg-deep-subtype/i4297.scala @@ -3,11 +3,11 @@ class Test { def test[X <: Option[Int]](x: X) = x.isInstanceOf[Some[Int]] def test1[Y <: Int, X <: Option[Y]](x: X) = x.isInstanceOf[Some[Int]] - def test2(x: Any) = x.isInstanceOf[Function1[Nothing, _]] - def test3a(x: Any) = x.isInstanceOf[Function1[Any, _]] // error - def test3b(x: Any) = x.isInstanceOf[Function1[Int, _]] // error - def test4[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, _]] // error + def test2(x: Any) = x.isInstanceOf[Function1[Nothing, ?]] + def test3a(x: Any) = x.isInstanceOf[Function1[Any, ?]] // error + def test3b(x: Any) = x.isInstanceOf[Function1[Int, ?]] // error + def test4[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, ?]] // error def test5[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, Unit]] // error def test6[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, Any]] // error - def test7[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[_, Unit]] + def test7[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[?, Unit]] } diff --git a/tests/neg-deep-subtype/i5826b.scala b/tests/neg-deep-subtype/i5826b.scala index 2ee8ac2b092a..a3c3382bbc51 100644 --- a/tests/neg-deep-subtype/i5826b.scala +++ b/tests/neg-deep-subtype/i5826b.scala @@ -2,12 +2,12 @@ class Foo { def test1[A]: List[Int] | A => Int = { - case ls: List[_] => ls.head // error + case ls: List[?] => ls.head // error case _ => 0 } def test2[A]: List[Int] | A => Int = { - case ls: List[_] => ls.size + case ls: List[?] => ls.size case _ => 0 } } diff --git a/tests/neg-deep-subtype/or-type-trees.scala b/tests/neg-deep-subtype/or-type-trees.scala index ad86bf20e2a3..d0338ffe6066 100644 --- a/tests/neg-deep-subtype/or-type-trees.scala +++ b/tests/neg-deep-subtype/or-type-trees.scala @@ -14,7 +14,7 @@ object Test1 { def foo3(myTree: Tree | (Context => Tree)) = myTree match - case treeFn: (_ => _) => // ok + case treeFn: (? => ?) => // ok case _ => } @@ -35,6 +35,6 @@ object Test2 { def foo3(myTree: Tree[Type] | (Context => Tree[Type])) = myTree match - case treeFn: (_ => _) => // ok + case treeFn: (? => ?) => // ok case _ => } \ No newline at end of file diff --git a/tests/neg-deep-subtype/t2755.scala b/tests/neg-deep-subtype/t2755.scala index a8d888f3a821..ec3cb6aadefc 100644 --- a/tests/neg-deep-subtype/t2755.scala +++ b/tests/neg-deep-subtype/t2755.scala @@ -9,16 +9,16 @@ object Test { case x: Array[Float] => x.sum.toInt case x: Array[String] => x.size case x: Array[AnyRef] => 5 - case x: Array[_] => 6 + case x: Array[?] => 6 case _ => 7 } - def f2(a: Array[_]) = a match { + def f2(a: Array[?]) = a match { case x: Array[Int] => x(0) case x: Array[Double] => 2 case x: Array[Float] => x.sum.toInt case x: Array[String] => x.size case x: Array[AnyRef] => 5 - case x: Array[_] => 6 + case x: Array[?] => 6 case _ => 7 // error: only null is matched } def f3[T](a: Array[T]) = a match { @@ -27,7 +27,7 @@ object Test { case x: Array[Float] => x.sum.toInt case x: Array[String] => x.size case x: Array[AnyRef] => 5 - case x: Array[_] => 6 + case x: Array[?] => 6 case _ => 7 // error: only null is matched } diff --git a/tests/neg/IsInstanceOfClassTag.scala b/tests/neg/IsInstanceOfClassTag.scala index 65a7ecb031b2..139ca7eae5a6 100644 --- a/tests/neg/IsInstanceOfClassTag.scala +++ b/tests/neg/IsInstanceOfClassTag.scala @@ -17,7 +17,7 @@ object IsInstanceOfClassTag { xs.head.substring(0) } - safeCast[List[_]](List[Int](1)) match { + safeCast[List[?]](List[Int](1)) match { case None => case Some(xs) => xs.head.substring(0) // error diff --git a/tests/neg/IsInstanceOfClassTag2.scala b/tests/neg/IsInstanceOfClassTag2.scala index 9246c7fca84d..9d32ee401092 100644 --- a/tests/neg/IsInstanceOfClassTag2.scala +++ b/tests/neg/IsInstanceOfClassTag2.scala @@ -16,7 +16,7 @@ object IsInstanceOfClassTag { case Some(xs) => } - safeCast[List[_]](List[Int](1)) match { + safeCast[List[?]](List[Int](1)) match { case None => case Some(xs) => } diff --git a/tests/neg/i12284.scala b/tests/neg/i12284.scala index 11635a1638cb..c1e35a3eac41 100644 --- a/tests/neg/i12284.scala +++ b/tests/neg/i12284.scala @@ -1,7 +1,7 @@ trait I[F[_], A] def magic[F[_], A](in: I[F, A]): F[A] = - val deps: Vector[I[F, _]] = ??? + val deps: Vector[I[F, ?]] = ??? val xx = deps.map(i => magic(i)) val y: Vector[F[Any]] = xx // error ??? diff --git a/tests/neg/i15662.scala b/tests/neg/i15662.scala index 1b6070f26e00..c84ed6e5e341 100644 --- a/tests/neg/i15662.scala +++ b/tests/neg/i15662.scala @@ -2,12 +2,12 @@ case class Composite[T](v: T) -def m(composite: Composite[_]): Unit = +def m(composite: Composite[?]): Unit = composite match { case Composite[Int](v) => println(v) // error: cannot be checked at runtime } -def m2(composite: Composite[_]): Unit = +def m2(composite: Composite[?]): Unit = composite match { case Composite(v) => println(v) // ok } diff --git a/tests/neg/i15893.scala b/tests/neg/i15893.scala index d66da9ebec8b..a62ddc3ae653 100644 --- a/tests/neg/i15893.scala +++ b/tests/neg/i15893.scala @@ -27,17 +27,17 @@ transparent inline def transparentInlineMod2(inline n: NatT): NatT = inline n m def dependentlyTypedMod2[N <: NatT](n: N): Mod2[N] = n match case Zero(): Zero => Zero() // error case Succ(Zero()): Succ[Zero] => Succ(Zero()) // error - case Succ(Succ(predPredN)): Succ[Succ[_]] => dependentlyTypedMod2(predPredN) // error + case Succ(Succ(predPredN)): Succ[Succ[?]] => dependentlyTypedMod2(predPredN) // error inline def inlineDependentlyTypedMod2[N <: NatT](inline n: N): Mod2[N] = inline n match case Zero(): Zero => Zero() // error case Succ(Zero()): Succ[Zero] => Succ(Zero()) // error - case Succ(Succ(predPredN)): Succ[Succ[_]] => inlineDependentlyTypedMod2(predPredN) // error + case Succ(Succ(predPredN)): Succ[Succ[?]] => inlineDependentlyTypedMod2(predPredN) // error transparent inline def transparentInlineDependentlyTypedMod2[N <: NatT](inline n: N): Mod2[N] = inline n match case Zero(): Zero => Zero() // error case Succ(Zero()): Succ[Zero] => Succ(Zero()) // error - case Succ(Succ(predPredN)): Succ[Succ[_]] => transparentInlineDependentlyTypedMod2(predPredN) // error + case Succ(Succ(predPredN)): Succ[Succ[?]] => transparentInlineDependentlyTypedMod2(predPredN) // error def foo(n: NatT): NatT = mod2(n) match case Succ(Zero()) => Zero() diff --git a/tests/neg/i18058.check b/tests/neg/i18058.check index 2622eeb82a45..f610d9e7abb1 100644 --- a/tests/neg/i18058.check +++ b/tests/neg/i18058.check @@ -1,4 +1,4 @@ -- Error: tests/neg/i18058.scala:4:21 ---------------------------------------------------------------------------------- -4 |type G = (f: _ <: F) => f.A // error +4 |type G = (f: ? <: F) => f.A // error | ^ | invalid new prefix <: F cannot replace f.type in type f.A diff --git a/tests/neg/i18058.scala b/tests/neg/i18058.scala index b7309294aade..b032f810d2fd 100644 --- a/tests/neg/i18058.scala +++ b/tests/neg/i18058.scala @@ -1,4 +1,4 @@ trait F: type A -type G = (f: _ <: F) => f.A // error +type G = (f: ? <: F) => f.A // error diff --git a/tests/neg/i4382.check b/tests/neg/i4382.check index 4905638ab62a..bf4dc4a192d8 100644 --- a/tests/neg/i4382.check +++ b/tests/neg/i4382.check @@ -1,23 +1,23 @@ -- [E043] Type Error: tests/neg/i4382.scala:3:10 ----------------------------------------------------------------------- -3 | def v1: Id[_] = ??? // error +3 | def v1: Id[?] = ??? // error | ^^^^^ | unreducible application of higher-kinded type App.Id to wildcard arguments | | longer explanation available when compiling with `-explain` -- [E043] Type Error: tests/neg/i4382.scala:6:10 ----------------------------------------------------------------------- -6 | def v2: HkL[_] = ??? // error +6 | def v2: HkL[?] = ??? // error | ^^^^^^ | unreducible application of higher-kinded type App.HkL to wildcard arguments | | longer explanation available when compiling with `-explain` -- [E043] Type Error: tests/neg/i4382.scala:9:10 ----------------------------------------------------------------------- -9 | def v3: HkU[_] = ??? // error +9 | def v3: HkU[?] = ??? // error | ^^^^^^ | unreducible application of higher-kinded type App.HkU to wildcard arguments | | longer explanation available when compiling with `-explain` -- [E043] Type Error: tests/neg/i4382.scala:12:10 ---------------------------------------------------------------------- -12 | def v4: HkAbs[_] = ??? // error +12 | def v4: HkAbs[?] = ??? // error | ^^^^^^^^ | unreducible application of higher-kinded type App.HkAbs to wildcard arguments | diff --git a/tests/neg/i4382.scala b/tests/neg/i4382.scala index aefe23094ce9..80f0948fa82c 100644 --- a/tests/neg/i4382.scala +++ b/tests/neg/i4382.scala @@ -1,13 +1,13 @@ object App { type Id[A] >: A <: A - def v1: Id[_] = ??? // error + def v1: Id[?] = ??? // error type HkL[A] >: A - def v2: HkL[_] = ??? // error + def v2: HkL[?] = ??? // error type HkU[A] <: A - def v3: HkU[_] = ??? // error + def v3: HkU[?] = ??? // error type HkAbs[A] - def v4: HkAbs[_] = ??? // error + def v4: HkAbs[?] = ??? // error } diff --git a/tests/neg/i4986c.scala b/tests/neg/i4986c.scala index 31458a7e9cbb..13b608a69707 100644 --- a/tests/neg/i4986c.scala +++ b/tests/neg/i4986c.scala @@ -57,7 +57,7 @@ object Test { implicitly[U[Int, Option, Map]] // error - val u = new U[String, List, [A, _] =>> List[Option[_]]] { } + val u = new U[String, List, [A, _] =>> List[Option[?]]] { } val i = new u.I[Int] i.m[Option[Long]] // error } diff --git a/tests/neg/i5077.scala b/tests/neg/i5077.scala index 64de24bfd669..d705ffe52dd9 100644 --- a/tests/neg/i5077.scala +++ b/tests/neg/i5077.scala @@ -7,7 +7,7 @@ case class C[A](is: Is[A], value: A) @main def Test = { val c_string: C[String] = C(IsString, "name") - val c_any: C[_] = c_string + val c_any: C[?] = c_string val any: Any = c_string // Case 1: error diff --git a/tests/neg/i6724.check b/tests/neg/i6724.check index 4dd50236bbcb..0d2481ddaa2b 100644 --- a/tests/neg/i6724.check +++ b/tests/neg/i6724.check @@ -1,4 +1,4 @@ -- [E008] Not Found Error: tests/neg/i6724.scala:7:17 ------------------------------------------------------------------ -7 | def f(foo: Foo.Baz): Foo[_] = foo // error +7 | def f(foo: Foo.Baz): Foo[?] = foo // error | ^^^^^^^ | type Baz is not a member of object Foo - did you mean Foo.Bar? diff --git a/tests/neg/i6724.scala b/tests/neg/i6724.scala index 7cb4d8eddbfb..18b660e7bc0c 100644 --- a/tests/neg/i6724.scala +++ b/tests/neg/i6724.scala @@ -4,5 +4,5 @@ enum Foo[T] { } object Main { - def f(foo: Foo.Baz): Foo[_] = foo // error + def f(foo: Foo.Baz): Foo[?] = foo // error } diff --git a/tests/neg/i8736.scala b/tests/neg/i8736.scala index 9724e5f81b2a..b2e7a0a66cb6 100644 --- a/tests/neg/i8736.scala +++ b/tests/neg/i8736.scala @@ -13,7 +13,7 @@ object App extends App { type Rec[K <: String, V0] = Rec0[K] { def get(k: K): V0 } def field[V](s: String)(v: V): Rec[s.type, V] = Rec0(Map(s -> v)).asInstanceOf[Rec[s.type, V]] - implicit class RecOps[R <: Rec0[_]](has: R) { + implicit class RecOps[R <: Rec0[?]](has: R) { def +[K1 <: String, V1](that: Rec[K1, V1]): R & Rec[K1, V1] = Rec0(has.map ++ that.map).asInstanceOf[R & Rec[K1, V1]] } diff --git a/tests/neg/matchtype-seq.check b/tests/neg/matchtype-seq.check index dbc53eaf6707..980329d585dc 100644 --- a/tests/neg/matchtype-seq.check +++ b/tests/neg/matchtype-seq.check @@ -285,7 +285,7 @@ | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg/matchtype-seq.scala:109:29 ---------------------------------------------------- -109 | identity[T9[Tuple2[_, _]]]("") // error +109 | identity[T9[Tuple2[?, ?]]]("") // error | ^^ | Found: ("" : String) | Required: Test.T9[(?, ?)] @@ -302,7 +302,7 @@ | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg/matchtype-seq.scala:110:29 ---------------------------------------------------- -110 | identity[T9[Tuple2[_, _]]](1) // error +110 | identity[T9[Tuple2[?, ?]]](1) // error | ^ | Found: (1 : Int) | Required: Test.T9[(?, ?)] diff --git a/tests/neg/matchtype-seq.scala b/tests/neg/matchtype-seq.scala index 79a38fb2f5e4..46f9c02e5262 100644 --- a/tests/neg/matchtype-seq.scala +++ b/tests/neg/matchtype-seq.scala @@ -106,8 +106,8 @@ object Test { identity[T9[Tuple2[String, Nothing]]]("1") // error identity[T9[Tuple2[Int, Nothing]]](1) // error identity[T9[Tuple2[Nothing, Int]]]("1") // error - identity[T9[Tuple2[_, _]]]("") // error - identity[T9[Tuple2[_, _]]](1) // error + identity[T9[Tuple2[?, ?]]]("") // error + identity[T9[Tuple2[?, ?]]](1) // error identity[T9[Tuple2[Any, Any]]]("") // error identity[T9[Tuple2[Any, Any]]](1) // error diff --git a/tests/neg/type-test-syntesize-b.scala b/tests/neg/type-test-syntesize-b.scala index 79be9357387e..b5402eb92c66 100644 --- a/tests/neg/type-test-syntesize-b.scala +++ b/tests/neg/type-test-syntesize-b.scala @@ -15,7 +15,7 @@ object Test { test[Any, Int] test[Any, String] - test[Any, Some[_]] + test[Any, Some[?]] test[Any, Array[Int]] test[Seq[Int], List[Int]] diff --git a/tests/neg/wildcard-type-syntax-3.4.check b/tests/neg/wildcard-type-syntax-3.4.check new file mode 100644 index 000000000000..9b2d755b64eb --- /dev/null +++ b/tests/neg/wildcard-type-syntax-3.4.check @@ -0,0 +1,5 @@ +-- Error: tests/neg/wildcard-type-syntax-3.4.scala:7:17 ---------------------------------------------------------------- +7 | case _: List[_] => // error: migration warning + | ^ + | `_` is deprecated for wildcard arguments of types: use `?` instead + | This construct can be rewritten automatically under -rewrite -source 3.4-migration. diff --git a/tests/neg/wildcard-type-syntax-3.4.scala b/tests/neg/wildcard-type-syntax-3.4.scala new file mode 100644 index 000000000000..1123c9cbbe35 --- /dev/null +++ b/tests/neg/wildcard-type-syntax-3.4.scala @@ -0,0 +1,8 @@ +//> using options -Werror + +import scala.language.`3.4-migration` + +def test = + Seq() match + case _: List[_] => // error: migration warning + case _: Seq[?] => diff --git a/tests/neg/wildcard-type-syntax-future-migration.scala b/tests/neg/wildcard-type-syntax-future-migration.scala new file mode 100644 index 000000000000..6a5367385ab0 --- /dev/null +++ b/tests/neg/wildcard-type-syntax-future-migration.scala @@ -0,0 +1,8 @@ +//> using options -Werror + +import scala.language.`future-migration` + +def test = + Seq() match + case _: List[_] => // error: migration warning + case _: Seq[?] => diff --git a/tests/neg/wildcard-type-syntax-future.scala b/tests/neg/wildcard-type-syntax-future.scala new file mode 100644 index 000000000000..750fd55ec226 --- /dev/null +++ b/tests/neg/wildcard-type-syntax-future.scala @@ -0,0 +1,6 @@ +import scala.language.future + +def test = + Seq() match + case _: List[_] => // error + case _: Seq[?] => diff --git a/tests/patmat/exhausting.scala b/tests/patmat/exhausting.scala index 9f17fae9def5..f65efb18cf9c 100644 --- a/tests/patmat/exhausting.scala +++ b/tests/patmat/exhausting.scala @@ -5,7 +5,7 @@ object Test { case object Bar3 extends Foo[AnyRef] def ex1[T](xs: List[T]) = xs match { - case ys: List[_] => "ok" + case ys: List[?] => "ok" } def ex2[T](xx: (Foo[T], Foo[T])) = xx match { case (Bar1, Bar1) => () @@ -14,7 +14,7 @@ object Test { case (_, Bar2) => () } def ex3[T](xx: (Foo[T], Foo[T])) = xx match { - case (_: Foo[_], _: Foo[_]) => () + case (_: Foo[?], _: Foo[?]) => () } // fails for: ::(_, Nil), ::(_, ::(_, ::(_, _))), ... diff --git a/tests/patmat/gadt.scala b/tests/patmat/gadt.scala index 0541ed61f95b..484dac39a973 100644 --- a/tests/patmat/gadt.scala +++ b/tests/patmat/gadt.scala @@ -35,14 +35,14 @@ object Test { // case _: Or => true } - def foo4a(x: Expr[_]) = x match { + def foo4a(x: Expr[?]) = x match { case _: IntLit => true case _: Sum => true case _: BooleanLit => true case _: Or => true } - def foo4b(x: Expr[_]) = x match { + def foo4b(x: Expr[?]) = x match { case _: Sum => true case _: Or => true } diff --git a/tests/patmat/gadt2.scala b/tests/patmat/gadt2.scala index f6a3978c773c..feb096b1d209 100644 --- a/tests/patmat/gadt2.scala +++ b/tests/patmat/gadt2.scala @@ -4,12 +4,12 @@ case class Succ[T]() extends Nat[T] // +N is incorrect, as in `foo` we can have `N = Zero | Succ[Zero]`, // then it's correct for exhaustivity check to produce two warnings. -sealed trait Vect[N <: Nat[_], +T] +sealed trait Vect[N <: Nat[?], +T] case class VN[T]() extends Vect[Zero, T] -case class VC[T, N <: Nat[_]](x: T, xs: Vect[N, T]) extends Vect[Succ[N], T] +case class VC[T, N <: Nat[?]](x: T, xs: Vect[N, T]) extends Vect[Succ[N], T] object Test { - def foo[N <: Nat[_], A, B](v1: Vect[N, A], v2: Vect[N, B]) = (v1, v2) match { + def foo[N <: Nat[?], A, B](v1: Vect[N, A], v2: Vect[N, B]) = (v1, v2) match { case (VN(), VN()) => 1 case (VC(x, xs), VC(y, ys)) => 2 } diff --git a/tests/patmat/gadt4.scala b/tests/patmat/gadt4.scala index d5212be2d406..069d0f8be7c3 100644 --- a/tests/patmat/gadt4.scala +++ b/tests/patmat/gadt4.scala @@ -4,12 +4,12 @@ case class Succ[T]() extends Nat[T] // +N is incorrect, as in `foo` we can have `N = Zero | Succ[Zero]`, // then it's correct for exhaustivity check to produce two warnings. -sealed trait Vect[+N <: Nat[_], +T] +sealed trait Vect[+N <: Nat[?], +T] case class VN[T]() extends Vect[Zero, T] -case class VC[T, N <: Nat[_]](x: T, xs: Vect[N, T]) extends Vect[Succ[N], T] +case class VC[T, N <: Nat[?]](x: T, xs: Vect[N, T]) extends Vect[Succ[N], T] object Test { - def foo[N <: Nat[_], A, B](v1: Vect[N, A], v2: Vect[N, B]) = (v1, v2) match { + def foo[N <: Nat[?], A, B](v1: Vect[N, A], v2: Vect[N, B]) = (v1, v2) match { case (VN(), VN()) => 1 case (VC(x, xs), VC(y, ys)) => 2 } diff --git a/tests/patmat/gadt5.scala b/tests/patmat/gadt5.scala index 8cc9e77f1cdd..d057ef5230f0 100644 --- a/tests/patmat/gadt5.scala +++ b/tests/patmat/gadt5.scala @@ -15,12 +15,12 @@ object Try1 { case class Succ[T](n: Nat[T]) extends Nat[TSucc[T]] //We can index Vect with the types of value-level Nat, but this is a bit overkill. Still, no warnings. - sealed trait Vect[N <: Nat[_], +T] + sealed trait Vect[N <: Nat[?], +T] case class VN[T]() extends Vect[Zero, T] - case class VC[T, N <: Nat[_]](x: T, xs: Vect[N, T]) extends Vect[Succ[N], T] + case class VC[T, N <: Nat[?]](x: T, xs: Vect[N, T]) extends Vect[Succ[N], T] object Test { - def foo[N <: Nat[_], A, B](v1: Vect[N, A], v2: Vect[N, B]) = + def foo[N <: Nat[?], A, B](v1: Vect[N, A], v2: Vect[N, B]) = (v1, v2) match { case (VN(), VN()) => 1 case (VC(x, xs), VC(y, ys)) => 2 @@ -65,7 +65,7 @@ object Try3 { case (VC(x, xs), VC(y, ys)) => 2 } //a call-site which would cause a MatchError (maybe that error should be tested) - def bar = foo[TZero | TSucc[_], Int, String](VN(), VC("", VN())) + def bar = foo[TZero | TSucc[?], Int, String](VN(), VC("", VN())) } } diff --git a/tests/patmat/i12241.scala b/tests/patmat/i12241.scala index 4f61027e2f65..fe21eab4f3c3 100644 --- a/tests/patmat/i12241.scala +++ b/tests/patmat/i12241.scala @@ -26,7 +26,7 @@ object EndpointInput { object Test extends App { import EndpointInput._ - def compare(left: EndpointInput[_], right: EndpointInput[_]): Boolean = + def compare(left: EndpointInput[?], right: EndpointInput[?]): Boolean = (left, right) match { case (Pair(), Pair()) => true case (MappedPair(), MappedPair()) => true @@ -50,7 +50,7 @@ object Test extends App { case (_, _) => false } - def compare2(left: EndpointInput[_], right: EndpointInput[_]): Boolean = + def compare2(left: EndpointInput[?], right: EndpointInput[?]): Boolean = (left, right) match { case (Pair(), Pair()) => true case (MappedPair(), MappedPair()) => true diff --git a/tests/patmat/i12805-fallout.scala b/tests/patmat/i12805-fallout.scala index 66d9c0d598fd..f460c91f080c 100644 --- a/tests/patmat/i12805-fallout.scala +++ b/tests/patmat/i12805-fallout.scala @@ -25,7 +25,7 @@ case class CaseDef[-T >: Untyped]() extends Tree[T] def test[T >: Untyped](tree: Tree[T], tp: Type) = tree.withType(tp) match { case Ident() => 1 case DefDef() => 2 - case _: Inlined[_] => 3 + case _: Inlined[?] => 3 case CaseDef() => 4 case _ => 5 } diff --git a/tests/patmat/i4030.scala b/tests/patmat/i4030.scala index c0c7a76eb813..75845bb5e945 100644 --- a/tests/patmat/i4030.scala +++ b/tests/patmat/i4030.scala @@ -6,9 +6,9 @@ case class C4[X, Y]() extends Root[(X => X)|(Y => Y)|(X => Y)] object TestGADT { - def f[A <: Seq[_], B, Foo >: A => B](v: Root[Foo], u: Root[Foo]) = (v, u) match { + def f[A <: Seq[?], B, Foo >: A => B](v: Root[Foo], u: Root[Foo]) = (v, u) match { case (C3(), C3()) => } // The following line no longer type checks - // f(C3[Seq[_], Long](), C4[Seq[_], Long]()) + // f(C3[Seq[?], Long](), C4[Seq[?], Long]()) } diff --git a/tests/patmat/i6197c.scala b/tests/patmat/i6197c.scala index 81142ebaac3c..4c8ec65f10f9 100644 --- a/tests/patmat/i6197c.scala +++ b/tests/patmat/i6197c.scala @@ -1,5 +1,5 @@ def foo(x: Option[Any]) = x match { - case _: Some[Some[_]] => - case _: Some[_] => // unreachable + case _: Some[Some[?]] => + case _: Some[?] => // unreachable case None => } \ No newline at end of file diff --git a/tests/patmat/i6197d.scala b/tests/patmat/i6197d.scala index 4754e948c684..c09315d4a073 100644 --- a/tests/patmat/i6197d.scala +++ b/tests/patmat/i6197d.scala @@ -1,8 +1,8 @@ //> using options -Ycheck-all-patmat def foo(x: Array[String]) = x match { - case _: Array[_] => + case _: Array[?] => } def bar(x: Array[String]) = x match { - case _: Array[_ <: Int] => + case _: Array[? <: Int] => } diff --git a/tests/patmat/t11620b.scala b/tests/patmat/t11620b.scala index a71f9ee4ade5..e6084619c0e0 100644 --- a/tests/patmat/t11620b.scala +++ b/tests/patmat/t11620b.scala @@ -9,7 +9,7 @@ import Length.* case class Indent[T <: Length](length: T) -def withIndent[T <: Length](indent: => Indent[_]): Unit = +def withIndent[T <: Length](indent: => Indent[?]): Unit = indent match { case Indent(Num(0)) => println("this") case x => println(x) // "unreachable" diff --git a/tests/patmat/t2425.scala b/tests/patmat/t2425.scala index 477d5467aab3..8d925fb34918 100644 --- a/tests/patmat/t2425.scala +++ b/tests/patmat/t2425.scala @@ -3,8 +3,8 @@ class D extends B object Test extends App { def foo[T](bar: T) = { bar match { - case _: Array[Array[_]] => println("array 2d") - case _: Array[_] => println("array 1d") + case _: Array[Array[?]] => println("array 2d") + case _: Array[?] => println("array 1d") case _ => println("something else") } } diff --git a/tests/patmat/t3097.scala b/tests/patmat/t3097.scala index 3ff61b3c7b87..77f65d7e87bd 100644 --- a/tests/patmat/t3097.scala +++ b/tests/patmat/t3097.scala @@ -1,7 +1,7 @@ sealed trait ISimpleValue sealed trait IListValue extends ISimpleValue { - def items: List[IAtomicValue[_]] + def items: List[IAtomicValue[?]] } sealed trait IAtomicValue[O] extends ISimpleValue { @@ -13,7 +13,7 @@ sealed trait IAbstractDoubleValue[O] extends IAtomicValue[O] { sealed trait IDoubleValue extends IAbstractDoubleValue[Double] -case class ListValue(val items: List[IAtomicValue[_]]) extends IListValue +case class ListValue(val items: List[IAtomicValue[?]]) extends IListValue class DoubleValue(val data: Double) extends IDoubleValue { def asDouble = data @@ -28,7 +28,7 @@ object Test { val v: ISimpleValue = new DoubleValue(1) v match { case m: IListValue => println("list") - case a: IAtomicValue[_] => println("atomic") + case a: IAtomicValue[?] => println("atomic") } } diff --git a/tests/patmat/t6450.scala b/tests/patmat/t6450.scala index 92194c2e48ab..559fc438d368 100644 --- a/tests/patmat/t6450.scala +++ b/tests/patmat/t6450.scala @@ -2,7 +2,7 @@ sealed abstract class FoundNode[T] case class A[T](x: T) extends FoundNode[T] object Foo { - val v: (Some[_], FoundNode[_]) = (???, ???) + val v: (Some[?], FoundNode[?]) = (???, ???) v match { case (x: Some[t], _) => } diff --git a/tests/patmat/t9779.scala b/tests/patmat/t9779.scala index 9c418b0b1dc5..0f272b586507 100644 --- a/tests/patmat/t9779.scala +++ b/tests/patmat/t9779.scala @@ -7,7 +7,7 @@ trait Elems { } class BadMatch[A <: Elems](a: A) { - private def toLuaValue(eX: a.Elem[_]): String = eX match { + private def toLuaValue(eX: a.Elem[?]): String = eX match { case a.UnitElement => "" // type mismatch } } \ No newline at end of file diff --git a/tests/pos/i15717.scala b/tests/pos/i15717.scala index 337a1f08ed10..0e4c3f072163 100644 --- a/tests/pos/i15717.scala +++ b/tests/pos/i15717.scala @@ -1,10 +1,10 @@ //> using options -Werror class Test: - def pmat(xs: java.util.Vector[_]): String = xs.get(0) match + def pmat(xs: java.util.Vector[?]): String = xs.get(0) match case d: Double => d.toString() // was: error: unreachable case, which is spurious case _ => "shrug" - def pmatR(xs: java.util.Vector[_]): String = + def pmatR(xs: java.util.Vector[?]): String = val scr = xs.get(0) 1.0 match case `scr` => scr.toString() // for the reverse provablyDisjoint case diff --git a/tests/pos/t6963c.scala b/tests/pos/t6963c.scala index 9154c0506d23..6effd4082065 100644 --- a/tests/pos/t6963c.scala +++ b/tests/pos/t6963c.scala @@ -2,22 +2,22 @@ // import collection.Seq object Test { - def f1(x: Any) = x.isInstanceOf[Seq[_]] + def f1(x: Any) = x.isInstanceOf[Seq[?]] def f2(x: Any) = x match { - case _: Seq[_] => true + case _: Seq[?] => true case _ => false } def f3(x: Any) = x match { - case _: Array[_] => true + case _: Array[?] => true case _ => false } - def f4(x: Any) = x.isInstanceOf[Iterable[_]] + def f4(x: Any) = x.isInstanceOf[Iterable[?]] def f5(x1: Any, x2: Any, x3: AnyRef) = (x1, x2, x3) match { - case (Some(_: Seq[_]), Nil, _) => 1 - case (None, List(_: List[_], _), _) => 2 + case (Some(_: Seq[?]), Nil, _) => 1 + case (None, List(_: List[?], _), _) => 2 case _ => 3 } diff --git a/tests/pos/wildcard-type-syntax-future-migration.scala b/tests/pos/wildcard-type-syntax-future-migration.scala new file mode 100644 index 000000000000..3075c609ffdc --- /dev/null +++ b/tests/pos/wildcard-type-syntax-future-migration.scala @@ -0,0 +1,6 @@ +import scala.language.`future-migration` + +def test = + Seq() match + case _: List[_] => // warn + case _: Seq[?] => diff --git a/tests/pos/wildcard-type-syntax.scala b/tests/pos/wildcard-type-syntax.scala new file mode 100644 index 000000000000..26bbaa319277 --- /dev/null +++ b/tests/pos/wildcard-type-syntax.scala @@ -0,0 +1,8 @@ +//> using options -Werror + +import scala.language.`3.3` + +def test = + Seq() match + case _: List[_] => + case _: Seq[?] => diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index d189a824b2c9..56e84c25b297 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -62,7 +62,7 @@ Text => empty Language => Scala Symbols => 61 entries Occurrences => 143 entries -Diagnostics => 1 entries +Diagnostics => 4 entries Synthetics => 3 entries Symbols: @@ -274,6 +274,12 @@ Occurrences: [53:39..53:47): toString -> scala/Tuple2#toString(). Diagnostics: +[20:15..20:15): [warning] `_` is deprecated for wildcard arguments of types: use `?` instead +This construct can be rewritten automatically under -rewrite -source 3.4-migration. +[21:15..21:15): [warning] `_` is deprecated for wildcard arguments of types: use `?` instead +This construct can be rewritten automatically under -rewrite -source 3.4-migration. +[39:20..39:20): [warning] `_` is deprecated for wildcard arguments of types: use `?` instead +This construct can be rewritten automatically under -rewrite -source 3.4-migration. [40:12..40:15): [warning] unused local definition Synthetics: @@ -389,7 +395,7 @@ Text => empty Language => Scala Symbols => 23 entries Occurrences => 50 entries -Diagnostics => 1 entries +Diagnostics => 4 entries Synthetics => 2 entries Symbols: @@ -470,6 +476,12 @@ Occurrences: [23:42..23:45): ??? -> scala/Predef.`???`(). Diagnostics: +[9:14..9:14): [warning] `_` is deprecated for wildcard arguments of types: use `?` instead +This construct can be rewritten automatically under -rewrite -source 3.4-migration. +[9:22..9:22): [warning] `_` is deprecated for wildcard arguments of types: use `?` instead +This construct can be rewritten automatically under -rewrite -source 3.4-migration. +[11:29..11:29): [warning] `_` is deprecated for wildcard arguments of types: use `?` instead +This construct can be rewritten automatically under -rewrite -source 3.4-migration. [14:8..14:9): [warning] unused local definition Synthetics: @@ -5064,7 +5076,7 @@ Text => empty Language => Scala Symbols => 143 entries Occurrences => 246 entries -Diagnostics => 3 entries +Diagnostics => 4 entries Synthetics => 1 entries Symbols: @@ -5466,6 +5478,8 @@ Diagnostics: This construct can be rewritten automatically under -rewrite -source 3.4-migration. [63:25..63:29): [warning] with as a type operator has been deprecated; use & instead This construct can be rewritten automatically under -rewrite -source 3.4-migration. +[71:31..71:31): [warning] `_` is deprecated for wildcard arguments of types: use `?` instead +This construct can be rewritten automatically under -rewrite -source 3.4-migration. Synthetics: [68:20..68:24):@ann => *[Int]