Skip to content

Commit f9f7f56

Browse files
committed
Spec: Syntax of imports.
This already includes `given` imports, although the rest of contextual abstractions are not there yet.
1 parent d6e9bb0 commit f9f7f56

File tree

4 files changed

+82
-55
lines changed

4 files changed

+82
-55
lines changed

docs/_spec/02-identifiers-names-and-scopes.md

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,11 @@ The compiler supplies imports in a preamble to every source file.
7474
This preamble conceptually has the following form, where braces indicate nested scopes:
7575

7676
```scala
77-
import java.lang._
77+
import java.lang.*
7878
{
79-
import scala._
79+
import scala.*
8080
{
81-
import Predef._
81+
import Predef.*
8282
{ /* source */ }
8383
}
8484
}
@@ -95,8 +95,8 @@ This allows redundant type aliases to be imported without introducing an ambigui
9595
object X { type T = annotation.tailrec }
9696
object Y { type T = annotation.tailrec }
9797
object Z {
98-
import X._, Y._, annotation.{tailrec => T} // OK, all T mean tailrec
99-
@T def f: Int = { f ; 42 } // error, f is not tail recursive
98+
import X.*, Y.*, annotation.tailrec as T // OK, all T mean tailrec
99+
@T def f: Int = { f ; 42 } // error, f is not tail recursive
100100
}
101101
```
102102

@@ -107,7 +107,7 @@ Similarly, imported aliases of names introduced by package statements are allowe
107107
package p { class C }
108108

