-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Mention named givens in double def explainer #23833
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 |
---|---|---|
@@ -0,0 +1,45 @@ | ||
-- [E120] Naming Error: tests/neg/i23832a.scala:9:8 -------------------------------------------------------------------- | ||
9 | given Special[Option[Int]] = ??? // error | ||
| ^ | ||
| Conflicting definitions: | ||
| final lazy given val given_Special_Option: Special[Option[Long]] in object syntax at line 8 and | ||
| final lazy given val given_Special_Option: Special[Option[Int]] in object syntax at line 9 | ||
|--------------------------------------------------------------------------------------------------------------------- | ||
| Explanation (enabled by `-explain`) | ||
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
| | ||
| As part of the Scala compilation pipeline every type is reduced to its erased | ||
| (runtime) form. In this phase, among other transformations, generic parameters | ||
| disappear and separate parameter-list boundaries are flattened. | ||
| | ||
| For example, both `f[T](x: T)(y: String): Unit` and `f(x: Any, z: String): Unit` | ||
| erase to the same runtime signature `f(x: Object, y: String): Unit`. Note that | ||
| parameter names are irrelevant. | ||
| | ||
| In your code the two declarations | ||
| | ||
| final lazy given val given_Special_Option: Special[Option[Long]] | ||
| final lazy given val given_Special_Option: Special[Option[Int]] | ||
| | ||
| erase to the identical signature | ||
| | ||
| Special | ||
| | ||
| so the compiler cannot keep both: the generated bytecode symbols would collide. | ||
| | ||
| To fix this error, you must disambiguate the two definitions by doing one of the following: | ||
| | ||
| 1. Rename one of the definitions. Provide an explicit, unique name to given definitions, | ||
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. maybe 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. All these errors fail at the first pair that is noticed; and "already defined" in particular works with just minimal info; it does not try to enumerate all problematic definitions and their types. The spec will sometimes say "pairwise distinct", and the user only needs to fix one pair at a time. |
||
| since the names assigned to anonymous givens may clash. For example: | ||
| | ||
| given myGiven: Special[Option[Int]] | ||
| | ||
| 2. Keep the same names in source but give one definition a distinct | ||
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. and |
||
| bytecode-level name via `@targetName`; for example: | ||
| | ||
| @targetName("given_Special_Option_2") | ||
| final lazy given val given_Special_Option: Special[Option[Int]] | ||
| | ||
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. there is 3rd option on how to name them, specifically in for-comprehension (it could shadow previous one): for {
// ...
givenName @ given Type <- ???
// ... 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. @mr-git that is a different error ID, though a similar explainer about "how to name givens" may be warranted (since it is not obvious); presumably it is obvious how to rename other things? 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. Will you create a ticket and PR for that? I struggled with this case the most. 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. @mr-git I added some explain text on the other PR. There is no pattern syntax for given here because there is no equivalent to |
||
| Choose the `@targetName` argument carefully: it is the name that will be used | ||
| when calling the method externally, so it should be unique and descriptive. | ||
--------------------------------------------------------------------------------------------------------------------- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
//> using options -explain | ||
|
||
// follow-up to neg/i23402*.scala | ||
|
||
trait Special[A] | ||
|
||
object syntax: | ||
given Special[Option[Long]] = ??? | ||
given Special[Option[Int]] = ??? // error |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
-- [E120] Naming Error: tests/neg/i23832b.scala:9:8 -------------------------------------------------------------------- | ||
9 | given [A] => Special[Option[A]] = ??? // error | ||
| ^ | ||
| Conflicting definitions: | ||
| final lazy given val given_Special_Option: Special[Option[Long]] in object syntax at line 8 and | ||
| final given def given_Special_Option[A]: Special[Option[A]] in object syntax at line 9 | ||
|--------------------------------------------------------------------------------------------------------------------- | ||
| Explanation (enabled by `-explain`) | ||
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
| | ||
| As part of the Scala compilation pipeline every type is reduced to its erased | ||
| (runtime) form. In this phase, among other transformations, generic parameters | ||
| disappear and separate parameter-list boundaries are flattened. | ||
| | ||
| For example, both `f[T](x: T)(y: String): Unit` and `f(x: Any, z: String): Unit` | ||
| erase to the same runtime signature `f(x: Object, y: String): Unit`. Note that | ||
| parameter names are irrelevant. | ||
| | ||
| In your code the two declarations | ||
| | ||
| final lazy given val given_Special_Option: Special[Option[Long]] | ||
| final given def given_Special_Option[A]: Special[Option[A]] | ||
| | ||
| erase to the identical signature | ||
| | ||
| (): Special | ||
| | ||
| so the compiler cannot keep both: the generated bytecode symbols would collide. | ||
| | ||
| To fix this error, you must disambiguate the two definitions by doing one of the following: | ||
| | ||
| 1. Rename one of the definitions. Provide an explicit, unique name to given definitions, | ||
| since the names assigned to anonymous givens may clash. For example: | ||
| | ||
| given myGiven: [A] => Special[Option[A]] | ||
| | ||
| 2. Keep the same names in source but give one definition a distinct | ||
| bytecode-level name via `@targetName`; for example: | ||
| | ||
| @targetName("given_Special_Option_2") | ||
| final given def given_Special_Option[A]: Special[Option[A]] | ||
| | ||
| Choose the `@targetName` argument carefully: it is the name that will be used | ||
| when calling the method externally, so it should be unique and descriptive. | ||
--------------------------------------------------------------------------------------------------------------------- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
//> using options -explain | ||
|
||
// follow-up to neg/i23402*.scala | ||
|
||
trait Special[A] | ||
|
||
object syntax: | ||
given Special[Option[Long]] = ??? | ||
given [A] => Special[Option[A]] = ??? // error |
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.
shouldn't it be something like:
which leads to 2 identical signatures:
given_Special_Option
?When Developer names the
val
s, it is very obvious which names the Developer gives them - problems usually start with non-obvious auto-naming.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.
The declarations are not printed with "fidelity". That could be fixed as a follow-up. (I assume but did not check that the syntax changed faster than the printer.)