Skip to content

Commit 405f2b0

Browse files
committed
Disallow _ for wildcard arguments of types and use ?
1 parent 1e95432 commit 405f2b0

File tree

463 files changed

+1020
-1006
lines changed

Some content is hidden

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

463 files changed

+1020
-1006
lines changed

compiler/src/dotty/tools/dotc/config/Feature.scala

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ object Feature:
2626
val dependent = experimental("dependent")
2727
val erasedDefinitions = experimental("erasedDefinitions")
2828
val symbolLiterals = deprecated("symbolLiterals")
29+
val underscoreWildcards = deprecated("underscoreWildcards")
2930
val fewerBraces = experimental("fewerBraces")
3031
val saferExceptions = experimental("saferExceptions")
3132
val clauseInterleaving = experimental("clauseInterleaving")

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -1856,9 +1856,12 @@ object Parsers {
18561856
val start = in.skipToken()
18571857
Ident(tpnme.USCOREkw).withSpan(Span(start, in.lastOffset, start))
18581858
else
1859-
if sourceVersion.isAtLeast(future) then
1860-
deprecationWarning(em"`_` is deprecated for wildcard arguments of types: use `?` instead")
1861-
patch(source, Span(in.offset, in.offset + 1), "?")
1859+
if !in.featureEnabled(Feature.underscoreWildcards) then
1860+
report.errorOrMigrationWarning(
1861+
em"`_` is deprecated for wildcard arguments of types: use `?` instead${rewriteNotice(`3.4-migration`)}",
1862+
in.sourcePos(), from = `3.4`)
1863+
if sourceVersion == `3.4-migration` then
1864+
patch(source, Span(in.offset, in.offset + 1), "?")
18621865
val start = in.skipToken()
18631866
typeBounds().withSpan(Span(start, in.lastOffset, start))
18641867
// Allow symbols -_ and +_ through for compatibility with code written using kind-projector in Scala 3 underscore mode.
+2-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
//> using options -source:future -deprecation
1+
//> using options -language:`3.4-migration` -deprecation
22
scala> type M[X] = X match { case Int => String case _ => Int }
33
scala> type N[X] = X match { case List[_] => Int }
4-
1 warning found
5-
-- Deprecation Warning: --------------------------------------------------------
4+
-- Error: ----------------------------------------------------------------------
65
1 | type N[X] = X match { case List[_] => Int }
76
| ^
87
| `_` is deprecated for wildcard arguments of types: use `?` instead

compiler/test-resources/repl/i6643

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ scala> import scala.collection._
33
scala>:type 1
44
Int
55

6-
scala> object IterableTest { def g[CC[_] <: Iterable[_] with IterableOps[_, _, _]](from: CC[Int]): IterableFactory[CC] = ??? }
6+
scala> object IterableTest { def g[CC[_] <: Iterable[?] with IterableOps[?, ?, ?]](from: CC[Int]): IterableFactory[CC] = ??? }
77
// defined object IterableTest

compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ class DottyBytecodeTests extends DottyBytecodeTest {
334334
| def test =
335335
| try print("foo")
336336
| catch {
337-
| case _: scala.runtime.NonLocalReturnControl[_] => ()
337+
| case _: scala.runtime.NonLocalReturnControl[?] => ()
338338
| }
339339
|}
340340
""".stripMargin

library/src/scala/Tuple.scala

+6-6
Original file line numberDiff line numberDiff line change
@@ -97,25 +97,25 @@ object Tuple {
9797

9898
/** Type of the head of a tuple */
9999
type Head[X <: NonEmptyTuple] = X match {
100-
case x *: _ => x
100+
case x *: xs => x
101101
}
102102

103103
/** Type of the initial part of the tuple without its last element */
104104
type Init[X <: Tuple] <: Tuple = X match {
105-
case _ *: EmptyTuple => EmptyTuple
105+
case x *: EmptyTuple => EmptyTuple
106106
case x *: xs =>
107107
x *: Init[xs]
108108
}
109109

110110
/** Type of the tail of a tuple */
111111
type Tail[X <: NonEmptyTuple] <: Tuple = X match {
112-
case _ *: xs => xs
112+
case x *: xs => xs
113113
}
114114

115115
/** Type of the last element of a tuple */
116116
type Last[X <: Tuple] = X match {
117117
case x *: EmptyTuple => x
118-
case _ *: xs => Last[xs]
118+
case x *: xs => Last[xs]
119119
}
120120

121121
/** Type of the concatenation of two tuples */
@@ -182,8 +182,8 @@ object Tuple {
182182
*/
183183
type Zip[T1 <: Tuple, T2 <: Tuple] <: Tuple = (T1, T2) match {
184184
case (h1 *: t1, h2 *: t2) => (h1, h2) *: Zip[t1, t2]
185-
case (EmptyTuple, _) => EmptyTuple
186-
case (_, EmptyTuple) => EmptyTuple
185+
case (EmptyTuple, ?) => EmptyTuple
186+
case (?, EmptyTuple) => EmptyTuple
187187
case _ => Tuple
188188
}
189189

library/src/scala/runtime/stdLibPatches/language.scala

+4
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ object language:
114114
*/
115115
@compileTimeOnly("`symbolLiterals` can only be used at compile time in import statements")
116116
object symbolLiterals
117+
118+
/** TODO */
119+
@compileTimeOnly("`underscoreWildcards` can only be used at compile time in import statements")
120+
object underscoreWildcards
117121
end deprecated
118122

119123
/** Where imported, auto-tupling is disabled.

project/Build.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -1008,7 +1008,10 @@ object Build {
10081008
Seq("-sourcepath", ((Compile/sourceManaged).value / "scala-library-src").toString)
10091009
},
10101010
Compile / doc / scalacOptions += "-Ydocument-synthetic-types",
1011-
scalacOptions += "-Ycompile-scala2-library",
1011+
scalacOptions ++= Seq(
1012+
"-Ycompile-scala2-library",
1013+
"-language:deprecated.underscoreWildcards",
1014+
),
10121015
scalacOptions -= "-Xfatal-warnings",
10131016
ivyConfigurations += SourceDeps.hide,
10141017
transitiveClassifiers := Seq("sources"),
@@ -1292,6 +1295,7 @@ object Build {
12921295
mtagsSharedSources
12931296
} (Set(mtagsSharedSourceJar)).toSeq
12941297
}.taskValue,
1298+
scalacOptions += "-language:deprecated.underscoreWildcards",
12951299
)
12961300
}
12971301

@@ -1361,6 +1365,7 @@ object Build {
13611365
dependsOn(`scala3-library-bootstrappedJS`).
13621366
settings(
13631367
bspEnabled := false,
1368+
scalacOptions += "-language:deprecated.underscoreWildcards",
13641369
scalacOptions --= Seq("-Xfatal-warnings", "-deprecation"),
13651370

13661371
// Required to run Scala.js tests.

sbt-test/compilerReporter/i14576/Test.scala

-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,3 @@ object Test:
1212

1313
// private[this] and = _ are deprecated under -source:future
1414
private[this] var x: AnyRef = _
15-
16-
// under -source:future, `_` is deprecated for wildcard arguments of types: use `?` instead
17-
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 3 deprecation warnings; re-run with -deprecation for details"))
27+
FakePrintWriter.messages.exists(_.contains("there were 2 deprecation warnings; re-run with -deprecation for details"))
2828
}
2929
},
3030
assertNoDeprecationSummary := {

sbt-test/scala2-compat/erasure/dottyApp/Api.scala

+33-33
Original file line numberDiff line numberDiff line change
@@ -156,41 +156,41 @@ class Z {
156156
def int_63(x: AnyVal with Int): Unit = {}
157157

158158
def intARRAY_64(x: Array[Int with Singleton]): Unit = {}
159-
def intARRAY_65(x: Array[_ <: Int]): Unit = {}
160-
def intARRAY_66(x: Array[_ <: Int with Singleton]): Unit = {}
161-
def intARRAY_67(x: Array[_ <: Singleton with Int]): Unit = {}
162-
def intARRAY_68(x: Array[_ <: Int with Any]): Unit = {}
163-
def intARRAY_69(x: Array[_ <: Any with Int]): Unit = {}
164-
def intARRAY_70(x: Array[_ <: Int with AnyVal]): Unit = {}
165-
def intARRAY_71(x: Array[_ <: AnyVal with Int]): Unit = {}
166-
def intARRAY_71a(x: Array[_ <: Int | Int]): Unit = {}
167-
def intARRAY_71b(x: Array[_ <: 1 | 2]): Unit = {}
159+
def intARRAY_65(x: Array[? <: Int]): Unit = {}
160+
def intARRAY_66(x: Array[? <: Int with Singleton]): Unit = {}
161+
def intARRAY_67(x: Array[? <: Singleton with Int]): Unit = {}
162+
def intARRAY_68(x: Array[? <: Int with Any]): Unit = {}
163+
def intARRAY_69(x: Array[? <: Any with Int]): Unit = {}
164+
def intARRAY_70(x: Array[? <: Int with AnyVal]): Unit = {}
165+
def intARRAY_71(x: Array[? <: AnyVal with Int]): Unit = {}
166+
def intARRAY_71a(x: Array[? <: Int | Int]): Unit = {}
167+
def intARRAY_71b(x: Array[? <: 1 | 2]): Unit = {}
168168

169169
def stringARRAY_72(x: Array[String with Singleton]): Unit = {}
170-
def stringARRAY_73(x: Array[_ <: String]): Unit = {}
171-
def stringARRAY_74(x: Array[_ <: String with Singleton]): Unit = {}
172-
def stringARRAY_75(x: Array[_ <: Singleton with String]): Unit = {}
173-
def stringARRAY_76(x: Array[_ <: String with Any]): Unit = {}
174-
def stringARRAY_77(x: Array[_ <: Any with String]): Unit = {}
175-
def stringARRAY_78(x: Array[_ <: String with AnyRef]): Unit = {}
176-
def stringARRAY_79(x: Array[_ <: AnyRef with String]): Unit = {}
177-
def stringARRAY_79a(x: Array[_ <: String | String]): Unit = {}
178-
def stringARRAY_79b(x: Array[_ <: "a" | "b"]): Unit = {}
179-
180-
def object_80(x: Array[_ <: Singleton]): Unit = {}
181-
def object_81(x: Array[_ <: AnyVal]): Unit = {}
182-
def objectARRAY_82(x: Array[_ <: AnyRef]): Unit = {}
183-
def object_83(x: Array[_ <: Any]): Unit = {}
184-
def object_83a(x: Array[_ <: Matchable]): Unit = {}
185-
def object_83b(x: Array[_ <: Int | Double]): Unit = {}
186-
def object_83c(x: Array[_ <: String | Int]): Unit = {}
187-
def object_83d(x: Array[_ <: Int | Matchable]): Unit = {}
188-
def object_83e(x: Array[_ <: AnyRef | AnyVal]): Unit = {}
189-
190-
def serializableARRAY_84(x: Array[_ <: Serializable]): Unit = {}
191-
def univARRAY_85(x: Array[_ <: Univ]): Unit = {}
192-
def aARRAY_86(x: Array[_ <: A]): Unit = {}
193-
def aARRAY_87(x: Array[_ <: A with B]): Unit = {}
170+
def stringARRAY_73(x: Array[? <: String]): Unit = {}
171+
def stringARRAY_74(x: Array[? <: String with Singleton]): Unit = {}
172+
def stringARRAY_75(x: Array[? <: Singleton with String]): Unit = {}
173+
def stringARRAY_76(x: Array[? <: String with Any]): Unit = {}
174+
def stringARRAY_77(x: Array[? <: Any with String]): Unit = {}
175+
def stringARRAY_78(x: Array[? <: String with AnyRef]): Unit = {}
176+
def stringARRAY_79(x: Array[? <: AnyRef with String]): Unit = {}
177+
def stringARRAY_79a(x: Array[? <: String | String]): Unit = {}
178+
def stringARRAY_79b(x: Array[? <: "a" | "b"]): Unit = {}
179+
180+
def object_80(x: Array[? <: Singleton]): Unit = {}
181+
def object_81(x: Array[? <: AnyVal]): Unit = {}
182+
def objectARRAY_82(x: Array[? <: AnyRef]): Unit = {}
183+
def object_83(x: Array[? <: Any]): Unit = {}
184+
def object_83a(x: Array[? <: Matchable]): Unit = {}
185+
def object_83b(x: Array[? <: Int | Double]): Unit = {}
186+
def object_83c(x: Array[? <: String | Int]): Unit = {}
187+
def object_83d(x: Array[? <: Int | Matchable]): Unit = {}
188+
def object_83e(x: Array[? <: AnyRef | AnyVal]): Unit = {}
189+
190+
def serializableARRAY_84(x: Array[? <: Serializable]): Unit = {}
191+
def univARRAY_85(x: Array[? <: Univ]): Unit = {}
192+
def aARRAY_86(x: Array[? <: A]): Unit = {}
193+
def aARRAY_87(x: Array[? <: A with B]): Unit = {}
194194

195195
def objectARRAY_88(x: Array[Any]): Unit = {}
196196
def objectARRAY_89(x: Array[AnyRef]): Unit = {}
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
import i11173.Bar
22

3-
def test(x: Bar[_]): Unit = ()
3+
def test(x: Bar[?]): Unit = ()

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

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

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 {

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)

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"))

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")

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..

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:

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
)

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)

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)

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)

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

tests/bench/inductive-implicits.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ package shapeless {
2525
def ::[HH](h : HH) : HH :: H :: T = shapeless.::(h, this)
2626

2727
override def toString = head match {
28-
case _: ::[_, _] => "("+head.toString+") :: "+tail.toString
28+
case _: ::[?, ?] => "("+head.toString+") :: "+tail.toString
2929
case _ => head.toString+" :: "+tail.toString
3030
}
3131
}

tests/explicit-nulls/pos/array.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class Foo {
55

66
def test = {
77
// accept any array of string
8-
def f(xs: Array[_ >: String <: String | Null] | Null): Unit = ???
8+
def f(xs: Array[? >: String <: String | Null] | Null): Unit = ???
99

1010
val a1: Array[String] = ???
1111
val a2: Array[String] | Null = ???

tests/explicit-nulls/pos/flow-inline.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ class TreeOps {
77
abstract class Tree[A, B](val key: A, val value: B)
88
class RedTree[A, B](override val key: A, override val value: B) extends Tree[A, B](key, value)
99

10-
private transparent inline def isRedTree(tree: Tree[_, _] | Null) =
11-
(tree != null) && tree.isInstanceOf[RedTree[_, _]]
10+
private transparent inline def isRedTree(tree: Tree[?, ?] | Null) =
11+
(tree != null) && tree.isInstanceOf[RedTree[?, ?]]
1212

1313
def foo[A, B](tree: Tree[A, B] | Null): Unit = {
1414
if (isRedTree(tree)) {

tests/generic-java-signatures/arrayBound.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
class Foo[
2-
T <: Array[_],
2+
T <: Array[?],
33
U <: Array[T],
44
V <: java.util.List[Array[T]],
5-
W <: java.util.List[_ <: java.util.Date],
6-
X <: java.util.HashMap[Array[_], java.util.ArrayList[_ <: java.util.Date]],
5+
W <: java.util.List[? <: java.util.Date],
6+
X <: java.util.HashMap[Array[?], java.util.ArrayList[? <: java.util.Date]],
77
T1,
88
U1 <: Array[T1],
99
V1 <: Array[Array[T1]]
1010
]
1111
object Test {
1212
def main(args: Array[String]): Unit = {
13-
val tParams = classOf[Foo[_, _, _, _, _, _, _, _]].getTypeParameters()
13+
val tParams = classOf[Foo[?, ?, ?, ?, ?, ?, ?, ?]].getTypeParameters()
1414
tParams.foreach { tp =>
1515
println(tp.getName + " <: " + tp.getBounds.map(_.getTypeName).mkString(", "))
1616
}

0 commit comments

Comments
 (0)