-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add migration helpers for named tuples #21681
Comments
Maybe suitable for the next Spree? |
This issue was picked for the Scala Issue Spree of tomorrow, Monday, October 21st. @nicolasstucki, @bracevac and I will be working on it. If you have any insight into the issue or guidance on how to fix it, please leave it here. |
Seems to me that the simplest would be to add a check in diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
index e1a6b97fc7..e32b5ac1ab 100644
--- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
@@ -1605,9 +1605,10 @@ object desugar {
/** Translate tuple expressions
*
- * () ==> ()
- * (t) ==> t
- * (t1, ..., tN) ==> TupleN(t1, ..., tN)
+ * () ==> ()
+ * (t) ==> t
+ * (t1, ..., tN) ==> TupleN(t1, ..., tN)
+ * (n1 = t1, ..., nN = tN) ==> NamedTuple.build[(n1, ..., nN)]()(TupleN(t1, ..., tN))
*/
def tuple(tree: Tuple, pt: Type)(using Context): Tree =
var elems = checkWellFormedTupleElems(tree.trees)
@@ -1638,6 +1639,7 @@ object desugar {
if ctx.mode.is(Mode.Type) then
AppliedTypeTree(ref(defn.NamedTupleTypeRef), namesTuple :: tup :: Nil)
else
+ checkNamedTuple(names, elemValues)
Apply(
Apply(
TypeApply(
@@ -1646,6 +1648,10 @@ object desugar {
Nil), // ++ ()
tup :: Nil) // .++ ((values...))
+ def checkNamedTuple(names: List[Name], values: List[Tree])(using Context): Unit =
+ println(i"checkNamedTuple($names, $values)") Would that make sense? Could we try alternative interpretations of the named tuple expression there? |
The approach I suggested above should work okay for the assignment case ( def checkNamedTuple(names: List[Name], values: List[Tree])(using Context): Unit =
println(i"checkNamedTuple($names, $values)")
if names.length == 1 && ctx.scope.lookup(names.head).is(Flags.Mutable) then
report.migrationWarning(
em"""`(${names.head} = ${values.head})` is interpreted as a named tuple containing a single element,
|not as an assignment. If you meant to write an assignment, use curly braces
|instead of parentheses: `{${names.head} = ${values.head}}`.""",
values.head.srcPos
) For the named argument case ( |
does this mean |
@ritschwumm |
For the record: I have experienced this issue when testing my project against 3.6.1 RC. There is a small part of the project using a DSL for constructing trees in unit tests. It took me a while to realize that this code is now interpreted as named tuples and that I need to use dot notation to avoid the issue:
|
Compiler version
3.6
Minimized example
From the SIP 58 proposal, which was recently accepted:
There are some source incompatibilities involving named tuples of length one.
First, what was previously classified as an assignment could now be interpreted as a named tuple. Example:
This was an assignment in parentheses before, and is a named tuple of arity one now. It is however not idiomatic Scala code, since assignments are not usually enclosed in parentheses.
Second, what was a named argument to an infix operator can now be interpreted as a named tuple.
then
will now construct a tuple as second operand instead of passing a named parameter.
Expectation
These problems can be detected and diagnosed fairly straightforwardly: When faced with a unary named tuple, try to interpret it as an assignment, and if that succeeds, issue a migration error and suggest a workaround of these kinds:
The text was updated successfully, but these errors were encountered: