-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fix #10857: export from wildcard defs with same name as user declared ones #10949
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,7 +47,6 @@ An export clause has the same format as an import clause. Its general form is: | |
|
||
```scala | ||
export path . { sel_1, ..., sel_n } | ||
export given path . { sel_1, ..., sel_n } | ||
``` | ||
|
||
It consists of a qualifier expression `path`, which must be a stable identifier, followed by | ||
|
@@ -58,7 +57,8 @@ of one of the following forms: | |
- A _renaming selector_ `x => y` creates aliases for all eligible members of `path` that are named `x`, but the alias is named `y` instead of `x`. | ||
- An _omitting selector_ `x => _` prevents `x` from being aliased by a subsequent | ||
wildcard selector. | ||
- A _wildcard selector_ creates aliases for all eligible members of `path` except for | ||
- A _given selector_ `given x` has an optional type bound `x`. It creates aliases for all eligible given instances that conform to either `x`, or `Any` if `x` is omitted, except for members that are named by a previous simple, renaming, or omitting selector. | ||
- A _wildcard selector_ `_` creates aliases for all eligible members of `path` except for given instances, | ||
synthetic members generated by the compiler and those members that are named by a previous simple, renaming, or omitting selector. | ||
|
||
A member is _eligible_ if all of the following holds: | ||
|
@@ -68,8 +68,7 @@ A member is _eligible_ if all of the following holds: | |
a base class of the class containing the export clause. | ||
- it is accessible at the export clause, | ||
- it is not a constructor, nor the (synthetic) class part of an object, | ||
- it is a given instance (or an old-style `implicit` value) | ||
if and only if the export is tagged with `given`. | ||
- it is a given instance (declared with `given`) if and only if the export is from a _given selector_. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this change comes from observation that implicit forwarders are only generated from wildcard selectors and not given selectors |
||
|
||
It is a compile-time error if a simple or renaming selector does not identify any eligible | ||
members. | ||
|
@@ -95,6 +94,8 @@ def f: c.T = ... | |
<a id="note_class"></a> | ||
Export clauses can appear in classes or they can appear at the top-level. An export clause cannot appear as a statement in a block. | ||
|
||
If an export clause contains a wildcard or given selector, it is forbidden for its qualifier path to refer to a package. This is because it is not yet known how to safely track wildcard dependencies to a package for the purposes of incremental compilation. | ||
|
||
(\*) **Note:** Unless otherwise stated, the term "class" in this discussion also includes object and trait definitions. | ||
|
||
## Motivation | ||
|
@@ -111,11 +112,21 @@ more flexible way. | |
## Syntax changes: | ||
|
||
``` | ||
TemplateStat ::= ... | ||
| Export | ||
TopStat ::= ... | ||
| Export | ||
Export ::= ‘export’ [‘given’] ImportExpr {‘,’ ImportExpr} | ||
TemplateStat ::= ... | ||
| Export | ||
TopStat ::= ... | ||
| Export | ||
Import ::= ‘import’ ImportExpr {‘,’ ImportExpr} | ||
ImportExpr ::= StableId ‘.’ ImportSpec | ||
ImportSpec ::= id | ||
| ‘_’ | ||
| ‘given’ | ||
| ‘{’ ImportSelectors) ‘}’ | ||
ImportSelectors ::= id [‘=>’ id | ‘=>’ ‘_’] [‘,’ ImportSelectors] | ||
| WildCardSelector {‘,’ WildCardSelector} | ||
WildCardSelector ::= ‘_' | ||
| ‘given’ [InfixType] | ||
Export ::= ‘export’ ImportExpr {‘,’ ImportExpr} | ||
``` | ||
|
||
## Elaboration of Export Clauses | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
object Module: | ||
|
||
class Bar | ||
class Baz | ||
class Qux | ||
|
||
object Givens: | ||
given GivenBar: Bar = new Bar() | ||
def GivenBar(ignored: Int): Bar = new Bar() | ||
class GivenBar | ||
|
||
object Members: | ||
given Member: Baz = new Baz() | ||
private def Member(ignored1: String)(ignored2: Int): Bar = new Bar() | ||
def Member(ignored: Int): Baz = new Baz() | ||
class Member | ||
|
||
object Combined: | ||
given GivenQux: Qux = new Qux() | ||
def GivenQux(ignored: Int): Qux = new Qux() | ||
|
||
enum Color: | ||
case Red, Green, Blue | ||
|
||
export Color._ // will only export synthetic defs with same name as standard definition | ||
export Givens.given // should only export given values | ||
export Members._ // should only export values that are not given | ||
export Combined.{_, given} // should only export values that are not given | ||
|
||
@main def Test = | ||
|
||
println(Module.Red) | ||
println(Module.valueOf("Red")) // error: value valueOf is not a member | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. e.g. here |
||
|
||
println(summon[Module.Bar]) | ||
println(new Module.GivenBar()) // error: type GivenBar is not a member | ||
println(Module.GivenBar(23)) // error: method GivenBar does not take parameters | ||
|
||
println(new Module.Member()) | ||
println(Module.Member(23)) | ||
println(Module.Member("?")(23)) // error: Found: ("?" : String) Required: Int | ||
println(summon[Module.Baz]) // error: no implicit argument of type Module.Baz was found | ||
|
||
println(summon[Module.Qux]) | ||
println(Module.GivenQux(23)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
object Module: | ||
|
||
enum Foo: | ||
case Value | ||
case Parameterised(i: Int) | ||
|
||
export Foo._ | ||
|
||
@main def Test = | ||
import Module.given | ||
println(Module.Parameterised.apply(23)) // synthetic companion object is exported | ||
println(Module.Value) |
Uh oh!
There was an error while loading. Please reload this page.