Skip to content

Commit

Permalink
Print warning for ()(implicit ...) prefix unary operators too
Browse files Browse the repository at this point in the history
  • Loading branch information
eed3si9n committed Jun 25, 2020
1 parent 12f1c41 commit 8cdf16e
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 15 deletions.
12 changes: 7 additions & 5 deletions src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2816,12 +2816,14 @@ self =>
expr()
}
if (nme.isEncodedUnary(name) && vparamss.nonEmpty) {
val tpeStr = if (restype.isEmpty) "" else s" : $restype"
def unaryMsg(what: String) = s"unary prefix operator definition with empty parameter list is $what: instead, remove () to declare as `def ${name.decodedName}$tpeStr`"
def instead = DefDef(newmods, name.toTermName.decodedName, tparams, vparamss.drop(1), restype, rhs)
def unaryMsg(what: String) = s"unary prefix operator definition with empty parameter list is $what: instead, remove () to declare as `$instead`"
def warnNilary(): Unit =
if (currentRun.isScala3) syntaxError(nameOffset, unaryMsg("unsupported"))
else deprecationWarning(nameOffset, unaryMsg("deprecated"), "2.13.4")
vparamss match {
case List(List()) =>
if (currentRun.isScala3) syntaxError(nameOffset, unaryMsg("unsupported"))
else deprecationWarning(nameOffset, unaryMsg("deprecated"), "2.13.4")
case List(List()) => warnNilary()
case List(List(), x :: xs) if x.mods.isImplicit => warnNilary()
case _ => // ok
}
}
Expand Down
14 changes: 9 additions & 5 deletions src/reflect/scala/reflect/internal/Printers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ trait Printers extends api.Printers { self: SymbolTable =>
def indent() = indentMargin += indentStep
def undent() = indentMargin -= indentStep

protected def checkForBlank(cond: Boolean) = if (cond) " " else ""
protected def blankForOperatorName(name: Name) = checkForBlank(name.isOperatorName)
protected def blankForName(name: Name) = checkForBlank(name.isOperatorName || name.endsWith("_"))

def printPosition(tree: Tree) =
if (printPositions) comment(print(tree.pos.show))

Expand Down Expand Up @@ -356,7 +360,11 @@ trait Printers extends api.Printers { self: SymbolTable =>
}

case dd @ DefDef(mods, name, tparams, vparamss, tp, rhs) =>
printDefDef(dd, symName(tree, name))(printOpt(": ", tp))(printOpt(" = ", rhs))
printDefDef(dd, symName(tree, name)) {
// place space after symbolic def name (def !: Unit does not compile)
if (tparams.isEmpty && vparamss.isEmpty) printOpt(blankForName(name.encodedName) + ": ", tp)
else printOpt(": ", tp)
} (printOpt(" = ", rhs))

case td @ TypeDef(mods, name, tparams, rhs) =>
printTypeDef(td, symName(tree, name))
Expand Down Expand Up @@ -593,10 +601,6 @@ trait Printers extends api.Printers { self: SymbolTable =>
}
}

protected def checkForBlank(cond: Boolean) = if (cond) " " else ""
protected def blankForOperatorName(name: Name) = checkForBlank(name.isOperatorName)
protected def blankForName(name: Name) = checkForBlank(name.isOperatorName || name.endsWith("_"))

protected def resolveSelect(t: Tree): String = {
t match {
// case for: 1) (if (a) b else c).meth1.meth2 or 2) 1 + 5 should be represented as (1).+(5)
Expand Down
9 changes: 6 additions & 3 deletions test/files/neg/prefix-unary-nilary-deprecation.check
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
prefix-unary-nilary-deprecation.scala:4: warning: unary prefix operator definition with empty parameter list is deprecated: instead, remove () to declare as `def unary_~ : Foo`
prefix-unary-nilary-deprecation.scala:4: warning: unary prefix operator definition with empty parameter list is deprecated: instead, remove () to declare as `def unary_~ : Foo = this`
def unary_~() : Foo = this
^
prefix-unary-nilary-deprecation.scala:10: warning: Auto-application to `()` is deprecated. Supply the empty argument list `()` explicitly to invoke method unary_~,
prefix-unary-nilary-deprecation.scala:5: warning: unary prefix operator definition with empty parameter list is deprecated: instead, remove () to declare as `def unary_-(implicit pos: Long) = this`
def unary_-()(implicit pos: Long) = this
^
prefix-unary-nilary-deprecation.scala:12: warning: Auto-application to `()` is deprecated. Supply the empty argument list `()` explicitly to invoke method unary_~,
or remove the empty argument list from its definition (Java-defined methods are exempt).
In Scala 3, an unapplied method like this will be eta-expanded into a function.
val f2 = ~f
^
error: No warnings can be incurred under -Werror.
2 warnings
3 warnings
1 error
2 changes: 2 additions & 0 deletions test/files/neg/prefix-unary-nilary-deprecation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
//
class Foo {
def unary_~() : Foo = this
def unary_-()(implicit pos: Long) = this

def unary_! : Foo = this // ok
def unary_+(implicit pos: Long) = this // ok
}
object Test {
val f = new Foo
Expand Down
7 changes: 5 additions & 2 deletions test/files/neg/prefix-unary-nilary-removal.check
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
prefix-unary-nilary-removal.scala:4: error: unary prefix operator definition with empty parameter list is unsupported: instead, remove () to declare as `def unary_~ : Foo`
prefix-unary-nilary-removal.scala:4: error: unary prefix operator definition with empty parameter list is unsupported: instead, remove () to declare as `def unary_~ : Foo = this`
def unary_~() : Foo = this
^
1 error
prefix-unary-nilary-removal.scala:5: error: unary prefix operator definition with empty parameter list is unsupported: instead, remove () to declare as `def unary_-(implicit pos: Long) = this`
def unary_-()(implicit pos: Long) = this
^
2 errors
2 changes: 2 additions & 0 deletions test/files/neg/prefix-unary-nilary-removal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
//
class Foo {
def unary_~() : Foo = this
def unary_-()(implicit pos: Long) = this

def unary_! : Foo = this // ok
def unary_+(implicit pos: Long) = this // ok
}
object Test {
val f = new Foo
Expand Down

0 comments on commit 8cdf16e

Please sign in to comment.