Skip to content

Commit

Permalink
Allow import x.{*, given} under -Xsource:3
Browse files Browse the repository at this point in the history
Imagine a Scala 3 library containing:
```
object A {
  val a: Int = 1
  given b: Int = 2
}
```
To import all members of `A` from Scala 2, we write `import A.*`,
but to do the same from Scala 3, we need to write `import A.{*, given}`
instead. This complicates cross-compilation for projects which depend on
Scala 3 libraries (unless these libraries exclusively use `implicit`
which is not something we want to encourage).

This commit remedies this by allowing `import x.{*, given}` (and `import
x.{given, *}`), this is easy to do since we can just pretend the user
wrote `import x.*` which will give us both regular and given members in
Scala 2 code and therefore match the semantics of Scala 3.
  • Loading branch information
smarter committed Aug 24, 2021
1 parent 891e58b commit 3af1547
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 2 deletions.
11 changes: 10 additions & 1 deletion src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Expand Up @@ -2700,7 +2700,16 @@ self =>
* }}}
*/
def importSelectors(): List[ImportSelector] = {
val selectors = inBracesOrNil(commaSeparated(importSelector()))
val selectors0 = inBracesOrNil(commaSeparated(importSelector()))

// Treat an import of `*, given` or `given, *` as if it was an import of `*`
// since the former in Scala 3 has the same semantics as the latter in Scala 2.
val selectors =
if (currentRun.isScala3 && selectors0.exists(_.isWildcard))
selectors0.filterNot(sel => sel.name == nme.`given` && sel.rename == sel.name)
else
selectors0

for (t <- selectors.init if t.isWildcard) syntaxError(t.namePos, "Wildcard import must be in last position")
selectors
}
Expand Down
2 changes: 1 addition & 1 deletion test/files/pos/import-future.scala
Expand Up @@ -26,7 +26,7 @@ class C {

object starring {

import scala.concurrent.*, duration.{Duration as D, *}, ExecutionContext.Implicits.*
import scala.concurrent.{*, given}, duration.{given, Duration as D, *}, ExecutionContext.Implicits.*

val f = Future(42)
val r = Await.result(f, D.Inf)
Expand Down

0 comments on commit 3af1547

Please sign in to comment.