Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse +_ and -_ in types as identifiers under -Xsource:3 to support Scala 3.2 placeholder syntax #9605

Merged
merged 4 commits into from May 10, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Expand Up @@ -1140,7 +1140,13 @@ self =>
else
atPos(start)(makeSafeTupleType(inParens(types())))
case _ =>
if (isWildcardType)
if ((in.name == raw.PLUS || in.name == raw.MINUS) && lookingAhead(in.token == USCORE)) {
val start = in.offset
val identName = in.name.encode.append("_").toTypeName
in.nextToken()
in.nextToken()
atPos(start)(Ident(identName))
} else if (isWildcardType)
wildcardType(in.skipToken())
else
path(thisOK = false, typeOK = true) match {
Expand Down
7 changes: 7 additions & 0 deletions test/files/neg/variant-placeholders-future.check
@@ -0,0 +1,7 @@
variant-placeholders-future.scala:2: error: `=`, `>:`, or `<:` expected
type -_ = Int // error -_ not allowed as a type def name without backticks
^
variant-placeholders-future.scala:3: error: `=`, `>:`, or `<:` expected
type +_ = Int // error +_ not allowed as a type def name without backticks
^
2 errors
4 changes: 4 additions & 0 deletions test/files/neg/variant-placeholders-future.scala
@@ -0,0 +1,4 @@
object Test {
type -_ = Int // error -_ not allowed as a type def name without backticks
type +_ = Int // error +_ not allowed as a type def name without backticks
}
33 changes: 33 additions & 0 deletions test/files/pos/variant-placeholders-future.scala
@@ -0,0 +1,33 @@
object Test {
type `-_` = Int
type `+_` = Long

val fnMinusPlus1: -_ => +_ = (_: Int).toLong
val fnMinusPlus2: (-_) => +_ = fnMinusPlus1
val fnMinusPlus3: -_ => (+_) = fnMinusPlus2

val fnTupMinusPlus2: (=> -_, -_) => +_ = (a, b) => ((a: Int) + (b: Int)).toLong
def defMinusPlus2(byname: => -_, vararg: -_*): +_ = ((vararg.sum: Int) + (byname: -_)).toLong
val infixMinusPlus2: -_ Either +_ = Right[-_, +_](1L)

val optPlus: Option[+_] = Some[ + _ ](1L) // spaces allowed
optPlus match {
case opt: Option[ + _ ] =>
val opt1: + _ = opt.get
val opt2: Long = opt1
}

val optMinus: Option[-_] = Some[ - _ ](1) // spaces allowed
optMinus match {
case opt: Option[ - _ ] =>
val opt1: `-_` = opt.get
val optErr: - _ = opt.get
val opt2: Int = opt1
}

locally {
type `-_`[A] = A
type `+_`[A] = Option[A]
val optOpt: Option[ + _ [+_[-_[Int]]]] = Some(Some(Some(1)))
}
}