Skip to content

Commit 99548bd

Browse files
authored
Merge pull request #9949 from dotty-staging/change-given-wildcard-import
Change wildcard given selectors
2 parents 63dd4f9 + f48b816 commit 99548bd

File tree

20 files changed

+51
-41
lines changed

20 files changed

+51
-41
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3094,16 +3094,18 @@ object Parsers {
30943094
/** ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpec
30953095
* ImportSpec ::= id
30963096
* | ‘_’
3097+
* | ‘given’
30973098
* | ‘{’ ImportSelectors) ‘}’
30983099
*/
30993100
def importExpr(mkTree: ImportConstr): () => Tree = {
31003101

31013102
/** '_' */
31023103
def wildcardSelectorId() = atSpan(in.skipToken()) { Ident(nme.WILDCARD) }
3104+
def givenSelectorId(start: Offset) = atSpan(start) { Ident(nme.EMPTY) }
31033105

31043106
/** ImportSelectors ::= id [‘=>’ id | ‘=>’ ‘_’] [‘,’ ImportSelectors]
31053107
* | WildCardSelector {‘,’ WildCardSelector}
3106-
* WildCardSelector ::= ‘given’ (‘_' | InfixType)
3108+
* WildCardSelector ::= ‘given’ [InfixType]
31073109
* | ‘_'
31083110
*/
31093111
def importSelectors(idOK: Boolean): List[ImportSelector] =
@@ -3114,12 +3116,13 @@ object Parsers {
31143116
ImportSelector(wildcardSelectorId())
31153117
case GIVEN =>
31163118
val start = in.skipToken()
3117-
def givenSelector() = atSpan(start) { Ident(nme.EMPTY) }
31183119
if in.token == USCORE then
31193120
in.nextToken()
3120-
ImportSelector(givenSelector()) // Let the selector span all of `given _`; needed for -Ytest-pickler
3121+
ImportSelector(givenSelectorId(start)) // Let the selector span all of `given _`; needed for -Ytest-pickler
3122+
else if canStartTypeTokens.contains(in.token) then
3123+
ImportSelector(givenSelectorId(start), bound = rejectWildcardType(infixType()))
31213124
else
3122-
ImportSelector(givenSelector(), bound = infixType())
3125+
ImportSelector(givenSelectorId(start))
31233126
case _ =>
31243127
val from = termIdent()
31253128
if !idOK then syntaxError(i"named imports cannot follow wildcard imports")
@@ -3143,6 +3146,8 @@ object Parsers {
31433146
in.token match
31443147
case USCORE =>
31453148
mkTree(qual, ImportSelector(wildcardSelectorId()) :: Nil)
3149+
case GIVEN =>
3150+
mkTree(qual, ImportSelector(givenSelectorId(in.skipToken())) :: Nil)
31463151
case LBRACE =>
31473152
mkTree(qual, inBraces(importSelectors(idOK = true)))
31483153
case _ =>

compiler/src/dotty/tools/dotc/parsing/Tokens.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ object Tokens extends TokensCommon {
261261
final val canStartStatTokens3: TokenSet = canStartExprTokens3 | mustStartStatTokens | BitSet(
262262
AT, CASE)
263263

264-
final val canEndStatTokens: TokenSet = atomicExprTokens | BitSet(TYPE, RPAREN, RBRACE, RBRACKET, OUTDENT)
264+
final val canEndStatTokens: TokenSet = atomicExprTokens | BitSet(TYPE, GIVEN, RPAREN, RBRACE, RBRACKET, OUTDENT)
265265

266266
/** Tokens that stop a lookahead scan search for a `<-`, `then`, or `do`.
267267
* Used for disambiguating between old and new syntax.

docs/docs/internals/syntax.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,10 +348,11 @@ Import ::= ‘import’ ImportExpr {‘,’ ImportExpr}
348348
ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpec Import(expr, sels)
349349
ImportSpec ::= id
350350
| ‘_’
351+
| ‘given’
351352
| ‘{’ ImportSelectors) ‘}’
352353
ImportSelectors ::= id [‘=>’ id | ‘=>’ ‘_’] [‘,’ ImportSelectors]
353354
| WildCardSelector {‘,’ WildCardSelector}
354-
WildCardSelector ::= ‘given’ (‘_' | InfixType)
355+
WildCardSelector ::= ‘given’ [InfixType]
355356
| ‘_'
356357
Export ::= ‘export’ [‘given’] ImportExpr {‘,’ ImportExpr}
357358

docs/docs/reference/contextual/given-imports.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,22 @@ object A {
1414

1515
object B {
1616
import A._
17-
import A.{given _}
17+
import A.given
1818
}
1919
```
2020

2121
In the code above, the `import A._` clause of object `B` will import all members
22-
of `A` _except_ the given instance `tc`. Conversely, the second import `import A.{given _}` will import _only_ that given instance.
22+
of `A` _except_ the given instance `tc`. Conversely, the second import `import A.given` will import _only_ that given instance.
2323
The two import clauses can also be merged into one:
2424

2525
```scala
2626
object B {
27-
import A.{given _, _}
27+
import A.{given, _}
2828
}
2929
```
3030

3131
Generally, a normal wildcard selector `_` brings all definitions other than givens or extensions into scope
32-
whereas a `given _` selector brings all givens (including those resulting from extensions) into scope.
32+
whereas a `given` selector brings all givens (including those resulting from extensions) into scope.
3333

3434
There are two main benefits arising from these rules:
3535

@@ -106,13 +106,13 @@ normal imports to givens and given imports.
106106
The following modifications avoid this hurdle to migration.
107107

108108
1. A `given` import selector also brings old style implicits into scope. So, in Scala 3.0
109-
an old-style implicit definition can be brought into scope either by a `_` or a `given _` wildcard selector.
109+
an old-style implicit definition can be brought into scope either by a `_` or a `given` wildcard selector.
110110

111111
2. In Scala 3.1, old-style implicits accessed through a `_` wildcard import will give a deprecation warning.
112112

113113
3. In some version after 3.1, old-style implicits accessed through a `_` wildcard import will give a compiler error.
114114

115-
These rules mean that library users can use `given _` selectors to access old-style implicits in Scala 3.0,
115+
These rules mean that library users can use `given` selectors to access old-style implicits in Scala 3.0,
116116
and will be gently nudged and then forced to do so in later versions. Libraries can then switch to
117117
given instances once their user base has migrated.
118118

@@ -123,10 +123,11 @@ Import ::= ‘import’ ImportExpr {‘,’ ImportExpr}
123123
ImportExpr ::= StableId ‘.’ ImportSpec
124124
ImportSpec ::= id
125125
| ‘_’
126+
| ‘given’
126127
| ‘{’ ImportSelectors) ‘}’
127128
ImportSelectors ::= id [‘=>’ id | ‘=>’ ‘_’] [‘,’ ImportSelectors]
128129
| WildCardSelector {‘,’ WildCardSelector}
129130
WildCardSelector ::= ‘_'
130-
| ‘given’ (‘_' | InfixType)
131+
| ‘given’ [InfixType]
131132
Export ::= ‘export’ ImportExpr {‘,’ ImportExpr}
132133
```

tests/disabled/pos-macros/i7853/SummonJsonEncoderTest_2.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import scala.deriving._
22
import scala.quoted._
3-
import JsonEncoder.{given _, _}
3+
import JsonEncoder.{given, _}
44

55
object SummonJsonEncoderTest {
66

tests/neg-custom-args/impl-conv/B.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package implConv
22

33
object B {
4-
import A.{_, given _}
4+
import A.{_, given}
55

66
"".foo
77

tests/neg-custom-args/implicit-conversions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ object D {
2121
}
2222

2323
object Test {
24-
import D.{given _}
24+
import D.given
2525

2626
val x1: A = new B // error under -Xfatal-warnings -feature
2727
val x2: B = new A // error under -Xfatal-warnings -feature

tests/neg-macros/i7048e.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ abstract class Test {
1313

1414
{
1515
val t: Test = this
16-
import t.{given _}
16+
import t.given
1717
println(summon[Type[t.T]].show)
1818
// val r = '{Option.empty[t.T]} // access to value t from wrong staging level
1919
val r2 = '{Option.empty[${t.T}]} // works

tests/neg/import-implied.scala renamed to tests/neg/import-given.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@ object C {
1616
foo(using tc) // ok
1717
}
1818
object D {
19-
import A.{foo, given _}
19+
import A.{foo, given}
2020
foo // ok
2121
foo(using tc) // ok
2222
}
2323
object E {
24-
import A.{_, given _}
24+
import A.{_, given}
2525
foo // ok
2626
foo(using tc) // ok
2727
}
28+
object F:
29+
import A.{given ?} // error: unbound wildcard type
30+

tests/pos-macros/i7011/Macros_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import scala.quoted._
33
inline def mcr(body: => Any): Unit = ${mcrImpl('body)}
44

55
def mcrImpl[T](body: Expr[Any])(using ctx: QuoteContext) : Expr[Any] = {
6-
import ctx.tasty.{_, given _}
6+
import ctx.tasty.{_, given}
77

88
val bTree = body.unseal
99
val under = bTree.underlyingArgument

0 commit comments

Comments
 (0)