109109
// xy.scala
110-
import p._
110+
import p.*
111111
package p { class X extends C }
112112
package q { class Y extends C }
113113
```
@@ -132,27 +132,32 @@ package q {
132132
The following program illustrates different kinds of bindings and precedences between them.
133133

134134
```scala
135-
package p { // `X' bound by package clause
136-
import Console._ // `println' bound by wildcard import
137-
object Y {
138-
println(s"L4: $X") // `X' refers to `p.X' here
139-
locally {
140-
import q._ // `X' bound by wildcard import
141-
println(s"L7: $X") // `X' refers to `q.X' here
142-
import X._ // `x' and `y' bound by wildcard import
143-
println(s"L9: $x") // `x' refers to `q.X.x' here
135+
package p { // `X' bound by package clause
136+
import Console.* // `println' bound by wildcard import
137+
object Y {
138+
println(s"L4: $X") // `X' refers to `p.X' here
144139
locally {
145-
val x = 3 // `x' bound by local definition
146-
println(s"L12: $x") // `x' refers to constant `3' here
140+
import q.* // `X' bound by wildcard import
141+
println(s"L7: $X") // `X' refers to `q.X' here
142+
import X.* // `x' and `y' bound by wildcard import
143+
println(s"L9: $x") // `x' refers to `q.X.x' here
147144
locally {
148-
import q.X._ // `x' and `y' bound by wildcard import
149-
// println(s"L15: $x") // reference to `x' is ambiguous here
150-
import X.y // `y' bound by explicit import
151-
println(s"L17: $y") // `y' refers to `q.X.y' here
145+
val x = 3 // `x' bound by local definition
146+
println(s"L12: $x") // `x' refers to constant `3' here
152147
locally {
153-
val x = "abc" // `x' bound by local definition
154-
import p.X._ // `x' and `y' bound by wildcard import
155-
// println(s"L21: $y") // reference to `y' is ambiguous here
156-
println(s"L22: $x") // `x' refers to string "abc" here
157-
}}}}}}
148+
import q.X.* // `x' and `y' bound by wildcard import
149+
// println(s"L15: $x") // reference to `x' is ambiguous here
150+
import X.y // `y' bound by explicit import
151+
println(s"L17: $y") // `y' refers to `q.X.y' here
152+
locally {
153+
val x = "abc" // `x' bound by local definition
154+
import p.X.* // `x' and `y' bound by wildcard import
155+
// println(s"L21: $y") // reference to `y' is ambiguous here
156+
println(s"L22: $x") // `x' refers to string "abc" here
157+
}
158+
}
159+
}
160+
}
161+
}
162+
}
158163
```

docs/_spec/04-basic-declarations-and-definitions.md

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ type ´t´ >: Nothing
248248
type ´t´ >:\mathit{tps'}\,´] =>> ´L´
249249
<:\mathit{tps'}\,´] =>> ´U´
250250
```
251-
251+
252252
If at least one of the ´\mathit{tps}´ contains an explicit variance annotation, then ´\mathit{tps'} = \mathit{tps}´, otherwise we infer the variance of each type parameter as with the user-written type lambda `[´\mathit{tps}\,´] =>> ´U´`.
253253

254254
The same desugaring applies to type parameters. For instance,
@@ -695,64 +695,86 @@ completely. It is an error if the types of two alternatives ´T_i´ and
695695

696696
## Import Clauses
697697

698-
```ebnf
699-
Import ::= ‘import’ ImportExpr {‘,’ ImportExpr}
700-
ImportExpr ::= StableId ‘.’ (id | ‘_’ | ImportSelectors)
701-
ImportSelectors ::= ‘{’ {ImportSelector ‘,’}
702-
(ImportSelector | ‘_’) ‘}’
703-
ImportSelector ::= id [‘=>’ id |=>’ ‘_’]
704698
```
699+
Import ::= ‘import’ ImportExpr {‘,’ ImportExpr}
700+
ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpecifier
701+
| SimpleRef `as` id
702+
ImportSpecifier ::= NamedSelector
703+
| WildcardSelector
704+
| ‘{’ ImportSelectors ‘}’
705+
NamedSelector ::= id [(‘as’ |=>’) (id | ‘_’)]
706+
WildcardSelector ::=*| ’_’ |given’ [InfixType]
707+
ImportSelectors ::= NamedSelector [‘,’ ImportSelectors]
708+
| WildCardSelector {‘,’ WildcardSelector}
709+
```
710+
711+
- In a `NamedSelector`, `=>` can only be used when inside an `ImportSelectors` and is then equivalent to `as`, to be deprecated in the future.
712+
- In a `WildcardSelector`, `_` is equivalent to `*`, to be deprecated in the future.
713+
714+
An `ImportSpecifier` that is a single `NamedSelector` or `WildcardSelector` is equivalent to an `‘{‘ ImportSelectors ‘}‘` list with that single selector.
715+
716+
An import clause with multiple import expressions `import ´p_1´.´I_1, ..., p_n´.´I_n´` is interpreted as a sequence of import clauses `import ´p_1´.´I_1´; ...; import ´p_n´.´I_n´`.
705717

706-
An import clause has the form `import ´p´.´I´` where ´p´ is a [stable identifier](03-types.html#paths) and ´I´ is an import expression.
707-
The import expression determines a set of names of importable members of ´p´ which are made available without qualification.
718+
An import clause with a single import expression has the form `import ´p´.´I´` where ´p´ is a [prefix](03-types.html#designator-types) and ´I´ is an import specifier.
719+
The import specifier determines a set of names of importable members of ´p´ which are made available without qualification as well as a set of importable `given` members which are made available in the implicit scope.
708720
A member ´m´ of ´p´ is _importable_ if it is [accessible](05-classes-and-objects.html#modifiers).
709-
The most general form of an import expression is a list of _import selectors_
721+
The most general form of an import specifier is a list of _import selectors_
710722

711723
```scala
712-
{ ´x_1´ => ´y_1, ..., x_n´ => ´y_n´, _ }
724+
{ ´x_1´ as ´y_1, ..., x_n´ as ´y_n´, *, given ´T_1´, ..., given ´T_m´, given }
713725
```
714726

715-
for ´n \geq 0´, where the final wildcard `‘_’` may be absent.
716-
It makes available each importable member `´p´.´x_i´` under the unqualified name ´y_i´. I.e. every import selector `´x_i´ => ´y_i´` renames `´p´.´x_i´` to
717-
´y_i´.
718-
If a final wildcard is present, all importable members ´z´ of ´p´ other than `´x_1, ..., x_n,y_1, ..., y_n´` are also made available under their own unqualified names.
727+
for ´n \geq 0´ and ´m \geq 0´, where the wildcards `‘*’` and `’given’` may be absent.
728+
They are decomposed into non-given selectors and given selectors.
719729

720-
Import selectors work in the same way for type and term members.
721-
For instance, an import clause `import ´p´.{´x´ => ´y\,´}` renames the term
722-
name `´p´.´x´` to the term name ´y´ and the type name `´p´.´x´` to the type name ´y´.
730+
### Non-given Imports
731+
732+
Non-given selectors make available each importable member `´p´.´x_i´` under the unqualified name ´y_i´.
733+
In other words, every import selector `´x_i´ as ´y_i´` renames `´p´.´x_i´` to ´y_i´.
734+
When `as ´y_i´` is omitted, ´y_i´ is assumed to be ´x_i´.
735+
If a final wildcard `‘*’` is present, all non-`given` importable members ´z´ of ´p´ other than `´x_1, ..., x_n, y_1, ..., y_n´` are also made available under their own unqualified names.
736+
737+
Non-given import selectors work in the same way for type and term members.
738+
For instance, an import clause `import ´p´.{´x´ => ´y´}` renames the term name `´p´.´x´` to the term name ´y´ and the type name `´p´.´x´` to the type name ´y´.
723739
At least one of these two names must reference an importable member of ´p´.
724740

725-
If the target in an import selector is a wildcard, the import selector hides access to the source member.
726-
For instance, the import selector `´x´ => _`renames” ´x´ to the wildcard symbol (which is unaccessible as a name in user programs), and thereby effectively prevents unqualified access to ´x´.
741+
If the target in an import selector is an underscore `as _`, the import selector hides access to the source member instead of importing it.
742+
For instance, the import selector `´x´ as _`renames” ´x´ to the underscore symbol (which is not accessible as a name in user programs), and thereby effectively prevents unqualified access to ´x´.
727743
This is useful if there is a final wildcard in the same import selector list, which imports all members not mentioned in previous import selectors.
728744

729-
The scope of a binding introduced by an import-clause starts immediately after the import clause and extends to the end of the enclosing block, template, package clause, or compilation unit, whichever comes first.
745+
The scope of a binding introduced by a non-given import clause starts immediately after the import clause and extends to the end of the enclosing block, template, package clause, or compilation unit, whichever comes first.
730746

731-
Several shorthands exist. An import selector may be just a simple name ´x´.
732-
In this case, ´x´ is imported without renaming, so the import selector is equivalent to `´x´ => ´x´`.
733-
Furthermore, it is possible to replace the whole import selector list by a single identifier or wildcard.
734-
The import clause `import ´p´.´x´` is equivalent to `import ´p´.{´x\,´}`, i.e. it makes available without qualification the member ´x´ of ´p´. The import clause `import ´p´._` is equivalent to `import ´p´.{_}`, i.e. it makes available without qualification all members of ´p´ (this is analogous to `import ´p´.*` in Java).
747+
### Given Imports
735748

736-
An import clause with multiple import expressions `import ´p_1´.´I_1, ..., p_n´.´I_n´` is interpreted as a sequence of import clauses `import ´p_1´.´I_1´; ...; import ´p_n´.´I_n´`.
749+
Given selectors make available in the implicit scope all the importable `given` and `implicit` members `´p´.´x´` such that `´p.x´` is a subtype of ´T_i´.
750+
A bare `given` selector without type is equivalent to `given scala.Any`.
751+
752+
The names of the given members are irrelevant for the selection, and are not made available in the normal scope of unqualified names.
737753

738754
###### Example
739755
Consider the object definition:
740756

741757
```scala
742758
object M {
743-
def z = 0, one = 1
759+
def z = 0
760+
def one = 1
744761
def add(x: Int, y: Int): Int = x + y
745762
}
746763
```
747764

748765
Then the block
749766

750767
```scala
751-
{ import M.{one, z => zero, _}; add(zero, one) }
768+
{
769+
import M.{one, z as zero, *}
770+
add(zero, one)
771+
}
752772
```
753773

754774
is equivalent to the block
755775

756776
```scala
757-
{ M.add(M.z, M.one) }
777+
{
778+
M.add(M.z, M.one)
779+
}
758780
```

0 commit comments

Comments
 (0)