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

Accept and ignore using in method signature (to aid cross-building with Scala 3) #10075

Merged
merged 1 commit into from Jul 18, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions spec/06-expressions.md
Expand Up @@ -240,6 +240,7 @@ depending on whether `B` is mixed in with class `Root` or `A`.
```ebnf
SimpleExpr ::= SimpleExpr1 ArgumentExprs
ArgumentExprs ::= ‘(’ [Exprs] ‘)’
| ‘(’ ‘using’ Exprs ‘)’
| ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’
| [nl] BlockExpr
Exprs ::= Expr {‘,’ Expr}
Expand Down Expand Up @@ -323,6 +324,9 @@ sum(List(1, 2, 3, 4))

would not typecheck.

An argument list may begin with the soft keyword `using` to facilitate cross-compilation with Scala 3.
The keyword is ignored.

### Named and Default Arguments

If an application is to use named arguments $p = e$ or default
Expand Down
15 changes: 11 additions & 4 deletions src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Expand Up @@ -1831,7 +1831,8 @@ self =>
}

/** {{{
* ArgumentExprs ::= `(' [Exprs] `)'
* ArgumentExprs ::= `(` [Exprs] `)`
* | `(` `using` Exprs `)`
* | [nl] BlockExpr
* }}}
*/
Expand All @@ -1840,9 +1841,15 @@ self =>
if (isIdent) treeInfo.assignmentToMaybeNamedArg(expr()) else expr()
)
in.token match {
case LBRACE => List(blockExpr())
case LPAREN => inParens(if (in.token == RPAREN) Nil else args())
case _ => Nil
case LBRACE => List(blockExpr())
case LPAREN => inParens {
in.token match {
case RPAREN => Nil
case IDENTIFIER if in.name == nme.using && lookingAhead(isExprIntro) => in.nextToken() ; args()
case _ => args()
}
}
case _ => Nil
}
}
/** A succession of argument lists. */
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
Expand Up @@ -141,6 +141,7 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett
val require = MultiStringSetting ("-Xplugin-require", "plugin", "Abort if a named plugin is not loaded.")
val pluginsDir = StringSetting ("-Xpluginsdir", "path", "Path to search for plugin archives.", Defaults.scalaPluginPath)
val Xprint = PhasesSetting ("-Xprint", "Print out program after")
.withAbbreviation ("-Vprint")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏

val Xprintpos = BooleanSetting ("-Xprint-pos", "Print tree positions, as offsets.")
val printtypes = BooleanSetting ("-Xprint-types", "Print tree types (debugging option).")
val printArgs = StringSetting ("-Xprint-args", "file", "Print all compiler arguments to the specified location. Use - to echo to the reporter.", "-")
Expand All @@ -151,6 +152,7 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett
val Xshowcls = StringSetting ("-Xshow-class", "class", "Show internal representation of class.", "")
val Xshowobj = StringSetting ("-Xshow-object", "object", "Show internal representation of object.", "")
val showPhases = BooleanSetting ("-Xshow-phases", "Print a synopsis of compiler phases.")
.withAbbreviation ("-Vphases")
val sourceReader = StringSetting ("-Xsource-reader", "classname", "Specify a custom method for reading source files.", "")
val reporter = StringSetting ("-Xreporter", "classname", "Specify a custom subclass of FilteringReporter for compiler messages.", "scala.tools.nsc.reporters.ConsoleReporter")
val strictInference = BooleanSetting ("-Xstrict-inference", "Don't infer known-unsound types")
Expand Down
1 change: 1 addition & 0 deletions src/compiler/scala/tools/nsc/settings/Warnings.scala
Expand Up @@ -23,6 +23,7 @@ trait Warnings {

// Warning semantics.
val fatalWarnings = BooleanSetting("-Xfatal-warnings", "Fail the compilation if there are any warnings.")
.withAbbreviation("-Werror")

private val WconfDefault = List("cat=deprecation:ws", "cat=feature:ws", "cat=optimizer:ws")
// Note: user-defined settings are added on the right, but the value is reversed before
Expand Down
1 change: 1 addition & 0 deletions src/reflect/scala/reflect/internal/StdNames.scala
Expand Up @@ -639,6 +639,7 @@ trait StdNames {
// Scala 3 soft keywords
val infix: NameType = "infix"
val open: NameType = "open"
val using: NameType = "using"

// Scala 3 hard keywords
val `given`: NameType = "given"
Expand Down
7 changes: 7 additions & 0 deletions test/files/neg/i15552.check
@@ -0,0 +1,7 @@
i15552.scala:4: error: not found: value g
def f() = g(42)(using ctx) // error: no g
^
i15552.scala:22: error: not found: value using
def f() = g(using) // error: no using, does not actually suggest Using
^
two errors found
40 changes: 40 additions & 0 deletions test/files/neg/i15552.scala
@@ -0,0 +1,40 @@
// scalac: -Werror
class C {
val ctx: C = new C()
def f() = g(42)(using ctx) // error: no g
}

class Innocent {
val using = 42
def g(i: Int) = i
def f() = g(using)
}

class Malicious {
val using = 42
def g(i: Int) = i
def f() = g(using using)
}

class Suggest {
import scala.util._
def g(i: Int) = i
def f() = g(using) // error: no using, does not actually suggest Using
}

class Fancy {
def g(i: Int) = i
def f() = g(using if (true) 42 else 17)
}

/*
was:

i15552.scala:4: error: not found: value g
def f() = g(42)(using ctx)
^
i15552.scala:4: error: not found: value using
def f() = g(42)(using ctx)
^
i15552.scala:4: error: postfix operator ctx needs to be enabled
*/