Skip to content

Commit 276e368

Browse files
committed
Allow ? as a wildcard even without -Xsource:3
Like scala#9721, the goal here is to ease cross-compilation between Scala 2 and 3 code as we prepare for `_` as wildcard to be deprecated in Scala 3 (cf scala/scala3#5379). This is technically a source-breaking change, but using a type named ? without backticks is deprecated since 2.13.6 (scala#9626) and defining a type named ? without backticks is disallowed since 2.13.7 (scala#9735). The only known user of ? as a type name was the kind-projector plugin, but support for this syntax was removed from the plugin a year ago (typelevel/kind-projector#186), so I believe this change won't be disruptive.
1 parent 6471120 commit 276e368

File tree

4 files changed

+6
-30
lines changed

4 files changed

+6
-30
lines changed

src/compiler/scala/tools/nsc/ast/parser/Parsers.scala

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -713,13 +713,9 @@ self =>
713713
def isRawIdent = in.token == IDENTIFIER
714714

715715
def isWildcardType = in.token == USCORE || isScala3WildcardType
716-
def isScala3WildcardType = settings.isScala3 && isRawIdent && in.name == raw.QMARK
717-
def checkQMarkUsage() =
718-
if (!settings.isScala3 && isRawIdent && in.name == raw.QMARK)
719-
deprecationWarning(in.offset,
720-
"Wrap `?` in backticks to continue to use it as an identifier, or use `-Xsource:3` to use it as a wildcard like in Scala 3.", "2.13.6")
716+
def isScala3WildcardType = isRawIdent && in.name == raw.QMARK
721717
def checkQMarkDefinition() =
722-
if (isRawIdent && in.name == raw.QMARK)
718+
if (isScala3WildcardType)
723719
syntaxError(in.offset, "using `?` as a type name requires backticks.")
724720
def checkKeywordDefinition() =
725721
if (isRawIdent && scala3Keywords.contains(in.name))
@@ -1149,7 +1145,6 @@ self =>
11491145
val scala3Wildcard = isScala3WildcardType
11501146
wildcardType(in.skipToken(), scala3Wildcard)
11511147
} else {
1152-
checkQMarkUsage()
11531148
path(thisOK = false, typeOK = true) match {
11541149
case r @ SingletonTypeTree(_) => r
11551150
case r => convertToTypeId(r)
@@ -2075,7 +2070,6 @@ self =>
20752070
if (in.token == SUBTYPE || in.token == SUPERTYPE) wildcardType(start, scala3Wildcard)
20762071
else atPos(start) { Bind(tpnme.WILDCARD, EmptyTree) }
20772072
} else {
2078-
checkQMarkUsage()
20792073
typ() match {
20802074
case Ident(name: TypeName) if nme.isVariableName(name) =>
20812075
atPos(start) { Bind(name, EmptyTree) }

test/files/neg/qmark-deprecated.check

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ qmark-deprecated.scala:4: error: using `?` as a type name requires backticks.
22
class Foo[?] // error
33
^
44
qmark-deprecated.scala:6: error: using `?` as a type name requires backticks.
5-
class Bar[M[?] <: List[?]] // errors
5+
class Bar[M[?] <: List[?]] // error on the definition
66
^
77
qmark-deprecated.scala:10: error: using `?` as a type name requires backticks.
88
class ? { val x = 1 } // error
@@ -22,20 +22,4 @@ qmark-deprecated.scala:35: error: using `?` as a type name requires backticks.
2222
qmark-deprecated.scala:38: error: using `?` as a type name requires backticks.
2323
type A[?] = Int // error
2424
^
25-
qmark-deprecated.scala:6: warning: Wrap `?` in backticks to continue to use it as an identifier, or use `-Xsource:3` to use it as a wildcard like in Scala 3.
26-
class Bar[M[?] <: List[?]] // errors
27-
^
28-
qmark-deprecated.scala:27: warning: Wrap `?` in backticks to continue to use it as an identifier, or use `-Xsource:3` to use it as a wildcard like in Scala 3.
29-
val x: Array[?] = new Array[?](0) // errors
30-
^
31-
qmark-deprecated.scala:27: warning: Wrap `?` in backticks to continue to use it as an identifier, or use `-Xsource:3` to use it as a wildcard like in Scala 3.
32-
val x: Array[?] = new Array[?](0) // errors
33-
^
34-
qmark-deprecated.scala:30: warning: Wrap `?` in backticks to continue to use it as an identifier, or use `-Xsource:3` to use it as a wildcard like in Scala 3.
35-
def foo1[T <: Array[?]](x: T): Array[?] = x // errors
36-
^
37-
qmark-deprecated.scala:30: warning: Wrap `?` in backticks to continue to use it as an identifier, or use `-Xsource:3` to use it as a wildcard like in Scala 3.
38-
def foo1[T <: Array[?]](x: T): Array[?] = x // errors
39-
^
40-
5 warnings
4125
8 errors

test/files/neg/qmark-deprecated.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
class Foo[?] // error
55
class Foo2[`?`] // ok
6-
class Bar[M[?] <: List[?]] // errors
6+
class Bar[M[?] <: List[?]] // error on the definition
77
class Bar2[M[`?`] <: List[`?`]] // ok
88

99
object G {
@@ -24,10 +24,10 @@ object I {
2424
object I2 {
2525
type `?` = Int // ok
2626

27-
val x: Array[?] = new Array[?](0) // errors
27+
val x: Array[?] = new Array[?](0) // no error reported here because we stop before running typer
2828
val y: Array[`?`] = new Array[`?`](0) // ok
2929

30-
def foo1[T <: Array[?]](x: T): Array[?] = x // errors
30+
def foo1[T <: Array[?]](x: T): Array[?] = x // ok
3131
def foo2[T <: Array[`?`]](x: T): Array[`?`] = x // ok
3232

3333
def bar1[?] = {} // error

test/files/pos/wildcards-future.scala renamed to test/files/pos/wildcards-present.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// scalac: -Xsource:3
2-
//
31
object Test {
42
val xs: List[?] = List(1, 2, 3)
53
val ys: Map[? <: AnyRef, ? >: Null] = Map()

0 commit comments

Comments
 (0)