-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand value references to packages to their underlying package objects #22011
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
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
docs/_docs/reference/experimental/package-object-values.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--- | ||
layout: doc-page | ||
title: "Reference-able Package Objects" | ||
redirectFrom: /docs/reference/experimental/package-object-values.html | ||
nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/package-object-values.html | ||
--- | ||
|
||
One limitation with `package object`s is that we cannot currently assign them to values: `a.b` fails to compile when `b` is a `package object`, even though it succeeds when `b` is a normal `object`. The workaround is to call | ||
```scala | ||
a.b.`package` | ||
``` | ||
But this is ugly and non-obvious. Or one could use a normal `object`, which is not always possible. | ||
|
||
The `packageObjectValues` language extension drops this limitation. The extension is enabled by the language import `import scala.language.experimental.packageObjectValues` or by setting the command line option `-language:experimental.packageObjectValues`. | ||
|
||
The extension, turns the following into valid code: | ||
|
||
```scala | ||
package a | ||
package object b | ||
|
||
val z = a.b // Currently fails with "package is not a value" | ||
``` | ||
|
||
Currently the workaround is to use a `.package` suffix: | ||
|
||
```scala | ||
val z = a.b.`package` | ||
``` | ||
|
||
With the extension, a reference such as `a.b` where `b` is a `package` containing a `package object`, expands to `a.b.package` automatically | ||
|
||
## Limitations | ||
|
||
* `a.b` only expands to `a.b.package` when used "standalone", i.e. not when part of a larger select chain `a.b.c` or equivalent postfix expression `a.b c`, prefix expression `!a.b`, or infix expression `a.b c d`. | ||
|
||
* `a.b` expands to `a.b.package` of the type `a.b.package.type`, and only contains the contents of the `package object`. It does not contain other things in the `package` `a.b` that are outside of the `package object` | ||
|
||
Both these requirements are necessary for backwards compatibility, and anyway do not impact the main goal of removing the irregularity between `package object`s and normal `object`s. | ||
|
41 changes: 41 additions & 0 deletions
41
docs/_docs/reference/other-new-features/toplevel-definitions.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
--- | ||
layout: doc-page | ||
title: "Toplevel Definitions" | ||
nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/toplevel-definitions.html | ||
--- | ||
|
||
All kind of definitions can now be written at the top-level. | ||
Example: | ||
```scala | ||
package p | ||
type Labelled[T] = (String, T) | ||
val a: Labelled[Int] = ("count", 1) | ||
def b = a._2 | ||
|
||
case class C() | ||
|
||
extension (x: C) def pair(y: C) = (x, y) | ||
``` | ||
Previously, `type`, `val` or `def` definitions had to be wrapped in a package object. Now, | ||
there may be several source files in a package containing such top-level definitions, and source files can freely mix top-level value, method, and type definitions with classes and objects. | ||
|
||
The compiler generates synthetic objects that wrap top-level definitions falling into one of the following categories: | ||
|
||
- all pattern, value, method, and type definitions, | ||
- implicit classes and objects, | ||
- companion objects of opaque type aliases. | ||
|
||
If a source file `src.scala` contains such top-level definitions, they will be put in a synthetic object named `src$package`. The wrapping is transparent, however. The definitions in `src` can still be accessed as members of the enclosing package. The synthetic object will be placed last in the file, | ||
after any other package clauses, imports, or object and class definitions. | ||
|
||
**Note:** This means that | ||
1. The name of a source file containing wrapped top-level definitions is relevant for binary compatibility. If the name changes, so does the name of the generated object and its class. | ||
|
||
2. A top-level main method `def main(args: Array[String]): Unit = ...` is wrapped as any other method. If it appears | ||
in a source file `src.scala`, it could be invoked from the command line using a command like `scala src$package`. Since the | ||
"program name" is mangled it is recommended to always put `main` methods in explicitly named objects. | ||
|
||
3. The notion of `private` is independent of whether a definition is wrapped or not. A `private` top-level definition is always visible from everywhere in the enclosing package. | ||
|
||
4. If several top-level definitions are overloaded variants with the same name, | ||
they must all come from the same source file. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Foo was created | ||
Foo was created | ||
Foo was created | ||
Foo was created |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import language.experimental.packageObjectValues | ||
|
||
package a: | ||
package object b: | ||
class Foo: | ||
println("Foo was created") | ||
|
||
def foo() = Foo() | ||
end b | ||
|
||
def test = | ||
val bb = b | ||
bb.foo() | ||
new bb.Foo() | ||
end a | ||
|
||
@main def Test = | ||
a.test | ||
val ab: a.b.type = a.b | ||
ab.foo() | ||
new ab.Foo() | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This page will still show up in google search results, so eventually it will need to have a comment mentioning it's outdated pointing to the new doc.